From c25de936edd8db6baec45d67fd31da4cdda4c4fa Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 3 Feb 2020 21:33:07 +1100 Subject: [PATCH] Refactor - moving away from jobs. (#3279) * Implement Services * implement service pattern * Service patterns * Refactoring invoice paid * refactoring invoice * Refactor jobs * Refactor - remove jobs * Refactor jobs * Refactoring jobs * Refactoring away from jobs * Refactoring jobs * Add Credits to test data --- app/Console/Commands/CreateTestData.php | 55 ++++ app/DataMapper/CompanySettings.php | 1 + app/Http/Controllers/CreditController.php | 2 +- app/Http/Controllers/InvoiceController.php | 2 +- .../Requests/Payment/StorePaymentRequest.php | 2 + app/Jobs/Client/UpdateClientBalance.php | 54 ---- app/Jobs/Client/UpdateClientPaidToDate.php | 53 ---- app/Jobs/Credit/ApplyCreditPayment.php | 2 - app/Jobs/Credit/MarkCreditPaid.php | 4 - app/Jobs/Invoice/ApplyClientPayment.php | 65 ---- app/Jobs/Invoice/ApplyInvoiceNumber.php | 86 ------ app/Jobs/Invoice/ApplyInvoicePayment.php | 110 ------- app/Jobs/Invoice/ApplyPaymentToInvoice.php | 4 +- app/Jobs/Invoice/MarkInvoicePaid.php | 87 ------ app/Jobs/Invoice/ReverseInvoicePayment.php | 7 +- app/Jobs/Invoice/UpdateInvoicePayment.php | 64 ++-- .../Credit/CreateCreditInvitation.php | 56 ++++ app/Models/Client.php | 31 ++ app/Models/Invoice.php | 290 +++++++++--------- app/Models/Payment.php | 3 +- app/Repositories/InvoiceRepository.php | 5 +- app/Repositories/PaymentRepository.php | 10 +- app/Services/Client/ClientService.php | 53 ++++ app/Services/Invoice/ApplyNumber.php | 57 ++++ app/Services/Invoice/ApplyPayment.php | 61 ++++ app/Services/Invoice/InvoiceService.php | 165 ++++++++++ app/Services/Invoice/MarkPaid.php | 67 ++++ app/Services/Invoice/MarkSent.php | 53 ++++ app/Services/Invoice/UpdateBalance.php | 47 +++ app/Services/Payment/PaymentService.php | 45 +++ app/Utils/Traits/Payment/Refundable.php | 2 +- database/seeds/RandomDataSeeder.php | 30 +- tests/Integration/MarkInvoicePaidTest.php | 12 +- tests/Integration/UpdateCompanyLedgerTest.php | 3 +- 34 files changed, 910 insertions(+), 678 deletions(-) delete mode 100644 app/Jobs/Client/UpdateClientBalance.php delete mode 100644 app/Jobs/Client/UpdateClientPaidToDate.php delete mode 100644 app/Jobs/Invoice/ApplyClientPayment.php delete mode 100644 app/Jobs/Invoice/ApplyInvoiceNumber.php delete mode 100644 app/Jobs/Invoice/ApplyInvoicePayment.php delete mode 100644 app/Jobs/Invoice/MarkInvoicePaid.php create mode 100644 app/Listeners/Credit/CreateCreditInvitation.php create mode 100644 app/Services/Client/ClientService.php create mode 100644 app/Services/Invoice/ApplyNumber.php create mode 100644 app/Services/Invoice/ApplyPayment.php create mode 100644 app/Services/Invoice/InvoiceService.php create mode 100644 app/Services/Invoice/MarkPaid.php create mode 100644 app/Services/Invoice/MarkSent.php create mode 100644 app/Services/Invoice/UpdateBalance.php create mode 100644 app/Services/Payment/PaymentService.php diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index 8650d6c9a3..bcec391cfa 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -15,6 +15,7 @@ use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; use App\Jobs\Invoice\CreateInvoiceInvitations; use App\Jobs\Invoice\UpdateInvoicePayment; use App\Jobs\Quote\CreateQuoteInvitations; +use App\Listeners\Credit\CreateCreditInvitation; use App\Listeners\Invoice\CreateInvoiceInvitation; use App\Models\CompanyToken; use App\Models\Payment; @@ -136,6 +137,9 @@ class CreateTestData extends Command $this->info('creating invoice for client #'.$client->id); $this->createInvoice($client); + $this->info('creating credit for client #'.$client->id); + $this->createCredit($client); + $this->info('creating quote for client #'.$client->id); $this->createQuote($client); @@ -221,6 +225,12 @@ class CreateTestData extends Command for($i=0; $i<$this->count; $i++) $this->createInvoice($client); + $this->info('creating credit for client #'.$client->id); + + for($i=0; $i<$this->count; $i++) + $this->createCredit($client); + + $this->info('creating quote for client #'.$client->id); for($i=0; $i<$this->count; $i++) @@ -312,6 +322,9 @@ class CreateTestData extends Command $this->info('creating invoice for client #'.$client->id); $this->createInvoice($client); + $this->info('creating credit for client #'.$client->id); + $this->createCredit($client); + $this->info('creating quote for client #'.$client->id); $this->createQuote($client); @@ -472,6 +485,48 @@ class CreateTestData extends Command } } + private function createCredit($client) + { + $faker = \Faker\Factory::create(); + + $credit = factory(\App\Models\Credit::class)->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]); + + //$invoice = InvoiceFactory::create($client->company->id, $client->user->id);//stub the company and user_id + //$invoice->client_id = $client->id; +// $invoice->date = $faker->date(); + $dateable = Carbon::now()->subDays(rand(0,90)); + $credit->date = $dateable; + + $credit->line_items = $this->buildLineItems(rand(1,10)); + $credit->uses_inclusive_taxes = false; + + if (rand(0, 1)) { + $credit->tax_name1 = 'GST'; + $credit->tax_rate1 = 10.00; + } + + if (rand(0, 1)) { + $credit->tax_name2 = 'VAT'; + $credit->tax_rate2 = 17.50; + } + + if (rand(0, 1)) { + $credit->tax_name3 = 'CA Sales Tax'; + $credit->tax_rate3 = 5; + } + + $credit->save(); + + $invoice_calc = new InvoiceSum($credit); + $invoice_calc->build(); + + $credit = $invoice_calc->getInvoice(); + + $credit->save(); + + event(new CreateCreditInvitation($credit)); + + } private function createQuote($client) { diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index be41e8b8cd..6c4ad46381 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -71,6 +71,7 @@ class CompanySettings extends BaseSettings public $counter_number_applied = 'when_saved'; // when_saved , when_sent , when_paid public $quote_number_applied = 'when_saved'; // when_saved , when_sent + /* Counters */ public $invoice_number_pattern = ''; public $invoice_number_counter = 1; diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index e39a044da4..2263d38a78 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -142,7 +142,7 @@ class CreditController extends BaseController if ($credit->balance < 0 || $credit->status_id == Credit::STATUS_PAID || $credit->is_deleted === true) { return $this->errorResponse(['message' => 'Credit cannot be marked as paid'], 400); } - + //@todo fix and replace $credit = MarkInvoicePaid::dispatchNow($credit, $credit->company); if (!$bulk) { diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index ac241216ce..afc7e7f534 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -618,7 +618,7 @@ class InvoiceController extends BaseController return $this->errorResponse(['message' => 'Invoice cannot be marked as paid'], 400); } - $invoice = MarkInvoicePaid::dispatchNow($invoice, $invoice->company); + $invoice = $invoice->markPaid(); if (!$bulk) { return $this->itemResponse($invoice); diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index 00f26baeb0..b71bb8a31a 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -77,6 +77,8 @@ class StorePaymentRequest extends Request $input['amount'] = $invoices_total - $credits_total; } + $input['is_manual'] = true; + $this->replace($input); } diff --git a/app/Jobs/Client/UpdateClientBalance.php b/app/Jobs/Client/UpdateClientBalance.php deleted file mode 100644 index da2201357d..0000000000 --- a/app/Jobs/Client/UpdateClientBalance.php +++ /dev/null @@ -1,54 +0,0 @@ -amount = $amount; - $this->client = $client; - $this->company = $company; - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - $this->client->balance += $this->amount; - $this->client->save(); - } -} diff --git a/app/Jobs/Client/UpdateClientPaidToDate.php b/app/Jobs/Client/UpdateClientPaidToDate.php deleted file mode 100644 index d1d184deb1..0000000000 --- a/app/Jobs/Client/UpdateClientPaidToDate.php +++ /dev/null @@ -1,53 +0,0 @@ -amount = $amount; - $this->client = $client; - $this->company = $company; - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - $this->client->paid_to_date += $this->amount; - $this->client->save(); - } -} diff --git a/app/Jobs/Credit/ApplyCreditPayment.php b/app/Jobs/Credit/ApplyCreditPayment.php index d37bf12a26..4b7d47fde4 100644 --- a/app/Jobs/Credit/ApplyCreditPayment.php +++ b/app/Jobs/Credit/ApplyCreditPayment.php @@ -13,8 +13,6 @@ namespace App\Jobs\Credit; use App\Events\Payment\PaymentWasCreated; use App\Factory\PaymentFactory; -use App\Jobs\Client\UpdateClientBalance; -use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; use App\Jobs\Credit\ApplyPaymentToCredit; use App\Libraries\MultiDB; diff --git a/app/Jobs/Credit/MarkCreditPaid.php b/app/Jobs/Credit/MarkCreditPaid.php index 1815b347e8..00f3ba7b45 100644 --- a/app/Jobs/Credit/MarkCreditPaid.php +++ b/app/Jobs/Credit/MarkCreditPaid.php @@ -14,8 +14,6 @@ namespace App\Jobs\Invoice; use App\Events\Payment\PaymentWasCreated; use App\Factory\CreditFactory; use App\Factory\PaymentFactory; -use App\Jobs\Client\UpdateClientBalance; -use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; use App\Libraries\MultiDB; use App\Models\Company; @@ -77,8 +75,6 @@ class MarkCreditPaid implements ShouldQueue event(new PaymentWasCreated($payment, $payment->company)); // UpdateCompanyLedgerWithPayment::dispatchNow($payment, ($payment->amount*-1), $this->company); - // UpdateClientBalance::dispatchNow($payment->client, $payment->amount*-1, $this->company); - // UpdateClientPaidToDate::dispatchNow($payment->client, $payment->amount, $this->company); return $this->credit; } diff --git a/app/Jobs/Invoice/ApplyClientPayment.php b/app/Jobs/Invoice/ApplyClientPayment.php deleted file mode 100644 index 32b97cf939..0000000000 --- a/app/Jobs/Invoice/ApplyClientPayment.php +++ /dev/null @@ -1,65 +0,0 @@ -payment = $payment; - $this->company = $company; - } - - /** - * Execute the job. - * - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - $client = $this->payment->client; - $client->credit_balance += $this->payment->amount; - $client->paid_to_date += $this->payment->amount; - $client->save(); - } -} diff --git a/app/Jobs/Invoice/ApplyInvoiceNumber.php b/app/Jobs/Invoice/ApplyInvoiceNumber.php deleted file mode 100644 index f142f79093..0000000000 --- a/app/Jobs/Invoice/ApplyInvoiceNumber.php +++ /dev/null @@ -1,86 +0,0 @@ -invoice = $invoice; - - $this->settings = $settings; - - $this->company = $company; - } - - /** - * Execute the job. - * - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - - //return early - if ($this->invoice->number != '') { - return $this->invoice; - } - - switch ($this->settings->counter_number_applied) { - case 'when_saved': - $this->invoice->number = $this->getNextInvoiceNumber($this->invoice->client); - break; - case 'when_sent': - if ($this->invoice->status_id == Invoice::STATUS_SENT) { - $this->invoice->number = $this->getNextInvoiceNumber($this->invoice->client); - } - break; - - default: - # code... - break; - } - - $this->invoice->save(); - - return $this->invoice; - } -} diff --git a/app/Jobs/Invoice/ApplyInvoicePayment.php b/app/Jobs/Invoice/ApplyInvoicePayment.php deleted file mode 100644 index bee6178327..0000000000 --- a/app/Jobs/Invoice/ApplyInvoicePayment.php +++ /dev/null @@ -1,110 +0,0 @@ -invoice = $invoice; - $this->payment = $payment; - $this->amount = $amount; - $this->company = $company; - } - - /** - * Execute the job. - * - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($this->amount*-1), $this->company); - UpdateClientBalance::dispatchNow($this->payment->client, $this->amount*-1, $this->company); - //UpdateClientPaidToDate::dispatchNow($this->payment->client, $this->amount, $this->company); - - /* Update Pivot Record amount */ - $this->payment->invoices->each(function ($inv) { - if ($inv->id == $this->invoice->id) { - $inv->pivot->amount = $this->amount; - $inv->pivot->save(); - } - }); - - if ($this->invoice->hasPartial()) { - //is partial and amount is exactly the partial amount - if ($this->invoice->partial == $this->amount) { - $this->invoice->clearPartial(); - $this->invoice->setDueDate(); - $this->invoice->setStatus(Invoice::STATUS_PARTIAL); - $this->invoice->updateBalance($this->amount*-1); - } elseif ($this->invoice->partial > 0 && $this->invoice->partial > $this->amount) { //partial amount exists, but the amount is less than the partial amount - $this->invoice->partial -= $this->amount; - $this->invoice->updateBalance($this->amount*-1); - } elseif ($this->invoice->partial > 0 && $this->invoice->partial < $this->amount) { //partial exists and the amount paid is GREATER than the partial amount - $this->invoice->clearPartial(); - $this->invoice->setDueDate(); - $this->invoice->setStatus(Invoice::STATUS_PARTIAL); - $this->invoice->updateBalance($this->amount*-1); - } - } elseif ($this->amount == $this->invoice->balance) { //total invoice paid. - $this->invoice->clearPartial(); - //$this->invoice->setDueDate(); - $this->invoice->setStatus(Invoice::STATUS_PAID); - $this->invoice->updateBalance($this->amount*-1); - } elseif($this->amount < $this->invoice->balance) { //partial invoice payment made - $this->invoice->clearPartial(); - $this->invoice->updateBalance($this->amount*-1); - } - - /* Update Payment Applied Amount*/ - // $this->payment->applied += $this->amount; - // $this->payment->save(); - } - - -} diff --git a/app/Jobs/Invoice/ApplyPaymentToInvoice.php b/app/Jobs/Invoice/ApplyPaymentToInvoice.php index 38f84150fa..d5f5094cd4 100644 --- a/app/Jobs/Invoice/ApplyPaymentToInvoice.php +++ b/app/Jobs/Invoice/ApplyPaymentToInvoice.php @@ -12,7 +12,6 @@ namespace App\Jobs\Invoice; use App\Events\Invoice\InvoiceWasPaid; -use App\Jobs\Invoice\ApplyInvoiceNumber; use App\Libraries\MultiDB; use App\Models\Company; use App\Models\Invoice; @@ -38,6 +37,7 @@ class ApplyPaymentToInvoice implements ShouldQueue private $company; /** + * @deprecated confirm to be deleted * Create a new job instance. * * @return void @@ -113,7 +113,7 @@ class ApplyPaymentToInvoice implements ShouldQueue $this->invoice->save(); - $this->invoice = ApplyInvoiceNumber::dispatchNow($this->invoice, $invoice->client->getMergedSettings(), $this->invoice->company); + $this->invoice = $this->invoice->applyNumber()->save(); return $this->invoice; } diff --git a/app/Jobs/Invoice/MarkInvoicePaid.php b/app/Jobs/Invoice/MarkInvoicePaid.php deleted file mode 100644 index f33e89d756..0000000000 --- a/app/Jobs/Invoice/MarkInvoicePaid.php +++ /dev/null @@ -1,87 +0,0 @@ -invoice = $invoice; - $this->company = $company; - } - - /** - * Execute the job. - * - * - * @return void - */ - public function handle() - { - MultiDB::setDB($this->company->db); - - if($this->invoice->status_id == Invoice::STATUS_DRAFT) - $this->invoice->markSent(); - - /* Create Payment */ - $payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id); - - $payment->amount = $this->invoice->balance; - $payment->status_id = Payment::STATUS_COMPLETED; - $payment->client_id = $this->invoice->client_id; - $payment->transaction_reference = ctrans('texts.manual_entry'); - /* Create a payment relationship to the invoice entity */ - $payment->save(); - - $payment->invoices()->attach($this->invoice->id, [ - 'amount' => $payment->amount - ]); - - $this->invoice->updateBalance($payment->amount*-1); - - /* Update Invoice balance */ - event(new PaymentWasCreated($payment, $payment->company)); - - UpdateCompanyLedgerWithPayment::dispatchNow($payment, ($payment->amount*-1), $this->company); - UpdateClientBalance::dispatchNow($payment->client, $payment->amount*-1, $this->company); - UpdateClientPaidToDate::dispatchNow($payment->client, $payment->amount, $this->company); - - return $this->invoice; - } -} diff --git a/app/Jobs/Invoice/ReverseInvoicePayment.php b/app/Jobs/Invoice/ReverseInvoicePayment.php index 28f880ab4d..35ab365250 100644 --- a/app/Jobs/Invoice/ReverseInvoicePayment.php +++ b/app/Jobs/Invoice/ReverseInvoicePayment.php @@ -11,8 +11,6 @@ namespace App\Jobs\Invoice; -use App\Jobs\Client\UpdateClientBalance; -use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; use App\Jobs\Util\SystemLogger; @@ -70,8 +68,9 @@ class ReverseInvoicePayment implements ShouldQueue UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($this->payment->amount), $this->company); - UpdateClientBalance::dispatchNow($client, $this->payment->amount, $this->company); + $client->updateBalance($this->payment->amount) + ->updatePaidToDate($this->payment->amount*-1) + ->save(); - UpdateClientPaidToDate::dispatchNow($client, $this->payment->amount*-1, $this->company); } } diff --git a/app/Jobs/Invoice/UpdateInvoicePayment.php b/app/Jobs/Invoice/UpdateInvoicePayment.php index 64c953b055..b932a13897 100644 --- a/app/Jobs/Invoice/UpdateInvoicePayment.php +++ b/app/Jobs/Invoice/UpdateInvoicePayment.php @@ -11,8 +11,6 @@ namespace App\Jobs\Invoice; -use App\Jobs\Client\UpdateClientBalance; -use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; use App\Jobs\Util\SystemLogger; @@ -36,6 +34,7 @@ class UpdateInvoicePayment implements ShouldQueue private $company; /** + * @deprecated we only use this in test data creation. shouldn't be used in production * Create the event listener. * * @return void @@ -64,14 +63,18 @@ class UpdateInvoicePayment implements ShouldQueue if (strval($invoices_total) === strval($this->payment->amount)) { $invoices->each(function ($invoice) { UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($invoice->balance*-1), $this->company); - UpdateClientBalance::dispatchNow($this->payment->client, $invoice->balance*-1, $this->company); - UpdateClientPaidToDate::dispatchNow($this->payment->client, $invoice->balance, $this->company); - + + $this->payment->client + ->updateBalance($invoice->balance*-1) + ->updatePaidToDate($invoice->balance) + ->save(); + $invoice->pivot->amount = $invoice->balance; $invoice->pivot->save(); - $invoice->clearPartial(); - $invoice->updateBalance($invoice->balance*-1); + $invoice->clearPartial() + ->updateBalance($invoice->balance*-1) + ->save(); }); } /*Combination of partials and full invoices are being paid*/ @@ -92,25 +95,30 @@ class UpdateInvoicePayment implements ShouldQueue $invoices->each(function ($invoice) { if ($invoice->hasPartial()) { UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($invoice->partial*-1), $this->company); - UpdateClientBalance::dispatchNow($this->payment->client, $invoice->partial*-1, $this->company); - UpdateClientPaidToDate::dispatchNow($this->payment->client, $invoice->partial, $this->company); + + $this->payment->client->updateBalance($invoice->partial*-1) + ->updatePaidToDate($invoice->partial) + ->save(); + $invoice->pivot->amount = $invoice->partial; $invoice->pivot->save(); - $invoice->updateBalance($invoice->partial*-1); - $invoice->clearPartial(); - $invoice->setDueDate(); - $invoice->setStatus(Invoice::STATUS_PARTIAL); + $invoice->updateBalance($invoice->partial*-1) + ->clearPartial() + ->setDueDate() + ->setStatus(Invoice::STATUS_PARTIAL) + ->save(); } else { UpdateCompanyLedgerWithPayment::dispatchNow($this->payment, ($invoice->balance*-1), $this->company); - UpdateClientBalance::dispatchNow($this->payment->client, $invoice->balance*-1, $this->company); - UpdateClientPaidToDate::dispatchNow($this->payment->client, $invoice->balance, $this->company); + + $this->payment->client->updateBalance($invoice->balance*-1) + ->updatePaidToDate($invoice->balance) + ->save(); $invoice->pivot->amount = $invoice->balance; $invoice->pivot->save(); - $invoice->clearPartial(); - $invoice->updateBalance($invoice->balance*-1); + $invoice->clearPartial()->updateBalance($invoice->balance*-1)->save(); } }); } else { @@ -138,25 +146,3 @@ class UpdateInvoicePayment implements ShouldQueue } } } - -/* - $this->payment = $event->payment; - $invoice = $this->payment->invoice; - $adjustment = $this->payment->amount * -1; - $partial = max(0, $invoice->partial - $this->payment->amount); - - $invoice->updateBalances($adjustment, $partial); - $invoice->updatePaidStatus(true); - - // store a backup of the invoice - $activity = Activity::wherePaymentId($this->payment->id) - ->whereActivityTypeId(ACTIVITY_TYPE_CREATE_PAYMENT) - ->first(); - $activity->json_backup = $invoice->hidePrivateFields()->toJSON(); - $activity->save(); - - if ($invoice->balance == 0 && $this->payment->account->auto_archive_invoice) { - $invoiceRepo = app('App\Ninja\Repositories\InvoiceRepository'); - $invoiceRepo->archive($invoice); - } -*/ diff --git a/app/Listeners/Credit/CreateCreditInvitation.php b/app/Listeners/Credit/CreateCreditInvitation.php new file mode 100644 index 0000000000..d9cad47552 --- /dev/null +++ b/app/Listeners/Credit/CreateCreditInvitation.php @@ -0,0 +1,56 @@ +credit; + + $contacts = $credit->client->contacts; + + $contacts->each(function ($contact) use ($credit) { + $invitation = InvoiceInvitation::whereCompanyId($credit->company_id) + ->whereClientContactId($contact->id) + ->whereCreditId($credit->id) + ->first(); + + if (!$invitation && $contact->send_credit) { + $ii = CreditInvitationFactory::create($credit->company_id, $credit->user_id); + $ii->credit_id = $credit->id; + $ii->client_contact_id = $contact->id; + $ii->save(); + } elseif ($invitation && !$contact->send_credit) { + $invitation->delete(); + } + }); + } +} diff --git a/app/Models/Client.php b/app/Models/Client.php index ae3e1c046c..f55de9884b 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -26,6 +26,7 @@ use App\Models\GroupSetting; use App\Models\Language; use App\Models\Timezone; use App\Models\User; +use App\Services\Client\ClientService; use App\Utils\Traits\CompanyGatewaySettings; use App\Utils\Traits\GeneratesCounter; use App\Utils\Traits\MakesDates; @@ -206,6 +207,36 @@ class Client extends BaseModel })->first(); } + public function service() :ClientService + { + return new ClientService($this); + } + + public function updatePaidToDate($amount) :ClientService + { + return $this->service()->updatePaidToDate($amount); + } + + public function updateBalance($amount) :ClientService + { + return $this->service()->updateBalance($amount); + } + /** + * Adjusts client "balances" when a client + * makes a payment that goes on file, but does + * not effect the client.balance record + * + * @param float $amount Adjustment amount + * @return Client + */ + public function processUnappliedPayment($amount) :Client + { + + return $this->service()->updatePaidToDate($amount) + ->adjustCreditBalance($amount) + ->save(); + } + /** * * Returns the entire filtered set diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 0dbbd44a8f..79a35cb594 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -18,11 +18,11 @@ use App\Helpers\Invoice\InvoiceSum; use App\Helpers\Invoice\InvoiceSumInclusive; use App\Jobs\Client\UpdateClientBalance; use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; -use App\Jobs\Invoice\ApplyInvoiceNumber; use App\Jobs\Invoice\CreateInvoicePdf; use App\Models\Currency; use App\Models\Filterable; use App\Models\PaymentTerm; +use App\Services\Invoice\InvoiceService; use App\Utils\Number; use App\Utils\Traits\InvoiceEmailBuilder; use App\Utils\Traits\MakesDates; @@ -115,22 +115,6 @@ class Invoice extends BaseModel const STATUS_UNPAID = -2; const STATUS_REVERSED = -3; - - public function getStatusAttribute() - { - if ($this->status_id == Invoice::STATUS_SENT && $this->due_date > Carbon::now()) { - return Invoice::STATUS_UNPAID; - } elseif ($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date > Carbon::now()) { - return Invoice::STATUS_UNPAID; - } elseif ($this->status_id == Invoice::STATUS_SENT && $this->due_date < Carbon::now()) { - return Invoice::STATUS_OVERDUE; - } elseif ($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date < Carbon::now()) { - return Invoice::STATUS_OVERDUE; - } else { - return $this->status_id; - } - } - public function company() { return $this->belongsTo(Company::class); @@ -176,11 +160,83 @@ class Invoice extends BaseModel return $this->belongsToMany(Credit::class)->using(Paymentable::class)->withPivot('amount','refunded')->withTimestamps();; } + /** + * Service entry points + */ + public function service() :InvoiceService + { + return new InvoiceService($this); + } + + public function markPaid() :InvoiceService + { + return $this->service()->markPaid(); + } + + public function applyNumber() :InvoiceService + { + return $this->service()->applyNumber(); + } + + public function applyPayment($payment, $payment_amount) :InvoiceService + { + return $this->service()->applyPayment($payment, $payment_amount); + } + + public function updateBalance($balance_adjustment) :InvoiceService + { + return $this->service()->updateBalance($balance_adjustment); + } + + public function setDueDate() :InvoiceService + { + return $this->service->setDueDate(); + } + + public function setStatus($status) :InvoiceService + { + return $this->service()->setStatus($status); + } + + public function clearPartial() :InvoiceService + { + return $this->service()->clearPartial(); + } + + public function updatePartial($amount) :InvoiceService + { + return $this->service()->updatePartial($amount); + } + + public function markSent() :InvoiceService + { + return $this->service()->markSent(); + } + + public function markViewed() :InvoiceService + { + return $this->service()->markViewed(); + } /* ---------------- */ /* Settings getters */ /* ---------------- */ + public function getStatusAttribute() + { + if ($this->status_id == Invoice::STATUS_SENT && $this->due_date > Carbon::now()) { + return Invoice::STATUS_UNPAID; + } elseif ($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date > Carbon::now()) { + return Invoice::STATUS_UNPAID; + } elseif ($this->status_id == Invoice::STATUS_SENT && $this->due_date < Carbon::now()) { + return Invoice::STATUS_OVERDUE; + } elseif ($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date < Carbon::now()) { + return Invoice::STATUS_OVERDUE; + } else { + return $this->status_id; + } + } + /** * If True, prevents an invoice from being * modified once it has been marked as sent @@ -192,30 +248,6 @@ class Invoice extends BaseModel return $this->client->getSetting('lock_sent_invoices'); } -// /** -// * Determines if invoice overdue. -// * -// * @param float $balance The balance -// * @param date. $due_date The due date -// * -// * @return boolean True if overdue, False otherwise. -// */ -// public static function isOverdue($balance, $due_date) -// { -// if (! $this->formatValue($balance,2) > 0 || ! $due_date) { -// return false; -// } -// -// // it isn't considered overdue until the end of the day -// return strtotime($this->createClientDate(date(), $this->client->timezone()->name)) > (strtotime($due_date) + (60 * 60 * 24)); -// } - - public function markViewed() :void - { - $this->last_viewed = Carbon::now()->format('Y-m-d H:i'); - $this->save(); - } - public function isPayable() : bool { if ($this->status_id == Invoice::STATUS_SENT && $this->is_deleted == false) { @@ -244,6 +276,22 @@ class Invoice extends BaseModel } + /** + * @return bool + */ + public function isPartial() : bool + { + return $this->status_id >= self::STATUS_PARTIAL; + } + + /** + * @return bool + */ + public function hasPartial() : bool + { + return ($this->partial && $this->partial > 0) === true; + } + public static function badgeForStatus(int $status) { switch ($status) { @@ -368,122 +416,12 @@ class Invoice extends BaseModel return $storage_path; } - /** - * @param bool $save - */ - public function updatePaidStatus($paid = false, $save = true) : bool - { - $status_id = false; - if ($paid && $this->balance == 0) { - $status_id = self::STATUS_PAID; - } elseif ($paid && $this->balance > 0 && $this->balance < $this->amount) { - $status_id = self::STATUS_PARTIAL; - } elseif ($this->hasPartial() && $this->balance > 0) { - $status_id = ($this->balance == $this->amount ? self::STATUS_SENT : self::STATUS_PARTIAL); - } - - if ($status_id && $status_id != $this->status_id) { - $this->status_id = $status_id; - if ($save) { - $this->save(); - } - } - } - - /** - * @return bool - */ - public function hasPartial() : bool - { - return ($this->partial && $this->partial > 0) === true; - } - - /** - * @return bool - */ - public function isPartial() : bool - { - return $this->status_id >= self::STATUS_PARTIAL; - } - - /** - * Clear partial fields - * @return void - */ - public function clearPartial() : void - { - $this->partial = null; - $this->partial_due_date = null; - $this->save(); - } - - /** - * @param float $balance_adjustment - */ - public function updateBalance($balance_adjustment) - { - if ($this->is_deleted) { - return; - } - - $balance_adjustment = floatval($balance_adjustment); - - $this->balance = $this->balance + $balance_adjustment; - - if ($this->balance == 0) { - $this->status_id = self::STATUS_PAID; - $this->save(); - event(new InvoiceWasPaid($this, $this->company)); - - return; - } - - $this->save(); - } - - public function setDueDate() - { - $this->due_date = Carbon::now()->addDays($this->client->getSetting('payment_terms')); - $this->save(); - } - - public function setStatus($status) - { - $this->status_id = $status; - $this->save(); - } - - public function markSent() - { - /* Return immediately if status is not draft */ - if ($this->status_id != Invoice::STATUS_DRAFT) { - return $this; - } - - $this->status_id = Invoice::STATUS_SENT; - - $this->markInvitationsSent(); - - $this->setReminder(); - - event(new InvoiceWasMarkedSent($this, $this->company)); - - UpdateClientBalance::dispatchNow($this->client, $this->balance, $this->company); - - ApplyInvoiceNumber::dispatchNow($this, $this->client->getMergedSettings(), $this->company); - - UpdateCompanyLedgerWithInvoice::dispatchNow($this, $this->balance, $this->company); - - $this->save(); - - return $this; - } /** * Updates Invites to SENT * */ - private function markInvitationsSent() + public function markInvitationsSent() { $this->invitations->each(function ($invitation) { if (!isset($invitation->sent_date)) { @@ -492,4 +430,52 @@ class Invoice extends BaseModel } }); } + + +/* Graveyard */ + +// /** +// * Determines if invoice overdue. +// * +// * @param float $balance The balance +// * @param date. $due_date The due date +// * +// * @return boolean True if overdue, False otherwise. +// */ +// public static function isOverdue($balance, $due_date) +// { +// if (! $this->formatValue($balance,2) > 0 || ! $due_date) { +// return false; +// } +// +// // it isn't considered overdue until the end of the day +// return strtotime($this->createClientDate(date(), $this->client->timezone()->name)) > (strtotime($due_date) + (60 * 60 * 24)); +// } + + + /** + * @param bool $save + * + * Has this been dragged from V1? + */ + // public function updatePaidStatus($paid = false, $save = true) : bool + // { + // $status_id = false; + // if ($paid && $this->balance == 0) { + // $status_id = self::STATUS_PAID; + // } elseif ($paid && $this->balance > 0 && $this->balance < $this->amount) { + // $status_id = self::STATUS_PARTIAL; + // } elseif ($this->hasPartial() && $this->balance > 0) { + // $status_id = ($this->balance == $this->amount ? self::STATUS_SENT : self::STATUS_PARTIAL); + // } + + // if ($status_id && $status_id != $this->status_id) { + // $this->status_id = $status_id; + // if ($save) { + // $this->save(); + // } + // } + // } + + } diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 1395f671ae..94feb80dc2 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -59,7 +59,8 @@ class Payment extends BaseModel 'amount', 'date', 'transaction_reference', - 'number' + 'number', + 'is_manual' ]; protected $casts = [ diff --git a/app/Repositories/InvoiceRepository.php b/app/Repositories/InvoiceRepository.php index 730a2fa319..3fc1aef117 100644 --- a/app/Repositories/InvoiceRepository.php +++ b/app/Repositories/InvoiceRepository.php @@ -16,7 +16,6 @@ use App\Events\Invoice\InvoiceWasUpdated; use App\Factory\InvoiceInvitationFactory; use App\Helpers\Invoice\InvoiceSum; use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; -use App\Jobs\Invoice\ApplyInvoiceNumber; use App\Jobs\Invoice\CreateInvoiceInvitations; use App\Jobs\Product\UpdateOrCreateProduct; use App\Listeners\Invoice\CreateInvoiceInvitation; @@ -115,7 +114,7 @@ class InvoiceRepository extends BaseRepository UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, ($finished_amount - $starting_amount), $invoice->company); } - $invoice = ApplyInvoiceNumber::dispatchNow($invoice, $invoice->client->getMergedSettings(), $invoice->company); + $invoice = $invoice->applyNumber()->save(); if ($invoice->company->update_products !== false) { UpdateOrCreateProduct::dispatch($invoice->line_items, $invoice, $invoice->company); @@ -133,6 +132,6 @@ class InvoiceRepository extends BaseRepository */ public function markSent(Invoice $invoice) : ?Invoice { - return $invoice->markSent(); + return $invoice->markSent()->save(); } } diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index ebcf1480bf..54d3b987df 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -13,11 +13,8 @@ namespace App\Repositories; use App\Events\Payment\PaymentWasCreated; use App\Factory\CreditFactory; -use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; use App\Jobs\Credit\ApplyCreditPayment; -use App\Jobs\Invoice\ApplyClientPayment; -use App\Jobs\Invoice\ApplyInvoicePayment; use App\Jobs\Invoice\UpdateInvoicePayment; use App\Models\Credit; use App\Models\Invoice; @@ -80,8 +77,7 @@ class PaymentRepository extends BaseRepository if (!$payment->number) $payment->number = $payment->client->getNextPaymentNumber($payment->client); - //we only ever update the ACTUAL amount of money transferred - UpdateClientPaidToDate::dispatchNow($payment->client, $payment->amount, $payment->company); + $payment->client->updatePaidToDate($payment->amount)->save(); $invoice_totals = 0; $credit_totals = 0; @@ -98,12 +94,12 @@ class PaymentRepository extends BaseRepository $invoice = Invoice::whereId($paid_invoice['invoice_id'])->first(); if ($invoice) { - ApplyInvoicePayment::dispatchNow($invoice, $payment, $paid_invoice['amount'], $invoice->company); + $invoice->applyPayment($payment, $paid_invoice['amount'])->save(); } } } else { //payment is made, but not to any invoice, therefore we are applying the payment to the clients credit - ApplyClientPayment::dispatchNow($payment, $payment->company); + $payment->client->processUnappliedPayment($payment->amount); } if (array_key_exists('credits', $data) && is_array($data['credits'])) { diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php new file mode 100644 index 0000000000..7e5fe342af --- /dev/null +++ b/app/Services/Client/ClientService.php @@ -0,0 +1,53 @@ +client = $client; + } + + public function updateBalance(float $amount) + { + $this->client->balance += $amount; + + return $this; + } + + public function updatePaidToDate(float $amount) + { + $this->client->paid_to_date += $amount; + + return $this; + } + + public function adjustCreditBalance(float $amount) + { + $this->client->credit_balance += $amount; + + return $this; + } + + public function save() :Client + { + $this->client->save(); + + return $this->client; + } +} diff --git a/app/Services/Invoice/ApplyNumber.php b/app/Services/Invoice/ApplyNumber.php new file mode 100644 index 0000000000..cab9a58ef2 --- /dev/null +++ b/app/Services/Invoice/ApplyNumber.php @@ -0,0 +1,57 @@ +client = $client; + } + + public function __invoke($invoice) + { + + if ($invoice->number != '') + return $invoice; + + switch ($this->client->getSetting('counter_number_applied')) { + case 'when_saved': + $invoice->number = $this->getNextInvoiceNumber($this->client); + break; + case 'when_sent': + if ($invoice->status_id == Invoice::STATUS_SENT) { + $invoice->number = $this->getNextInvoiceNumber($this->client); + } + break; + + default: + # code... + break; + } + + return $invoice; + } +} \ No newline at end of file diff --git a/app/Services/Invoice/ApplyPayment.php b/app/Services/Invoice/ApplyPayment.php new file mode 100644 index 0000000000..737b934900 --- /dev/null +++ b/app/Services/Invoice/ApplyPayment.php @@ -0,0 +1,61 @@ +invoice = $invoice; + } + + public function __invoke($payment, $payment_amount) + { + + UpdateCompanyLedgerWithPayment::dispatchNow($payment, ($payment_amount*-1), $payment->company); + + $payment->client->updateBalance($payment_amount*-1)->save(); + + /* Update Pivot Record amount */ + $payment->invoices->each(function ($inv) use($payment_amount){ + if ($inv->id == $this->invoice->id) { + $inv->pivot->amount = $payment_amount; + $inv->pivot->save(); + } + }); + + if ($this->invoice->hasPartial()) { + //is partial and amount is exactly the partial amount + if ($this->invoice->partial == $payment_amount) { + $this->invoice->clearPartial()->setDueDate()->setStatus(Invoice::STATUS_PARTIAL)->updateBalance($payment_amount*-1); + } elseif ($this->invoice->partial > 0 && $this->invoice->partial > $payment_amount) { //partial amount exists, but the amount is less than the partial amount + $this->invoice->updatePartial($payment_amount*-1)->updateBalance($payment_amount*-1); + } elseif ($this->invoice->partial > 0 && $this->invoice->partial < $payment_amount) { //partial exists and the amount paid is GREATER than the partial amount + $this->invoice->clearPartial()->setDueDate()->setStatus(Invoice::STATUS_PARTIAL)->updateBalance($payment_amount*-1); + } + } elseif ($payment_amount == $this->invoice->balance) { //total invoice paid. + $this->invoice->clearPartial()->setStatus(Invoice::STATUS_PAID)->updateBalance($payment_amount*-1); + } elseif($payment_amount < $this->invoice->balance) { //partial invoice payment made + $this->invoice->clearPartial()->updateBalance($payment_amount*-1); + } + + return $this->invoice; + } +} \ No newline at end of file diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php new file mode 100644 index 0000000000..c1da6aca59 --- /dev/null +++ b/app/Services/Invoice/InvoiceService.php @@ -0,0 +1,165 @@ +invoice = $invoice; + + $this->client_service = new ClientService($invoice->client); + + } + + /** + * Marks as invoice as paid + * and executes child sub functions + * @return $this InvoiceService object + */ + public function markPaid() + { + $mark_invoice_paid = new MarkPaid($this->client_service); + + $this->invoice = $mark_invoice_paid($this->invoice); + + return $this; + } + + /** + * Applies the invoice number + * @return $this InvoiceService object + */ + public function applyNumber() + { + $apply_number = new ApplyNumber($this->invoice->client); + + $this->invoice = $apply_number($this->invoice); + + return $this; + } + + /** + * Apply a payment amount to an invoice. + * @param Payment $payment The Payment + * @param float $payment_amount The Payment amount + * @return InvoiceService Parent class object + */ + public function applyPayment(Payment $payment, float $payment_amount) + { + $apply_payment = new ApplyPayment($this->invoice); + + $this->invoice = $apply_payment($payment, $payment_amount); + + return $this; + } + + /** + * Update an invoice balance + * @param float $balance_adjustment The amount to adjust the invoice by + * a negative amount will REDUCE the invoice balance, a positive amount will INCREASE + * the invoice balance + * @return InvoiceService Parent class object + */ + public function updateBalance($balance_adjustment) + { + $update_balance = new UpdateBalance($this->invoice); + + $this->invoice = $update_balance($balance_adjustment); + + return $this; + } + + public function markSent() + { + $mark_sent = new MarkSent($this->invoice->client); + + $this->invoice = $mark_sent($this->invoice); + + return $this; + } + + public function markViewed() + { + $this->invoice->last_viewed = Carbon::now()->format('Y-m-d H:i'); + + return $this; + } + + /* One liners */ + public function setDueDate() + { + $this->invoice->due_date = Carbon::now()->addDays($this->invoice->client->getSetting('payment_terms')); + + return $this; + } + + public function setStatus($status) + { + $this->invoice->status_id = $status; + + return $this; + } + + public function clearPartial() + { + $this->invoice->partial = null; + $this->invoice->partial_due_date = null; + + return $this; + } + + public function updatePartial($amount) + { + $this->invoice->partial += $amount; + + return $this; + } + + + + + + + + + + + + + + + + /** + * Saves the invoice + * @return Invoice object + */ + public function save() :?Invoice + { + $this->invoice->save(); + + return $this->invoice; + } +} diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php new file mode 100644 index 0000000000..22f08d728d --- /dev/null +++ b/app/Services/Invoice/MarkPaid.php @@ -0,0 +1,67 @@ +client_service = $client_service; + } + + public function __invoke($invoice) + { + + if($invoice->status_id == Invoice::STATUS_DRAFT) + $invoice->markSent(); + + /* Create Payment */ + $payment = PaymentFactory::create($invoice->company_id, $invoice->user_id); + + $payment->amount = $invoice->balance; + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->client_id = $invoice->client_id; + $payment->transaction_reference = ctrans('texts.manual_entry'); + /* Create a payment relationship to the invoice entity */ + $payment->save(); + + $payment->invoices()->attach($invoice->id, [ + 'amount' => $payment->amount + ]); + + $invoice->updateBalance($payment->amount*-1)->save(); + + /* Update Invoice balance */ + event(new PaymentWasCreated($payment, $payment->company)); + + UpdateCompanyLedgerWithPayment::dispatchNow($payment, ($payment->amount*-1), $payment->company); + + $this->client_service + ->updateBalance($payment->amount*-1) + ->updatePaidToDate($payment->amount) + ->save(); + + return $invoice; + } + +} + diff --git a/app/Services/Invoice/MarkSent.php b/app/Services/Invoice/MarkSent.php new file mode 100644 index 0000000000..dafd30e7a4 --- /dev/null +++ b/app/Services/Invoice/MarkSent.php @@ -0,0 +1,53 @@ +client = $client; + } + + public function __invoke($invoice) + { + + /* Return immediately if status is not draft */ + if ($invoice->status_id != Invoice::STATUS_DRAFT) { + return $invoice; + } + + $invoice->status_id = Invoice::STATUS_SENT; + + $invoice->markInvitationsSent(); + + $invoice->setReminder(); + + event(new InvoiceWasMarkedSent($invoice, $invoice->company)); + + $this->client->updateBalance($invoice->balance)->save(); + + $invoice->applyNumber()->save(); + + UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, $invoice->balance, $invoice->company); + + return $invoice; + + } +} diff --git a/app/Services/Invoice/UpdateBalance.php b/app/Services/Invoice/UpdateBalance.php new file mode 100644 index 0000000000..1c623c4a23 --- /dev/null +++ b/app/Services/Invoice/UpdateBalance.php @@ -0,0 +1,47 @@ +invoice = $invoice; + } + + + public function __invoke($balance_adjustment) + { + + if ($this->invoice->is_deleted) { + return; + } + + $balance_adjustment = floatval($balance_adjustment); + + $this->invoice->balance += $balance_adjustment; + + if ($this->invoice->balance == 0) { + $this->status_id = Invoice::STATUS_PAID; + // $this->save(); + // event(new InvoiceWasPaid($this, $this->company)); + + } + + return $this->invoice; + } +} \ No newline at end of file diff --git a/app/Services/Payment/PaymentService.php b/app/Services/Payment/PaymentService.php new file mode 100644 index 0000000000..0971265723 --- /dev/null +++ b/app/Services/Payment/PaymentService.php @@ -0,0 +1,45 @@ +payment = $payment; + } + + public function manualPayment($invoice) :?Payment + { + /* Create Payment */ + $payment = PaymentFactory::create($invoice->company_id, $invoice->user_id); + + $payment->amount = $invoice->balance; + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->client_id = $invoice->client_id; + $payment->transaction_reference = ctrans('texts.manual_entry'); + /* Create a payment relationship to the invoice entity */ + $payment->save(); + + $payment->invoices()->attach($invoice->id, [ + 'amount' => $payment->amount + ]); + + return $payment; + } +} diff --git a/app/Utils/Traits/Payment/Refundable.php b/app/Utils/Traits/Payment/Refundable.php index 86c5fa57a8..1419be6499 100644 --- a/app/Utils/Traits/Payment/Refundable.php +++ b/app/Utils/Traits/Payment/Refundable.php @@ -225,7 +225,7 @@ trait Refundable { $invoice = Invoice::find($refunded_invoice['invoice_id']); - $invoice->updateBalance($refunded_invoice['amount']); + $invoice->updateBalance($refunded_invoice['amount'])->save(); if($invoice->amount == $invoice->balance) $invoice->setStatus(Invoice::STATUS_SENT); diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index 303430a198..0a75caff7f 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -10,12 +10,14 @@ use App\Helpers\Invoice\InvoiceSum; use App\Helpers\Invoice\InvoiceSumInclusive; use App\Jobs\Company\UpdateCompanyLedgerWithInvoice; use App\Jobs\Invoice\UpdateInvoicePayment; +use App\Listeners\Credit\CreateCreditInvitation; use App\Listeners\Invoice\CreateInvoiceInvitation; use App\Models\Account; use App\Models\Client; use App\Models\ClientContact; use App\Models\CompanyGateway; use App\Models\CompanyToken; +use App\Models\Credit; use App\Models\GatewayType; use App\Models\GroupSetting; use App\Models\Invoice; @@ -23,6 +25,7 @@ use App\Models\Payment; use App\Models\PaymentType; use App\Models\User; use App\Models\UserAccount; +use App\Repositories\CreditRepository; use App\Repositories\InvoiceRepository; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Cache; @@ -163,7 +166,7 @@ class RandomDataSeeder extends Seeder UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, $invoice->balance, $invoice->company); - $invoice_repo->markSent($invoice); + $invoice->markSent()->save(); event(new InvoiceWasMarkedSent($invoice, $company)); @@ -188,6 +191,31 @@ class RandomDataSeeder extends Seeder }); + /*Credits*/ + factory(\App\Models\Credit::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); + + $credits = Credit::cursor(); + $credit_repo = new CreditRepository(); + + $credits->each(function ($credit) use($credit_repo, $user, $company, $client){ + + $credit_calc = null; + + if($credit->uses_inclusive_taxes) + $credit_calc = new InvoiceSumInclusive($credit); + else + $credit_calc = new InvoiceSum($credit); + + $credit = $credit_calc->build()->getInvoice(); + + $credit->save(); + + event(new CreateCreditInvitation($credit)); + + //$invoice->markSent()->save(); + + }); + /** Recurring Invoice Factory */ factory(\App\Models\RecurringInvoice::class,10)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); diff --git a/tests/Integration/MarkInvoicePaidTest.php b/tests/Integration/MarkInvoicePaidTest.php index 39affd4613..0e5dd7c693 100644 --- a/tests/Integration/MarkInvoicePaidTest.php +++ b/tests/Integration/MarkInvoicePaidTest.php @@ -15,7 +15,7 @@ use Tests\TestCase; /** * @test - * @covers App\Jobs\Invoice\MarkInvoicePaid + * @covers App\Services\Invoice\MarkInvoicePaid */ class MarkInvoicePaidTest extends TestCase { @@ -37,9 +37,15 @@ class MarkInvoicePaidTest extends TestCase public function testMarkInvoicePaidInvoice() { - MarkInvoicePaid::dispatchNow($this->invoice, $this->company); + $invoice = Invoice::find($this->invoice->id); + $invoice_balance = $invoice->balance; + $client = $invoice->client; + $client_balance = $client->balance; + + $this->invoice->markPaid(); $invoice = Invoice::find($this->invoice->id); + $client = $invoice->client; $this->assertEquals(0.00, $invoice->balance); @@ -52,7 +58,7 @@ class MarkInvoicePaidTest extends TestCase //events are not firing which makes this impossible to control. $this->assertEquals(0.00, $invoice->balance); - + $this->assertEquals(($client_balance - $invoice_balance), $client->balance); } } \ No newline at end of file diff --git a/tests/Integration/UpdateCompanyLedgerTest.php b/tests/Integration/UpdateCompanyLedgerTest.php index 0627238866..e55c62b030 100644 --- a/tests/Integration/UpdateCompanyLedgerTest.php +++ b/tests/Integration/UpdateCompanyLedgerTest.php @@ -37,8 +37,7 @@ class UpdateCompanyLedgerTest extends TestCase public function testPaymentIsPresentInLedger() { - $invoice = MarkInvoicePaid::dispatchNow($this->invoice, $this->company); - + $invoice = $this->invoice->markPaid()->save(); $ledger = CompanyLedger::whereClientId($invoice->client_id) ->whereCompanyId($invoice->company_id)