From df193fd737f4004090b95ae03c04d0137893ae44 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Thu, 15 May 2025 23:46:36 +0800 Subject: [PATCH] E-Invoice - Do not allow customer to edit PO when customer already has made partial payment --- .../CreateBookingPaymentLogic.php | 14 ++-- .../DataTransferObjects/ConfirmBookingDTO.php | 2 +- .../UpdateCompanyEInvoiceInfoLogic.php | 6 +- .../UpdateCompanyEInvoiceRequestLogic.php | 2 +- .../DataTransferObjects/EInvoiceInfoDTO.php | 2 +- .../EInvoiceRequestDTO.php | 2 +- .../CheckEInvoiceRuleLogic.php | 8 +-- .../CheckPurchaseOrderRuleLogic.php | 8 +-- ...le.php => CanPassEInvoicePromptedRule.php} | 6 +- .../Standards/Rules/CanPassEditingPORule.php | 67 +++++++++++++++++++ ...rRule.php => CanPassPurchaseOrderRule.php} | 4 +- ...nProceedTINRule.php => CanPassTINRule.php} | 4 +- .../CreatePurchaseOrderTransactionLogic.php | 30 +++++++-- .../CreatePurchaseOrderDTO.php | 25 +++++++ .../forms/PurchaseOrderFormComponent.vue | 8 ++- 15 files changed, 152 insertions(+), 36 deletions(-) rename app/Classes/Modules/{Rules => Bookings}/DataTransferObjects/ConfirmBookingDTO.php (89%) rename app/Classes/Modules/{Rules => Companies}/DataTransferObjects/EInvoiceInfoDTO.php (95%) rename app/Classes/Modules/{Rules => Companies}/DataTransferObjects/EInvoiceRequestDTO.php (89%) rename app/Classes/Modules/Rules/Standards/Rules/{CanProceedEInvoicePromptedRule.php => CanPassEInvoicePromptedRule.php} (85%) create mode 100644 app/Classes/Modules/Rules/Standards/Rules/CanPassEditingPORule.php rename app/Classes/Modules/Rules/Standards/Rules/{CanProceedPurchaseOrderRule.php => CanPassPurchaseOrderRule.php} (96%) rename app/Classes/Modules/Rules/Standards/Rules/{CanProceedTINRule.php => CanPassTINRule.php} (93%) create mode 100644 app/Classes/Modules/Transactions/DataTransferObjects/CreatePurchaseOrderDTO.php diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index 6b75dd49..ce8bec20 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -16,10 +16,10 @@ use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; -use App\Classes\Modules\Rules\DataTransferObjects\ConfirmBookingDTO; -use App\Classes\Modules\Rules\Standards\Rules\CanProceedEInvoicePromptedRule; -use App\Classes\Modules\Rules\Standards\Rules\CanProceedPurchaseOrderRule; -use App\Classes\Modules\Rules\Standards\Rules\CanProceedTINRule; +use App\Classes\Modules\Bookings\DataTransferObjects\ConfirmBookingDTO; +use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule; +use App\Classes\Modules\Rules\Standards\Rules\CanPassPurchaseOrderRule; +use App\Classes\Modules\Rules\Standards\Rules\CanPassTINRule; use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor; use App\Classes\Modules\Vouchers\Processors\Voucherify\BookingToVoucherifyProcessor; use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance; @@ -131,9 +131,9 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic { $dto = new ConfirmBookingDTO($request->all()); $result = $this->ruleEvaluator->evaluate([ - App()->make(CanProceedEInvoicePromptedRule::class), - App()->make(CanProceedTINRule::class), - App()->make(CanProceedPurchaseOrderRule::class), + App()->make(CanPassEInvoicePromptedRule::class), + App()->make(CanPassTINRule::class), + App()->make(CanPassPurchaseOrderRule::class), ], $dto); if ($result->failed()) { diff --git a/app/Classes/Modules/Rules/DataTransferObjects/ConfirmBookingDTO.php b/app/Classes/Modules/Bookings/DataTransferObjects/ConfirmBookingDTO.php similarity index 89% rename from app/Classes/Modules/Rules/DataTransferObjects/ConfirmBookingDTO.php rename to app/Classes/Modules/Bookings/DataTransferObjects/ConfirmBookingDTO.php index 2c154833..49f7e727 100644 --- a/app/Classes/Modules/Rules/DataTransferObjects/ConfirmBookingDTO.php +++ b/app/Classes/Modules/Bookings/DataTransferObjects/ConfirmBookingDTO.php @@ -1,6 +1,6 @@ all()); $result = $this->ruleEvaluator->evaluate([ - App()->make(CanProceedEInvoicePromptedRule::class), + App()->make(CanPassEInvoicePromptedRule::class), ], $dto); if ($result->failed()) { diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php index 86051447..09700f5d 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php @@ -6,7 +6,7 @@ namespace App\Classes\Modules\Companies\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Companies\Services\UpdatesCompanyEInvoiceRequest; use App\Classes\Modules\Companies\Services\FetchesCompany; -use App\Classes\Modules\Rules\DataTransferObjects\EInvoiceRequestDTO; +use App\Classes\Modules\Companies\DataTransferObjects\EInvoiceRequestDTO; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; diff --git a/app/Classes/Modules/Rules/DataTransferObjects/EInvoiceInfoDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php similarity index 95% rename from app/Classes/Modules/Rules/DataTransferObjects/EInvoiceInfoDTO.php rename to app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php index f768b2c1..2717bf7c 100644 --- a/app/Classes/Modules/Rules/DataTransferObjects/EInvoiceInfoDTO.php +++ b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php @@ -1,6 +1,6 @@ all()); $result = $this->ruleEvaluator->evaluate([ - App()->make(CanProceedEInvoicePromptedRule::class), - App()->make(CanProceedTINRule::class), + App()->make(CanPassEInvoicePromptedRule::class), + App()->make(CanPassTINRule::class), ], $dto); if ($result->failed()) { diff --git a/app/Classes/Modules/Rules/ControllersLogic/CheckPurchaseOrderRuleLogic.php b/app/Classes/Modules/Rules/ControllersLogic/CheckPurchaseOrderRuleLogic.php index 577e4618..41f24c22 100644 --- a/app/Classes/Modules/Rules/ControllersLogic/CheckPurchaseOrderRuleLogic.php +++ b/app/Classes/Modules/Rules/ControllersLogic/CheckPurchaseOrderRuleLogic.php @@ -7,8 +7,8 @@ use App\Classes\Exceptions\CriteriaNotFulfilledException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Rules\DataTransferObjects\CheckPurchaseOrderRuleDTO; use App\Classes\Modules\Rules\Services\RuleEvaluator; -use App\Classes\Modules\Rules\Standards\Rules\CanProceedEInvoicePromptedRule; -use App\Classes\Modules\Rules\Standards\Rules\CanProceedPurchaseOrderRule; +use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule; +use App\Classes\Modules\Rules\Standards\Rules\CanPassPurchaseOrderRule; use App\Http\Resources\RuleResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -49,8 +49,8 @@ class CheckPurchaseOrderRuleLogic extends AbstractControllerLogic $dto = new CheckPurchaseOrderRuleDTO($request->all()); $result = $this->ruleEvaluator->evaluate([ - App()->make(CanProceedEInvoicePromptedRule::class), - App()->make(CanProceedPurchaseOrderRule::class), + App()->make(CanPassEInvoicePromptedRule::class), + App()->make(CanPassPurchaseOrderRule::class), ], $dto); if ($result->failed()) { diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanProceedEInvoicePromptedRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php similarity index 85% rename from app/Classes/Modules/Rules/Standards/Rules/CanProceedEInvoicePromptedRule.php rename to app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php index dcddbcdd..5ab57fdf 100644 --- a/app/Classes/Modules/Rules/Standards/Rules/CanProceedEInvoicePromptedRule.php +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php @@ -6,14 +6,14 @@ use App\Classes\Exceptions\CriteriaNotFulfilledException; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Companies\Services\FetchesCompany; -class CanProceedEInvoicePromptedRule extends AbstractRule +class CanPassEInvoicePromptedRule extends AbstractRule { /** @var FetchesCompany */ private $fetchesCompany; /** - * CanProceedEInvoicePromptedRule constructor. + * CanPassEInvoicePromptedRule constructor. * @param FetchesCompany $fetchesCompany */ public function __construct(FetchesCompany $fetchesCompany) @@ -48,7 +48,7 @@ class CanProceedEInvoicePromptedRule extends AbstractRule //Check if account requires E-Invoice $company = $this->fetchesCompany->execute(['id' => $object->companyId]); if($company->e_invoice === null){ - throw new CriteriaNotFulfilledException("Please refresh page to answer question related to E-Invoice."); + throw new CriteriaNotFulfilledException("Please refresh page and click 'Make Payment' first to answer question related to E-Invoice."); } return true; } diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanPassEditingPORule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassEditingPORule.php new file mode 100644 index 00000000..62293b6d --- /dev/null +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassEditingPORule.php @@ -0,0 +1,67 @@ +fetchesBooking = $fetchesBooking; + $this->fetchesCompany = $fetchesCompany; + } + + /** + * @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 user is allow to edit purchase order + $booking = $this->fetchesBooking->execute(['id' => $object->bookingId]); + + $paidAmount = floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($booking, $booking->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($booking, $booking->fix_currency_id)); + + if($paidAmount > 0){ + throw new CriteriaNotFulfilledException("Purchase order form is no longer allow to be edited."); + } + return true; + } +} diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanProceedPurchaseOrderRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassPurchaseOrderRule.php similarity index 96% rename from app/Classes/Modules/Rules/Standards/Rules/CanProceedPurchaseOrderRule.php rename to app/Classes/Modules/Rules/Standards/Rules/CanPassPurchaseOrderRule.php index f9483835..c6782cf5 100644 --- a/app/Classes/Modules/Rules/Standards/Rules/CanProceedPurchaseOrderRule.php +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassPurchaseOrderRule.php @@ -13,7 +13,7 @@ use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\ServiceType; use Illuminate\Support\Facades\Log; -class CanProceedPurchaseOrderRule extends AbstractRule +class CanPassPurchaseOrderRule extends AbstractRule { /** @var FetchesBooking */ @@ -23,7 +23,7 @@ class CanProceedPurchaseOrderRule extends AbstractRule private $fetchesCompany; /** - * CanProceedPurchaseOrderRule constructor. + * CanPassPurchaseOrderRule constructor. * @param FetchesBooking $fetchesBooking * @param FetchesCompany $fetchesCompany */ diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanProceedTINRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php similarity index 93% rename from app/Classes/Modules/Rules/Standards/Rules/CanProceedTINRule.php rename to app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php index a4adc674..3f767912 100644 --- a/app/Classes/Modules/Rules/Standards/Rules/CanProceedTINRule.php +++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php @@ -7,14 +7,14 @@ use App\Classes\Exceptions\CriteriaNotFulfilledException; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Companies\Services\FetchesCompany; -class CanProceedTINRule extends AbstractRule +class CanPassTINRule extends AbstractRule { /** @var FetchesCompany */ private $fetchesCompany; /** - * CanProceedTINRule constructor. + * CanPassTINRule constructor. * @param FetchesCompany $fetchesCompany */ public function __construct(FetchesCompany $fetchesCompany) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php index 9bab107f..862945f0 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php @@ -3,9 +3,11 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; +use App\Classes\Exceptions\CriteriaNotFulfilledException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\Services\FetchesBooking; use App\Classes\Modules\Companies\Services\FetchesCompany; +use App\Classes\Modules\Transactions\DataTransferObjects\CreatePurchaseOrderDTO; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor; use App\Classes\Modules\Transactions\Services\CreatesTransaction; @@ -15,6 +17,8 @@ use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Transactions\Services\UpdatesTransaction; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use App\Classes\Modules\Rules\Services\RuleEvaluator; +use App\Classes\Modules\Rules\Standards\Rules\CanPassEditingPORule; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; @@ -46,17 +50,27 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic /** @var CreatePurchaseOrderTransactionProcessor */ private $createPurchaseOrderTransactionProcessor; + /** @var RuleEvaluator */ + private $ruleEvaluator; + + /** @var CanPassEditingPORule */ + private $canPassEditingPORule; + /** * CreatePurchaseOrderTransactionLogic constructor. * @param FetchesBooking $fetchesBooking * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber * @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor + * @param RuleEvaluator $ruleEvaluator + * @param CanPassEditingPORule $canPassEditingPORule */ - public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor) + public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor, RuleEvaluator $ruleEvaluator, CanPassEditingPORule $canPassEditingPORule) { $this->fetchesBooking = $fetchesBooking; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + $this->ruleEvaluator = $ruleEvaluator; + $this->canPassEditingPORule = $canPassEditingPORule; } /** @@ -64,9 +78,20 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic * @param string $id * @return JsonResponse * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException */ public function logic(Request $request, $id = '') : JsonResponse { + + $dto = new CreatePurchaseOrderDTO($request->all()); + $result = $this->ruleEvaluator->evaluate([ + $this->canPassEditingPORule + ], $dto); + + if ($result->failed()) { + throw new CriteriaNotFulfilledException("- " . implode("
- ", $result->messages())); + } + /** @var Booking $booking */ $booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]); @@ -87,7 +112,4 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic return $this->resourceResponse(new TransactionResource($transaction)); } - - - } diff --git a/app/Classes/Modules/Transactions/DataTransferObjects/CreatePurchaseOrderDTO.php b/app/Classes/Modules/Transactions/DataTransferObjects/CreatePurchaseOrderDTO.php new file mode 100644 index 00000000..074640ad --- /dev/null +++ b/app/Classes/Modules/Transactions/DataTransferObjects/CreatePurchaseOrderDTO.php @@ -0,0 +1,25 @@ +bookingId = $data['booking_id']; + $this->companyId = $data['company_id']; + } + + public function toArray(): array + { + return [ + 'booking_id' => $this->bookingId, + 'company_id' => $this->companyId, + ]; + } +} diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index de4e496b..4636db2a 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -188,12 +188,12 @@
@@ -281,7 +281,9 @@ submitForm(){ this.uploadFiles = false; this.parameters = { - products: this.products + products: this.products, + booking_id: this.data.id, + company_id: this.data.company.id, }; this.submit(route('api.transaction.po.create', this.data.id), 'post', this.section, true, true);