Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend VatCode resource #138

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 92 additions & 5 deletions src/ApiConnectors/VatCodeApiConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,93 @@

namespace PhpTwinfield\ApiConnectors;

use PhpTwinfield\DomDocuments\VatCodesDocument;
use PhpTwinfield\Exception;
use PhpTwinfield\Mappers\VatCodeMapper;
use PhpTwinfield\Office;
use PhpTwinfield\Request as Request;
use PhpTwinfield\Response\MappedResponseCollection;
use PhpTwinfield\Response\Response;
use PhpTwinfield\Services\FinderService;
use PhpTwinfield\VatCode;
use Webmozart\Assert\Assert;

/**
* A facade to make interaction with the the Twinfield service easier when trying to retrieve or send information about
* VAT codes.
* VatCodes.
*
* If you require more complex interactions or a heavier amount of control over the requests to/from then look inside
* the methods or see the advanced guide detailing the required usages.
*
* @author Emile Bons <[email protected]>
* @author Yannick Aerssens <[email protected]>, based on ArticleMapper by Willem van de Sande <[email protected]>. Original method by Emile Bons <[email protected]>
*/
class VatCodeApiConnector extends BaseApiConnector
{
/**
* Requests a specific VatCode based off the passed in code and optionally the office.
*
* @param string $code
* @param Office $office If no office has been passed it will instead take the default office from the
* passed in config class.
* @return VatCode|bool The requested VAT code or false if it can't be found.
* @throws Exception
*/
public function get(string $code, Office $office): VatCode
{
// Make a request to read a single VatCode. Set the required values
$request_vatCode = new Request\Read\VatCode();
$request_vatCode
->setOffice($office->getCode())
->setCode($code);

// Send the Request document and set the response to this instance.
$response = $this->sendXmlDocument($request_vatCode);

return VatCodeMapper::map($response);
}

/**
* Sends a VatCode instance to Twinfield to update or add.
*
* @param VatCode $vatCode
* @return VatCode
* @throws Exception
*/
public function send(VatCode $vatCode): VatCode
{
foreach($this->sendAll([$vatCode]) as $each) {
return $each->unwrap();
}
}

/**
* @param VatCode[] $vatCodes
* @return MappedResponseCollection
* @throws Exception
*/
public function sendAll(array $vatCodes): MappedResponseCollection
{
Assert::allIsInstanceOf($vatCodes, VatCode::class);

/** @var Response[] $responses */
$responses = [];

foreach ($this->getProcessXmlService()->chunk($vatCodes) as $chunk) {

$vatCodesDocument = new VatCodesDocument();

foreach ($chunk as $vatCode) {
$vatCodesDocument->addVatCode($vatCode);
}

$responses[] = $this->sendXmlDocument($vatCodesDocument);
}

return $this->getProcessXmlService()->mapAll($responses, "vat", function(Response $response): VatCode {
return VatCodeMapper::map($response);
});
}

/**
* List all VAT codes.
*
Expand All @@ -38,17 +111,31 @@ public function listAll(
int $maxRows = 100,
array $options = []
): array {
$response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_CODES, $pattern, $field, $firstRow, $maxRows, $options);
$optionsArrayOfString = array('ArrayOfString' => array());

foreach ($options as $key => $value) {
$optionsArrayOfString['ArrayOfString'][] = array($key, $value);
}

$response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_CODES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString);

if ($response->data->TotalRows == 0) {
return [];
}

$vatCodes = [];

foreach ($response->data->Items->ArrayOfString as $vatCodeArray) {
$vatCode = new VatCode();
$vatCode->setCode($vatCodeArray->string[0]);
$vatCode->setName($vatCodeArray->string[1]);

if (isset($vatCodeArray->string[0])) {
$vatCode->setCode($vatCodeArray->string[0]);
$vatCode->setName($vatCodeArray->string[1]);
} else {
$vatCode->setCode($vatCodeArray[0]);
$vatCode->setName($vatCodeArray[1]);
}

$vatCodes[] = $vatCode;
}

Expand Down
164 changes: 164 additions & 0 deletions src/DomDocuments/VatCodesDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php

namespace PhpTwinfield\DomDocuments;

use PhpTwinfield\VatCode;

/**
* The Document Holder for making new XML VatCode. Is a child class
* of DOMDocument and makes the required DOM tree for the interaction in
* creating a new VatCode.
*
* @package PhpTwinfield
* @subpackage VatCode\DOM
* @author Yannick Aerssens <[email protected]>, based on ArticlesDocument by Willem van de Sande <[email protected]>
*/
class VatCodesDocument extends \DOMDocument
{
/**
* Holds the <vat> element
* that all additional elements should be a child of
* @var \DOMElement
*/
private $vatCodeElement;

/**
* Creates the <vat> element and adds it to the property
* vatCodeElement
*
* @access public
*/
public function __construct()
{
parent::__construct();

$this->vatCodeElement = $this->createElement('vat');
$this->appendChild($this->vatCodeElement);
}

/**
* Turns a passed VatCode class into the required markup for interacting
* with Twinfield.
*
* This method doesn't return anything, instead just adds the VatCode to
* this DOMDOcument instance for submission usage.
*
* @access public
* @param VatCode $vatCode
* @return void | [Adds to this instance]
*/
public function addVatCode(VatCode $vatCode)
{
$rootElement = $this->vatCodeElement;

$status = $vatCode->getStatus();

if (!empty($status)) {
$rootElement->setAttribute('status', $status);
}

// VatCode elements and their methods
$vatCodeTags = array(
'code' => 'getCode',
'name' => 'getName',
'shortname' => 'getShortName',
'type' => 'getType',
);

// Go through each VatCode element and use the assigned method
foreach ($vatCodeTags as $tag => $method) {
// Make text node for method value
$nodeValue = $vatCode->$method();
if (is_bool($nodeValue)) {
$nodeValue = ($nodeValue) ? 'true' : 'false';
}
$node = $this->createTextNode($nodeValue);

// Make the actual element and assign the node
$element = $this->createElement($tag);
$element->appendChild($node);

// Add the full element
$rootElement->appendChild($element);
}

$percentages = $vatCode->getPercentages();

if (!empty($percentages)) {
// Make percentages element
$percentagesElement = $this->createElement('percentages');
$this->vatCodeElement->appendChild($percentagesElement);

// Element tags and their methods for percentages
$percentageTags = [
'date' => 'getDate',
'name' => 'getName',
'percentage' => 'getPercentage',
'shortname' => 'getShortName',
];

// Go through each percentage assigned to the vatCode
foreach ($percentages as $percentage) {
// Makes new VatCodePercentage element
$percentageElement = $this->createElement('percentage');
$percentagesElement->appendChild($percentageElement);

// Go through each percentage element and use the assigned method
foreach ($percentageTags as $tag => $method) {
// Make the text node for the method value
$node = $this->createTextNode($percentage->$method());

// Make the actual element and assign the text node
$element = $this->createElement($tag);
$element->appendChild($node);

// Add the completed element
$percentageElement->appendChild($element);
}

$accounts = $percentage->getAccounts();

if (!empty($accounts)) {
// Make addresses element
$accountsElement = $this->createElement('accounts');
$percentageElement->appendChild($accountsElement);

// Element tags and their methods for accounts
$accountTags = [
'dim1' => 'getDim1',
'group' => 'getGroup',
'groupcountry' => 'getGroupCountry',
'linetype' => 'getLineType',
'percentage' => 'getPercentage',
];

// Go through each account assigned to the percentage
foreach ($accounts as $account) {
// Makes new VatCodeAccount element
$accountElement = $this->createElement('account');
$accountsElement->appendChild($accountElement);

$id = $account->getID();

if (!empty($id)) {
$accountElement->setAttribute('id', $id);
}

// Go through each account element and use the assigned method
foreach ($accountTags as $tag => $method) {
// Make the text node for the method value
$node = $this->createTextNode($account->$method());

// Make the actual element and assign the text node
$element = $this->createElement($tag);
$element->appendChild($node);

// Add the completed element
$accountElement->appendChild($element);
}
}
}
}
}
}
}
Loading