Merge pull request #2960 from novag/document-number-service
decouple document number generation
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
							
								
								
									
										12
									
								
								app/Interfaces/Service/DocumentNumberService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Interfaces/Service/DocumentNumberService.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Interfaces\Service; | ||||
|  | ||||
| use App\Models\Common\Contact; | ||||
|  | ||||
| interface DocumentNumberService | ||||
| { | ||||
|     public function getNextDocumentNumber(string $type, ?Contact $contact): string; | ||||
|  | ||||
|     public function increaseNextDocumentNumber(string $type, ?Contact $contact): void; | ||||
| } | ||||
| @@ -3,6 +3,7 @@ | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Interfaces\Service\DocumentNumberService; | ||||
| use App\Models\Common\Media as MediaModel; | ||||
| use App\Models\Setting\Tax; | ||||
| use App\Scopes\Document as Scope; | ||||
| @@ -251,7 +252,7 @@ class Document extends Model | ||||
|         } | ||||
|  | ||||
|         $this->status          = 'draft'; | ||||
|         $this->document_number = $this->getNextDocumentNumber($type); | ||||
|         $this->document_number = app(DocumentNumberService::class)->getNextDocumentNumber($type, $src->contact); | ||||
|     } | ||||
|  | ||||
|     public function getSentAtAttribute(string $value = null) | ||||
|   | ||||
							
								
								
									
										19
									
								
								app/Providers/Service.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/Providers/Service.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Providers; | ||||
|  | ||||
| use App\Interfaces\Service\DocumentNumberService; | ||||
| use App\Services\Document\CoreDocumentNumberService; | ||||
| use Illuminate\Support\ServiceProvider; | ||||
|  | ||||
| class Service extends ServiceProvider | ||||
| { | ||||
|     /** | ||||
|      * All container bindings that should be registered. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     public array $bindings = [ | ||||
|         DocumentNumberService::class => CoreDocumentNumberService::class, | ||||
|     ]; | ||||
| } | ||||
							
								
								
									
										39
									
								
								app/Services/Document/CoreDocumentNumberService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Services/Document/CoreDocumentNumberService.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Services\Document; | ||||
|  | ||||
| use App\Interfaces\Service\DocumentNumberService; | ||||
| use App\Models\Common\Contact; | ||||
|  | ||||
| class CoreDocumentNumberService implements DocumentNumberService | ||||
| { | ||||
|     public function getNextDocumentNumber(string $type, ?Contact $contact): string | ||||
|     { | ||||
|         $type = $this->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; | ||||
|     } | ||||
| } | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user