diff --git a/app/Classes/Exceptions/CriteriaNotFulfilledException.php b/app/Classes/Exceptions/CriteriaNotFulfilledException.php new file mode 100644 index 00000000..da105690 --- /dev/null +++ b/app/Classes/Exceptions/CriteriaNotFulfilledException.php @@ -0,0 +1,14 @@ +addresses()->where('id', $id)->first() ?? new Address(); + + $model->reference = $object->getReference(); + $model->street_one = $object->getStreetOne(); + $model->street_two = $object->getStreetTwo(); + $model->country_id = $object->getCountryId(); + $model->state_id = $object->getStateId(); + $model->district_id = $object->getDistrictId(); + $model->postcode = $object->getPostCode(); + $model->status = $object->getStatus(); + $model->type = $object->getType(); + + return $this->handler($addressable->addresses(), $model); + } +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php b/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php new file mode 100644 index 00000000..30f7642c --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php @@ -0,0 +1,69 @@ + 'Retrieved Company E-Invoice Info', + 'message' => 'You have successfully retrieved a Company E-Invoice Info' + ]; + } + + /** @var CanFetchCompany */ + private $canFetchCompany; + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** + * FetchCompanyEInvoiceInfoLogic constructor. + * @param CanFetchCompany $canFetchCompany + * @param FetchesCompany $fetchesCompany + */ + public function __construct(CanFetchCompany $canFetchCompany, FetchesCompany $fetchesCompany) + { + $this->canFetchCompany = $canFetchCompany; + $this->fetchesCompany = $fetchesCompany; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $this->canFetchCompany->passes(); + + $company = $this->fetchesCompany->execute(['id' => $request->route('id')]); + $eInvoiceInfo = $company->companyModules()->first()->addresses()->where('type', '=', AddressType::E_INVOICE)->latest()->first(); + + if($eInvoiceInfo){ + $eInvoiceInfo->tin = $company->tin; + $eInvoiceInfo->msic_code = $company->msic_code; + $eInvoiceInfo->e_invoice = $company->e_invoice; + } + else{ + return $this->response([]); + } + + return $this->resourceResponse(new EInvoiceInfoResource($eInvoiceInfo)); + } +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php new file mode 100644 index 00000000..fe1c2c23 --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php @@ -0,0 +1,133 @@ + 'Update Company Details', + 'message' => 'You have successfully updated the Company Details' + ]; + } + /** @var CanUpdateCompany */ + private $canUpdateCompany; + + /** @var UpdatesCompany */ + private $updatesCompany; + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var UpdatesCompanyDebtor */ + private $updatesCompanyDebtor; + + /** @var CanCreateAddress */ + private $canCreateAddress; + + /** @var FetchesDistrict */ + private $fetchesDistrict; + + /** @var UpsertsAddress */ + private $upsertsAddress; + + /** @var UpdatesCompanyEInvoiceInfo */ + private $updatesCompanyEInvoiceInfo; + + /** @var UpdatesCompanyModuleName */ + private $updatesCompanyModuleName; + + /** + * UpdateCompanyDetailsLogic constructor. + * @param CanUpdateCompany $canUpdateCompany + * @param UpdatesCompany $updatesCompany + * @param FetchesCompany $fetchesCompany + * @param UpdatesCompanyDebtor $updatesCompanyDebtor + * @param CanCreateAddress $canCreateAddress + * @param FetchesDistrict $fetchesDistrict + * @param UpsertsAddress $upsertsAddress + * @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo; + * @param UpdatesCompanyModuleName $updatesCompanyModuleName + */ + public function __construct( + CanUpdateCompany $canUpdateCompany, + UpdatesCompany $updatesCompany, + FetchesCompany $fetchesCompany, + UpdatesCompanyDebtor $updatesCompanyDebtor, + CanCreateAddress $canCreateAddress, + FetchesDistrict $fetchesDistrict, + UpsertsAddress $upsertsAddress, + UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo, + UpdatesCompanyModuleName $updatesCompanyModuleName + ) + { + $this->canUpdateCompany = $canUpdateCompany; + $this->updatesCompany = $updatesCompany; + $this->fetchesCompany = $fetchesCompany; + $this->updatesCompanyDebtor = $updatesCompanyDebtor; + $this->canCreateAddress = $canCreateAddress; + $this->fetchesDistrict = $fetchesDistrict; + $this->upsertsAddress = $upsertsAddress; + $this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo; + $this->updatesCompanyModuleName = $updatesCompanyModuleName; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $dto = new UpdateCompanyDetailsDTO($request->all()); + $object = new CompanyObject($dto->name, $dto->reference, $dto->type); + + $this->canUpdateCompany->passes($object); + $company = $this->fetchesCompany->execute(['id' => $request->route('id')]); + + $this->updatesCompanyModuleName->execute($company->companyModules()->first(), $object->getName()); + + //Update Name and Debtor, Type + $company = $this->updatesCompany->execute($company, $object); + + if ($request->input('debtor') || $company->first()->debtor !== null) { + $this->updatesCompanyDebtor->execute($company, $request->input('debtor')); + } + + //Update EInvoice Related Info + if($company->e_invoice){ + $district = $this->fetchesDistrict->execute(['id' => $dto->districtId]); + $addObj = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode, AddressType::E_INVOICE, ApprovalStatus::APPROVED, 'E-Invoice'); + + $this->canCreateAddress->passes($addObj); + + $this->upsertsAddress->execute($company->companyModules()->first(), $addObj, $dto->addressId); + $this->updatesCompanyEInvoiceInfo->execute($company, $dto->tin, $dto->msicCode); + } + + return $this->resourceResponse(new CompanyResource($company)); + } +} + diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php new file mode 100644 index 00000000..319fa1a2 --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php @@ -0,0 +1,109 @@ + 'EInvoice Info Update', + 'message' => 'You have successfully updated company E-Invoice information' + ]; + } + + /** @var CanCreateAddress */ + private $canCreateAddress; + + /** @var FetchesDistrict */ + private $fetchesDistrict; + + /** @var FetchesCompanyModule */ + private $fetchesCompanyModule; + + /** @var CreatesAddress */ + private $createsAddress; + + /** @var RuleEvaluator */ + private $ruleEvaluator; + + /** @var UpdatesCompanyEInvoiceInfo */ + private $updatesCompanyEInvoiceInfo; + + /** @var CanPassEInvoicePromptedRule */ + private $canPassEInvoicePromptedRule; + + /** + * UpdateCompanyEInvoiceInfoLogic constructor. + * @param CanCreateAddress $canCreateAddress + * @param FetchesDistrict $fetchesDistrict + * @param FetchesCompanyModule $fetchesCompanyModule + * @param CreatesAddress $createsAddress + * @param RuleEvaluator $ruleEvaluator; + * @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo; + * @param CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule + */ + public function __construct(CanCreateAddress $canCreateAddress, FetchesDistrict $fetchesDistrict, FetchesCompanyModule $fetchesCompanyModule, CreatesAddress $createsAddress, RuleEvaluator $ruleEvaluator, UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule) + { + $this->canCreateAddress = $canCreateAddress; + $this->fetchesDistrict = $fetchesDistrict; + $this->fetchesCompanyModule = $fetchesCompanyModule; + $this->createsAddress = $createsAddress; + $this->ruleEvaluator = $ruleEvaluator; + $this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo; + $this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException + */ + public function logic(Request $request) : JsonResponse + { + $dto = new EInvoiceInfoDTO($request->all()); + $result = $this->ruleEvaluator->evaluate([ + $this->canPassEInvoicePromptedRule, + ], $dto); + + if ($result->failed()) { + throw new CriteriaNotFulfilledException("- " . implode("
- ", $result->messages())); + } + + $district = $this->fetchesDistrict->execute(['id' => $dto->districtId]); + $object = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode, AddressType::E_INVOICE, ApprovalStatus::APPROVED, 'E-Invoice'); + + //Update Address + $this->canCreateAddress->passes($object); + $companyModule = $this->fetchesCompanyModule->execute(['id' => $dto->companyModuleId]); + $this->createsAddress->execute($companyModule, $object); + + //Update tin, msic code + $this->updatesCompanyEInvoiceInfo->execute($companyModule->company, $dto->tin, $dto->msicCode); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php new file mode 100644 index 00000000..a065802d --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php @@ -0,0 +1,59 @@ + 'Updated EInvoice Request', + 'message' => 'You have successfully updated company E-Invoice request' + ]; + } + + /** @var FetchesCompanyModule */ + private $fetchesCompanyModule; + + /** @var UpdatesCompanyEInvoiceRequest */ + private $updatesCompanyEInvoiceRequest; + + + /** + * UpdateCompanyEInvoiceRequestLogic constructor. + * @param FetchesCompanyModule $fetchesCompanyModule + * @param UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest + */ + public function __construct(FetchesCompanyModule $fetchesCompanyModule, UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest) + { + $this->fetchesCompanyModule = $fetchesCompanyModule; + $this->updatesCompanyEInvoiceRequest = $updatesCompanyEInvoiceRequest; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $dto = new EInvoiceRequestDTO($request->all()); + $companyModule = $this->fetchesCompanyModule->execute(['id' => $dto->companyModuleId]); + $this->updatesCompanyEInvoiceRequest->execute($companyModule->company, $dto->eInvoiceRequest); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php new file mode 100644 index 00000000..a9cf02f1 --- /dev/null +++ b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php @@ -0,0 +1,43 @@ +tin = (string) ($data['tin'] ?? ''); + $this->msicCode = (int) ($data['msic_code'] ?? 0); + $this->districtId = (int) ($data['district_id'] ?? 0); + $this->stateId = (int) ($data['state_id'] ?? 0); + $this->companyModuleId = (int) ($data['company_module_id'] ?? 0); + $this->streetOne = (string) ($data['street_one'] ?? ''); + $this->streetTwo = (string) ($data['street_two'] ?? ''); + $this->postCode = (int) ($data['post_code'] ?? 0); + } + + public function toArray(): array + { + return [ + 'tin' => $this->tin, + 'msic_code' => $this->msicCode, + 'district_id' => $this->districtId, + 'state_id' => $this->stateId, + 'company_module_id' => $this->companyModuleId, + 'street_one' => $this->streetOne, + 'street_two' => $this->streetTwo, + 'post_code' => $this->postCode, + ]; + } +} diff --git a/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php new file mode 100644 index 00000000..1c46f2df --- /dev/null +++ b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php @@ -0,0 +1,25 @@ +eInvoiceRequest = $data['e_invoice_request']; + $this->companyModuleId = $data['company_module_id']; + } + + public function toArray(): array + { + return [ + 'e_invoice_request' => $this->eInvoiceRequest, + 'company_module_id' => $this->companyModuleId, + ]; + } +} diff --git a/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php new file mode 100644 index 00000000..e9a76434 --- /dev/null +++ b/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php @@ -0,0 +1,64 @@ +id = (int) ($data['id'] ?? 0); + $this->name = (string) ($data['name'] ?? ''); + $this->debtor = (string) ($data['debtor'] ?? ''); + $this->reference = (string) ($data['reference'] ?? ''); + $this->type = (int) ($data['type'] ?? 0); + + $this->tin = (string) ($data['tin'] ?? 0); + $this->msicCode = (int) ($data['msic_code'] ?? 0); + $this->addressId = (int) ($data['address_id'] ?? 0); + $this->districtId = (int) ($data['district_id'] ?? 0); + $this->stateId = (int) ($data['state_id'] ?? 0); + $this->companyId = (int) ($data['company_id'] ?? 0); + $this->streetOne = (string) ($data['street_one'] ?? ''); + $this->streetTwo = (string) ($data['street_two'] ?? ''); + $this->postCode = (int) ($data['post_code'] ?? 0); + } + + public function toArray(): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'debtor' => $this->debtor, + 'reference' => $this->reference, + 'type' => $this->type, + + 'tin' => $this->tin, + 'msic_code' => $this->msicCode, + 'address_id' => $this->addressId, + 'district_id' => $this->districtId, + 'state_id' => $this->stateId, + 'company_id' => $this->companyId, + 'street_one' => $this->streetOne, + 'street_two' => $this->streetTwo, + 'post_code' => $this->postCode, + ]; + } +} diff --git a/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php new file mode 100644 index 00000000..0a2c5cc5 --- /dev/null +++ b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php @@ -0,0 +1,25 @@ +tin = $tin; + $model->msic_code = $msicCode; + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php new file mode 100644 index 00000000..bdef7fc8 --- /dev/null +++ b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php @@ -0,0 +1,29 @@ +e_invoice_requested_at)) { + if($eInvoice){ + $model->e_invoice_requested_at = now(); + } + } + $model->e_invoice = $eInvoice; + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php b/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php new file mode 100644 index 00000000..9c690686 --- /dev/null +++ b/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php @@ -0,0 +1,70 @@ + 'Rule Check E-Invoice', + 'message' => 'You have successfully passed all rules evaluated' + ]; + } + + /** @var RuleEvaluator */ + private $ruleEvaluator; + + /** @var CanPassEInvoicePromptedRule */ + private $canPassEInvoicePromptedRule; + + /** @var CanPassTINRule */ + private $canPassTINRule; + + /** + * CheckEInvoiceRuleLogic constructor. + */ + public function __construct(RuleEvaluator $ruleEvaluator, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule, CanPassTINRule $canPassTINRule) + { + $this->ruleEvaluator = $ruleEvaluator; + $this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule; + $this->canPassTINRule = $canPassTINRule; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException + */ + public function logic(Request $request) : JsonResponse + { + $dto = new CheckEInvoiceRuleDTO($request->all()); + + $result = $this->ruleEvaluator->evaluate([ + $this->canPassEInvoicePromptedRule, + $this->canPassTINRule, + ], $dto); + + if ($result->failed()) { + throw new CriteriaNotFulfilledException("- " . implode("
- ", $result->messages())); + } + + return $this->resourceResponse(new RuleResource((object)$result)); + } +} diff --git a/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php b/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php new file mode 100644 index 00000000..c982aeb0 --- /dev/null +++ b/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php @@ -0,0 +1,22 @@ +companyModuleId = $data['company_module_id']; + } + + public function toArray(): array + { + return [ + 'company_module_id' => $this->companyModuleId, + ]; + } +} diff --git a/app/Classes/Modules/Rules/Services/RuleEvaluator.php b/app/Classes/Modules/Rules/Services/RuleEvaluator.php new file mode 100644 index 00000000..ac248a25 --- /dev/null +++ b/app/Classes/Modules/Rules/Services/RuleEvaluator.php @@ -0,0 +1,44 @@ +passes($object)) { + $success = false; + $messages[] = get_class($rule) . ' failed without exception'; + } + } catch (AccessForbiddenException | RequestValidationException | CriteriaNotFulfilledException $e) { + $success = false; + $messages[] = $e->getMessage(); + } catch (\Exception $e) { + $success = false; + $messages[] = 'Unexpected error in ' . get_class($rule) . ': ' . $e->getMessage(); + } + } + + return new RuleEvaluationResult($success, $messages); + } + +} diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php new file mode 100644 index 00000000..61d1dfcb --- /dev/null +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php @@ -0,0 +1,57 @@ +fetchesCompanyModule = $fetchesCompanyModule; + } + + /** + * @return bool + */ + protected function authorized($object): bool + { + return true; + + } + + /** + * @return bool + */ + protected function validators($object): bool + { + return true; + + } + + + /** + * @return bool + */ + protected function criteria($object): bool + { + //Check if account requires E-Invoice + $companyModule = $this->fetchesCompanyModule->execute(['id' => $object->companyModuleId]); + if($companyModule->company->e_invoice === null){ + throw new CriteriaNotFulfilledException("Please refresh page to answer question related to E-Invoice."); + } + return true; + } + +} diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php new file mode 100644 index 00000000..5ec859cb --- /dev/null +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php @@ -0,0 +1,55 @@ +fetchesCompanyModule = $fetchesCompanyModule; + } + + /** + * @return bool + */ + protected function authorized($object): bool + { + return true; + } + + /** + * @return bool + */ + protected function validators($object): bool + { + return true; + } + + + /** + * @return bool + */ + protected function criteria($object): bool + { + //Check if TIN already provided if account requires E-Invoice + $companyModule = $this->fetchesCompanyModule->execute(['id' => $object->companyModuleId]); + if($companyModule->company->e_invoice === 1 && !$companyModule->company->tin){ + throw new CriteriaNotFulfilledException("Please provide all requested E-Invoice Info."); + } + return true; + } + +} diff --git a/app/Classes/ValueObjects/Constants/AddressType.php b/app/Classes/ValueObjects/Constants/AddressType.php index 614b9774..b9952a3e 100644 --- a/app/Classes/ValueObjects/Constants/AddressType.php +++ b/app/Classes/ValueObjects/Constants/AddressType.php @@ -10,4 +10,6 @@ final class AddressType { public const PICK_UP = 3; + public const E_INVOICE = 4; + } diff --git a/app/Classes/ValueObjects/Response/RuleEvaluationResult.php b/app/Classes/ValueObjects/Response/RuleEvaluationResult.php new file mode 100644 index 00000000..264eaf26 --- /dev/null +++ b/app/Classes/ValueObjects/Response/RuleEvaluationResult.php @@ -0,0 +1,30 @@ +success = $success; + $this->messages = $messages; + } + + public function failed(): bool + { + return ! $this->success; + } + + public function passed(): bool + { + return $this->success; + } + + public function messages(): array + { + return $this->messages; + } +} diff --git a/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php b/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php new file mode 100644 index 00000000..d506e24e --- /dev/null +++ b/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php b/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php new file mode 100644 index 00000000..e8cbfd1c --- /dev/null +++ b/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php @@ -0,0 +1,21 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php b/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php new file mode 100644 index 00000000..9157e9de --- /dev/null +++ b/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php @@ -0,0 +1,29 @@ +execute($request); + } + + /** + * @param Request $request + * @param UpdateCompanyEInvoiceRequestLogic $logic + * @return JsonResponse + */ + public function updateRequest(Request $request, UpdateCompanyEInvoiceRequestLogic $logic): JsonResponse { + return $logic->execute($request); + } +} diff --git a/app/Http/Controllers/Rules/CheckRuleController.php b/app/Http/Controllers/Rules/CheckRuleController.php new file mode 100644 index 00000000..af95e185 --- /dev/null +++ b/app/Http/Controllers/Rules/CheckRuleController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Http/Resources/CompanyModuleResource.php b/app/Http/Resources/CompanyModuleResource.php index 5ffc40f8..1e54674e 100644 --- a/app/Http/Resources/CompanyModuleResource.php +++ b/app/Http/Resources/CompanyModuleResource.php @@ -51,6 +51,11 @@ class CompanyModuleResource extends JsonResource 'connections' => $this->connections, 'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), 'debtor' => $this->company->debtor, + 'e_invoice' => $this->company->e_invoice, + 'tin' => $this->company->tin, + 'msic_code' => $this->company->msic_code, + 'address_einvoice' => $this->company->e_invoice ? new AddressResource($this->when($this->has('addresses'), $this->addresses->where('type', AddressType::E_INVOICE)->sortByDesc('created_at')->first())) : null, + ]; } diff --git a/app/Http/Resources/EInvoiceInfoResource.php b/app/Http/Resources/EInvoiceInfoResource.php new file mode 100644 index 00000000..565e86a7 --- /dev/null +++ b/app/Http/Resources/EInvoiceInfoResource.php @@ -0,0 +1,31 @@ + $this->id, + 'street_one' => $this->street_one, + 'street_two' => $this->street_two, + 'district' => $this->district, + 'state' => $this->state, + 'post_code' => $this->postcode, + 'country' => $this->country, + 'billing' => (int) $this->billing, + 'msic_code' => (int) $this->msic_code, + 'tin' => (string) $this->tin, + 'e_invoice' => (int) $this->e_invoice, + ]; + } +} diff --git a/app/Http/Resources/RuleResource.php b/app/Http/Resources/RuleResource.php new file mode 100644 index 00000000..1fb42181 --- /dev/null +++ b/app/Http/Resources/RuleResource.php @@ -0,0 +1,22 @@ + $this->success, + 'messages' => $this->messages, + ]; + } +} diff --git a/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php b/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php new file mode 100644 index 00000000..ed5f2c58 --- /dev/null +++ b/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php @@ -0,0 +1,38 @@ +string('tin')->nullable()->after('debtor'); + $table->string('msic_code')->nullable()->after('debtor')->comment("5-digit code representing business activity"); + $table->timestamp('e_invoice_requested_at')->nullable()->after('debtor'); + $table->boolean('e_invoice')->nullable()->default(null)->after('debtor'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('companies', function (Blueprint $table) { + $table->dropColumn('tin'); + $table->dropColumn('msic_code'); + $table->dropColumn('e_invoice_requested_at'); + $table->dropColumn('e_invoice'); + }); + } +} diff --git a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue index b71287c5..bef39049 100644 --- a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue +++ b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue @@ -16,7 +16,8 @@
- + +
{{item.name}} @@ -158,14 +159,14 @@
Company Type
- +
{{item.type_name}} -
+
diff --git a/resources/assets/vue/components/companies/elements/EInvoiceInfoComponent.vue b/resources/assets/vue/components/companies/elements/EInvoiceInfoComponent.vue new file mode 100644 index 00000000..ef38aa8c --- /dev/null +++ b/resources/assets/vue/components/companies/elements/EInvoiceInfoComponent.vue @@ -0,0 +1,68 @@ + + diff --git a/resources/assets/vue/components/companies/forms/EInvoiceInfoFormComponent.vue b/resources/assets/vue/components/companies/forms/EInvoiceInfoFormComponent.vue new file mode 100644 index 00000000..a4d53e4a --- /dev/null +++ b/resources/assets/vue/components/companies/forms/EInvoiceInfoFormComponent.vue @@ -0,0 +1,246 @@ + + diff --git a/resources/assets/vue/components/companies/forms/EInvoiceRequestFormComponent.vue b/resources/assets/vue/components/companies/forms/EInvoiceRequestFormComponent.vue new file mode 100644 index 00000000..f6cd76e8 --- /dev/null +++ b/resources/assets/vue/components/companies/forms/EInvoiceRequestFormComponent.vue @@ -0,0 +1,65 @@ + + + diff --git a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue index 0c0e7bca..ece7adc6 100644 --- a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue @@ -58,12 +58,52 @@
+ +
+
+ + Submit E-Invoice Info + +
+
+
+
+ + View E-Invoice Info + +
+
Change Billing Address
+ + + + + + + + + + @@ -90,6 +130,7 @@ required: true, } }, + data(){ return { section: 'orderListSection', @@ -100,7 +141,7 @@ computed: { pendingQueue () { return this.$store.getters.isInCompleteQueue(this.section); - } + }, }, watch: { pendingQueue(inComplete){ @@ -117,11 +158,31 @@ this.isLoading = true; this.submit(route('api.company.show', this.company_id), 'get', this.section, false, false) }, - successHandler(response){ + successHandler(response, section){ this.$store.dispatch('completeList', {'name': this.section, 'data': []}); this.isLoading = false; this.company = response.payload.data; - } + + if(this.company.company_module.e_invoice === null){ + this.$nextTick(() => { + $('#modal-einvoice-request').modal('show'); + }); + } + else if( this.company.company_module.e_invoice && (this.company.company_module.tin === null || this.company.company_module.msic_code === null) ) + { + this.$nextTick(() => { + $('#modal-einvoice-info').modal('show'); + }); + } + }, + errorHandler(error, statusCode, section) { //E-Invoice + if(section === this.section + 'CheckEInvoiceRule' && statusCode === 422){ + $('#modal-einvoice-info').modal('show'); + } + }, + updatedEInvoiceInfo(info){ + this.$store.dispatch('reloadList', {'name': this.section}); + }, } } diff --git a/resources/assets/vue/components/general/elements/ModalComponent.vue b/resources/assets/vue/components/general/elements/ModalComponent.vue index db0181fc..3424b988 100644 --- a/resources/assets/vue/components/general/elements/ModalComponent.vue +++ b/resources/assets/vue/components/general/elements/ModalComponent.vue @@ -1,5 +1,6 @@ @@ -24,7 +27,10 @@ minLength: 'this field must have at least', minValue: 'this field must at least be', sameAs: 'this field must match the', - numeric: 'this field can only contain numbers' + numeric: 'this field can only contain numbers', + maxValue: 'this value must not exceeds', + alphaNum: 'this value must be alphanumeric', + fiveDigits: 'this value must be exactly 5 digits', //custom }, } }, diff --git a/resources/assets/vue/components/orders/elements/OrderComponent.vue b/resources/assets/vue/components/orders/elements/OrderComponent.vue index ea18c931..4a67a1c1 100644 --- a/resources/assets/vue/components/orders/elements/OrderComponent.vue +++ b/resources/assets/vue/components/orders/elements/OrderComponent.vue @@ -102,7 +102,7 @@
@@ -145,10 +145,10 @@
- + - +
@@ -160,10 +160,18 @@ }, data(){ return { - expanded: false + expanded: false, + section: 'orderList' } }, methods: { + successHandler(response, section){ + if(section === this.section + 'CheckEInvoiceRule'){ + if(response.payload.data.isPassed){ + window.location.href = route('order.show', this.item.reference); + } + } + }, download(param) { let url = route('order.qr.download', param.id); if(window.LARAVEL_VAPOR_ENABLED){ @@ -185,6 +193,12 @@ window.open(url, '_blank'); } }, + checkEInvoiceRule(){ + this.parameters = { + company_module_id: this.item.company_module.id, + }; + this.submit(route('api.rule.check.einvoice'), 'post', this.section + 'CheckEInvoiceRule', false, true); + }, }, mixins: [componentHandler] } diff --git a/resources/assets/vue/components/orders/forms/ChangeCustomerCompanyDetailsFormComponent.vue b/resources/assets/vue/components/orders/forms/ChangeCustomerCompanyDetailsFormComponent.vue new file mode 100644 index 00000000..f4dd6613 --- /dev/null +++ b/resources/assets/vue/components/orders/forms/ChangeCustomerCompanyDetailsFormComponent.vue @@ -0,0 +1,209 @@ + + diff --git a/resources/assets/vue/general/mixins/request.js b/resources/assets/vue/general/mixins/request.js index 13babef8..36e24753 100644 --- a/resources/assets/vue/general/mixins/request.js +++ b/resources/assets/vue/general/mixins/request.js @@ -18,11 +18,11 @@ export default { if(!success){ this.openModal(); errorNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'error'}): null; - this.errorHandler(response, statusCode); return; + this.errorHandler(response, statusCode, section); return; } successNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'success'}): null; - this.successHandler(response, section) + this.successHandler(response, section, this.parameters); }); diff --git a/routes/api.php b/routes/api.php index 5b419754..89749ee9 100644 --- a/routes/api.php +++ b/routes/api.php @@ -71,9 +71,11 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/help_menu.php'; require __DIR__ . '/permits_reminder.php'; - + require __DIR__ . '/job.php'; + require __DIR__ . '/rule.php'; + }); require __DIR__ . '/announcement.php'; diff --git a/routes/company.php b/routes/company.php index ad0ca9ee..2bafb203 100644 --- a/routes/company.php +++ b/routes/company.php @@ -1,6 +1,9 @@ 'company', 'as' => 'company.', 'namespace' => 'Companies'], function () { Route::get('/{id}/show', 'FetchCompanyController@fetch')->name('show'); @@ -39,4 +42,9 @@ Route::group(['prefix' => 'company', 'as' => 'company.', 'namespace' => 'Compani }); Route::get('/module/list', 'ListCompanyModulesController@list')->name('module.list'); + + Route::put('/details/update/{id}', [UpdateCompanyDetailsController::class, 'update'])->name('update.details'); + Route::get('/e-invoice/info/{id}', [FetchCompanyEInvoiceInfoController::class, 'fetch'])->name('einvoice.info'); + Route::post('/e-invoice/info/update', [UpdateCompanyEInvoiceInfoController::class, 'updateInfo'])->name('einvoice.info.update'); + Route::post('/e-invoice/request/update', [UpdateCompanyEInvoiceInfoController::class, 'updateRequest'])->name('einvoice.request.update'); }); diff --git a/routes/rule.php b/routes/rule.php new file mode 100644 index 00000000..6154c67b --- /dev/null +++ b/routes/rule.php @@ -0,0 +1,10 @@ +as('rule.') + ->group(function () { + Route::post('/check/eInvoice', [CheckRuleController::class, 'checkEInvoiceRule'])->name('check.einvoice'); + }); diff --git a/routes/web.php b/routes/web.php index 94909ea0..0164f7a3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -274,6 +274,13 @@ Route::get('/customer/{marking}/payment-and-billing', function ($marking) { Route::get('/customer-invoices/{company_module_id}/payment-and-billing', function ($company_module_id) { // todo-new: check company_module_id + $companyModule = CompanyModule::where('id', $company_module_id)->first(); + $isValid = $companyModule->company->e_invoice !== null; + + if (!$isValid) { + return redirect()->route('dashboard'); + } + return view('pages.customers.paymentsBilling', ['company_module_id' => $company_module_id]); })->name('customer.payment-and-billing-by-company-module-id');