diff --git a/src/Account.php b/src/Account.php new file mode 100644 index 00000000..d7ee5f1c --- /dev/null +++ b/src/Account.php @@ -0,0 +1,83 @@ +id; + } + + public function setId($id): self + { + $this->id = $id; + return $this; + } + + public function getDim1(): string + { + return $this->dim1; + } + + public function setDim1(string $dim1): self + { + $this->dim1 = $dim1; + return $this; + } + + public function getGroupCountry(): string + { + return $this->groupCountry; + } + + public function setGroupCountry(string $groupCountry): self + { + $this->groupCountry = $groupCountry; + return $this; + } + + public function getGroup(): string + { + return $this->group; + } + + public function setGroup(string $group): self + { + $this->group = $group; + return $this; + } + + public function getPercentage(): float + { + return $this->percentage; + } + + public function setPercentage(float $percentage): self + { + $this->percentage = $percentage; + return $this; + } + + public function getLineType(): LineType + { + return $this->lineType; + } + + public function setLineType(LineType $lineType): self + { + $this->lineType = $lineType; + return $this; + } +} diff --git a/src/ApiConnectors/VatCodeApiConnector.php b/src/ApiConnectors/VatCodeApiConnector.php index 17b69251..a4619414 100644 --- a/src/ApiConnectors/VatCodeApiConnector.php +++ b/src/ApiConnectors/VatCodeApiConnector.php @@ -2,7 +2,10 @@ namespace PhpTwinfield\ApiConnectors; +use PhpTwinfield\Mappers\VatMapper; +use PhpTwinfield\Office; use PhpTwinfield\Services\FinderService; +use PhpTwinfield\VatCodeDetail; use PhpTwinfield\VatCode; /** @@ -54,4 +57,14 @@ public function listAll( return $vatCodes; } + + public function get(string $code, Office $office): VatCodeDetail + { + $response = $this->sendXmlDocument(new \PhpTwinfield\Request\Read\VatCode( + $office, + $code, + )); + + return VatMapper::map($response); + } } diff --git a/src/Mappers/VatMapper.php b/src/Mappers/VatMapper.php new file mode 100644 index 00000000..34e5f4fb --- /dev/null +++ b/src/Mappers/VatMapper.php @@ -0,0 +1,85 @@ +getResponseDocument(); + + // Set the status attribute + $vatElement = $responseDOM->getElementsByTagName('vat')->item(0); + $vatCodeDetail->setStatus($vatElement->getAttribute('status')); + + // Vat elements and their methods + $vatTags = [ + 'code' => 'setCode', + 'name' => 'setName', + 'shortname' => 'setShortName', + 'uid' => 'setUID', + 'created' => 'setCreatedFromString', + 'modified' => 'setModifiedFromString', + 'touched' => 'setTouched', + 'type' => 'setType', + 'user' => 'setUser', + ]; + + // Loop through all the tags + foreach ($vatTags as $tag => $method) { + self::setFromTagValue($responseDOM, $tag, [$vatCodeDetail, $method]); + } + + $xpath = new \DOMXPath($responseDOM); + $percentages = []; + foreach ($xpath->query('/vat/percentages/percentage', $vatElement) as $percentageNode) { + $percentages[] = $percentage = new VatCodePercentage(); + + $percentage + ->setStatus($percentageNode->getAttribute('status')) + ->setInUse($percentageNode->getAttribute('inuse') === 'true') + ->setDateFromString(self::getField($percentageNode, 'date')) + ->setPercentage((float) self::getField($percentageNode, 'percentage')) + ->setCreatedFromString(self::getField($percentageNode, 'created')) + ->setName(self::getField($percentageNode, 'name')) + ->setShortname(self::getField($percentageNode, 'shortname')) + ->setUser(self::getField($percentageNode, 'user')); + + $accounts = []; + foreach ($xpath->query('accounts/account', $percentageNode) as $accountNode) { + $accounts[] = $account = new Account(); + + $account + ->setId($accountNode->getAttribute('id')) + ->setDim1(self::getField($accountNode, 'dim1')) + ->setGroupCountry(self::getField($accountNode, 'groupcountry')) + ->setGroup(self::getField($accountNode, 'group')) + ->setPercentage((float) self::getField($accountNode, 'percentage')) + ->setLineType(new LineType(self::getField($accountNode, 'linetype'))); + } + + $percentage->setAccounts($accounts); + } + $vatCodeDetail->setPercentages($percentages); + + return $vatCodeDetail; + } +} diff --git a/src/Request/Read/VatCode.php b/src/Request/Read/VatCode.php new file mode 100644 index 00000000..5478e310 --- /dev/null +++ b/src/Request/Read/VatCode.php @@ -0,0 +1,18 @@ +add('type', 'vat'); + + $this->add('office', $office); + $this->add('code', $code); + } +} diff --git a/src/VatCodeDetail.php b/src/VatCodeDetail.php new file mode 100644 index 00000000..0c260843 --- /dev/null +++ b/src/VatCodeDetail.php @@ -0,0 +1,151 @@ +status; + } + + public function setStatus(string $status): self + { + $this->status = $status; + return $this; + } + + public function getCode(): string + { + return $this->code; + } + + public function setCode(string $code): self + { + $this->code = $code; + return $this; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + return $this; + } + + public function getShortName(): string + { + return $this->shortName; + } + + public function setShortName(string $shortName): self + { + $this->shortName = $shortName; + return $this; + } + + public function getUID(): string + { + return $this->uid; + } + + public function setUID(string $uid): self + { + $this->uid = $uid; + return $this; + } + + public function getCreated(): \DateTimeInterface + { + return $this->created; + } + + public function setCreatedFromString(string $dateStr): self + { + $this->created = Util::parseDateTime($dateStr); + return $this; + } + + public function getModified(): \DateTimeInterface + { + return $this->created; + } + + public function setModifiedFromString(string $dateStr): self + { + $this->modified = Util::parseDateTime($dateStr); + return $this; + } + + public function getTouched(): int + { + return $this->touched; + } + + public function setTouched(int $touched): self + { + $this->touched = $touched; + return $this; + } + + public function getType(): string + { + return $this->type; + } + + public function setType(string $type): self + { + $this->type = $type; + return $this; + } + + public function getUser(): string + { + return $this->user; + } + + public function setUser(string $user): self + { + $this->user = $user; + return $this; + } + + /** + * @return VatCodePercentage[] + */ + public function getPercentages(): array + { + return $this->percentages; + } + + public function setPercentages(array $percentages): self + { + Assert::allIsInstanceOf($percentages, VatCodePercentage::class); + + $this->percentages = $percentages; + return $this; + } +} diff --git a/src/VatCodePercentage.php b/src/VatCodePercentage.php new file mode 100644 index 00000000..8a55b0d0 --- /dev/null +++ b/src/VatCodePercentage.php @@ -0,0 +1,124 @@ +status; + } + + public function setStatus($status): self + { + $this->status = $status; + return $this; + } + + public function isInUse(): bool + { + return $this->inUse; + } + + public function setInUse(bool $inUse): self + { + $this->inUse = $inUse; + return $this; + } + + public function getDate(): \DateTimeInterface + { + return $this->date; + } + + public function setDateFromString(string $dateStr): self + { + $this->date = Util::parseDate($dateStr); + return $this; + } + + public function getPercentage(): float + { + return $this->percentage; + } + + public function setPercentage(float $percentage): self + { + $this->percentage = $percentage; + return $this; + } + + public function getCreated(): \DateTimeInterface + { + return $this->created; + } + + public function setCreatedFromString(string $dateTimeStr): self + { + $this->created = Util::parseDateTime($dateTimeStr); + return $this; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + return $this; + } + + public function getShortname(): string + { + return $this->shortname; + } + + public function setShortname(string $shortname): self + { + $this->shortname = $shortname; + return $this; + } + + public function getUser(): string + { + return $this->user; + } + + public function setUser(string $user): self + { + $this->user = $user; + return $this; + } + + /** + * @return Account[] + */ + public function getAccounts(): array + { + return $this->accounts; + } + + public function setAccounts(array $accounts): self + { + Assert::allIsInstanceOf($accounts, Account::class); + + $this->accounts = $accounts; + return $this; + } +} diff --git a/tests/IntegrationTests/VatCodeIntegrationTest.php b/tests/IntegrationTests/VatCodeIntegrationTest.php new file mode 100644 index 00000000..56a14eb3 --- /dev/null +++ b/tests/IntegrationTests/VatCodeIntegrationTest.php @@ -0,0 +1,88 @@ +vatCodeApiConnector = new VatCodeApiConnector($this->connection); + } + + public function testGetVatCodeDetailWorks() + { + $response = Response::fromString( + file_get_contents(__DIR__ . '/resources/vatCodeGetResponse.xml') + ); + + $this->processXmlService + ->expects($this->once()) + ->method("sendDocument") + ->with($this->isInstanceOf(\PhpTwinfield\Request\Read\VatCode::class)) + ->willReturn($response); + + $vatCode = $this->vatCodeApiConnector->get('VH', $this->office); + + $this->assertSame('VH', $vatCode->getCode()); + $this->assertSame('BTW Hoog', $vatCode->getName()); + $this->assertSame('VH', $vatCode->getShortName()); + $this->assertSame('8b16d247-81de-4334-8810-8dcb30386f42', $vatCode->getUID()); + $this->assertEquals(new \DateTimeImmutable('2004-10-27 10:13:42'), $vatCode->getCreated()); + $this->assertEquals(new \DateTimeImmutable('2004-10-27 10:13:42'), $vatCode->getModified()); + $this->assertSame(0, $vatCode->getTouched()); + $this->assertSame('JDOE', $vatCode->getUser()); + $this->assertCount(2, $vatCode->getPercentages()); + + [$percentage1, $percentage2] = $vatCode->getPercentages(); + + $this->assertSame('active', $percentage1->getStatus()); + $this->assertTrue($percentage1->isInUse()); + $this->assertEquals(new \DateTimeImmutable('2000-01-01'), $percentage1->getDate()); + $this->assertSame(19.0, $percentage1->getPercentage()); + $this->assertEquals(new \DateTimeImmutable('2013-10-02 11:40:36'), $percentage1->getCreated()); + $this->assertSame('BTW Hoog', $percentage1->getName()); + $this->assertSame('VH', $percentage1->getShortname()); + $this->assertSame('JDOE', $percentage1->getUser()); + $this->assertCount(1, $percentage1->getAccounts()); + + [$account] = $percentage1->getAccounts(); + $this->assertSame('1', $account->getId()); + $this->assertSame('17120', $account->getDim1()); + $this->assertSame('NL', $account->getGroupCountry()); + $this->assertSame('NL1A', $account->getGroup()); + $this->assertSame(100.0, $account->getPercentage()); + $this->assertEquals(LineType::VAT(), $account->getLineType()); + + $this->assertSame('active', $percentage2->getStatus()); + $this->assertTrue($percentage2->isInUse()); + $this->assertEquals(new \DateTimeImmutable('2012-10-01'), $percentage2->getDate()); + $this->assertSame(21.0, $percentage2->getPercentage()); + $this->assertEquals(new \DateTimeImmutable('2013-10-02 11:40:36'), $percentage2->getCreated()); + $this->assertSame('BTW Hoog', $percentage2->getName()); + $this->assertSame('VH', $percentage2->getShortname()); + $this->assertSame('JDOE', $percentage2->getUser()); + $this->assertCount(1, $percentage2->getAccounts()); + + [$account] = $percentage2->getAccounts(); + $this->assertSame('1', $account->getId()); + $this->assertSame('17120', $account->getDim1()); + $this->assertSame('NL', $account->getGroupCountry()); + $this->assertSame('NL1A', $account->getGroup()); + $this->assertSame(100.0, $account->getPercentage()); + $this->assertEquals(LineType::VAT(), $account->getLineType()); + } +} diff --git a/tests/IntegrationTests/resources/vatCodeGetResponse.xml b/tests/IntegrationTests/resources/vatCodeGetResponse.xml new file mode 100644 index 00000000..0f2d2a89 --- /dev/null +++ b/tests/IntegrationTests/resources/vatCodeGetResponse.xml @@ -0,0 +1,52 @@ + + + VH + BTW Hoog + VH + 8b16d247-81de-4334-8810-8dcb30386f42 + 20041027101342 + 20041027101342 + 0 + JDOE + sales + + + 20000101 + 19.000000000 + 20131002114036 + BTW Hoog + VH + JDOE + + + + + 17120 + NL + NL1A + 100.0 + vat + + + + + 20121001 + 21.000000000 + 20131002114036 + BTW Hoog + VH + JDOE + + + + + 17120 + NL + NL1A + 100.0 + vat + + + + +