From 200b26d80901bfd53eb05d59fe7dab81e47e0c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Wed, 26 Feb 2020 22:21:12 +0100 Subject: [PATCH] Refactor save() method to apply DRY for invoices, Quotes & Credits (#3387) * Refactor save() method to apply DRY * Update BaseRepository.php --- app/Repositories/BaseRepository.php | 121 +++++++++++++++++++++++++ app/Repositories/CreditRepository.php | 73 +-------------- app/Repositories/InvoiceRepository.php | 94 +------------------ app/Repositories/QuoteRepository.php | 70 +------------- app/Services/Credit/ApplyNumber.php | 2 +- app/Services/Credit/CreditService.php | 2 +- 6 files changed, 128 insertions(+), 234 deletions(-) diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index f1eaf08cfb..22f251e9c1 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -11,8 +11,15 @@ namespace App\Repositories; +use App\Factory\InvoiceInvitationFactory; +use App\Factory\QuoteInvitationFactory; +use App\Jobs\Product\UpdateOrCreateProduct; use App\Models\Client; +use App\Models\ClientContact; +use App\Models\Invoice; +use App\Models\InvoiceInvitation; use App\Utils\Traits\MakesHash; +use ReflectionClass; /** * @@ -158,4 +165,118 @@ class BaseRepository { return $this->getInstance()->scope($ids)->withTrashed()->get(); } + + public function getInvitationByKey($key) + { + return InvoiceInvitation::whereRaw("BINARY `key`= ?", [$key])->first(); + } + + /** + * Alternative save used for Invoices, Quotes & Credits. + */ + protected function alternativeSave($data, $model) + { + $class = new ReflectionClass($model); + $state = []; + $resource = explode('\\', $class->name)[2]; /** This will extract 'Invoice' from App\Models\Invoice */ + + if ($class->name == 'App\Models\Invoice') { + $state['starting_amount'] = $model->amount; + + if (!$model->id) { + $client = Client::find($data['client_id']); + $model->uses_inclusive_taxes = $client->getSetting('inclusive_taxes'); + } + } + + if ($class->name == 'App\Models\Quote') { + $state['starting_amount'] = $model->amount; + } + + $model->fill($data); + $model->save(); + + $invitation_factory_class = sprintf("App\\Factory\\%sInvitationFactory", $resource); + + if (isset($data['client_contacts'])) { + foreach ($data['client_contacts'] as $contact) { + if ($contact['send_email'] == 1 && is_string($contact['id'])) { + $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id'])); + $client_contact->send_email = true; + $client_contact->save(); + } + } + } + + if (isset($data['invitations'])) { + $invitations = collect($data['invitations']); + + /* Get array of Keys which have been removed from the invitations array and soft delete each invitation */ + $model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) { + $this->getInvitationByKey($invitation)->delete(); + }); + + foreach ($data['invitations'] as $invitation) { + $inv = false; + + if (array_key_exists('key', $invitation)) { + $inv = $this->getInvitationByKey([$invitation['key']]); + + if($inv) + $inv->forceDelete(); + + } + + if (!$inv) { + + if (isset($invitation['id'])) { + unset($invitation['id']); + } + + $new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id); + $new_invitation->quote_id = $model->id; + $new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']); + $new_invitation->save(); + + } + } + } + + $model->load('invitations'); + + /* If no invitations have been created, this is our fail safe to maintain state*/ + if ($model->invitations->count() == 0) { + $model->service()->createInvitations(); + } + + $state['finished_amount'] = $model->amount; + + $model = $model->service()->applyNumber()->save(); + + if ($class->name == 'App\Models\Invoice') { + + if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) { + $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount'])); + } + + if ($model->company->update_products !== false) { + UpdateOrCreateProduct::dispatch($model->line_items, $model, $model->company); + } + + $model = $model->calc()->getInvoice(); + + } + + if ($class->name == 'App\Models\Credit') { + $model = $model->calc()->getCredit(); + } + + if ($class->name == 'App\Models\Quote') { + $model = $model->calc()->getQuote(); + } + + $model->save(); + + return $model->fresh(); + } } diff --git a/app/Repositories/CreditRepository.php b/app/Repositories/CreditRepository.php index 05a3e648e4..cf690dec18 100644 --- a/app/Repositories/CreditRepository.php +++ b/app/Repositories/CreditRepository.php @@ -49,78 +49,7 @@ class CreditRepository extends BaseRepository */ public function save(array $data, Credit $credit) : ?Credit { - - $credit->fill($data); - - $credit->save(); - - if(!$credit->number) - $credit->number = $credit->client->getNextCreditNumber($credit->client); - - if (isset($data['client_contacts'])) { - foreach ($data['client_contacts'] as $contact) { - if ($contact['send_email'] == 1 && is_string($contact['id'])) { - $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id'])); - $client_contact->send_email = true; - $client_contact->save(); - } - } - } - - - if (isset($data['invitations'])) { - $invitations = collect($data['invitations']); - - /* Get array of Keys which have been removed from the invitations array and soft delete each invitation */ - $credit->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) { - - $invite = $this->getInvitationByKey($invitation); - - if($invite) - $invite->forceDelete(); - - }); - - foreach ($data['invitations'] as $invitation) { - $inv = false; - - if (array_key_exists('key', $invitation)) { - $inv = $this->getInvitationByKey($invitation['key']); - } - - if (!$inv) { - - if (isset($invitation['id'])) { - unset($invitation['id']); - } - - $new_invitation = CreditInvitationFactory::create($credit->company_id, $credit->user_id); - $new_invitation->fill($invitation); - $new_invitation->credit_id = $credit->id; - $new_invitation->client_contact_id = $invitation['client_contact_id']; - $new_invitation->save(); - - } - } - } - - $credit->load('invitations'); - - /* If no invitations have been created, this is our fail safe to maintain state*/ - if ($credit->invitations->count() == 0) { - $credit->service()->createInvitations(); - } - /** - * Perform calculations on the - * credit note - */ - - $credit = $credit->calc()->getCredit(); - - $credit->save(); - - return $credit->fresh(); - + return $this->alternativeSave($data, $credit); } public function getInvitationByKey($key) :?CreditInvitation diff --git a/app/Repositories/InvoiceRepository.php b/app/Repositories/InvoiceRepository.php index 43f03130aa..cf033ffb57 100644 --- a/app/Repositories/InvoiceRepository.php +++ b/app/Repositories/InvoiceRepository.php @@ -43,92 +43,9 @@ class InvoiceRepository extends BaseRepository { * * @return Invoice|InvoiceSum|\App\Models\Invoice|null Returns the invoice object */ - public function save($data, Invoice $invoice):?Invoice { - - /* Always carry forward the initial invoice amount this is important for tracking client balance changes later......*/ - $starting_amount = $invoice->amount; - - if(!$invoice->id) { - $client = Client::find($data['client_id']); - $invoice->uses_inclusive_taxes = $client->getSetting('inclusive_taxes'); - } - - $invoice->fill($data); - - $invoice->save(); - - if (isset($data['client_contacts'])) { - foreach ($data['client_contacts'] as $contact) { - if ($contact['send_email'] == 1 && is_string($contact['id'])) { - $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id'])); - $client_contact->send_email = true; - $client_contact->save(); - } - } - } - - if (isset($data['invitations'])) { - $invitations = collect($data['invitations']); - - /* Get array of Keys which have been removed from the invitations array and soft delete each invitation */ - $invoice->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) { - - $invite = $this->getInvitationByKey($invitation); - - if($invite) - $invite->forceDelete(); - - }); - - foreach ($data['invitations'] as $invitation) { - $inv = false; - - if (array_key_exists('key', $invitation)) { - $inv = $this->getInvitationByKey($invitation['key']); - } - - if (!$inv) { - - if (isset($invitation['id'])) { - unset($invitation['id']); - } - - $new_invitation = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id); - //$new_invitation->fill($invitation); - $new_invitation->invoice_id = $invoice->id; - $new_invitation->client_contact_id = $invitation['client_contact_id']; - $new_invitation->save(); - - } - } - } - - - $invoice->load('invitations'); - - /* If no invitations have been created, this is our fail safe to maintain state*/ - if ($invoice->invitations->count() == 0) { - $invoice->service()->createInvitations(); - } - - $invoice = $invoice->calc()->getInvoice(); - - $invoice->save(); - - $finished_amount = $invoice->amount; - - /**/ - if (($finished_amount != $starting_amount) && ($invoice->status_id != Invoice::STATUS_DRAFT)) { - $invoice->ledger()->updateInvoiceBalance(($finished_amount-$starting_amount)); - } - - $invoice = $invoice->service()->applyNumber()->save(); - - if ($invoice->company->update_products !== false) { - UpdateOrCreateProduct::dispatch($invoice->line_items, $invoice, $invoice->company); - } - - return $invoice->fresh(); + public function save($data, Invoice $invoice):?Invoice + { + return $this->alternativeSave($data, $invoice); } /** @@ -141,9 +58,4 @@ class InvoiceRepository extends BaseRepository { public function markSent(Invoice $invoice):?Invoice { return $invoice->service()->markSent()->save(); } - - public function getInvitationByKey($key) - { - return InvoiceInvitation::whereRaw("BINARY `key`= ?", [$key])->first(); - } } diff --git a/app/Repositories/QuoteRepository.php b/app/Repositories/QuoteRepository.php index eba429354c..f1c0b63d2d 100644 --- a/app/Repositories/QuoteRepository.php +++ b/app/Repositories/QuoteRepository.php @@ -37,75 +37,7 @@ class QuoteRepository extends BaseRepository public function save($data, Quote $quote) : ?Quote { - - /* Always carry forward the initial invoice amount this is important for tracking client balance changes later......*/ - $starting_amount = $quote->amount; - - $quote->fill($data); - - $quote->save(); - - if (isset($data['client_contacts'])) { - foreach ($data['client_contacts'] as $contact) { - if ($contact['send_email'] == 1 && is_string($contact['id'])) { - $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id'])); - $client_contact->send_email = true; - $client_contact->save(); - } - } - } - - - if (isset($data['invitations'])) { - $invitations = collect($data['invitations']); - - /* Get array of Keys which have been removed from the invitations array and soft delete each invitation */ - $quote->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) { - $this->getInvitationByKey($invitation)->delete(); - }); - - foreach ($data['invitations'] as $invitation) { - $inv = false; - - if (array_key_exists('key', $invitation)) { - $inv = $this->getInvitationByKey([$invitation['key']]); - - if($inv) - $inv->forceDelete(); - - } - - if (!$inv) { - - if (isset($invitation['id'])) { - unset($invitation['id']); - } - - $new_invitation = QuoteInvitationFactory::create($quote->company_id, $quote->user_id); - $new_invitation->quote_id = $quote->id; - $new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']); - $new_invitation->save(); - - } - } - } - - $quote->load('invitations'); - - /* If no invitations have been created, this is our fail safe to maintain state*/ - if ($quote->invitations->count() == 0) { - $quote->service()->createInvitations(); - } - - $quote = $quote->calc()->getQuote(); - - $quote->save(); - - $finished_amount = $quote->amount; - - $quote = $quote->service()->applyNumber()->save(); - - return $quote->fresh(); + return $this->alternativeSave($data, $quote); } public function getInvitationByKey($key) :?QuoteInvitation diff --git a/app/Services/Credit/ApplyNumber.php b/app/Services/Credit/ApplyNumber.php index 6b81e9d4db..8c926ecefd 100644 --- a/app/Services/Credit/ApplyNumber.php +++ b/app/Services/Credit/ApplyNumber.php @@ -2,7 +2,7 @@ namespace App\Services\Credit; -use App\Credit; +use App\Models\Credit; use App\Events\Payment\PaymentWasCreated; use App\Factory\PaymentFactory; use App\Jobs\Customer\UpdateCustomerBalance; diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 943526b9cd..1ba9e09c05 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -1,7 +1,7 @@