diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php new file mode 100644 index 00000000..39dc6674 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php @@ -0,0 +1,115 @@ + 'Recorded Booking Amount', + 'message' => 'You have successfully recorded the Booking Amount to be updated' + ]; + } + + /** @var CanUpdateBooking */ + private $canUpdateBooking; + + /** @var UpdatesBookingFixedAmount */ + private $updatesBookingFixedAmount; + + /** @var FetchesBooking */ + private $fetchesBooking; + + /** @var CalculatesBookingOutstanding */ + private $calculatesBookingOutstanding; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** @var CreatesKeyValuePair */ + private $createsKeyValuePair; + + /** @var UpdatesKeyValuePair */ + private $updatesKeyValuePair; + + /** + * UpdateBookingAmountLogic constructor. + * @param CanUpdateBooking $canUpdateBooking + * @param UpdatesBookingFixedAmount $updatesBookingFixedAmount + * @param FetchesBooking $fetchesBooking + * @param CalculatesBookingOutstanding $calculatesBookingOutstanding + * @param UpdatesTransactionStatus $updatesTransactionStatus + * @param CreatesKeyValuePair $createsKeyValuePair + * @param UpdatesKeyValuePair $updatesKeyValuePair + */ + public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair) + { + $this->canUpdateBooking = $canUpdateBooking; + $this->updatesBookingFixedAmount = $updatesBookingFixedAmount; + $this->fetchesBooking = $fetchesBooking; + $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->createsKeyValuePair = $createsKeyValuePair; + $this->updatesKeyValuePair = $updatesKeyValuePair; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); + + $input_amount = number_format( floatval(str_replace(',', '', $request->input('amount_to_edit', $booking->fix_amount))), 5, '.', ''); + + $minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking); + + if (((float)$input_amount + 0.01) < (float)$minimum_amount) { + throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.'); + } + + $key = "BOOKING_AMOUNT_UPDATE"; + $keyValuePairObject = new KeyValuePairObject($key, $input_amount); + $metadata = $booking->attributesKVP()->where('key', $key)->first(); + if($metadata){ + $this->updatesKeyValuePair->execute($metadata, $keyValuePairObject); + } + else{ + $this->createsKeyValuePair->execute($booking, $keyValuePairObject); + } + + $poTransaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); + // $booking->transactions()->where('type', TransactionType::PROFORMA)->delete(); + + if($poTransaction) { + $this->updatesTransactionStatus->execute($poTransaction, ApprovalStatus::PENDING_SUBMISSION); + } + + // $booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount); + + return $this->resourceResponse(new BookingResource($booking)); + } + +} diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php new file mode 100644 index 00000000..eaa477a5 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php @@ -0,0 +1,78 @@ + 'Update Purchase Order With Booking Amount Update', + 'message' => 'You have successfully updated booking amount' + ]; + } + + /** @var FetchesBooking */ + private $fetchesBooking; + + /** @var UpdatesBookingFixedAmount */ + private $updatesBookingFixedAmount; + + /** + * UpdateBookingAmountWithPOLogic constructor. + * @param FetchesBooking $fetchesBooking + * @param UpdatesBookingFixedAmount $updatesBookingFixedAmount + */ + public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount) + { + $this->fetchesBooking = $fetchesBooking; + $this->updatesBookingFixedAmount = $updatesBookingFixedAmount; + } + + /** + * @param Request $request + * @param string $id + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException + */ + public function logic(Request $request, $id = '') : JsonResponse + { + /** @var Booking $booking */ + $booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]); + $bookingAttribute = $booking->attributesKVP()->where('key', "BOOKING_AMOUNT_UPDATE")->first(); + + if($bookingAttribute){ + $total = collect($request->input('products'))->sum(function($product){ + return $product['quantity'] * floatval(str_replace(',', '', $product['unit_price'])); + }); + $bookingAmountUpdate = (float)$bookingAttribute->value; + $isTally = $total === $bookingAmountUpdate ? true : false; + if(!$isTally){ + throw new MalformedRequestException('Purchase Order total not tally with updated booking amount of ' . $bookingAmountUpdate); + } + $booking->transactions()->where('type', TransactionType::PROFORMA)->delete(); + $booking = $this->updatesBookingFixedAmount->execute($booking, $bookingAmountUpdate); + + $request->merge(['is_privilleged_update' => true]); + + $bookingAttribute->delete(); + } + + return $this->resourceResponse(new BookingResource($booking)); + } +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php index 59757fa1..d5d97536 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php @@ -39,7 +39,7 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic protected function notification():array { return [ 'title' => 'Update Purchase Order', - 'message' => 'You have successfully updated you booking\'s purchase order' + 'message' => 'You have successfully updated your booking\'s purchase order' ]; } @@ -84,7 +84,8 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic */ public function logic(Request $request, $id = '') : JsonResponse { - if(!in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){ + //This checking is excluded for (1) Admin, (2) Update of booking amount post payment as user + if(!in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES) && !$request->has('is_privilleged_update')){ $dto = new CreatePurchaseOrderDTO($request->all()); $result = $this->ruleEvaluator->evaluate([ $this->canPassEditingPORule diff --git a/app/Http/Controllers/Bookings/UpdateBookingAmountController.php b/app/Http/Controllers/Bookings/UpdateBookingAmountController.php index d0f6dd6c..394d4039 100644 --- a/app/Http/Controllers/Bookings/UpdateBookingAmountController.php +++ b/app/Http/Controllers/Bookings/UpdateBookingAmountController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Bookings; use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic; +use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountOnHoldLogic; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -17,4 +18,12 @@ class UpdateBookingAmountController return $logic->execute($request); } -} \ No newline at end of file + /** + * @param Request $request + * @param UpdateBookingAmountOnHoldLogic $logic + * @return JsonResponse + */ + public function updateOnHold(Request $request, UpdateBookingAmountOnHoldLogic $logic): JsonResponse { + return $logic->execute($request); + } +} diff --git a/app/Http/Controllers/Transactions/CreatePurchaseOrderTransactionController.php b/app/Http/Controllers/Transactions/CreatePurchaseOrderTransactionController.php index 67a74537..625f1afe 100644 --- a/app/Http/Controllers/Transactions/CreatePurchaseOrderTransactionController.php +++ b/app/Http/Controllers/Transactions/CreatePurchaseOrderTransactionController.php @@ -6,6 +6,8 @@ namespace App\Http\Controllers\Transactions; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\Modules\Transactions\ControllersLogic\CreatePurchaseOrderTransactionLogic; +use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountWithPOLogic; + class CreatePurchaseOrderTransactionController @@ -15,7 +17,13 @@ class CreatePurchaseOrderTransactionController * @param CreatePurchaseOrderTransactionLogic $logic * @return JsonResponse */ - public function create(Request $request, CreatePurchaseOrderTransactionLogic $logic) : JsonResponse { - return $logic->execute($request); + public function create(Request $request, CreatePurchaseOrderTransactionLogic $createLogic, UpdateBookingAmountWithPOLogic $updateLogic) : JsonResponse { + // return $logic->execute($request); + $updateResult = $updateLogic->execute($request); + + if ($updateResult instanceof JsonResponse && $updateResult->getStatusCode() !== 200) { + return $updateResult; + } + return $createLogic->execute($request); } } diff --git a/app/Models/Booking.php b/app/Models/Booking.php index 259ca01e..d488c1e4 100644 --- a/app/Models/Booking.php +++ b/app/Models/Booking.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\General\Interfaces\Documentable; +use App\Classes\General\Interfaces\KeyValueInterface; use App\Classes\General\Interfaces\Transactionable; use App\Classes\General\Interfaces\Voucherifiable; use App\Classes\General\Traits\LogData; @@ -26,7 +27,7 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships; * @property int convertible_currency_id * @property int conversion_currency_id */ -class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable +class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable, KeyValueInterface { use HasRelationships; use SoftDeletes; @@ -130,4 +131,12 @@ class Booking extends AbstractModel implements Documentable, Transactionable, Vo return $this->morphMany(VoucherEntityMapping::class, 'owner'); } + /** + * @return MorphMany + */ + public function attributesKVP(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } + } diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index f7d1f91e..53007c6b 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -336,7 +336,8 @@
To ensure both updates take effect, please update the purchase order details with the equivalent booking amount immediately after this update. If not done in sequence, neither update will be applied.
+