Merge pull request #4428 from turbo124/v5-develop

Refactor for handling Invoice deletion
This commit is contained in:
David Bomba 2020-12-04 07:41:42 +11:00 committed by GitHub
commit 20d313de71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 277 additions and 18 deletions

2
.gitignore vendored
View File

@ -17,7 +17,7 @@ local_version.txt
/resources/assets/bower
/public/logo
/storage/*
.env.dusk.local
/public/vendors/*
*.log

View File

@ -230,14 +230,16 @@ class InvoiceSumInclusive
private function setCalculatedAttributes()
{
/* If amount != balance then some money has been paid on the invoice, need to subtract this difference from the total to set the new balance */
if ($this->invoice->amount != $this->invoice->balance) {
$paid_to_date = $this->invoice->amount - $this->invoice->balance;
if ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
if ($this->invoice->amount != $this->invoice->balance) {
$paid_to_date = $this->invoice->amount - $this->invoice->balance;
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision) - $paid_to_date;
} else {
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision) - $paid_to_date;
} else {
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
}
}
/* Set new calculated total */
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);

View File

@ -102,7 +102,6 @@ class InvoiceController extends BaseController
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
@ -691,7 +690,7 @@ class InvoiceController extends BaseController
break;
case 'delete':
//need to make sure the invoice is cancelled first!!
$invoice->service()->handleCancellation()->save();
//$invoice->service()->handleCancellation()->save();
$this->invoice_repo->delete($invoice);

View File

@ -146,7 +146,7 @@ class CreateEntityPdf implements ShouldQueue
->build();
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
Storage::makeDirectory($path, 0775);
// Storage::makeDirectory($path, 0775);
$pdf = null;

View File

@ -45,7 +45,7 @@ class BouncedEmail extends Mailable implements ShouldQueue
$subject = ctrans("texts.notification_{$entity_type}_bounced_subject", ['invoice' => $invoice->number]);
return
$this->from(config('mail.from.name'), config('mail.from.address'))
$this->from(config('mail.from.address'), config('mail.from.name'))
->text()
->subject($subject);

View File

@ -30,7 +30,9 @@ class DownloadInvoices extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.name'), config('mail.from.address'))
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.download_files'))
->markdown(
'email.admin.download_files',

View File

@ -27,7 +27,9 @@ class ExistingMigration extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.name'), config('mail.from.address'))
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.existing');
}
}

View File

@ -29,7 +29,7 @@ class MigrationCompleted extends Mailable
{
$data['settings'] = auth()->user()->company()->settings;
return $this->from(config('mail.from.name'), config('mail.from.address'))
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.completed', $data);
}
}

View File

@ -31,7 +31,9 @@ class MigrationFailed extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.name'), config('mail.from.address'))
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.failed');
}
}

View File

@ -33,6 +33,7 @@ use Checkout\Library\Exceptions\CheckoutHttpException;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
/**
* Class BaseDriver.

View File

@ -69,13 +69,38 @@ class InvoiceRepository extends BaseRepository
return $invoice;
}
$invoice->service()->markDeleted()->handleCancellation()->save();
// $invoice->service()->markDeleted()->handleCancellation()->save();
$invoice = $invoice->service()->markDeleted()->save();
parent::delete($invoice);
return $invoice;
}
/**
* Handles the restoration on a deleted invoice.
*
* @param [type] $invoice [description]
* @return [type] [description]
*/
public function restore($invoice) :Invoice
{
//if we have just archived, only perform a soft restore
if(!$invoice->is_deleted) {
parent::restore($invoice);
return $invoice;
}
// reversed delete invoice actions
$invoice = $invoice->service()->handleRestore()->save();
parent::restore($invoice);
return $invoice;
}
public function reverse()
{
}

View File

@ -43,6 +43,7 @@ class MarkSent
->service()
->setStatus(Credit::STATUS_SENT)
->applyNumber()
->adjustBalance($this->credit->amount)
->save();

View File

