mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 11:04:37 -04:00
Use transaction when marking an invoice as paid
This commit is contained in:
parent
e961eb58fa
commit
384ce1fa8d
@ -237,6 +237,10 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
$data['$invoice.po_number'] = ['value' => $this->formatPoNumber(), 'label' => ctrans('texts.po_number')];
|
$data['$invoice.po_number'] = ['value' => $this->formatPoNumber(), 'label' => ctrans('texts.po_number')];
|
||||||
$data['$poNumber'] = &$data['$invoice.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['$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));
|
$arrKeysLength = array_map('strlen', array_keys($data));
|
||||||
array_multisort($arrKeysLength, SORT_DESC, $data);
|
array_multisort($arrKeysLength, SORT_DESC, $data);
|
||||||
@ -244,6 +248,22 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
return $data;
|
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()
|
private function formatInvoice()
|
||||||
{
|
{
|
||||||
$invoice = '';
|
$invoice = '';
|
||||||
@ -282,11 +302,15 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
$invoice_list = '<br><br>';
|
$invoice_list = '<br><br>';
|
||||||
|
|
||||||
foreach ($this->payment->invoices as $invoice) {
|
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_number_short')." {$invoice->number} <br>";
|
||||||
$invoice_list .= ctrans('texts.invoice_amount').' '.Number::formatMoney($invoice->pivot->amount, $this->client).'<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 .= ctrans('texts.invoice_balance').' '.Number::formatMoney($invoice->fresh()->balance, $this->client).'<br>';
|
||||||
$invoice_list .= '-----<br>';
|
$invoice_list .= '-----<br>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $invoice_list;
|
return $invoice_list;
|
||||||
|
@ -41,20 +41,37 @@ class MarkPaid extends AbstractService
|
|||||||
|
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
if ($this->invoice->status_id == Invoice::STATUS_DRAFT) {
|
|
||||||
$this->invoice->service()->markSent()->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Don't double pay*/
|
/*Don't double pay*/
|
||||||
if ($this->invoice->status_id == Invoice::STATUS_PAID) {
|
if ($this->invoice->status_id == Invoice::STATUS_PAID) {
|
||||||
return $this->invoice;
|
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 */
|
/* Create Payment */
|
||||||
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
|
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
|
||||||
|
|
||||||
$payment->amount = $this->invoice->balance;
|
$payment->amount = $payable_balance;
|
||||||
$payment->applied = $this->invoice->balance;
|
$payment->applied = $payable_balance;
|
||||||
$payment->status_id = Payment::STATUS_COMPLETED;
|
$payment->status_id = Payment::STATUS_COMPLETED;
|
||||||
$payment->client_id = $this->invoice->client_id;
|
$payment->client_id = $this->invoice->client_id;
|
||||||
$payment->transaction_reference = ctrans('texts.manual_entry');
|
$payment->transaction_reference = ctrans('texts.manual_entry');
|
||||||
@ -79,20 +96,20 @@ class MarkPaid extends AbstractService
|
|||||||
|
|
||||||
/* Create a payment relationship to the invoice entity */
|
/* Create a payment relationship to the invoice entity */
|
||||||
$payment->invoices()->attach($this->invoice->id, [
|
$payment->invoices()->attach($this->invoice->id, [
|
||||||
'amount' => $payment->amount,
|
'amount' => $payable_balance,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
event('eloquent.created: App\Models\Payment', $payment);
|
event('eloquent.created: App\Models\Payment', $payment);
|
||||||
|
|
||||||
$this->invoice->next_send_date = null;
|
$this->invoice->next_send_date = null;
|
||||||
|
|
||||||
$this->invoice
|
// $this->invoice
|
||||||
->service()
|
// ->service()
|
||||||
->setExchangeRate()
|
// ->setExchangeRate()
|
||||||
->updateBalance($payment->amount * -1)
|
// ->updateBalance($payment->amount * -1)
|
||||||
->updatePaidToDate($payment->amount)
|
// ->updatePaidToDate($payment->amount)
|
||||||
->setStatus(Invoice::STATUS_PAID)
|
// ->setStatus(Invoice::STATUS_PAID)
|
||||||
->save();
|
// ->save();
|
||||||
|
|
||||||
$this->invoice
|
$this->invoice
|
||||||
->service()
|
->service()
|
||||||
@ -101,7 +118,7 @@ class MarkPaid extends AbstractService
|
|||||||
->save();
|
->save();
|
||||||
|
|
||||||
$payment->ledger()
|
$payment->ledger()
|
||||||
->updatePaymentBalance($payment->amount * -1);
|
->updatePaymentBalance($payable_balance * -1);
|
||||||
|
|
||||||
\DB::connection(config('database.default'))->transaction(function () use ($payment) {
|
\DB::connection(config('database.default'))->transaction(function () use ($payment) {
|
||||||
|
|
||||||
|
@ -42,9 +42,9 @@ class ZeroCostProduct extends AbstractService
|
|||||||
|
|
||||||
$invoice = $this->subscription->service()->createInvoice($this->data);
|
$invoice = $this->subscription->service()->createInvoice($this->data);
|
||||||
|
|
||||||
$invoice->service()
|
$invoice = $invoice->service()
|
||||||
->markPaid()
|
->markPaid()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
$redirect_url = "/client/invoices/{$invoice->hashed_id}";
|
$redirect_url = "/client/invoices/{$invoice->hashed_id}";
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class EntityPaidToDateTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($invoice->balance, 20);
|
$this->assertEquals($invoice->balance, 20);
|
||||||
|
|
||||||
$invoice->service()->markPaid()->save();
|
$invoice = $invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$this->assertEquals($invoice->paid_to_date, 20);
|
$this->assertEquals($invoice->paid_to_date, 20);
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ class EntityPaidToDateTest extends TestCase
|
|||||||
{
|
{
|
||||||
$invoice = $this->bootNewInvoice();
|
$invoice = $this->bootNewInvoice();
|
||||||
|
|
||||||
$invoice->service()->markPaid()->save();
|
$invoice = $invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$this->assertEquals(20, $invoice->paid_to_date);
|
$this->assertEquals(20, $invoice->paid_to_date);
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class InvoiceAmountPaymentTest extends TestCase
|
|||||||
$this->assertEquals(25, $invoice->balance);
|
$this->assertEquals(25, $invoice->balance);
|
||||||
$this->assertEquals(25, $invoice->amount);
|
$this->assertEquals(25, $invoice->amount);
|
||||||
|
|
||||||
$invoice->service()->markPaid()->save();
|
$invoice = $invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$invoice->fresh();
|
$invoice->fresh();
|
||||||
|
|
||||||
|
@ -1422,7 +1422,7 @@ class PaymentTest extends TestCase
|
|||||||
$this->assertEquals(10, $this->invoice->balance);
|
$this->assertEquals(10, $this->invoice->balance);
|
||||||
$this->assertEquals(10, $this->invoice->client->fresh()->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->balance);
|
||||||
$this->assertEquals(0, $this->invoice->client->balance);
|
$this->assertEquals(0, $this->invoice->client->balance);
|
||||||
|
@ -40,7 +40,7 @@ class GoogleAnalyticsTest extends TestCase
|
|||||||
$invoice = $this->invoice;
|
$invoice = $this->invoice;
|
||||||
$client = $this->client;
|
$client = $this->client;
|
||||||
|
|
||||||
$invoice->service()->markPaid()->save();
|
$invoice = $invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$payment = $invoice->payments->first();
|
$payment = $invoice->payments->first();
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class InvoiceActionsTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->withoutEvents();
|
$this->withoutEvents();
|
||||||
|
|
||||||
$this->invoice->service()->markPaid()->save();
|
$this->invoice = $this->invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$this->assertFalse($this->invoiceDeletable($this->invoice));
|
$this->assertFalse($this->invoiceDeletable($this->invoice));
|
||||||
$this->assertTrue($this->invoiceReversable($this->invoice));
|
$this->assertTrue($this->invoiceReversable($this->invoice));
|
||||||
|
@ -82,7 +82,7 @@ class SubscriptionsCalcTest extends TestCase
|
|||||||
|
|
||||||
$this->assertFalse($sub_calculator->isPaidUp());
|
$this->assertFalse($sub_calculator->isPaidUp());
|
||||||
|
|
||||||
$invoice->service()->markPaid()->save();
|
$invoice = $invoice->service()->markPaid()->save();
|
||||||
|
|
||||||
$this->assertTrue($sub_calculator->isPaidUp());
|
$this->assertTrue($sub_calculator->isPaidUp());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user