diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index ea28645765f6..67d472836f49 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -46,7 +46,7 @@ class StorePaymentRequest extends Request $rules = [ 'client_id' => ['bail','required',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)->where('is_deleted', 0)], - 'invoices' => ['bail','sometimes', 'nullable', 'array', new ValidPayableInvoicesRule()], + 'invoices' => ['bail', 'sometimes', 'nullable', 'array', new ValidPayableInvoicesRule()], 'invoices.*.amount' => ['bail','required'], 'invoices.*.invoice_id' => ['bail','required','distinct', new ValidInvoicesRules($this->all()),Rule::exists('invoices', 'id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)], 'credits.*.credit_id' => ['bail','required','distinct', new ValidCreditsRules($this->all()),Rule::exists('credits', 'id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)], diff --git a/app/Http/ValidationRules/Payment/ValidInvoicesRules.php b/app/Http/ValidationRules/Payment/ValidInvoicesRules.php index 6e40a6e91ae6..043a2419efbb 100644 --- a/app/Http/ValidationRules/Payment/ValidInvoicesRules.php +++ b/app/Http/ValidationRules/Payment/ValidInvoicesRules.php @@ -85,11 +85,12 @@ class ValidInvoicesRules implements Rule //catch here nothing to do - we need this to prevent the last elseif triggering } elseif ($inv->status_id == Invoice::STATUS_DRAFT && floatval($invoice['amount']) > floatval($inv->amount)) { $this->error_msg = 'Amount cannot be greater than invoice balance'; - return false; } elseif (floatval($invoice['amount']) > floatval($inv->balance)) { $this->error_msg = ctrans('texts.amount_greater_than_balance_v5'); - + return false; + } elseif($inv->is_deleted){ + $this->error_msg = 'One or more invoices in this request have since been deleted'; return false; } } diff --git a/app/Http/ValidationRules/ValidPayableInvoicesRule.php b/app/Http/ValidationRules/ValidPayableInvoicesRule.php index be422be947ce..1473be96fc3b 100644 --- a/app/Http/ValidationRules/ValidPayableInvoicesRule.php +++ b/app/Http/ValidationRules/ValidPayableInvoicesRule.php @@ -35,7 +35,7 @@ class ValidPayableInvoicesRule implements Rule $invoices = []; if (is_array($value)) { - $invoices = Invoice::query()->whereIn('id', array_column($value, 'invoice_id'))->company()->get(); + $invoices = Invoice::query()->withTrashed()->whereIn('id', array_column($value, 'invoice_id'))->company()->get(); } foreach ($invoices as $invoice) { diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 07ef8532baee..2383c0f42af0 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -371,6 +371,14 @@ class Invoice extends BaseModel return $this->hasOne(Task::class); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function quote(): \Illuminate\Database\Eloquent\Relations\HasOne + { + return $this->hasOne(Quote::class); + } + public function expenses(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(Expense::class); @@ -423,7 +431,9 @@ class Invoice extends BaseModel public function isPayable(): bool { - if ($this->status_id == self::STATUS_DRAFT && $this->is_deleted == false) { + if($this->is_deleted) + return false; + elseif ($this->status_id == self::STATUS_DRAFT && $this->is_deleted == false) { return true; } elseif ($this->status_id == self::STATUS_SENT && $this->is_deleted == false) { return true; diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index fe1d0bbc1fec..a56ea37000e3 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -48,11 +48,9 @@ class Storecove { //config('ninja.storecove_api_key'); - //https://app.storecove.com/en/docs#_test_identifiers //check if identifier is able to send on the network. - //response = { "code": "OK", "email": false} public function discovery($identifier, $scheme, $network = 'peppol') { diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index 8387a799e4ad..4bc0ffe8ca3e 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -47,6 +47,8 @@ use InvoiceNinja\EInvoice\Models\Peppol\TaxCategoryType\ClassifiedTaxCategory; use InvoiceNinja\EInvoice\Models\Peppol\CustomerPartyType\AccountingCustomerParty; use InvoiceNinja\EInvoice\Models\Peppol\SupplierPartyType\AccountingSupplierParty; use InvoiceNinja\EInvoice\Models\Peppol\FinancialAccountType\PayeeFinancialAccount; +use InvoiceNinja\EInvoice\Models\Peppol\IdentifierType\ID; +use InvoiceNinja\EInvoice\Models\Peppol\PartyIdentification; class Peppol extends AbstractService { @@ -115,6 +117,7 @@ class Peppol extends AbstractService // ->setPaymentMeansCode($invoice->custom_value1) // ->setPayeeFinancialAccount($payeeFinancialAccount); // $ubl_invoice->setPaymentMeans($paymentMeans); + return $this; } @@ -464,6 +467,19 @@ $tax_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->calcInclusiv $party = new Party(); + if(strlen($this->invoice->client->vat_number ?? '') > 1) { + + $pi = new PartyIdentification; + $vatID = new ID; + $vatID->schemeID = 'IT:VAT'; + $vatID->value = $this->invoice->client->vat_number; + + $pi->ID = $vatID; + + $party->PartyIdentification[] = $pi; + + } + $party_name = new PartyName(); $party_name->Name = $this->invoice->client->present()->name(); $party->PartyName[] = $party_name; diff --git a/app/Services/Invoice/MarkInvoiceDeleted.php b/app/Services/Invoice/MarkInvoiceDeleted.php index 22860d97259d..65125740d0cb 100644 --- a/app/Services/Invoice/MarkInvoiceDeleted.php +++ b/app/Services/Invoice/MarkInvoiceDeleted.php @@ -13,6 +13,7 @@ namespace App\Services\Invoice; use App\Jobs\Inventory\AdjustProductInventory; use App\Models\Invoice; +use App\Models\Quote; use App\Services\AbstractService; use App\Utils\Traits\GeneratesCounter; @@ -45,7 +46,8 @@ class MarkInvoiceDeleted extends AbstractService ->deletePaymentables() ->adjustPayments() ->adjustPaidToDateAndBalance() - ->adjustLedger(); + ->adjustLedger() + ->triggeredActions(); return $this->invoice; } @@ -182,4 +184,15 @@ class MarkInvoiceDeleted extends AbstractService return $this; } + + private function triggeredActions(): self + { + if($this->invoice->quote){ + $this->invoice->quote->invoice_id = null; + $this->invoice->quote->status_id = Quote::STATUS_SENT; + $this->invoice->pushQuietly(); + } + + return $this; + } } diff --git a/tests/Integration/Einvoice/Storecove/StorecoveTest.php b/tests/Integration/Einvoice/Storecove/StorecoveTest.php index e121caf0ba5c..9b3178a44b0b 100644 --- a/tests/Integration/Einvoice/Storecove/StorecoveTest.php +++ b/tests/Integration/Einvoice/Storecove/StorecoveTest.php @@ -31,46 +31,44 @@ class StorecoveTest extends TestCase $this->markTestSkipped("do not run in CI"); } - public function testCreateLegalEntity() - { + // public function testCreateLegalEntity() + // { - $data = [ - 'acts_as_receiver' => true, - 'acts_as_sender' => true, - 'advertisements' => ['invoice'], - 'city' => $this->company->settings->city, - 'country' => 'DE', - 'county' => $this->company->settings->state, - 'line1' => $this->company->settings->address1, - 'line2' => $this->company->settings->address2, - 'party_name' => $this->company->present()->name(), - 'tax_registered' => true, - 'tenant_id' => $this->company->company_key, - 'zip' => $this->company->settings->postal_code, - 'peppol_identifiers' => [ - 'scheme' => 'DE:VAT', - 'id' => 'DE:VAT' - ], - ]; + // $data = [ + // 'acts_as_receiver' => true, + // 'acts_as_sender' => true, + // 'advertisements' => ['invoice'], + // 'city' => $this->company->settings->city, + // 'country' => 'DE', + // 'county' => $this->company->settings->state, + // 'line1' => $this->company->settings->address1, + // 'line2' => $this->company->settings->address2, + // 'party_name' => $this->company->present()->name(), + // 'tax_registered' => true, + // 'tenant_id' => $this->company->company_key, + // 'zip' => $this->company->settings->postal_code, + // 'peppol_identifiers' => [ + // 'scheme' => 'DE:VAT', + // 'id' => 'DE:VAT' + // ], + // ]; - $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); - $r = $sc->createLegalEntity($data, $this->company); + // $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + // $r = $sc->createLegalEntity($data, $this->company); - $this->assertIsArray($r); + // $this->assertIsArray($r); - } + // } - public function tesXAddPeppolIdentifier() - { + // public function testAddPeppolIdentifier() + // { - $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); - $r = $sc->addIdentifier(290868, "DE923356489", "DE:VAT"); + // $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + // $r = $sc->addIdentifier(290868, "DE923356489", "DE:VAT"); - // nlog($r->body()); - // $this->assertIsArray($r); - nlog($r); + // nlog($r); - } + // } // public function testUpdateLegalEntity() // { @@ -91,7 +89,6 @@ class StorecoveTest extends TestCase public function testGetLegalEntity() { - $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); $r = $sc->getLegalEntity(290868);