From 1719e977df411cfe0a87d866ad7a084645067c9a Mon Sep 17 00:00:00 2001 From: Hendrik Hagendorn Date: Fri, 28 Apr 2023 17:38:49 +0200 Subject: [PATCH] decouple document number generation --- .../View/Components/Documents/Form.php | 8 +++- .../Service/DocumentNumberService.php | 12 ++++++ app/Models/Document/Document.php | 3 +- app/Providers/Service.php | 19 +++++++++ .../Document/CoreDocumentNumberService.php | 39 +++++++++++++++++++ app/Traits/Documents.php | 30 +++++++------- config/app.php | 1 + database/factories/Document.php | 17 +++++--- 8 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 app/Interfaces/Service/DocumentNumberService.php create mode 100644 app/Providers/Service.php create mode 100644 app/Services/Document/CoreDocumentNumberService.php diff --git a/app/Abstracts/View/Components/Documents/Form.php b/app/Abstracts/View/Components/Documents/Form.php index c48e0484b..fff562d38 100644 --- a/app/Abstracts/View/Components/Documents/Form.php +++ b/app/Abstracts/View/Components/Documents/Form.php @@ -3,6 +3,7 @@ namespace App\Abstracts\View\Components\Documents; use App\Abstracts\View\Component; +use App\Interfaces\Service\DocumentNumberService; use App\Models\Common\Contact; use App\Models\Document\Document; use App\Models\Setting\Currency; @@ -266,6 +267,7 @@ abstract class Form extends Component * @return void */ public function __construct( + protected DocumentNumberService $documentNumberService, string $type, $model = false, $document = false, $currencies = false, $currency = false, $currency_code = false, string $formId = 'document', $formRoute = '', $formMethod = '', bool $hideCompany = false, string $textSectionCompaniesTitle = '', string $textSectionCompaniesDescription = '', @@ -815,10 +817,12 @@ abstract class Form extends Component return $document->document_number; } - $document_number = $this->getNextDocumentNumber($type); + $contact = ($this->contact instanceof \stdClass) ? null : $this->contact; + + $document_number = $this->documentNumberService->getNextDocumentNumber($type, $contact); if (empty($document_number)) { - $document_number = $this->getNextDocumentNumber(Document::INVOICE_TYPE); + $document_number = $this->documentNumberService->getNextDocumentNumber(Document::INVOICE_TYPE, $contact); } return $document_number; diff --git a/app/Interfaces/Service/DocumentNumberService.php b/app/Interfaces/Service/DocumentNumberService.php new file mode 100644 index 000000000..a7cd36a26 --- /dev/null +++ b/app/Interfaces/Service/DocumentNumberService.php @@ -0,0 +1,12 @@ +status = 'draft'; - $this->document_number = $this->getNextDocumentNumber($type); + $this->document_number = app(DocumentNumberService::class)->getNextDocumentNumber($type, $src->contact); } public function getSentAtAttribute(string $value = null) diff --git a/app/Providers/Service.php b/app/Providers/Service.php new file mode 100644 index 000000000..2c59cfebf --- /dev/null +++ b/app/Providers/Service.php @@ -0,0 +1,19 @@ + CoreDocumentNumberService::class, + ]; +} diff --git a/app/Services/Document/CoreDocumentNumberService.php b/app/Services/Document/CoreDocumentNumberService.php new file mode 100644 index 000000000..a97fed6e5 --- /dev/null +++ b/app/Services/Document/CoreDocumentNumberService.php @@ -0,0 +1,39 @@ +resolveTypeAlias($type); + + $prefix = setting($type . '.number_prefix'); + $next = (string)setting($type . '.number_next'); + $digit = (int)setting($type . '.number_digit'); + + return $prefix . str_pad($next, $digit, '0', STR_PAD_LEFT); + } + + public function increaseNextDocumentNumber(string $type, ?Contact $contact): void + { + $type = $this->resolveTypeAlias($type); + + $next = setting($type . '.number_next', 1) + 1; + + setting([$type . '.number_next' => $next]); + setting()->save(); + } + + protected function resolveTypeAlias(string $type): string + { + if ($alias = config('type.document.' . $type . '.alias')) { + return $alias . '.' . str_replace('-', '_', $type); + } + + return $type; + } +} diff --git a/app/Traits/Documents.php b/app/Traits/Documents.php index fc5f831be..2ed5a1855 100644 --- a/app/Traits/Documents.php +++ b/app/Traits/Documents.php @@ -2,6 +2,7 @@ namespace App\Traits; +use App\Interfaces\Service\DocumentNumberService; use App\Models\Document\Document; use App\Abstracts\View\Components\Documents\Document as DocumentComponent; use App\Utilities\Date; @@ -44,29 +45,24 @@ trait Documents return $recurring_types; } + /** + * Deprecated. Use the DocumentNumberService::getNextDocumentNumber() method instead. + * + * @deprecated This method is deprecated and will be removed in future versions. + */ public function getNextDocumentNumber(string $type): string { - if ($alias = config('type.document.' . $type . '.alias')) { - $type = $alias . '.' . str_replace('-', '_', $type); - } - - $prefix = setting($type . '.number_prefix'); - $next = (string) setting($type . '.number_next'); - $digit = (int) setting($type . '.number_digit'); - - return $prefix . str_pad($next, $digit, '0', STR_PAD_LEFT); + return app(DocumentNumberService::class)->getNextDocumentNumber($type, null); } + /** + * Deprecated. Use the DocumentNumberService::increaseNextDocumentNumber() method instead. + * + * @deprecated This method is deprecated and will be removed in future versions. + */ public function increaseNextDocumentNumber(string $type): void { - if ($alias = config('type.document.' . $type . '.alias')) { - $type = $alias . '.' . str_replace('-', '_', $type); - } - - $next = setting($type . '.number_next', 1) + 1; - - setting([$type . '.number_next' => $next]); - setting()->save(); + app(DocumentNumberService::class)->increaseNextDocumentNumber($type, null); } public function getDocumentStatuses(string $type): Collection diff --git a/config/app.php b/config/app.php index 3bccbbcd2..954153681 100644 --- a/config/app.php +++ b/config/app.php @@ -195,6 +195,7 @@ return [ App\Providers\Observer::class, App\Providers\Queue::class, App\Providers\Route::class, + App\Providers\Service::class, App\Providers\Validation::class, App\Providers\ViewComposer::class, diff --git a/database/factories/Document.php b/database/factories/Document.php index 9cfa0d261..6f6813441 100644 --- a/database/factories/Document.php +++ b/database/factories/Document.php @@ -9,6 +9,7 @@ use App\Events\Document\DocumentReceived; use App\Events\Document\DocumentSent; use App\Events\Document\DocumentViewed; use App\Events\Document\PaymentReceived; +use App\Interfaces\Service\DocumentNumberService; use App\Jobs\Document\UpdateDocument; use App\Models\Common\Contact; use App\Models\Common\Item; @@ -70,7 +71,7 @@ class Document extends AbstractFactory return [ 'type' => Model::INVOICE_TYPE, - 'document_number' => $this->getDocumentNumber(Model::INVOICE_TYPE), + 'document_number' => $this->getDocumentNumber(Model::INVOICE_TYPE, $contact), 'category_id' => $this->company->categories()->income()->get()->random(1)->pluck('id')->first(), 'contact_id' => $contact->id, 'contact_name' => $contact->name, @@ -101,7 +102,7 @@ class Document extends AbstractFactory return [ 'type' => Model::BILL_TYPE, - 'document_number' => $this->getDocumentNumber(Model::BILL_TYPE), + 'document_number' => $this->getDocumentNumber(Model::BILL_TYPE, $contact), 'category_id' => $this->company->categories()->expense()->get()->random(1)->pluck('id')->first(), 'contact_id' => $contact->id, 'contact_name' => $contact->name, @@ -207,9 +208,11 @@ class Document extends AbstractFactory { $type = $this->getRawAttribute('type') . '-recurring'; + $contact = Contact::find($this->getRawAttribute('contact_id')); + return $this->state([ 'type' => $type, - 'document_number' => $this->getDocumentNumber($type), + 'document_number' => $this->getDocumentNumber($type, $contact), 'recurring_started_at' => $this->getRawAttribute('issued_at'), 'recurring_frequency' => 'daily', 'recurring_interval' => '1', @@ -263,11 +266,13 @@ class Document extends AbstractFactory * Get document number * */ - public function getDocumentNumber($type) + public function getDocumentNumber($type, Contact $contact) { - $document_number = $this->getNextDocumentNumber($type); + $document_number_service = app(DocumentNumberService::class); - $this->increaseNextDocumentNumber($type); + $document_number = $document_number_service->getNextDocumentNumber($type, $contact); + + $document_number_service->increaseNextDocumentNumber($type, $contact); return $document_number; }