mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Support rolling back converted status on a quote when the invoice has been deleted
This commit is contained in:
parent
25d3668050
commit
cd2b45edc9
@ -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)],
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -371,6 +371,14 @@ class Invoice extends BaseModel
|
||||
return $this->hasOne(Task::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne<Quote>
|
||||
*/
|
||||
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;
|
||||
|
@ -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')
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user