1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-12 14:12:44 +01:00

Use transaction when marking an invoice as paid

This commit is contained in:
David Bomba 2022-08-29 18:15:50 +10:00
parent e961eb58fa
commit 384ce1fa8d
9 changed files with 66 additions and 25 deletions

View File

@ -237,6 +237,10 @@ class PaymentEmailEngine extends BaseEmailEngine
$data['$invoice.po_number'] = ['value' => $this->formatPoNumber(), 'label' => ctrans('texts.po_number')];
$data['$poNumber'] = &$data['$invoice.po_number'];
$data['$payment.status'] = ['value' => $this->payment->stringStatus($this->payment->status_id), 'label' => ctrans('texts.payment_status')];
$data['$invoices.amount'] = ['value' => $this->formatInvoiceField('amount'), 'label' => ctrans('texts.invoices')];
$data['$invoices.balance'] = ['value' => $this->formatInvoiceField('balance'), 'label' => ctrans('texts.invoices')];
$data['$invoices.due_date'] = ['value' => $this->formatInvoiceField('due_date'), 'label' => ctrans('texts.invoices')];
$data['$invoices.po_number'] = ['value' => $this->formatInvoiceField('po_number'), 'label' => ctrans('texts.invoices')];
$arrKeysLength = array_map('strlen', array_keys($data));
array_multisort($arrKeysLength, SORT_DESC, $data);
@ -244,6 +248,22 @@ class PaymentEmailEngine extends BaseEmailEngine
return $data;
}
private function formatInvoiceField($field)
{
$invoice = '';
foreach ($this->payment->invoices as $invoice) {
$invoice_field = $invoice->{$field};
$invoice .= ctrans('texts.invoice_number_short') . "{$invoice->number} {$invoice_field}";
}
return $invoice;
}
private function formatInvoice()
{
$invoice = '';
@ -282,11 +302,15 @@ class PaymentEmailEngine extends BaseEmailEngine
$invoice_list = '<br><br>';
foreach ($this->payment->invoices as $invoice) {
$invoice_list .= ctrans('texts.po_number')." {$invoice->po_number} <br>";
if(strlen($invoice->po_number) > 1)
$invoice_list .= ctrans('texts.po_number')." {$invoice->po_number} <br>";
$invoice_list .= ctrans('texts.invoice_number_short')." {$invoice->number} <br>";
$invoice_list .= ctrans('texts.invoice_amount').' '.Number::formatMoney($invoice->pivot->amount, $this->client).'<br>';
$invoice_list .= ctrans('texts.invoice_balance').' '.Number::formatMoney($invoice->fresh()->balance, $this->client).'<br>';
$invoice_list .= '-----<br>';
}
return $invoice_list;

View File

@ -41,20 +41,37 @@ class MarkPaid extends AbstractService
public function run()
{
if ($this->invoice->status_id == Invoice::STATUS_DRAFT) {
$this->invoice->service()->markSent()->save();
}
/*Don't double pay*/
if ($this->invoice->status_id == Invoice::STATUS_PAID) {
return $this->invoice;
}
if ($this->invoice->status_id == Invoice::STATUS_DRAFT) {
$this->invoice->service()->markSent()->save();
}
$payable_balance = $this->invoice->balance;
\DB::connection(config('database.default'))->transaction(function () use($payable_balance) {
$this->invoice = Invoice::where('id', $this->invoice->id)->lockForUpdate()->first();
$this->invoice
->service()
->setExchangeRate()
->updateBalance($payable_balance * -1)
->updatePaidToDate($payable_balance)
->setStatus(Invoice::STATUS_PAID)
->save();
}, 1);
/* Create Payment */
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
$payment->amount = $this->invoice->balance;
$payment->applied = $this->invoice->balance;
$payment->amount = $payable_balance;
$payment->applied = $payable_balance;
$payment->status_id = Payment::STATUS_COMPLETED;
$payment->client_id = $this->invoice->client_id;
$payment->transaction_reference = ctrans('texts.manual_entry');
@ -79,20 +96,20 @@ class MarkPaid extends AbstractService
/* Create a payment relationship to the invoice entity */
$payment->invoices()->attach($this->invoice->id, [
'amount' => $payment->amount,
'amount' => $payable_balance,
]);
event('eloquent.created: App\Models\Payment', $payment);
$this->invoice->next_send_date = null;
$this->invoice
->service()
->setExchangeRate()
->updateBalance($payment->amount * -1)
->updatePaidToDate($payment->amount)
->setStatus(Invoice::STATUS_PAID)
->save();
// $this->invoice
// ->service()
// ->setExchangeRate()
// ->updateBalance($payment->amount * -1)
// ->updatePaidToDate($payment->amount)
// ->setStatus(Invoice::STATUS_PAID)
// ->save();
$this->invoice
->service()
@ -101,7 +118,7 @@ class MarkPaid extends AbstractService
->save();
$payment->ledger()
->updatePaymentBalance($payment->amount * -1);
->updatePaymentBalance($payable_balance * -1);
\DB::connection(config('database.default'))->transaction(function () use ($payment) {

View File

@ -42,9 +42,9 @@ class ZeroCostProduct extends AbstractService
$invoice = $this->subscription->service()->createInvoice($this->data);
$invoice->service()
->markPaid()
->save();
$invoice = $invoice->service()
->markPaid()
->save();
$redirect_url = "/client/invoices/{$invoice->hashed_id}";

View File

@ -72,7 +72,7 @@ class EntityPaidToDateTest extends TestCase
$this->assertEquals($invoice->balance, 20);
$invoice->service()->markPaid()->save();
$invoice = $invoice->service()->markPaid()->save();
$this->assertEquals($invoice->paid_to_date, 20);
}
@ -81,7 +81,7 @@ class EntityPaidToDateTest extends TestCase
{
$invoice = $this->bootNewInvoice();
$invoice->service()->markPaid()->save();
$invoice = $invoice->service()->markPaid()->save();
$this->assertEquals(20, $invoice->paid_to_date);

View File

@ -185,7 +185,7 @@ class InvoiceAmountPaymentTest extends TestCase
$this->assertEquals(25, $invoice->balance);
$this->assertEquals(25, $invoice->amount);
$invoice->service()->markPaid()->save();
$invoice = $invoice->service()->markPaid()->save();
$invoice->fresh();

View File

@ -1422,7 +1422,7 @@ class PaymentTest extends TestCase
$this->assertEquals(10, $this->invoice->balance);
$this->assertEquals(10, $this->invoice->client->fresh()->balance);
$this->invoice->service()->markPaid()->save();
$this->invoice = $this->invoice->service()->markPaid()->save();
$this->assertEquals(0, $this->invoice->balance);
$this->assertEquals(0, $this->invoice->client->balance);

View File

@ -40,7 +40,7 @@ class GoogleAnalyticsTest extends TestCase
$invoice = $this->invoice;
$client = $this->client;
$invoice->service()->markPaid()->save();
$invoice = $invoice->service()->markPaid()->save();
$payment = $invoice->payments->first();

View File

@ -45,7 +45,7 @@ class InvoiceActionsTest extends TestCase
{
$this->withoutEvents();
$this->invoice->service()->markPaid()->save();
$this->invoice = $this->invoice->service()->markPaid()->save();
$this->assertFalse($this->invoiceDeletable($this->invoice));
$this->assertTrue($this->invoiceReversable($this->invoice));

View File

@ -82,7 +82,7 @@ class SubscriptionsCalcTest extends TestCase
$this->assertFalse($sub_calculator->isPaidUp());
$invoice->service()->markPaid()->save();
$invoice = $invoice->service()->markPaid()->save();
$this->assertTrue($sub_calculator->isPaidUp());