From 54588c15104e2d744dcfd6cc7c826d349dab90b9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 31 Jul 2024 17:41:12 +1000 Subject: [PATCH 1/9] Working on peppol --- app/Models/Presenters/UserPresenter.php | 5 +++ app/Services/EDocument/Standards/Peppol.php | 24 +++++++++------ composer.lock | 34 ++++++++++----------- tests/Feature/EInvoice/PeppolTest.php | 22 ++++++++++++- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/app/Models/Presenters/UserPresenter.php b/app/Models/Presenters/UserPresenter.php index 917cb43665d9..59211278e16c 100644 --- a/app/Models/Presenters/UserPresenter.php +++ b/app/Models/Presenters/UserPresenter.php @@ -95,4 +95,9 @@ class UserPresenter extends EntityPresenter { return $this->entity->phone ?? ' '; } + + public function email(): string + { + return $this->entity->email ?? ' '; + } } diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index c37fb46214aa..d887144972a5 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -575,9 +575,9 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv $party->PhysicalLocation = $address; $contact = new Contact(); - $contact->ElectronicMail = $this->invoice->company->owner()->email ?? 'owner@gmail.com'; - $contact->Telephone = ''; - $contact->Name = ''; + $contact->ElectronicMail = $this->getSetting('Invoice.AccountingSupplierParty.Party.Contact') ?? $this->invoice->company->owner()->present()->email(); + $contact->Telephone = $this->getSetting('Invoice.AccountingSupplierParty.Party.Telephone') ?? $this->invoice->company->getSetting('phone'); + $contact->Name = $this->getSetting('Invoice.AccountingSupplierParty.Party.Name') ?? $this->invoice->company->owner()->present()->name(); $party->Contact = $contact; @@ -703,20 +703,26 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv //only scans for top level props foreach($settings as $prop => $visibility){ - if($prop_value = PropertyResolver::resolve($this->invoice->client->e_invoice, $prop)) + if($prop_value = $this->getSetting($prop)) $this->p_invoice->{$prop} = $prop_value; - elseif($prop_value = PropertyResolver::resolve($this->invoice->company->e_invoice, $prop)) { - $this->p_invoice->{$prop} = $prop_value; - } } return $this; } - public function getSetting(object $e_invoice, string $property_path): mixed + public function getSetting(string $property_path): mixed { - return PropertyResolver::resolve($e_invoice, $property_path); + + if($prop_value = PropertyResolver::resolve($this->invoice->e_invoice, $property_path)) + return $prop_value; + elseif($prop_value = PropertyResolver::resolve($this->invoice->client->e_invoice, $property_path)) + return $prop_value; + elseif($prop_value = PropertyResolver::resolve($this->invoice->company->e_invoice, $property_path)) + return $prop_value; + + return null; + } public function countryLevelMutators():self diff --git a/composer.lock b/composer.lock index efa6a8ea7ee1..9cd2207e89a2 100644 --- a/composer.lock +++ b/composer.lock @@ -535,16 +535,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.316.3", + "version": "3.316.10", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "e832e594b3c213760e067e15ef2739f77505e832" + "reference": "eeb8df6ff6caa428e8bcd631ad2a96430900a249" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e832e594b3c213760e067e15ef2739f77505e832", - "reference": "e832e594b3c213760e067e15ef2739f77505e832", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/eeb8df6ff6caa428e8bcd631ad2a96430900a249", + "reference": "eeb8df6ff6caa428e8bcd631ad2a96430900a249", "shasum": "" }, "require": { @@ -624,9 +624,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.316.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.316.10" }, - "time": "2024-07-12T18:07:23+00:00" + "time": "2024-07-30T18:10:20+00:00" }, { "name": "bacon/bacon-qr-code", @@ -4552,16 +4552,16 @@ }, { "name": "laravel/framework", - "version": "v11.18.1", + "version": "v11.19.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8" + "reference": "5e103d499e9ee5bcfc184412d034c4e516b87085" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/b19ba518c56852567e99fbae9321bc436c2cc5a8", - "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8", + "url": "https://api.github.com/repos/laravel/framework/zipball/5e103d499e9ee5bcfc184412d034c4e516b87085", + "reference": "5e103d499e9ee5bcfc184412d034c4e516b87085", "shasum": "" }, "require": { @@ -4754,7 +4754,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-07-26T10:39:29+00:00" + "time": "2024-07-30T15:22:41+00:00" }, { "name": "laravel/pint", @@ -17347,16 +17347,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.28", + "version": "10.5.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275" + "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff7fb85cdf88131b83e721fb2a327b664dbed275", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e9e80872b4e8064401788ee8a32d40b4455318f", + "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f", "shasum": "" }, "require": { @@ -17428,7 +17428,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.28" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.29" }, "funding": [ { @@ -17444,7 +17444,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T14:54:16+00:00" + "time": "2024-07-30T11:08:00+00:00" }, { "name": "react/cache", diff --git a/tests/Feature/EInvoice/PeppolTest.php b/tests/Feature/EInvoice/PeppolTest.php index e7d85b759340..547d688851a7 100644 --- a/tests/Feature/EInvoice/PeppolTest.php +++ b/tests/Feature/EInvoice/PeppolTest.php @@ -19,18 +19,19 @@ use Tests\MockAccountData; use App\DataMapper\InvoiceItem; use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; +use App\Factory\CompanyUserFactory; use InvoiceNinja\EInvoice\EInvoice; use InvoiceNinja\EInvoice\Symfony\Encode; use App\Services\EDocument\Standards\Peppol; use App\Services\EDocument\Standards\FatturaPANew; use Illuminate\Routing\Middleware\ThrottleRequests; +use InvoiceNinja\EInvoice\Models\Peppol\PaymentMeans; use Illuminate\Foundation\Testing\DatabaseTransactions; use InvoiceNinja\EInvoice\Models\FatturaPA\FatturaElettronica; use InvoiceNinja\EInvoice\Models\Peppol\BranchType\FinancialInstitutionBranch; use InvoiceNinja\EInvoice\Models\Peppol\FinancialAccountType\PayeeFinancialAccount; use InvoiceNinja\EInvoice\Models\FatturaPA\FatturaElettronicaBodyType\FatturaElettronicaBody; use InvoiceNinja\EInvoice\Models\FatturaPA\FatturaElettronicaHeaderType\FatturaElettronicaHeader; -use InvoiceNinja\EInvoice\Models\Peppol\PaymentMeans; /** * @test @@ -92,6 +93,12 @@ class PeppolTest extends TestCase 'settings' => $settings, 'e_invoice' => $einvoice, ]); + + $cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id); + $cu->is_owner = true; + $cu->is_admin = true; + $cu->is_locked = false; + $cu->save(); $client_settings = ClientSettings::defaults(); $client_settings->currency_id = '3'; @@ -206,6 +213,12 @@ class PeppolTest extends TestCase 'e_invoice' => $einvoice, ]); + $cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id); + $cu->is_owner = true; + $cu->is_admin = true; + $cu->is_locked = false; + $cu->save(); + $client_settings = ClientSettings::defaults(); $client_settings->currency_id = '3'; @@ -301,6 +314,13 @@ class PeppolTest extends TestCase 'account_id' => $this->account->id, 'settings' => $settings, ]); + + + $cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id); + $cu->is_owner = true; + $cu->is_admin = true; + $cu->is_locked = false; + $cu->save(); $client_settings = ClientSettings::defaults(); $client_settings->currency_id = '3'; From afb8065dfef4007fe4efa4082612152831a54d87 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 1 Aug 2024 11:15:02 +1000 Subject: [PATCH 2/9] Fixes for task export date ranges --- app/Export/CSV/BaseExport.php | 5 ++++- app/Export/CSV/TaskExport.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index 605abff1e234..a3bac0bb1204 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -1258,7 +1258,7 @@ class BaseExport $date_range = $this->input['date_range']; - if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key']) > 1 && ($table_name && $this->columnExists($table_name, $this->input['date_key']))) { + if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key'] ?? '') > 1 && ($table_name && $this->columnExists($table_name, $this->input['date_key']))) { $this->date_key = $this->input['date_key']; } @@ -1270,6 +1270,9 @@ class BaseExport $custom_end_date = now(); } + nlog($custom_start_date->format('Y-m-d')); + nlog($custom_end_date->format('Y-m-d')); + switch ($date_range) { case 'all': $this->start_date = 'All available data'; diff --git a/app/Export/CSV/TaskExport.php b/app/Export/CSV/TaskExport.php index bc357d61a96f..155d61a88f48 100644 --- a/app/Export/CSV/TaskExport.php +++ b/app/Export/CSV/TaskExport.php @@ -29,7 +29,7 @@ class TaskExport extends BaseExport { private $entity_transformer; - public string $date_key = 'created_at'; + public string $date_key = 'calculated_start_date'; private string $date_format = 'Y-m-d'; From 19ba732adf99d90de871e6bb80d2907ec560141f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 1 Aug 2024 11:25:11 +1000 Subject: [PATCH 3/9] Add client model to invoice calculators --- app/Export/CSV/BaseExport.php | 3 --- app/Helpers/Invoice/InvoiceItemSum.php | 5 +++-- .../Invoice/InvoiceItemSumInclusive.php | 5 +++-- app/Helpers/Invoice/InvoiceSum.php | 17 +++++++------- app/Helpers/Invoice/InvoiceSumInclusive.php | 22 +++++++++---------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index a3bac0bb1204..4ea22fe974ee 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -1269,9 +1269,6 @@ class BaseExport $custom_start_date = now()->startOfYear(); $custom_end_date = now(); } - - nlog($custom_start_date->format('Y-m-d')); - nlog($custom_end_date->format('Y-m-d')); switch ($date_range) { case 'all': diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index 9f913c42a8bc..d1d7dd56cff0 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -15,6 +15,7 @@ use App\Models\Quote; use App\Utils\Number; use App\Models\Client; use App\Models\Credit; +use App\Models\Vendor; use App\Models\Invoice; use App\Models\PurchaseOrder; use App\Models\RecurringQuote; @@ -121,7 +122,7 @@ class InvoiceItemSum private $tax_collection; - private ?Client $client; + private Client | Vendor $client; private bool $calc_tax = false; @@ -132,10 +133,10 @@ class InvoiceItemSum $this->tax_collection = collect([]); $this->invoice = $invoice; + $this->client = $invoice->client ?? $invoice->vendor; if ($this->invoice->client) { $this->currency = $this->invoice->client->currency(); - $this->client = $this->invoice->client; $this->shouldCalculateTax(); } else { $this->currency = $this->invoice->vendor->currency(); diff --git a/app/Helpers/Invoice/InvoiceItemSumInclusive.php b/app/Helpers/Invoice/InvoiceItemSumInclusive.php index 8bcf87fc25a3..df9a897abefa 100644 --- a/app/Helpers/Invoice/InvoiceItemSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceItemSumInclusive.php @@ -15,6 +15,7 @@ use App\Models\Quote; use App\Utils\Number; use App\Models\Client; use App\Models\Credit; +use App\Models\Vendor; use App\Models\Invoice; use App\Models\PurchaseOrder; use App\Models\RecurringQuote; @@ -110,7 +111,7 @@ class InvoiceItemSumInclusive private bool $calc_tax = false; - private ?Client $client; + private Client | Vendor $client; private RuleInterface $rule; @@ -119,10 +120,10 @@ class InvoiceItemSumInclusive $this->tax_collection = collect([]); $this->invoice = $invoice; + $this->client = $invoice->client ?? $invoice->vendor; if ($this->invoice->client) { $this->currency = $this->invoice->client->currency(); - $this->client = $this->invoice->client; $this->shouldCalculateTax(); } else { $this->currency = $this->invoice->vendor->currency(); diff --git a/app/Helpers/Invoice/InvoiceSum.php b/app/Helpers/Invoice/InvoiceSum.php index c2979f73219e..12cb3a1b16de 100644 --- a/app/Helpers/Invoice/InvoiceSum.php +++ b/app/Helpers/Invoice/InvoiceSum.php @@ -11,12 +11,14 @@ namespace App\Helpers\Invoice; +use App\Models\Client; use App\Models\Credit; use App\Models\Invoice; use App\Models\PurchaseOrder; use App\Models\Quote; use App\Models\RecurringInvoice; use App\Models\RecurringQuote; +use App\Models\Vendor; use App\Utils\Number; use App\Utils\Traits\NumberFormatter; use Illuminate\Support\Collection; @@ -50,6 +52,8 @@ class InvoiceSum private $precision; + private Client | Vendor $client; + public InvoiceItemSum $invoice_items; private $rappen_rounding = false; @@ -60,18 +64,15 @@ class InvoiceSum */ public function __construct($invoice) { + $this->invoice = $invoice; + $this->client = $invoice->client ?? $invoice->vendor; - if ($this->invoice->client) { - $this->precision = $this->invoice->client->currency()->precision; - $this->rappen_rounding = $this->invoice->client->getSetting('enable_rappen_rounding'); - } else { - $this->precision = $this->invoice->vendor->currency()->precision; - $this->rappen_rounding = $this->invoice->vendor->getSetting('enable_rappen_rounding'); - - } + $this->precision = $this->client->currency()->precision; + $this->rappen_rounding = $this->client->getSetting('enable_rappen_rounding'); $this->tax_map = new Collection(); + } public function build() diff --git a/app/Helpers/Invoice/InvoiceSumInclusive.php b/app/Helpers/Invoice/InvoiceSumInclusive.php index 8b0b6f95cc93..07fdf3e86894 100644 --- a/app/Helpers/Invoice/InvoiceSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceSumInclusive.php @@ -13,7 +13,9 @@ namespace App\Helpers\Invoice; use App\Models\Quote; use App\Utils\Number; +use App\Models\Client; use App\Models\Credit; +use App\Models\Vendor; use App\Models\Invoice; use App\Models\PurchaseOrder; use App\Models\RecurringQuote; @@ -50,6 +52,8 @@ class InvoiceSumInclusive private $rappen_rounding = false; + private Client | Vendor $client; + public InvoiceItemSumInclusive $invoice_items; /** * Constructs the object with Invoice and Settings object. @@ -59,14 +63,10 @@ class InvoiceSumInclusive public function __construct($invoice) { $this->invoice = $invoice; - - if ($this->invoice->client) { - $this->precision = $this->invoice->client->currency()->precision; - $this->rappen_rounding = $this->invoice->client->getSetting('enable_rappen_rounding'); - } else { - $this->precision = $this->invoice->vendor->currency()->precision; - $this->rappen_rounding = $this->invoice->vendor->getSetting('enable_rappen_rounding'); - } + $this->client = $invoice->client ?? $invoice->vendor; + + $this->precision = $this->client->currency()->precision; + $this->rappen_rounding = $this->client->getSetting('enable_rappen_rounding'); $this->tax_map = new Collection(); } @@ -158,19 +158,19 @@ class InvoiceSumInclusive $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->client).'%', 'total' => $tax]; } if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) > 1) { $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate2, $amount); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->client).'%', 'total' => $tax]; } if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) > 1) { $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate3, $amount); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->client).'%', 'total' => $tax]; } return $this; From f4075d88ee2e53be9c7ea7aa923f14bdb93d5f29 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 1 Aug 2024 11:32:03 +1000 Subject: [PATCH 4/9] Fixes for invoice calcs --- app/Helpers/Invoice/InvoiceSum.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Helpers/Invoice/InvoiceSum.php b/app/Helpers/Invoice/InvoiceSum.php index 12cb3a1b16de..e69cf394a6ca 100644 --- a/app/Helpers/Invoice/InvoiceSum.php +++ b/app/Helpers/Invoice/InvoiceSum.php @@ -132,7 +132,7 @@ class InvoiceSum $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name1, $this->invoice->tax_rate1); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->client).'%', 'total' => $tax]; } if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) >= 2) { @@ -140,7 +140,7 @@ class InvoiceSum $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name2, $this->invoice->tax_rate2); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->client).'%', 'total' => $tax]; } if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) >= 2) { @@ -148,7 +148,7 @@ class InvoiceSum $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name3, $this->invoice->tax_rate3); $this->total_taxes += $tax; - $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->invoice->client).'%', 'total' => $tax]; + $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->client).'%', 'total' => $tax]; } return $this; From 528eef3cd8e61919ef1bbd99d99d76222586b0c5 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 1 Aug 2024 12:19:31 +1000 Subject: [PATCH 5/9] Peppol --- app/Services/EDocument/Standards/Peppol.php | 32 ++++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index c37fb46214aa..5d833f680ba5 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -188,16 +188,6 @@ class Peppol extends AbstractService $this->countryLevelMutators(); - // $this->p_invoice->PaymentMeans = $this->getPaymentMeans(); - - // $payeeFinancialAccount = (new PayeeFinancialAccount()) - // ->setBankId($company->settings->custom_value1) - // ->setBankName($company->settings->custom_value2); - - // $paymentMeans = (new PaymentMeans()) - // ->setPaymentMeansCode($invoice->custom_value1) - // ->setPayeeFinancialAccount($payeeFinancialAccount); - // $ubl_invoice->setPaymentMeans($paymentMeans); return $this; } @@ -485,7 +475,7 @@ class Peppol extends AbstractService $tax_amount = new TaxAmount(); $tax_amount->currencyID = $this->invoice->client->currency()->code; -$tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiveLineTax($item->tax_rate2, $item->line_total) : $this->calcAmountLineTax($item->tax_rate2, $item->line_total); + $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiveLineTax($item->tax_rate2, $item->line_total) : $this->calcAmountLineTax($item->tax_rate2, $item->line_total); $tax_subtotal = new TaxSubtotal(); $tax_subtotal->TaxAmount = $tax_amount; @@ -728,6 +718,26 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv return $this; } + private function setPaymentMeans(): self + { + $paymentMeans = new PaymentMeans(); + +// = $this->getPaymentMeans(); + +// $payeeFinancialAccount = (new PayeeFinancialAccount()) +// ->setBankId($company->settings->custom_value1) +// ->setBankName($company->settings->custom_value2); + +// $paymentMeans = (new PaymentMeans()) +// ->setPaymentMeansCode($invoice->custom_value1) +// ->setPayeeFinancialAccount($payeeFinancialAccount); +// $ubl_invoice->setPaymentMeans($paymentMeans); + + $this->p_invoice->PaymentMeans = $paymentMeans; + + return $this; + } + private function DE(): self { // accountingsupplierparty.party.contact MUST be set - Name / Telephone / Electronic Mail From 0d4a1b9043cdc34411c0074ef49d7b0c4f2bc240 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 1 Aug 2024 16:32:35 +1000 Subject: [PATCH 6/9] Peppol calculations --- app/Jobs/EDocument/CreateEDocument.php | 7 +- .../EDocument/Gateway/Storecove/Storecove.php | 46 +++++- app/Services/EDocument/Standards/Peppol.php | 96 +++++++---- .../Einvoice/Storecove/StorecoveTest.php | 153 +++++++++++++++++- 4 files changed, 258 insertions(+), 44 deletions(-) diff --git a/app/Jobs/EDocument/CreateEDocument.php b/app/Jobs/EDocument/CreateEDocument.php index 103ab05d9d2d..7f96af177a91 100644 --- a/app/Jobs/EDocument/CreateEDocument.php +++ b/app/Jobs/EDocument/CreateEDocument.php @@ -11,7 +11,6 @@ namespace App\Jobs\EDocument; -use App\Services\EDocument\Standards\RoEInvoice; use App\Utils\Ninja; use App\Models\Quote; use App\Models\Credit; @@ -23,10 +22,12 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; +use App\Services\EDocument\Standards\Peppol; use horstoeko\zugferd\ZugferdDocumentBuilder; +use App\Services\EDocument\Standards\FatturaPA; +use App\Services\EDocument\Standards\RoEInvoice; use App\Services\EDocument\Standards\OrderXDocument; use App\Services\EDocument\Standards\FacturaEInvoice; -use App\Services\EDocument\Standards\FatturaPA; use App\Services\EDocument\Standards\ZugferdEDokument; class CreateEDocument implements ShouldQueue @@ -68,6 +69,8 @@ class CreateEDocument implements ShouldQueue if ($this->document instanceof Invoice) { switch ($e_document_type) { + case "PEPPOL": + return (new Peppol($this->document))->toXml(); case "FACT1": return (new RoEInvoice($this->document))->generateXml(); case "FatturaPA": diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index a56ea37000e3..0ce0a8561372 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -95,6 +95,48 @@ class Storecove { // parseStrategy: ubl // } */ + public function sendJsonDocument($document) + { + + + $payload = [ + "legalEntityId" => 290868, + "idempotencyGuid" => \Illuminate\Support\Str::uuid(), + "routing" => [ + "eIdentifiers" => [], + "emails" => ["david@invoiceninja.com"] + ], + // "document" => [ + // 'documentType' => 'invoice', + // "rawDocumentData" => [ + // "document" => base64_encode($document), + // "parse" => true, + // "parseStrategy" => "ubl", + // ], + // ], + "document"=> [ + "documentType" => "invoice", + "invoice" => $document, + ], + ]; + + $uri = "document_submissions"; + + nlog($payload); + + $r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders()); + + nlog($r->body()); + nlog($r->json()); + + if($r->successful()) { + return $r->json()['guid']; + } + + return false; + + } + public function sendDocument($document) { @@ -256,8 +298,6 @@ class Storecove { } - - public function addIdentifier(int $legal_entity_id, string $identifier, string $scheme) { $uri = "legal_entities/{$legal_entity_id}/peppol_identifiers"; @@ -278,7 +318,6 @@ class Storecove { } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function getHeaders(array $headers = []) { @@ -300,5 +339,4 @@ class Storecove { return $r; } - } \ No newline at end of file diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index df803f421400..a0d7b4892f66 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -151,14 +151,36 @@ class Peppol extends AbstractService private InvoiceSum | InvoiceSumInclusive $calc; + private \InvoiceNinja\EInvoice\Models\Peppol\Invoice $p_invoice; /** * @param Invoice $invoice */ - public function __construct(public Invoice $invoice, public ?\InvoiceNinja\EInvoice\Models\Peppol\Invoice $p_invoice = null) + public function __construct(public Invoice $invoice) { - $this->p_invoice = $p_invoice ?? new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); $this->company = $invoice->company; $this->calc = $this->invoice->calc(); + $this->setInvoice(); + } + + private function setInvoice(): self + { + + + if($this->invoice->e_invoice){ + + + $e = new EInvoice(); + $this->p_invoice = $e->decode('Peppol', json_encode($this->invoice->e_invoice->Invoice), 'json'); + + return $this; + + } + + $this->p_invoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); + + $this->setInvoiceDefaults(); + + return $this; } public function getInvoice(): \InvoiceNinja\EInvoice\Models\Peppol\Invoice @@ -171,7 +193,31 @@ class Peppol extends AbstractService public function toXml(): string { $e = new EInvoice(); - return $e->encode($this->p_invoice, 'xml'); + $xml = $e->encode($this->p_invoice, 'xml'); + + $prefix = ' + '; + + return str_ireplace(['\n',''], ['', $prefix], $xml); + + } + + public function toJson(): string + { + $e = new EInvoice(); + $json = $e->encode($this->p_invoice, 'json'); + + return $json; + // $prefixes = str_ireplace(["cac:","cbc:"], "", $json); + // return str_ireplace(["InvoiceLine", "PostalAddress", "PartyName"], ["invoiceLines","address", "companyName"], $prefixes); + } + + public function toArray(): array + { + return json_decode($this->toJson(), true); } public function run() @@ -192,17 +238,6 @@ class Peppol extends AbstractService } - // private function getPaymentMeans(): PaymentMeans - // { - // $payeeFinancialAccount = new PayeeFinancialAccount() - // $payeeFinancialAccount-> - - // $ppm = new PaymentMeans(); - // $ppm->PayeeFinancialAccount = $payeeFinancialAccount; - - // return $ppm; - // } - private function getLegalMonetaryTotal(): LegalMonetaryTotal { $taxable = $this->getTaxable(); @@ -509,7 +544,7 @@ class Peppol extends AbstractService $tax_amount = new TaxAmount(); $tax_amount->currencyID = $this->invoice->client->currency()->code; -$tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiveLineTax($item->tax_rate3, $item->line_total) : $this->calcAmountLineTax($item->tax_rate3, $item->line_total); + $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiveLineTax($item->tax_rate3, $item->line_total) : $this->calcAmountLineTax($item->tax_rate3, $item->line_total); $tax_subtotal = new TaxSubtotal(); $tax_subtotal->TaxAmount = $tax_amount; @@ -724,22 +759,18 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv return $this; } - private function setPaymentMeans(): self + private function setPaymentMeans(bool $required = false): self { - $paymentMeans = new PaymentMeans(); + + if($this->p_invoice->PaymentMeans) + return $this; + elseif(!isset($this->p_invoice->PaymentMeans) && $paymentMeans = $this->getSetting('Invoice.PaymentMeans')){ + $this->p_invoice->PaymentMeans = is_array($paymentMeans) ? $paymentMeans : [$paymentMeans]; + return $this; + } -// = $this->getPaymentMeans(); - -// $payeeFinancialAccount = (new PayeeFinancialAccount()) -// ->setBankId($company->settings->custom_value1) -// ->setBankName($company->settings->custom_value2); - -// $paymentMeans = (new PaymentMeans()) -// ->setPaymentMeansCode($invoice->custom_value1) -// ->setPayeeFinancialAccount($payeeFinancialAccount); -// $ubl_invoice->setPaymentMeans($paymentMeans); - - $this->p_invoice->PaymentMeans = $paymentMeans; + if($required) + throw new \Exception('e-invoice generation halted:: Payment Means required'); return $this; } @@ -748,10 +779,9 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv { // accountingsupplierparty.party.contact MUST be set - Name / Telephone / Electronic Mail // this is forced by default. + + $this->setPaymentMeans(true); - // ONE payment means MUST be set - - // return $this; } @@ -778,7 +808,7 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv private function ES(): self { -// For B2B, provide an ES:DIRE routing identifier and an ES:VAT tax identifier. + // For B2B, provide an ES:DIRE routing identifier and an ES:VAT tax identifier. // both sender and receiver must be an ES company; // you must have a "credit_transfer" PaymentMean; // the "dueDate" property is mandatory. diff --git a/tests/Integration/Einvoice/Storecove/StorecoveTest.php b/tests/Integration/Einvoice/Storecove/StorecoveTest.php index f37af88946e5..57882e1feb46 100644 --- a/tests/Integration/Einvoice/Storecove/StorecoveTest.php +++ b/tests/Integration/Einvoice/Storecove/StorecoveTest.php @@ -11,18 +11,25 @@ namespace Tests\Integration\Einvoice\Storecove; -use App\DataMapper\ClientSettings; -use App\Models\Client; use Tests\TestCase; +use App\Models\Client; +use App\Models\Company; +use App\Models\Invoice; use Tests\MockAccountData; +use App\DataMapper\InvoiceItem; +use App\DataMapper\ClientSettings; +use App\DataMapper\CompanySettings; +use App\Services\EDocument\Standards\Peppol; use Illuminate\Foundation\Testing\DatabaseTransactions; - +use InvoiceNinja\EInvoice\Models\Peppol\PaymentMeans; class StorecoveTest extends TestCase { use MockAccountData; use DatabaseTransactions; + private string $routing_id = ''; + protected function setUp(): void { parent::setUp(); @@ -88,7 +95,7 @@ class StorecoveTest extends TestCase // nlog($r); // } - +/* public function testGetLegalEntity() { @@ -348,7 +355,7 @@ $x = ' $sc->sendDocument($x); } - +*/ public function testCreateCHClient() { @@ -390,4 +397,140 @@ $x = ' $this->assertInstanceOf(\App\Models\Client::class, $c); } + + private function createDEData() + { + + $this->routing_id = '290868'; + + $settings = CompanySettings::defaults(); + $settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png'; + $settings->website = 'www.invoiceninja.de'; + $settings->address1 = 'Musterstraße 1'; + $settings->address2 = 'Etage 2, Büro 3'; + $settings->city = 'Berlin'; + $settings->state = 'Berlin'; + $settings->postal_code = '10115'; + $settings->phone = '030 1234567'; + $settings->email = $this->faker->unique()->safeEmail(); + $settings->country_id = '276'; // Germany's ISO country code + $settings->vat_number = 'DE123456789'; + $settings->id_number = 'HRB 12345'; + $settings->use_credits_payment = 'always'; + $settings->timezone_id = '1'; // CET (Central European Time) + $settings->entity_send_time = 0; + $settings->e_invoice_type = 'PEPPOL'; + $settings->currency_id = '3'; + + $company = Company::factory()->create([ + 'account_id' => $this->account->id, + 'settings' => $settings, + ]); + + $this->user->companies()->attach($company->id, [ + 'account_id' => $this->account->id, + 'is_owner' => true, + 'is_admin' => 1, + 'is_locked' => 0, + 'permissions' => '', + 'notifications' => CompanySettings::notificationAdminDefaults(), + 'settings' => null, + ]); + + Client::unguard(); + + $c = + Client::create([ + 'company_id' => $company->id, + 'user_id' => $this->user->id, + 'name' => 'Beispiel Firma GmbH', + 'website' => 'https://www.beispiel-firma.de', + 'private_notes' => 'Dies sind private Notizen zum Testkunden.', + 'balance' => 0, + 'paid_to_date' => 0, + 'vat_number' => 'DE654321987', + 'id_number' => 'HRB 12345', // Typical format for German company registration numbers + 'custom_value1' => '2024-07-22 10:00:00', + 'custom_value2' => 'blau', + 'custom_value3' => 'musterwort', + 'custom_value4' => 'test@example.com', + 'address1' => 'Musterstraße 123', + 'address2' => '2. Etage, Büro 45', + 'city' => 'München', + 'state' => 'Bayern', + 'postal_code' => '80331', + 'country_id' => '276', // Germany + 'shipping_address1' => 'Musterstraße 123', + 'shipping_address2' => '2. Etage, Büro 45', + 'shipping_city' => 'München', + 'shipping_state' => 'Bayern', + 'shipping_postal_code' => '80331', + 'shipping_country_id' => '276', // Germany + 'settings' => ClientSettings::Defaults(), + 'client_hash' => \Illuminate\Support\Str::random(32), + 'routing_id' => '', + ]); + + + $item = new InvoiceItem(); + $item->product_key = "Product Key"; + $item->notes = "Product Description"; + $item->cost = 10; + $item->quantity = 10; + $item->tax_rate1 = 19; + $item->tax_name1 = 'mwst'; + + $invoice = Invoice::factory()->create([ + 'company_id' => $company->id, + 'user_id' => $this->user->id, + 'client_id' => $c->id, + 'discount' => 0, + 'uses_inclusive_taxes' => false, + 'status_id' => 1, + 'tax_rate1' => 0, + 'tax_name1' => '', + 'tax_rate2' => 0, + 'tax_rate3' => 0, + 'tax_name2' => '', + 'tax_name3' => '', + 'line_items' => [$item], + 'number' => 'DE-'.rand(1000, 100000), + 'date' => now()->format('Y-m-d') + ]); + + $invoice = $invoice->calc()->getInvoice(); + $invoice->service()->markSent()->save(); + + + return $invoice; + + } + + public function testDeRules() + { + $invoice = $this->createDEData(); + + $e_invoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); + + $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; + $invoice->save(); + + $this->assertInstanceOf(Invoice::class, $invoice); + $this->assertInstanceof(\InvoiceNinja\EInvoice\Models\Peppol\Invoice::class, $e_invoice); + + $p = new Peppol($invoice); + + $p->run(); + $xml = $p->toXml(); + nlog($xml); + $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + $sc->sendDocument($xml); + + + } + } From 3e79df88094ff7a46c7deb0c4e25e318b41297c7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 2 Aug 2024 12:22:39 +1000 Subject: [PATCH 7/9] Template service client variables: --- app/Services/Template/TemplateService.php | 85 +++++++---------------- 1 file changed, 26 insertions(+), 59 deletions(-) diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 13adb454d7f1..d4459049327c 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -557,15 +557,7 @@ class TemplateService 'reminder_last_sent' => $this->translateDate($invoice->reminder_last_sent, $invoice->client->date_format(), $invoice->client->locale()), 'paid_to_date' => Number::formatMoney($invoice->paid_to_date, $invoice->client), 'auto_bill_enabled' => (bool) $invoice->auto_bill_enabled, - 'client' => [ - 'name' => $invoice->client->present()->name(), - 'balance' => $invoice->client->balance, - 'payment_balance' => $invoice->client->payment_balance, - 'credit_balance' => $invoice->client->credit_balance, - 'vat_number' => $invoice->client->vat_number ?? '', - 'currency' => $invoice->client->currency()->code ?? 'USD', - 'locale' => substr($invoice->client->locale(), 0, 2), - ], + 'client' => $this->getClient($invoice), 'payments' => $payments, 'total_tax_map' => $invoice->calc()->getTotalTaxMap(), 'line_tax_map' => $invoice->calc()->getTaxMap(), @@ -680,14 +672,7 @@ class TemplateService 'custom_value4' => $payment->custom_value4 ?? '', 'created_at' => $this->translateDate($payment->created_at, $payment->client->date_format(), $payment->client->locale()), 'updated_at' => $this->translateDate($payment->updated_at, $payment->client->date_format(), $payment->client->locale()), - 'client' => [ - 'name' => $payment->client->present()->name(), - 'balance' => $payment->client->balance, - 'payment_balance' => $payment->client->payment_balance, - 'credit_balance' => $payment->client->credit_balance, - 'vat_number' => $payment->client->vat_number ?? '', - 'currency' => $payment->client->currency()->code ?? 'USD', - ], + 'client' => $this->getClient($payment), 'paymentables' => $pivot, 'refund_activity' => $this->getPaymentRefundActivity($payment), ]; @@ -760,14 +745,7 @@ class TemplateService 'amount' => Number::formatMoney($quote->amount, $quote->client), 'balance' => Number::formatMoney($quote->balance, $quote->client), 'balance_raw' => (float) $quote->balance, - 'client' => [ - 'name' => $quote->client->present()->name(), - 'balance' => $quote->client->balance, - 'payment_balance' => $quote->client->payment_balance, - 'credit_balance' => $quote->client->credit_balance, - 'vat_number' => $quote->client->vat_number ?? '', - 'currency' => $quote->client->currency()->code ?? 'USD', - ], + 'client' => $this->getClient($quote), 'status_id' => $quote->status_id, 'status' => Quote::stringStatus($quote->status_id), 'number' => $quote->number ?: '', @@ -888,14 +866,7 @@ class TemplateService 'reminder_last_sent' => $this->translateDate($credit->reminder_last_sent, $credit->client->date_format(), $credit->client->locale()), 'paid_to_date' => Number::formatMoney($credit->paid_to_date, $credit->client), 'auto_bill_enabled' => (bool) $credit->auto_bill_enabled, - 'client' => [ - 'name' => $credit->client->present()->name(), - 'balance' => $credit->client->balance, - 'payment_balance' => $credit->client->payment_balance, - 'credit_balance' => $credit->client->credit_balance, - 'vat_number' => $credit->client->vat_number ?? '', - 'currency' => $credit->client->currency()->code ?? 'USD', - ], + 'client' => $this->getClient($credit), 'payments' => $payments, 'total_tax_map' => $credit->calc()->getTotalTaxMap(), 'line_tax_map' => $credit->calc()->getTaxMap(), @@ -924,6 +895,25 @@ class TemplateService } + private function getClient($entity): array + { + + return $entity->client ? [ + 'name' => $entity->client->present()->name(), + 'balance' => $entity->client->balance, + 'payment_balance' => $entity->client->payment_balance, + 'credit_balance' => $entity->client->credit_balance, + 'vat_number' => $entity->client->vat_number ?? '', + 'currency' => $entity->client->currency()->code ?? 'USD', + 'custom_value1' => $entity->client->custom_value1 ?? '', + 'custom_value2' => $entity->client->custom_value2 ?? '', + 'custom_value3' => $entity->client->custom_value3 ?? '', + 'custom_value4' => $entity->client->custom_value4 ?? '', + 'address' => $entity->client->present()->address(), + 'shipping_address' => $entity->client->present()->shipping_address(), + 'locale' => substr($entity->client->locale(), 0, 2), + ] : []; + } /** * @todo refactor * @@ -953,14 +943,7 @@ class TemplateService 'custom_value4' => $task->custom_value4 ?: '', 'status' => $task->status ? $task->status->name : '', 'user' => $this->userInfo($task->user), - 'client' => $task->client ? [ - 'name' => $task->client->present()->name(), - 'balance' => $task->client->balance, - 'payment_balance' => $task->client->payment_balance, - 'credit_balance' => $task->client->credit_balance, - 'vat_number' => $task->client->vat_number ?? '', - 'currency' => $task->client->currency()->code ?? 'USD', - ] : [], + 'client' => $this->getClient($task), ]; @@ -1015,14 +998,7 @@ class TemplateService 'color' => (string) $project->color ?: '', 'current_hours' => (int) $project->current_hours ?: 0, 'tasks' => ($project->tasks && !$nested) ? $this->processTasks($project->tasks, true) : [], //@phpstan-ignore-line - 'client' => $project->client ? [ - 'name' => $project->client->present()->name(), - 'balance' => $project->client->balance, - 'payment_balance' => $project->client->payment_balance, - 'credit_balance' => $project->client->credit_balance, - 'vat_number' => $project->client->vat_number ?? '', - 'currency' => $project->client->currency()->code ?? 'USD', - ] : [], + 'client' => $this->getClient($project), 'user' => $this->userInfo($project->user), 'invoices' => $this->processInvoices($project->invoices) ]; @@ -1047,16 +1023,7 @@ class TemplateService ] : [], 'amount' => (float)$purchase_order->amount, 'balance' => (float)$purchase_order->balance, - 'client' => $purchase_order->client ? [ - 'name' => $purchase_order->client->present()->name(), - 'balance' => $purchase_order->client->balance, - 'payment_balance' => $purchase_order->client->payment_balance, - 'credit_balance' => $purchase_order->client->credit_balance, - 'vat_number' => $purchase_order->client->vat_number ?? '', - 'address' => $purchase_order->client->present()->address(), - 'shipping_address' => $purchase_order->client->present()->shipping_address(), - 'currency' => $purchase_order->client->currency()->code ?? 'USD', - ] : [], + 'client' => $this->getClient($purchase_order), 'status_id' => (string)($purchase_order->status_id ?: 1), 'status' => PurchaseOrder::stringStatus($purchase_order->status_id ?? 1), 'is_deleted' => (bool)$purchase_order->is_deleted, From 1d754758ee4d82c6bbcba34c7b932711c5e02bac Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 2 Aug 2024 12:54:26 +1000 Subject: [PATCH 8/9] Update paypal for fraudnet --- app/PaymentDrivers/PayPalRestPaymentDriver.php | 7 +++++++ .../gateways/paypal/ppcp/card.blade.php | 16 +++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/PaymentDrivers/PayPalRestPaymentDriver.php b/app/PaymentDrivers/PayPalRestPaymentDriver.php index ba1cbc62e7f2..029b185eff36 100644 --- a/app/PaymentDrivers/PayPalRestPaymentDriver.php +++ b/app/PaymentDrivers/PayPalRestPaymentDriver.php @@ -173,6 +173,13 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver })->implode("\n"); $order = [ + "payer" => [ + "name" => [ + "given_name" => $this->client->present()->first_name(), + "surname" => $this->client->present()->last_name() + ], + "email_address" => $this->client->present()->email(), + ], "intent" => "CAPTURE", "payment_source" => $this->getPaymentSource(), "purchase_units" => [ diff --git a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php index 43554bebb306..0171c295ba2c 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php @@ -14,10 +14,12 @@ @endphp @section('gateway_head') - + @endsection @section('gateway_content') @@ -86,7 +88,7 @@ } - + @if(isset($merchantId)) @@ -185,8 +187,8 @@ // Render each field after checking for eligibility if (cardField.isEligible()) { - const nameField = cardField.NameField(); - nameField.render("#card-name-field-container"); + // const nameField = cardField.NameField(); + // nameField.render("#card-name-field-container"); const numberField = cardField.NumberField({ inputEvents: { From c9d1d5f04f58fbff6ad7d00653b99f2bcf43345a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 2 Aug 2024 13:07:34 +1000 Subject: [PATCH 9/9] Update paypal for fraudnet --- .../PayPalPPCPPaymentDriver.php | 27 +++++++++++++---- .../PayPalRestPaymentDriver.php | 30 ++++++++++++------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/app/PaymentDrivers/PayPalPPCPPaymentDriver.php b/app/PaymentDrivers/PayPalPPCPPaymentDriver.php index 8a52fe617a58..a62b24b6be8b 100644 --- a/app/PaymentDrivers/PayPalPPCPPaymentDriver.php +++ b/app/PaymentDrivers/PayPalPPCPPaymentDriver.php @@ -273,14 +273,14 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver ] ]; - - if($shipping = $this->getShippingAddress()) { + if($shipping = $this->getShippingAddress()) $order['purchase_units'][0]["shipping"] = $shipping; - } - if(isset($data['payment_source'])) { + if(isset($data['payment_source'])) $order['payment_source'] = $data['payment_source']; - } + + if(isset($data['payer'])) + $order['payer'] = $data['payer']; $r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order); @@ -316,8 +316,17 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver ->firstOrFail(); $orderId = $response['orderID']; + $r = $this->gatewayRequest("/v1/checkout/orders/{$orderId}/", 'delete', ['body' => '']); + $data["payer"] = [ + "name" => [ + "given_name" => $this->client->present()->first_name(), + "surname" => $this->client->present()->last_name() + ], + "email_address" => $this->client->present()->email(), + ]; + $data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee; $data["payment_source"] = [ "card" => [ @@ -393,6 +402,14 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver $data = []; $this->payment_hash = $payment_hash; + $data["payer"] = [ + "name" => [ + "given_name" => $this->client->present()->first_name(), + "surname" => $this->client->present()->last_name() + ], + "email_address" => $this->client->present()->email(), + ]; + $data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee; $data["payment_source"] = [ "card" => [ diff --git a/app/PaymentDrivers/PayPalRestPaymentDriver.php b/app/PaymentDrivers/PayPalRestPaymentDriver.php index 029b185eff36..dfbf86b75943 100644 --- a/app/PaymentDrivers/PayPalRestPaymentDriver.php +++ b/app/PaymentDrivers/PayPalRestPaymentDriver.php @@ -157,10 +157,6 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver } - - - - public function createOrder(array $data): string { @@ -173,13 +169,6 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver })->implode("\n"); $order = [ - "payer" => [ - "name" => [ - "given_name" => $this->client->present()->first_name(), - "surname" => $this->client->present()->last_name() - ], - "email_address" => $this->client->present()->email(), - ], "intent" => "CAPTURE", "payment_source" => $this->getPaymentSource(), "purchase_units" => [ @@ -220,6 +209,10 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver $order['payment_source'] = $data['payment_source']; } + if(isset($data["payer"])){ + $order['payer'] = $data["payer"]; + } + $r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order); nlog($r->json()); @@ -281,6 +274,13 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver nlog($r->body()); + $data["payer"] = [ + "name" => [ + "given_name" => $this->client->present()->first_name(), + "surname" => $this->client->present()->last_name() + ], + "email_address" => $this->client->present()->email(), + ]; $data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee; $data["payment_source"] = [ "card" => [ @@ -356,6 +356,14 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver $data = []; $this->payment_hash = $payment_hash; + $data['payer'] = [ + "name" => [ + "given_name" => $this->client->present()->first_name(), + "surname" => $this->client->present()->last_name() + ], + "email_address" => $this->client->present()->email(), + ]; + $data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee; $data["payment_source"] = [ "card" => [