From 75078de048d4604aab997339cf03a16313e5cc0e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 28 Oct 2024 15:47:57 +1100 Subject: [PATCH] Updates for transforming PEPPOL => storecove --- .../Gateway/Storecove/Models/Invoice.php | 206 +++++++++------ .../Gateway/Storecove/Models/InvoiceLines.php | 7 - .../Storecove/PeppolToStorecoveNormalizer.php | 244 ------------------ .../Transformers/StorecoveTransformer.php | 123 +++++++++ .../Transformers/TransformerInterface.php | 22 ++ .../Einvoice/Storecove/StorecoveTest.php | 119 +++------ 6 files changed, 317 insertions(+), 404 deletions(-) delete mode 100644 app/Services/EDocument/Gateway/Storecove/PeppolToStorecoveNormalizer.php create mode 100644 app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php create mode 100644 app/Services/EDocument/Gateway/Transformers/TransformerInterface.php diff --git a/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php b/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php index b0485b69f4..78eadac357 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php @@ -1,67 +1,57 @@ invoiceNumber = $invoiceNumber; } - public function setIssueDate(DateTime $issueDate): void + public function setIssueDate($issueDate): void { $this->issueDate = $issueDate; } - public function setTaxPointDate(?DateTime $taxPointDate): void + public function setTaxPointDate($taxPointDate): void { $this->taxPointDate = $taxPointDate; } - public function setDueDate(DateTime $dueDate): void + public function setDueDate($dueDate): void { $this->dueDate = $dueDate; } - public function setInvoicePeriod(array $invoicePeriod): void + public function setInvoicePeriod($invoicePeriod): void { $this->invoicePeriod = $invoicePeriod; } - public function setReferences(array $references): void + public function setReferences( $references): void { $this->references = $references; } - public function setAccountingCost(?string $accountingCost): void + public function setAccountingCost($accountingCost): void { $this->accountingCost = $accountingCost; } - public function setNote(string $note): void + public function setNote($note): void { $this->note = $note; } - public function setAmountIncludingVat(float $amountIncludingVat): void + public function setAmountIncludingVat ($amountIncludingVat): void { $this->amountIncludingVat = $amountIncludingVat; } - public function setPrepaidAmount(?float $prepaidAmount): void + public function setPrepaidAmount( $prepaidAmount): void { $this->prepaidAmount = $prepaidAmount; } - public function setAccountingSupplierParty(array $accountingSupplierParty): void + public function setAccountingSupplierParty( $accountingSupplierParty): void { $this->accountingSupplierParty = $accountingSupplierParty; } - public function setAccountingCustomerParty(array $accountingCustomerParty): void + public function setAccountingCustomerParty( $accountingCustomerParty): void { $this->accountingCustomerParty = $accountingCustomerParty; } - public function setPaymentMeans(array $paymentMeans): void + public function setPaymentMeans( $paymentMeans): void { $this->paymentMeans = $paymentMeans; } - public function setTaxTotal(array $taxTotal): void + public function setTaxTotal( $taxTotal): void { $this->taxTotal = $taxTotal; } - /** - * @param InvoiceLines[] $invoiceLines - */ public function setInvoiceLines(array $invoiceLines): void { $this->invoiceLines = $invoiceLines; } - public function jsonSerialize(): mixed + public function getInvoiceLines() { - return [ - 'taxSystem' => $this->taxSystem, - 'documentCurrency' => $this->documentCurrency, - 'invoiceNumber' => $this->invoiceNumber, - 'issueDate' => $this->issueDate->format('Y-m-d'), - 'taxPointDate' => $this->taxPointDate ? $this->taxPointDate->format('Y-m-d') : null, - 'dueDate' => $this->dueDate->format('Y-m-d'), - 'invoicePeriod' => $this->invoicePeriod, - 'references' => $this->references, - 'accountingCost' => $this->accountingCost, - 'note' => $this->note, - 'amountIncludingVat' => $this->amountIncludingVat, - 'prepaidAmount' => $this->prepaidAmount, - 'accountingSupplierParty' => $this->accountingSupplierParty, - 'accountingCustomerParty' => $this->accountingCustomerParty, - 'paymentMeans' => $this->paymentMeans, - 'taxTotal' => $this->taxTotal, - 'invoiceLines' => $this->invoiceLines, - ]; + return $this->invoiceLines; + } + + public function getTaxSystem(): string + { + return $this->taxSystem; + } + + public function getDocumentCurrency(): string + { + return $this->documentCurrency; + } + + public function getInvoiceNumber(): string + { + return $this->invoiceNumber; + } + + public function getIssueDate(): string + { + return $this->issueDate; + } + + public function getTaxPointDate(): string + { + return $this->taxPointDate; + } + + public function getDueDate(): string + { + return $this->dueDate; + } + + public function getInvoicePeriod(): string + { + return $this->invoicePeriod; + } + + public function getReferences(): array + { + return $this->references; + } + + public function getAccountingCost(): ?string + { + return $this->accountingCost; + } + + public function getNote(): string + { + return $this->note; + } + + public function getAmountIncludingVat(): float + { + return $this->amountIncludingVat; + } + + public function getPrepaidAmount(): ?float + { + return $this->prepaidAmount; + } + + public function getAccountingSupplierParty(): array + { + return $this->accountingSupplierParty; + } + + public function getAccountingCustomerParty(): array + { + return $this->accountingCustomerParty; + } + + public function getPaymentMeans(): array + { + return $this->paymentMeans; + } + + public function getTaxTotal(): array + { + return $this->taxTotal; + } + + public function setTaxSystem(string $taxSystem): void + { + $this->taxSystem = $taxSystem; } } diff --git a/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php b/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php index 34dd1e1e06..9b949e7563 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php @@ -7,25 +7,18 @@ use Symfony\Component\Serializer\Annotation\SerializedName; class InvoiceLines { - #[SerializedName('ID.value')] public string $lineId = ''; - #[SerializedName('LineExtensionAmount.amount')] public float $amountExcludingVat = 0.0; - #[SerializedName('Price.PriceAmount.amount')] public float $itemPrice = 0.0; - #[SerializedName('InvoicedQuantity')] public int $quantity = 0; - #[SerializedName('InvoicedQuantity.unitCode')] public string $quantityUnitCode = ''; - #[SerializedName('Item.Name')] public string $name = ''; - #[SerializedName('Item.Description')] public string $description = ''; public Tax $tax; diff --git a/app/Services/EDocument/Gateway/Storecove/PeppolToStorecoveNormalizer.php b/app/Services/EDocument/Gateway/Storecove/PeppolToStorecoveNormalizer.php deleted file mode 100644 index 2490e89f2b..0000000000 --- a/app/Services/EDocument/Gateway/Storecove/PeppolToStorecoveNormalizer.php +++ /dev/null @@ -1,244 +0,0 @@ -serializer = $serializer; - -$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); -$metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory); -$this->objectNormalizer = new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter); - -} - - public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed -{ - $peppolInvoice = $data; - $storecoveInvoice = new StorecoveInvoice(); - - - $storecoveInvoice->setDocumentCurrency($peppolInvoice->DocumentCurrencyCode ?? ''); - $storecoveInvoice->setInvoiceNumber($peppolInvoice->ID ?? ''); - $storecoveInvoice->setIssueDate($peppolInvoice->IssueDate); - $storecoveInvoice->setDueDate($peppolInvoice->DueDate); - $storecoveInvoice->setNote($peppolInvoice->Note ?? ''); - $storecoveInvoice->setAmountIncludingVat((float)($peppolInvoice->LegalMonetaryTotal->TaxInclusiveAmount->amount ?? 0)); - - if (isset($peppolInvoice->InvoicePeriod[0])) { - $storecoveInvoice->setInvoicePeriod([ - 'startDate' => $peppolInvoice->InvoicePeriod[0]->StartDate, - 'endDate' => $peppolInvoice->InvoicePeriod[0]->EndDate, - ]); - } - - $storecoveInvoice->setReferences([ - 'buyerReference' => $peppolInvoice->BuyerReference ?? '', - 'orderReference' => $peppolInvoice->OrderReference->ID->value ?? '', - ]); - - if (isset($peppolInvoice->AccountingSupplierParty->Party)) { - $supplier = $peppolInvoice->AccountingSupplierParty->Party; - $storecoveInvoice->setAccountingSupplierParty([ - 'name' => $supplier->PartyName[0]->Name ?? '', - 'vatNumber' => $supplier->PartyIdentification[0]->ID->value ?? '', - 'streetName' => $supplier->PostalAddress->StreetName ?? '', - 'cityName' => $supplier->PostalAddress->CityName ?? '', - 'postalZone' => $supplier->PostalAddress->PostalZone ?? '', - 'countryCode' => $supplier->PostalAddress->Country->IdentificationCode->value ?? '', - ]); - } - - if (isset($peppolInvoice->AccountingCustomerParty->Party)) { - $customer = $peppolInvoice->AccountingCustomerParty->Party; - $storecoveInvoice->setAccountingCustomerParty([ - 'name' => $customer->PartyName[0]->Name ?? '', - 'vatNumber' => $customer->PartyIdentification[0]->ID->value ?? '', - 'streetName' => $customer->PostalAddress->StreetName ?? '', - 'cityName' => $customer->PostalAddress->CityName ?? '', - 'postalZone' => $customer->PostalAddress->PostalZone ?? '', - 'countryCode' => $customer->PostalAddress->Country->IdentificationCode->value ?? '', - ]); - } - - if (isset($peppolInvoice->PaymentMeans[0])) { - $storecoveInvoice->setPaymentMeans([ - 'paymentID' => $peppolInvoice->PaymentMeans[0]->PayeeFinancialAccount->ID->value ?? '', - ]); - } - - // Map tax total at invoice level - $taxTotal = []; - if (isset($peppolInvoice->InvoiceLine[0]->TaxTotal[0])) { - $taxTotal[] = [ - 'taxAmount' => (float)($peppolInvoice->InvoiceLine[0]->TaxTotal[0]->TaxAmount->amount ?? 0), - 'taxCurrency' => $peppolInvoice->DocumentCurrencyCode ?? '', - ]; - } - $storecoveInvoice->setTaxTotal($taxTotal); - - if (isset($peppolInvoice->InvoiceLine)) { - $invoiceLines = []; - foreach ($peppolInvoice->InvoiceLine as $line) { - $invoiceLine = new InvoiceLines(); - $invoiceLine->setLineId($line->ID->value ?? ''); - $invoiceLine->setAmountExcludingVat((float)($line->LineExtensionAmount->amount ?? 0)); - $invoiceLine->setQuantity((float)($line->InvoicedQuantity ?? 0)); - $invoiceLine->setQuantityUnitCode(''); // Not present in the provided JSON - $invoiceLine->setItemPrice((float)($line->Price->PriceAmount->amount ?? 0)); - $invoiceLine->setName($line->Item->Name ?? ''); - $invoiceLine->setDescription($line->Item->Description ?? ''); - - $tax = new Tax(); - if (isset($line->TaxTotal[0])) { - $taxTotal = $line->TaxTotal[0]; - $tax->setTaxAmount((float)($taxTotal->TaxAmount->amount ?? 0)); - - if (isset($line->Item->ClassifiedTaxCategory[0])) { - $taxCategory = $line->Item->ClassifiedTaxCategory[0]; - $tax->setTaxPercentage((float)($taxCategory->Percent ?? 0)); - $tax->setTaxCategory($taxCategory->ID->value ?? ''); - } - - $tax->setTaxableAmount((float)($line->LineExtensionAmount->amount ?? 0)); - } - $invoiceLine->setTax($tax); - - $invoiceLines[] = $invoiceLine; - } - $storecoveInvoice->setInvoiceLines($invoiceLines); - } - - return $storecoveInvoice; - - -} - -private function validateStorecoveInvoice(StorecoveInvoice $invoice): void -{ - $requiredFields = ['documentCurrency', 'invoiceNumber', 'issueDate', 'dueDate']; - foreach ($requiredFields as $field) { - if (empty($invoice->$field)) { - throw new \InvalidArgumentException("Required field '$field' is missing or empty"); - } - } - - if (empty($invoice->invoiceLines)) { - throw new \InvalidArgumentException("Invoice must have at least one line item"); - } - - // Add more validations as needed -} - - public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool - { - return $type === StorecoveInvoice::class && $data instanceof PeppolInvoice; - } - - public function getSupportedTypes(?string $format): array - { - return [ - StorecoveInvoice::class => true, - ]; - } - - private function mapNestedProperties($object, array $nestedPaths): array - { - $result = []; - foreach ($nestedPaths as $key => $path) { - if (is_array($path)) { - // Try multiple paths - foreach ($path as $possiblePath) { - $value = $this->getValueFromPath($object, $possiblePath); - if ($value !== null) { - $result[$key] = $value; - nlog("Mapped nested property: $key", ['path' => $possiblePath, 'value' => $value]); - break; - } - } - if (!isset($result[$key])) { - nlog("Failed to map nested property: $key", ['paths' => $path]); - } - } else { - $value = $this->getValueFromPath($object, $path); - if ($value !== null) { - $result[$key] = $value; - nlog("Mapped nested property: $key", ['path' => $path, 'value' => $value]); - } else { - nlog("Failed to map nested property: $key", ['path' => $path]); - } - } - } - return $result; - } - - private function getValueFromPath($object, string $path) - { - $parts = explode('.', $path); - $value = $object; - foreach ($parts as $part) { - if (preg_match('/(.+)\[(\d+)\]/', $part, $matches)) { - $property = $matches[1]; - $index = $matches[2]; - $value = $value->$property[$index] ?? null; - } else { - $value = $value->$part ?? null; - } - if ($value === null) { - nlog("Null value encountered in path: $path at part: $part"); - return null; - } - } - return $value instanceof \DateTime ? $value->format('Y-m-d') : $value; - } - - private function castValue(string $property, $value) - { - try { - $reflectionProperty = new \ReflectionProperty(StorecoveInvoice::class, $property); - $type = $reflectionProperty->getType(); - - if ($type instanceof \ReflectionNamedType) { - switch ($type->getName()) { - case 'float': - return (float) $value; - case 'int': - return (int) $value; - case 'string': - return (string) $value; - case 'bool': - return (bool) $value; - case 'array': - return (array) $value; - default: - return $value; - } - } - } catch (\ReflectionException $e) { - nlog("Error casting value for property: $property", ['error' => $e->getMessage()]); - } - - return $value; - } -} diff --git a/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php b/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php new file mode 100644 index 0000000000..7ad0709913 --- /dev/null +++ b/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php @@ -0,0 +1,123 @@ +s_invoice = new StorecoveInvoice(); + + $this->s_invoice->setDocumentCurrency($peppolInvoice->DocumentCurrencyCode ?? ''); + $this->s_invoice->setInvoiceNumber($peppolInvoice->ID ?? ''); + $this->s_invoice->setIssueDate($peppolInvoice->IssueDate->format('Y-m-d')); + $this->s_invoice->setTaxPointDate($peppolInvoice->IssueDate->format('Y-m-d')); + $this->s_invoice->setDueDate($peppolInvoice->DueDate->format('Y-m-d') ?? ''); + $this->s_invoice->setNote($peppolInvoice->Note ?? ''); + + // Only use this if we are billing for services between a period. + if (isset($peppolInvoice->InvoicePeriod[0]) && + isset($peppolInvoice->InvoicePeriod[0]->StartDate) && + isset($peppolInvoice->InvoicePeriod[0]->EndDate)) { + $this->s_invoice->setInvoicePeriod("{$peppolInvoice->InvoicePeriod[0]->StartDate} - {$peppolInvoice->InvoicePeriod[0]->EndDate}"); + } + + + + // $this->s_invoice->setReferences([ + // 'buyerReference' => $peppolInvoice->BuyerReference ?? '', + // 'orderReference' => $peppolInvoice->OrderReference->ID->value ?? '', + // ]); + + // $this->s_invoice->setAmountIncludingVat((float)($peppolInvoice->LegalMonetaryTotal->TaxInclusiveAmount->amount ?? 0)); +// if (isset($peppolInvoice->AccountingSupplierParty->Party)) { +// $supplier = $peppolInvoice->AccountingSupplierParty->Party; +// $this->s_invoice->setAccountingSupplierParty([ +// 'name' => $supplier->PartyName[0]->Name ?? '', +// 'vatNumber' => $supplier->PartyIdentification[0]->ID->value ?? '', +// 'streetName' => $supplier->PostalAddress->StreetName ?? '', +// 'cityName' => $supplier->PostalAddress->CityName ?? '', +// 'postalZone' => $supplier->PostalAddress->PostalZone ?? '', +// 'countryCode' => $supplier->PostalAddress->Country->IdentificationCode->value ?? '', +// ]); +// } + +// if (isset($peppolInvoice->AccountingCustomerParty->Party)) { +// $customer = $peppolInvoice->AccountingCustomerParty->Party; +// $this->s_invoice->setAccountingCustomerParty([ +// 'name' => $customer->PartyName[0]->Name ?? '', +// 'vatNumber' => $customer->PartyIdentification[0]->ID->value ?? '', +// 'streetName' => $customer->PostalAddress->StreetName ?? '', +// 'cityName' => $customer->PostalAddress->CityName ?? '', +// 'postalZone' => $customer->PostalAddress->PostalZone ?? '', +// 'countryCode' => $customer->PostalAddress->Country->IdentificationCode->value ?? '', +// ]); +// } + +// if (isset($peppolInvoice->PaymentMeans[0])) { +// $this->s_invoice->setPaymentMeans([ +// 'paymentID' => $peppolInvoice->PaymentMeans[0]->PayeeFinancialAccount->ID->value ?? '', +// ]); +// } + +// // Map tax total at invoice level +// $taxTotal = []; +// if (isset($peppolInvoice->InvoiceLine[0]->TaxTotal[0])) { +// $taxTotal[] = [ +// 'taxAmount' => (float)($peppolInvoice->InvoiceLine[0]->TaxTotal[0]->TaxAmount->amount ?? 0), +// 'taxCurrency' => $peppolInvoice->DocumentCurrencyCode ?? '', +// ]; +// } +// $this->s_invoice->setTaxTotal($taxTotal); + +// if (isset($peppolInvoice->InvoiceLine)) { +// $invoiceLines = []; +// foreach ($peppolInvoice->InvoiceLine as $line) { +// $invoiceLine = new InvoiceLines(); +// $invoiceLine->setLineId($line->ID->value ?? ''); +// $invoiceLine->setAmountExcludingVat((float)($line->LineExtensionAmount->amount ?? 0)); +// $invoiceLine->setQuantity((float)($line->InvoicedQuantity ?? 0)); +// $invoiceLine->setQuantityUnitCode(''); // Not present in the provided JSON +// $invoiceLine->setItemPrice((float)($line->Price->PriceAmount->amount ?? 0)); +// $invoiceLine->setName($line->Item->Name ?? ''); +// $invoiceLine->setDescription($line->Item->Description ?? ''); + +// $tax = new Tax(); +// if (isset($line->TaxTotal[0])) { +// $taxTotal = $line->TaxTotal[0]; +// $tax->setTaxAmount((float)($taxTotal->TaxAmount->amount ?? 0)); + +// if (isset($line->Item->ClassifiedTaxCategory[0])) { +// $taxCategory = $line->Item->ClassifiedTaxCategory[0]; +// $tax->setTaxPercentage((float)($taxCategory->Percent ?? 0)); +// $tax->setTaxCategory($taxCategory->ID->value ?? ''); +// } + +// $tax->setTaxableAmount((float)($line->LineExtensionAmount->amount ?? 0)); +// } +// $invoiceLine->setTax($tax); + +// $invoiceLines[] = $invoiceLine; +// } +// $this->s_invoice->setInvoiceLines($invoiceLines); +// } + +// return $this->s_invoice; + + } + + public function getInvoice(): StorecoveInvoice + { + return $this->s_invoice; + } + + public function toJson(): string + { + return json_encode($this->s_invoice, JSON_PRETTY_PRINT); + } +} \ No newline at end of file diff --git a/app/Services/EDocument/Gateway/Transformers/TransformerInterface.php b/app/Services/EDocument/Gateway/Transformers/TransformerInterface.php new file mode 100644 index 0000000000..a513c6396f --- /dev/null +++ b/app/Services/EDocument/Gateway/Transformers/TransformerInterface.php @@ -0,0 +1,22 @@ +createATData(); + + $stub = json_decode('{"Invoice":{"Note":"Nooo","PaymentMeans":[{"ID":{"value":"afdasfasdfasdfas"},"PayeeFinancialAccount":{"Name":"PFA-NAME","ID":{"value":"DE89370400440532013000"},"AliasName":"PFA-Alias","AccountTypeCode":{"value":"CHECKING"},"AccountFormatCode":{"value":"IBAN"},"CurrencyCode":{"value":"EUR"},"FinancialInstitutionBranch":{"ID":{"value":"DEUTDEMMXXX"},"Name":"Deutsche Bank"}}}]}}'); + foreach ($stub as $key => $value) { + $e_invoice->{$key} = $value; + } + + $invoice->e_invoice = $e_invoice; + + $p = new Peppol($invoice); + $p->run(); + $peppolInvoice = $p->getInvoice(); + + + $s_transformer = new StorecoveTransformer(); + $s_transformer->transform($peppolInvoice); + + $json = $s_transformer->toJson(); + + $this->assertJson($json); + + nlog($json); + } + public function testUnsetOfVatNumers() { @@ -1332,81 +1372,6 @@ class StorecoveTest extends TestCase } - - - public function testNormalizingToStorecove() - { - - $e_invoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); - - $invoice = $this->createATData(); - - $stub = json_decode('{"Invoice":{"Note":"Nooo","PaymentMeans":[{"ID":{"value":"afdasfasdfasdfas"},"PayeeFinancialAccount":{"Name":"PFA-NAME","ID":{"value":"DE89370400440532013000"},"AliasName":"PFA-Alias","AccountTypeCode":{"value":"CHECKING"},"AccountFormatCode":{"value":"IBAN"},"CurrencyCode":{"value":"EUR"},"FinancialInstitutionBranch":{"ID":{"value":"DEUTDEMMXXX"},"Name":"Deutsche Bank"}}}]}}'); - foreach ($stub as $key => $value) { - $e_invoice->{$key} = $value; - } - - $invoice->e_invoice = $e_invoice; - - -try { - // Assuming $invoice is already defined or created earlier in your test - $p = new Peppol($invoice); - $p->run(); - $peppolInvoice = $p->getInvoice(); - - nlog("Peppol Invoice: " . json_encode($peppolInvoice, JSON_PRETTY_PRINT)); - - // Create the serializer with all necessary normalizers - $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); - $metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory); - $objectNormalizer = new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter); - - $encoders = [new JsonEncoder()]; - $normalizers = [ - new ArrayDenormalizer(), - $objectNormalizer, - new ObjectNormalizer(), // This is a fallback normalizer - ]; - $serializer = new Serializer($normalizers, $encoders); - - // Create the PeppolToStorecoveNormalizer with the serializer - $peppolToStorecoveNormalizer = new PeppolToStorecoveNormalizer($serializer); - - // Denormalize the Peppol invoice to a Storecove invoice - $storecoveInvoice = $peppolToStorecoveNormalizer->denormalize($peppolInvoice, StorecoveInvoice::class); - - nlog("Storecove Invoice after denormalization: " . json_encode($storecoveInvoice, JSON_PRETTY_PRINT)); - - // Serialize the Storecove invoice to JSON - $jsonOutput = $serializer->serialize($storecoveInvoice, 'json', [ - 'json_encode_options' => JSON_PRETTY_PRINT - ]); - - nlog("Final JSON output: " . $jsonOutput); - - // Add assertions to verify the output - $this->assertInstanceOf(StorecoveInvoice::class, $storecoveInvoice); - $this->assertJson($jsonOutput); - - // Add more specific assertions based on your expected output - $decodedOutput = json_decode($jsonOutput, true); - $this->assertArrayHasKey('documentCurrency', $decodedOutput); - $this->assertArrayHasKey('invoiceNumber', $decodedOutput); - $this->assertArrayHasKey('invoiceLines', $decodedOutput); - $this->assertIsArray($decodedOutput['invoiceLines']); - // Add more assertions as needed - -} catch (\Exception $e) { - nlog("Error occurred: " . $e->getMessage()); - nlog("Stack trace: " . $e->getTraceAsString()); - throw $e; // Re-throw the exception to fail the test -} - - - } - - public function PestAtRules() { $this->routing_id = 293801;