@ -0,0 +1,111 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Services\Invoice;
use App\Models\Invoice;
use App\Services\AbstractService;
use Illuminate\Support\Facades\DB;
class HandleRestore extends AbstractService
{
private $invoice;
private $payment_total = 0;
public function __construct(Invoice $invoice)
{
$this->invoice = $invoice;
}
public function run()
{
if(!$this->invoice->is_deleted)
return $this->invoice;
//determine whether we need to un-delete payments OR just modify the payment amount /applied balances.
foreach($this->invoice->payments as $payment)
{
$payment->restore();
$payment->paymentables()
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->restore();
$payment_amount = $payment->paymentables()
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->sum(\DB::raw('amount'));
info($payment->amount . " == " . $payment_amount);
if($payment->amount == $payment_amount) {
$payment->is_deleted = false;
$payment->save();
}
else {
$payment->is_deleted = false;
$payment->amount += $this->payment_total;
$payment->applied += $this->payment_total;
$payment->save();
}
$this->payment_total += $payment_amount;
}
//adjust ledger balance
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, 'Restored invoice {$this->invoice->number}')->save();
//adjust paid to dates
$this->invoice->client->service()->updatePaidToDate($this->payment_total)->save();
$this->invoice->client->service()->updateBalance($this->invoice->balance)->save();
$this->invoice->ledger()->updatePaymentBalance($this->payment_total, 'Restored payment for invoice {$this->invoice->number}')->save();
$this->windBackInvoiceNumber();
return $this->invoice;
}
private function windBackInvoiceNumber()
{
$findme = '_' . ctrans('texts.deleted');
$pos = strpos($this->invoice->number, $findme);
$new_invoice_number = substr($this->invoice->number, 0, $pos);
try {
$this->invoice->number = $new_invoice_number;
$this->invoice->save();
}
catch(\Exception $e){
info("I could not wind back the invoice number");
}
}
}

View File

@ -164,6 +164,13 @@ class InvoiceService
return $this;
}
public function handleRestore()
{
$this->invoice = (new HandleRestore($this->invoice))->run();
return $this;
}
public function reverseCancellation()
{
$this->invoice = (new HandleCancellation($this->invoice))->reverse();

View File

@ -14,6 +14,7 @@ namespace App\Services\Invoice;
use App\Models\Invoice;
use App\Services\AbstractService;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Support\Facades\DB;
class MarkInvoiceDeleted extends AbstractService
{
@ -21,6 +22,10 @@ class MarkInvoiceDeleted extends AbstractService
private $invoice;
private $adjustment_amount = 0;
private $total_payments = 0;
public function __construct(Invoice $invoice)
{
$this->invoice = $invoice;
@ -28,7 +33,94 @@ class MarkInvoiceDeleted extends AbstractService
public function run()
{
if($this->invoice->is_deleted)
return $this->invoice;
// if(in_array($this->invoice->status_id, ['currencies', 'industries', 'languages', 'countries', 'banks']))
// return $this->
$this->cleanup()
->setAdjustmentAmount()
->deletePaymentables()
->adjustPayments()
->adjustPaidToDate()
->adjustBalance()
->adjustLedger();
return $this->invoice;
}
private function adjustLedger()
{
$this->invoice->ledger()->updatePaymentBalance($this->adjustment_amount * -1);
return $this;
}
private function adjustPaidToDate()
{
$this->invoice->client->service()->updatePaidToDate($this->adjustment_amount * -1)->save();
return $this;
}
private function adjustBalance()
{
$this->invoice->client->service()->updateBalance($this->invoice->balance * -1)->save();
return $this;
}
private function adjustPayments()
{
//if total payments = adjustment amount - that means we need to delete the payments as well.
if($this->adjustment_amount == $this->total_payments) {
$this->invoice->payments()->update(['payments.deleted_at' => now(), 'payments.is_deleted' => true]);
}
else {
//adjust payments down by the amount applied to the invoice payment.
$this->invoice->payments->each(function ($payment){
$payment_adjustment = $payment->paymentables
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->sum(DB::raw('amount'));
$payment->amount -= $payment_adjustment;
$payment->applied -= $payment_adjustment;
$payment->save();
});
}
return $this;
}
private function setAdjustmentAmount()
{
foreach ($this->invoice->payments as $payment) {
$this->adjustment_amount += $payment->paymentables
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->sum(DB::raw('amount'));
}
$this->total_payments = $this->invoice->payments->sum('amount');
return $this;
}
private function cleanup()
{
$check = false;
$x=0;
do {
@ -43,10 +135,10 @@ class MarkInvoiceDeleted extends AbstractService
$this->invoice->tasks()->update(['invoice_id' => null]);
$this->invoice->expenses()->update(['invoice_id' => null]);
return $this->invoice;
return $this;
}
private function calcNumber($x)
{
if ($x==0) {
@ -57,4 +149,19 @@ class MarkInvoiceDeleted extends AbstractService
return $number;
}
private function deletePaymentables()
{
$this->invoice->payments->each(function ($payment){
$payment->paymentables()
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->update(['deleted_at' => now()]);
});
return $this;
}
}