From d3c670aeed6a9121e4b833e753fe6d3327065564 Mon Sep 17 00:00:00 2001 From: Fairuz Date: Thu, 6 May 2021 18:03:48 +0800 Subject: [PATCH 01/12] EXCHANGE-149 - Layout, components for merge bookings (abit on backend for filter booking list) --- .gitignore | 13 +- .../Filters/ConvertibleCurrencyId.php | 20 ++ .../Eloquent/Filters/FixedCurrencyId.php | 20 ++ app/Classes/General/Eloquent/Filters/IdIn.php | 20 ++ .../ControllersLogic/MergeBookingLogic.php | 98 +++++++++ .../BookingMergeObject.php | 30 +++ .../Standards/Rules/CanMergeBooking.php | 51 +++++ .../Validators/BookingMergeValidation.php | 39 ++++ .../Bookings/MergeBookingController.php | 19 ++ .../elements/BookingMergeableComponent.vue | 58 ++++++ .../sections/BookingMergeSectionComponent.vue | 189 ++++++++++++++++++ resources/views/pages/booking_merge.blade.php | 8 + routes/booking.php | 1 + routes/web.php | 4 +- 14 files changed, 568 insertions(+), 2 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/ConvertibleCurrencyId.php create mode 100644 app/Classes/General/Eloquent/Filters/FixedCurrencyId.php create mode 100644 app/Classes/General/Eloquent/Filters/IdIn.php create mode 100644 app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php create mode 100644 app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php create mode 100644 app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php create mode 100644 app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php create mode 100644 app/Http/Controllers/Bookings/MergeBookingController.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue create mode 100644 resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue create mode 100644 resources/views/pages/booking_merge.blade.php diff --git a/.gitignore b/.gitignore index a4dfdd60..95d268cf 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,15 @@ npm-debug.log yarn-error.log /storage/file composer.lock -yarn.lock \ No newline at end of file +yarn.lock +.DS_Store +public/.DS_Store +public/images/.DS_Store +gox.iml +rebuild_docker.sh +docker/* +db/* +docker-compose.yml +package-lock.json +public/* +/public/* \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ConvertibleCurrencyId.php b/app/Classes/General/Eloquent/Filters/ConvertibleCurrencyId.php new file mode 100644 index 00000000..3d5701f7 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ConvertibleCurrencyId.php @@ -0,0 +1,20 @@ +where('convertible_currency_id', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/FixedCurrencyId.php b/app/Classes/General/Eloquent/Filters/FixedCurrencyId.php new file mode 100644 index 00000000..bd582f82 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/FixedCurrencyId.php @@ -0,0 +1,20 @@ +where('fix_currency_id', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/IdIn.php b/app/Classes/General/Eloquent/Filters/IdIn.php new file mode 100644 index 00000000..cfe9358e --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/IdIn.php @@ -0,0 +1,20 @@ +whereIn('id', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php new file mode 100644 index 00000000..23cce87f --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php @@ -0,0 +1,98 @@ + 'Merge Booking', + 'message' => 'You have successfully merged Booking' + ]; + } + + /** @var CanCreateBooking */ + private $canMergeBooking; + + /** @var CreatesBooking */ + private $createsBooking; + + /** @var GeneratesBookingMarking */ + private $generatesBookingMarking; + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var FetchesCompany */ + private $fetchesBooking; + + /** + * CreateBookingLogic constructor. + * @param CanMergeBooking $canMergeBooking + * @param CreatesBooking $createsBooking + * @param GeneratesBookingMarking $generatesBookingMarking + * @param FetchesCompany $fetchesCompany + */ + public function __construct(CanMergeBooking $canMergeBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, FetchesBooking $fetchesBooking) + { + $this->canMergeBooking = $canMergeBooking; + $this->createsBooking = $createsBooking; + $this->generatesBookingMarking = $generatesBookingMarking; + $this->fetchesCompany = $fetchesCompany; + $this->fetchesBooking = $fetchesBooking; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\RequestValidationException + * @throws \App\Classes\Exceptions\ResourceNotFoundException + */ + public function logic(Request $request) : JsonResponse + { + $object = new BookingMergeObject($request->get('booking_ids')); + + $this->canMergeBooking->passes($object); + + /* + $bookings = $this->fetchesBooking->execute([ + 'id_in'=> $object->getBookingIds(), + 'status' => ApprovalStatus::APPROVED, + ]); + */ + #TODO: Fetch transaction (+details) record, reassign transaction id & recalculate amount + + //dd($bookings); + + return $this->response(); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php new file mode 100644 index 00000000..5b590145 --- /dev/null +++ b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php @@ -0,0 +1,30 @@ +bookingIds = $bookingIds; + } + + /** + * @return array + */ + public function getBookingIds(): array + { + return $this->bookingIds; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php new file mode 100644 index 00000000..64e89127 --- /dev/null +++ b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php @@ -0,0 +1,51 @@ +bookingMergeValidation = $bookingMergeValidation; + } + + /** + * @return bool + */ + protected function authorized(): bool + { + return true; + } + + /** + * @param BookingObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->bookingMergeValidation->validate($object); + } + + /** + * @param BookingObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php b/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php new file mode 100644 index 00000000..b7e77712 --- /dev/null +++ b/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php @@ -0,0 +1,39 @@ + $object->getBookingIds() + ]; + } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'booking_ids' => 'required|array|min:2', + ]; + } + + /** + * @return array + */ + protected function messages(): array + { + return []; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Bookings/MergeBookingController.php b/app/Http/Controllers/Bookings/MergeBookingController.php new file mode 100644 index 00000000..40d733a9 --- /dev/null +++ b/app/Http/Controllers/Bookings/MergeBookingController.php @@ -0,0 +1,19 @@ +execute($request); + } +} \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue new file mode 100644 index 00000000..a8aea8a2 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue @@ -0,0 +1,58 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue new file mode 100644 index 00000000..b0f4b6c9 --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue @@ -0,0 +1,189 @@ + + \ No newline at end of file diff --git a/resources/views/pages/booking_merge.blade.php b/resources/views/pages/booking_merge.blade.php new file mode 100644 index 00000000..e23db5bd --- /dev/null +++ b/resources/views/pages/booking_merge.blade.php @@ -0,0 +1,8 @@ +@extends('layouts.base_portal') +@section('inner_content') +
+
+ +
+
+@endsection \ No newline at end of file diff --git a/routes/booking.php b/routes/booking.php index 8f60bfb2..8e89e4ff 100644 --- a/routes/booking.php +++ b/routes/booking.php @@ -6,6 +6,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::get('/show/{marking}', 'FetchBookingController@fetch')->name('show'); Route::get('/list', 'ListBookingsController@list')->name('list'); Route::post('/create', 'CreateBookingController@create')->name('create'); + Route::post('/merge', 'MergeBookingController@merge')->name('merge'); Route::put('/update/{id}', 'UpdateBookingController@update')->name('update'); Route::delete('/delete/{id}', 'DeleteBookingController@delete')->name('delete'); diff --git a/routes/web.php b/routes/web.php index c3c0c925..eca220e9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -37,4 +37,6 @@ Route::get('/transfer/{marking}', function ($marking) { return view('pages.booking_details', ['marking' => $marking]); })->name('booking.details'); - +Route::get('/transfer/merge/{marking}', function ($marking) { + return view('pages.booking_merge', ['marking' => $marking]); +})->name('booking.merge'); From 94904ee3738b7f2a61dfe3e72cde3787e36ebb37 Mon Sep 17 00:00:00 2001 From: Fairuz Date: Mon, 10 May 2021 17:02:33 +0800 Subject: [PATCH 02/12] EXCHANGE-149 - Confirmation modal for merge bookings (abit on backend for process merge) --- .../ControllersLogic/MergeBookingLogic.php | 71 +++++++++----- .../BookingMergeObject.php | 54 ++++++++++- .../Bookings/Services/FetchesBooking.php | 1 + .../Modules/Bookings/Services/GetBookings.php | 51 ++++++++++ .../Services/UpdatesBookingTransaction.php | 34 +++++++ .../Criterias/BookingsAreMergeable.php | 53 +++++++++++ .../Standards/Rules/CanMergeBooking.php | 14 ++- .../elements/BookingMergeModalComponent.vue | 66 +++++++++++++ .../elements/BookingMergeableComponent.vue | 80 +++++++++------- .../sections/BookingMergeSectionComponent.vue | 95 +++++++++++++++---- .../general/elements/ListComponent.vue | 2 +- routes/booking.php | 2 +- 12 files changed, 445 insertions(+), 78 deletions(-) create mode 100644 app/Classes/Modules/Bookings/Services/GetBookings.php create mode 100644 app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php create mode 100644 app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue diff --git a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php index 23cce87f..fbbbf28d 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php @@ -2,25 +2,21 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; -use App\Classes\Exceptions\ResourceNotFoundException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject; +use App\Classes\Modules\Bookings\Services\DeletesBooking; use App\Classes\Modules\Bookings\Services\FetchesBooking; +use App\Classes\Modules\Bookings\Services\GetBookings; use App\Classes\Modules\Bookings\Standards\Rules\CanMergeBooking; use App\Classes\Modules\Companies\Services\FetchesCompany; -use App\Classes\Modules\Banks\Services\FetchesBank; -use App\Classes\Modules\Currencies\Services\FetchesCurrency; use App\Classes\Modules\Bookings\Standards\Rules\CanCreateBooking; use App\Classes\Modules\Bookings\Services\CreatesBooking; use App\Classes\Modules\Bookings\Services\GeneratesBookingMarking; -use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; -use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Http\Resources\BookingResource; +use App\Classes\Modules\Bookings\Services\UpdatesBookingTransaction; -use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -49,8 +45,14 @@ class MergeBookingLogic extends AbstractControllerLogic /** @var FetchesCompany */ private $fetchesCompany; - /** @var FetchesCompany */ - private $fetchesBooking; + /** @var GetBookings */ + private $getBookings; + + /** @var UpdatesBookingTransaction */ + private $updatesBookingTransaction; + + /** @var DeletesBooking */ + private $deletesBooking; /** * CreateBookingLogic constructor. @@ -59,13 +61,15 @@ class MergeBookingLogic extends AbstractControllerLogic * @param GeneratesBookingMarking $generatesBookingMarking * @param FetchesCompany $fetchesCompany */ - public function __construct(CanMergeBooking $canMergeBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, FetchesBooking $fetchesBooking) + public function __construct(CanMergeBooking $canMergeBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, GetBookings $getBookings, UpdatesBookingTransaction $updatesBookingTransaction, DeletesBooking $deletesBooking) { $this->canMergeBooking = $canMergeBooking; $this->createsBooking = $createsBooking; $this->generatesBookingMarking = $generatesBookingMarking; $this->fetchesCompany = $fetchesCompany; - $this->fetchesBooking = $fetchesBooking; + $this->getBookings = $getBookings; + $this->updatesBookingTransaction = $updatesBookingTransaction; + $this->deletesBooking = $deletesBooking; } @@ -74,23 +78,46 @@ class MergeBookingLogic extends AbstractControllerLogic * @return JsonResponse * @throws \App\Classes\Exceptions\AccessForbiddenException * @throws \App\Classes\Exceptions\RequestValidationException - * @throws \App\Classes\Exceptions\ResourceNotFoundException + * @throws \App\Classes\Exceptions\MalformedRequestException */ public function logic(Request $request) : JsonResponse { - $object = new BookingMergeObject($request->get('booking_ids')); + $booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids')); - $this->canMergeBooking->passes($object); + $this->canMergeBooking->passes($booking_object); - /* - $bookings = $this->fetchesBooking->execute([ - 'id_in'=> $object->getBookingIds(), - 'status' => ApprovalStatus::APPROVED, - ]); - */ - #TODO: Fetch transaction (+details) record, reassign transaction id & recalculate amount - //dd($bookings); + $booking_main = $this->getBookings->handler(['id'=> $booking_object->getId()])[0]; + $bookings_to_merge = $this->getBookings->handler(['id_in'=> $booking_object->getBookingIds()]); + + $booking_amount = $booking_main->fix_amount; + $transaction_amount = 0; + + $booking_main_transactions = $booking_main->transactions()->get(); + + foreach($booking_main_transactions as $transaction) + { + $transaction_amount += $transaction->amount; + } + + foreach($bookings_to_merge as $booking) + { + $booking_amount += $booking->fix_amount; + $bookings_to_merge_transactions = $booking->transactions()->get(); + + foreach($bookings_to_merge_transactions as $transaction) + { + $transaction_amount += $transaction->amount; + } + //Soft-delete selected bookings + //$this->deletesBooking->execute($booking); + } + + $booking_object->setBookingAmount($booking_amount); + $booking_object->setTransactionAmount($transaction_amount); + + $this->updatesBookingTransaction->execute($booking_main,$bookings_to_merge, $booking_object); + dd('??'); return $this->response(); diff --git a/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php index 5b590145..03c90e2e 100644 --- a/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php +++ b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php @@ -7,18 +7,37 @@ use App\Classes\General\Interfaces\DataTransferObject; class BookingMergeObject implements DataTransferObject { + /** @var int */ + private $id; + /** @var array */ private $bookingIds; + /** @var float */ + private $bookingAmount; + + /** @var float */ + private $transactionAmount; + /** * BookingMergeObject constructor. + * @param int $id * @param array $bookingIds */ - public function __construct(array $bookingIds) + public function __construct(int $id, array $bookingIds) { + $this->id = $id; $this->bookingIds = $bookingIds; } + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + /** * @return array */ @@ -27,4 +46,37 @@ class BookingMergeObject implements DataTransferObject return $this->bookingIds; } + /** + * @return float + */ + public function getBookingAmount(): float + { + return $this->bookingAmount; + } + + /** + * @param float $amount + * @return float + */ + public function setBookingAmount(float $amount) + { + $this->bookingAmount = $amount; + } + + /** + * @return float + */ + public function getTransactionAmount(): float + { + return $this->transactionAmount; + } + + /** + * @param float $amount + * @return float + */ + public function setTransactionAmount(float $amount) + { + $this->transactionAmount = $amount; + } } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/FetchesBooking.php b/app/Classes/Modules/Bookings/Services/FetchesBooking.php index b38f5a15..fbb001ff 100644 --- a/app/Classes/Modules/Bookings/Services/FetchesBooking.php +++ b/app/Classes/Modules/Bookings/Services/FetchesBooking.php @@ -30,4 +30,5 @@ class FetchesBooking extends AbstractFetchRecord { return $this->repository->newQuery(); } + } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/GetBookings.php b/app/Classes/Modules/Bookings/Services/GetBookings.php new file mode 100644 index 00000000..b90697ae --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/GetBookings.php @@ -0,0 +1,51 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } + + /** + * @param Builder $query + * @return Collection + * @throws ResourceNotFoundException + */ + public function getResults(Builder $query):Collection + { + if (!$query->exists()) { + throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); + } + + return $query->get(); + } + + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php new file mode 100644 index 00000000..b4afbeb9 --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php @@ -0,0 +1,34 @@ +transactions()->get(); + + foreach ($bookings_to_merge_transactions as $transaction) { + var_dump( $transaction->booking_id); + $transaction->booking_id = $object->getId(); + $this->handler($transaction); + } + } + + $booking_main->fix_amount=$object->getBookingAmount(); + + return $this->handler($booking_main); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php b/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php new file mode 100644 index 00000000..f25aa2a8 --- /dev/null +++ b/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php @@ -0,0 +1,53 @@ +repository = $repository; + } + + + /** + * @param BookingMergeObject $object + * @return bool + * @throws ResourceNotFoundException + */ + public function execute(BookingMergeObject $object){ + + $bookingOriginal=$this->repository->where(['id'=> $object->getId(),'status' => ApprovalStatus::APPROVED,])->first(); + $bookingToMerge=$this->repository->whereIn('id', $object->getBookingIds()) + ->where([ + 'status' => ApprovalStatus::APPROVED, + 'service_id' => $bookingOriginal->service_id, + 'fix_currency_id' => $bookingOriginal->fix_currency_id, + 'convertible_currency_id' => $bookingOriginal->convertible_currency_id, + ])->get(); + + if($bookingOriginal===null || $bookingToMerge->count() !== count($object->getBookingIds())){ + throw new ResourceNotFoundException('The booking doesn\'t exist'); + } + return true; + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php index 64e89127..f348346e 100644 --- a/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php +++ b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php @@ -2,7 +2,10 @@ namespace App\Classes\Modules\Bookings\Standards\Rules; +use App\Classes\Exceptions\ResourceNotFoundException; use App\Classes\General\Abstracts\AbstractRule; +use App\Classes\Modules\Bookings\Standards\Criterias\BookingsAreMergeable; +use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject; use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; use App\Classes\Modules\Bookings\Standards\Validators\BookingMergeValidation; @@ -12,14 +15,19 @@ class CanMergeBooking extends AbstractRule /** @var BookingMergeValidation */ private $bookingMergeValidation; + /** @var BookingsAreMergeable */ + private $bookingsAreMergeable; + /** * CanCreateBooking constructor. * @param BookingMergeValidation $bookingMergeValidation + * @param BookingsAreMergeable $bookingsAreMergeable */ - public function __construct(BookingMergeValidation $bookingMergeValidation) + public function __construct(BookingMergeValidation $bookingMergeValidation, BookingsAreMergeable $bookingsAreMergeable) { $this->bookingMergeValidation = $bookingMergeValidation; + $this->bookingsAreMergeable = $bookingsAreMergeable; } /** @@ -41,11 +49,13 @@ class CanMergeBooking extends AbstractRule } /** - * @param BookingObject $object + * @param BookingMergeObject $object * @return bool + * @throws ResourceNotFoundException */ protected function criteria($object): bool { + $this->bookingsAreMergeable->execute($object); return true; } } \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue new file mode 100644 index 00000000..ff686674 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue @@ -0,0 +1,66 @@ + + + diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue index a8aea8a2..7510ab31 100644 --- a/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue @@ -1,56 +1,68 @@ \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue new file mode 100644 index 00000000..b0f4b6c9 --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue @@ -0,0 +1,189 @@ + + \ No newline at end of file diff --git a/resources/views/pages/booking_merge.blade.php b/resources/views/pages/booking_merge.blade.php new file mode 100644 index 00000000..e23db5bd --- /dev/null +++ b/resources/views/pages/booking_merge.blade.php @@ -0,0 +1,8 @@ +@extends('layouts.base_portal') +@section('inner_content') +
+
+ +
+
+@endsection \ No newline at end of file diff --git a/routes/booking.php b/routes/booking.php index 8f60bfb2..8e89e4ff 100644 --- a/routes/booking.php +++ b/routes/booking.php @@ -6,6 +6,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::get('/show/{marking}', 'FetchBookingController@fetch')->name('show'); Route::get('/list', 'ListBookingsController@list')->name('list'); Route::post('/create', 'CreateBookingController@create')->name('create'); + Route::post('/merge', 'MergeBookingController@merge')->name('merge'); Route::put('/update/{id}', 'UpdateBookingController@update')->name('update'); Route::delete('/delete/{id}', 'DeleteBookingController@delete')->name('delete'); diff --git a/routes/web.php b/routes/web.php index c3c0c925..eca220e9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -37,4 +37,6 @@ Route::get('/transfer/{marking}', function ($marking) { return view('pages.booking_details', ['marking' => $marking]); })->name('booking.details'); - +Route::get('/transfer/merge/{marking}', function ($marking) { + return view('pages.booking_merge', ['marking' => $marking]); +})->name('booking.merge'); From 095f4052bc140e6bf4dda98582418b10382c072c Mon Sep 17 00:00:00 2001 From: Fairuz Date: Mon, 10 May 2021 17:02:33 +0800 Subject: [PATCH 05/12] EXCHANGE-149 - Confirmation modal for merge bookings (abit on backend for process merge) --- .../ControllersLogic/MergeBookingLogic.php | 71 +++++++++----- .../BookingMergeObject.php | 54 ++++++++++- .../Bookings/Services/FetchesBooking.php | 1 + .../Modules/Bookings/Services/GetBookings.php | 51 ++++++++++ .../Services/UpdatesBookingTransaction.php | 34 +++++++ .../Criterias/BookingsAreMergeable.php | 53 +++++++++++ .../Standards/Rules/CanMergeBooking.php | 14 ++- .../elements/BookingMergeModalComponent.vue | 66 +++++++++++++ .../elements/BookingMergeableComponent.vue | 80 +++++++++------- .../sections/BookingMergeSectionComponent.vue | 95 +++++++++++++++---- .../general/elements/ListComponent.vue | 2 +- routes/booking.php | 2 +- 12 files changed, 445 insertions(+), 78 deletions(-) create mode 100644 app/Classes/Modules/Bookings/Services/GetBookings.php create mode 100644 app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php create mode 100644 app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue diff --git a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php index 23cce87f..fbbbf28d 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php @@ -2,25 +2,21 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; -use App\Classes\Exceptions\ResourceNotFoundException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject; +use App\Classes\Modules\Bookings\Services\DeletesBooking; use App\Classes\Modules\Bookings\Services\FetchesBooking; +use App\Classes\Modules\Bookings\Services\GetBookings; use App\Classes\Modules\Bookings\Standards\Rules\CanMergeBooking; use App\Classes\Modules\Companies\Services\FetchesCompany; -use App\Classes\Modules\Banks\Services\FetchesBank; -use App\Classes\Modules\Currencies\Services\FetchesCurrency; use App\Classes\Modules\Bookings\Standards\Rules\CanCreateBooking; use App\Classes\Modules\Bookings\Services\CreatesBooking; use App\Classes\Modules\Bookings\Services\GeneratesBookingMarking; -use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; -use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Http\Resources\BookingResource; +use App\Classes\Modules\Bookings\Services\UpdatesBookingTransaction; -use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -49,8 +45,14 @@ class MergeBookingLogic extends AbstractControllerLogic /** @var FetchesCompany */ private $fetchesCompany; - /** @var FetchesCompany */ - private $fetchesBooking; + /** @var GetBookings */ + private $getBookings; + + /** @var UpdatesBookingTransaction */ + private $updatesBookingTransaction; + + /** @var DeletesBooking */ + private $deletesBooking; /** * CreateBookingLogic constructor. @@ -59,13 +61,15 @@ class MergeBookingLogic extends AbstractControllerLogic * @param GeneratesBookingMarking $generatesBookingMarking * @param FetchesCompany $fetchesCompany */ - public function __construct(CanMergeBooking $canMergeBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, FetchesBooking $fetchesBooking) + public function __construct(CanMergeBooking $canMergeBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, GetBookings $getBookings, UpdatesBookingTransaction $updatesBookingTransaction, DeletesBooking $deletesBooking) { $this->canMergeBooking = $canMergeBooking; $this->createsBooking = $createsBooking; $this->generatesBookingMarking = $generatesBookingMarking; $this->fetchesCompany = $fetchesCompany; - $this->fetchesBooking = $fetchesBooking; + $this->getBookings = $getBookings; + $this->updatesBookingTransaction = $updatesBookingTransaction; + $this->deletesBooking = $deletesBooking; } @@ -74,23 +78,46 @@ class MergeBookingLogic extends AbstractControllerLogic * @return JsonResponse * @throws \App\Classes\Exceptions\AccessForbiddenException * @throws \App\Classes\Exceptions\RequestValidationException - * @throws \App\Classes\Exceptions\ResourceNotFoundException + * @throws \App\Classes\Exceptions\MalformedRequestException */ public function logic(Request $request) : JsonResponse { - $object = new BookingMergeObject($request->get('booking_ids')); + $booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids')); - $this->canMergeBooking->passes($object); + $this->canMergeBooking->passes($booking_object); - /* - $bookings = $this->fetchesBooking->execute([ - 'id_in'=> $object->getBookingIds(), - 'status' => ApprovalStatus::APPROVED, - ]); - */ - #TODO: Fetch transaction (+details) record, reassign transaction id & recalculate amount - //dd($bookings); + $booking_main = $this->getBookings->handler(['id'=> $booking_object->getId()])[0]; + $bookings_to_merge = $this->getBookings->handler(['id_in'=> $booking_object->getBookingIds()]); + + $booking_amount = $booking_main->fix_amount; + $transaction_amount = 0; + + $booking_main_transactions = $booking_main->transactions()->get(); + + foreach($booking_main_transactions as $transaction) + { + $transaction_amount += $transaction->amount; + } + + foreach($bookings_to_merge as $booking) + { + $booking_amount += $booking->fix_amount; + $bookings_to_merge_transactions = $booking->transactions()->get(); + + foreach($bookings_to_merge_transactions as $transaction) + { + $transaction_amount += $transaction->amount; + } + //Soft-delete selected bookings + //$this->deletesBooking->execute($booking); + } + + $booking_object->setBookingAmount($booking_amount); + $booking_object->setTransactionAmount($transaction_amount); + + $this->updatesBookingTransaction->execute($booking_main,$bookings_to_merge, $booking_object); + dd('??'); return $this->response(); diff --git a/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php index 5b590145..03c90e2e 100644 --- a/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php +++ b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php @@ -7,18 +7,37 @@ use App\Classes\General\Interfaces\DataTransferObject; class BookingMergeObject implements DataTransferObject { + /** @var int */ + private $id; + /** @var array */ private $bookingIds; + /** @var float */ + private $bookingAmount; + + /** @var float */ + private $transactionAmount; + /** * BookingMergeObject constructor. + * @param int $id * @param array $bookingIds */ - public function __construct(array $bookingIds) + public function __construct(int $id, array $bookingIds) { + $this->id = $id; $this->bookingIds = $bookingIds; } + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + /** * @return array */ @@ -27,4 +46,37 @@ class BookingMergeObject implements DataTransferObject return $this->bookingIds; } + /** + * @return float + */ + public function getBookingAmount(): float + { + return $this->bookingAmount; + } + + /** + * @param float $amount + * @return float + */ + public function setBookingAmount(float $amount) + { + $this->bookingAmount = $amount; + } + + /** + * @return float + */ + public function getTransactionAmount(): float + { + return $this->transactionAmount; + } + + /** + * @param float $amount + * @return float + */ + public function setTransactionAmount(float $amount) + { + $this->transactionAmount = $amount; + } } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/FetchesBooking.php b/app/Classes/Modules/Bookings/Services/FetchesBooking.php index b38f5a15..fbb001ff 100644 --- a/app/Classes/Modules/Bookings/Services/FetchesBooking.php +++ b/app/Classes/Modules/Bookings/Services/FetchesBooking.php @@ -30,4 +30,5 @@ class FetchesBooking extends AbstractFetchRecord { return $this->repository->newQuery(); } + } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/GetBookings.php b/app/Classes/Modules/Bookings/Services/GetBookings.php new file mode 100644 index 00000000..b90697ae --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/GetBookings.php @@ -0,0 +1,51 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } + + /** + * @param Builder $query + * @return Collection + * @throws ResourceNotFoundException + */ + public function getResults(Builder $query):Collection + { + if (!$query->exists()) { + throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); + } + + return $query->get(); + } + + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php new file mode 100644 index 00000000..b4afbeb9 --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php @@ -0,0 +1,34 @@ +transactions()->get(); + + foreach ($bookings_to_merge_transactions as $transaction) { + var_dump( $transaction->booking_id); + $transaction->booking_id = $object->getId(); + $this->handler($transaction); + } + } + + $booking_main->fix_amount=$object->getBookingAmount(); + + return $this->handler($booking_main); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php b/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php new file mode 100644 index 00000000..f25aa2a8 --- /dev/null +++ b/app/Classes/Modules/Bookings/Standards/Criterias/BookingsAreMergeable.php @@ -0,0 +1,53 @@ +repository = $repository; + } + + + /** + * @param BookingMergeObject $object + * @return bool + * @throws ResourceNotFoundException + */ + public function execute(BookingMergeObject $object){ + + $bookingOriginal=$this->repository->where(['id'=> $object->getId(),'status' => ApprovalStatus::APPROVED,])->first(); + $bookingToMerge=$this->repository->whereIn('id', $object->getBookingIds()) + ->where([ + 'status' => ApprovalStatus::APPROVED, + 'service_id' => $bookingOriginal->service_id, + 'fix_currency_id' => $bookingOriginal->fix_currency_id, + 'convertible_currency_id' => $bookingOriginal->convertible_currency_id, + ])->get(); + + if($bookingOriginal===null || $bookingToMerge->count() !== count($object->getBookingIds())){ + throw new ResourceNotFoundException('The booking doesn\'t exist'); + } + return true; + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php index 64e89127..f348346e 100644 --- a/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php +++ b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php @@ -2,7 +2,10 @@ namespace App\Classes\Modules\Bookings\Standards\Rules; +use App\Classes\Exceptions\ResourceNotFoundException; use App\Classes\General\Abstracts\AbstractRule; +use App\Classes\Modules\Bookings\Standards\Criterias\BookingsAreMergeable; +use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject; use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; use App\Classes\Modules\Bookings\Standards\Validators\BookingMergeValidation; @@ -12,14 +15,19 @@ class CanMergeBooking extends AbstractRule /** @var BookingMergeValidation */ private $bookingMergeValidation; + /** @var BookingsAreMergeable */ + private $bookingsAreMergeable; + /** * CanCreateBooking constructor. * @param BookingMergeValidation $bookingMergeValidation + * @param BookingsAreMergeable $bookingsAreMergeable */ - public function __construct(BookingMergeValidation $bookingMergeValidation) + public function __construct(BookingMergeValidation $bookingMergeValidation, BookingsAreMergeable $bookingsAreMergeable) { $this->bookingMergeValidation = $bookingMergeValidation; + $this->bookingsAreMergeable = $bookingsAreMergeable; } /** @@ -41,11 +49,13 @@ class CanMergeBooking extends AbstractRule } /** - * @param BookingObject $object + * @param BookingMergeObject $object * @return bool + * @throws ResourceNotFoundException */ protected function criteria($object): bool { + $this->bookingsAreMergeable->execute($object); return true; } } \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue new file mode 100644 index 00000000..ff686674 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue @@ -0,0 +1,66 @@ + + + diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue index a8aea8a2..7510ab31 100644 --- a/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue @@ -1,56 +1,68 @@ \ No newline at end of file From 9dd0a8d7868c0211fb27e2ff5d8e19dcc24f4400 Mon Sep 17 00:00:00 2001 From: Fairuz Date: Sat, 15 May 2021 13:23:23 +0800 Subject: [PATCH 09/12] EXCHANGE-149, EXCHANGE-156 - Bug fixes, clean-up. Added seeder to create sample transactions --- .../Eloquent/AbstractDeleteMultipleRecord.php | 2 +- .../ControllersLogic/MergeBookingLogic.php | 121 +++++--- .../Services/DeleteMultipleTransaction.php | 18 ++ .../Services/UpdatesBookingTransaction.php | 6 +- database/seeds/FakeBookingTransactions.php | 291 ++++++++++++++++++ .../elements/BookingMergeModalComponent.vue | 25 +- .../elements/BookingMergeableComponent.vue | 4 +- .../forms/PurchaseOrderFormComponent.vue | 2 +- .../sections/BookingMergeSectionComponent.vue | 14 +- 9 files changed, 409 insertions(+), 74 deletions(-) create mode 100644 app/Classes/Modules/Bookings/Services/DeleteMultipleTransaction.php create mode 100644 database/seeds/FakeBookingTransactions.php diff --git a/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php b/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php index 6b50d444..a6d1b493 100644 --- a/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php +++ b/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php @@ -23,7 +23,7 @@ abstract class AbstractDeleteMultipleRecord return ($record_deleted == count($ids)) ? true : false; } catch (QueryException|\Exception $exception){ - throw new MalformedRequestException('Unable to update the record due to unexpected error'); + throw new MalformedRequestException('Unable to delete the record due to unexpected error'); } } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php index fc49925f..70529125 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php @@ -2,18 +2,18 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; -use App\Classes\Exceptions\ErrorException; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Modules\Bookings\Services\DeleteMultipleTransaction; +use App\Classes\Modules\Bookings\Standards\Rules\CanMergeBooking; use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject; -use App\Classes\Modules\Bookings\Services\DeleteMultipleBooking; use App\Classes\Modules\Bookings\Services\GetBookings; -use App\Classes\Modules\Bookings\Standards\Rules\CanMergeBooking; use App\Classes\Modules\Bookings\Services\UpdatesBookingTransaction; +use App\Classes\Modules\Bookings\Services\DeleteMultipleBooking; +use App\Classes\Modules\Transactions\Services\FetchesTransactionDetail; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; class MergeBookingLogic extends AbstractControllerLogic { @@ -34,94 +34,113 @@ class MergeBookingLogic extends AbstractControllerLogic /** @var GetBookings */ private $getBookings; + /** @var FetchesTransactionDetail */ + private $fetchesTransactionDetail; + /** @var UpdatesBookingTransaction */ private $updatesBookingTransaction; /** @var DeleteMultipleBooking */ private $deletesMultipleBooking; + /** @var DeleteMultipleTransaction */ + private $deletesMultipleTransaction; /** * MergeBookingLogic constructor. * @param CanMergeBooking $canMergeBooking * @param GetBookings $getBookings + * @param FetchesTransactionDetail $fetchesTransactionDetail * @param UpdatesBookingTransaction $updatesBookingTransaction * @param DeleteMultipleBooking $deletesMultipleBooking + * @param DeleteMultipleTransaction $deletesMultipleTransaction */ - public function __construct(CanMergeBooking $canMergeBooking, GetBookings $getBookings, UpdatesBookingTransaction $updatesBookingTransaction, DeleteMultipleBooking $deletesMultipleBooking) + public function __construct(CanMergeBooking $canMergeBooking, GetBookings $getBookings, FetchesTransactionDetail $fetchesTransactionDetail, UpdatesBookingTransaction $updatesBookingTransaction, DeleteMultipleBooking $deletesMultipleBooking, DeleteMultipleTransaction $deletesMultipleTransaction) { $this->canMergeBooking = $canMergeBooking; $this->getBookings = $getBookings; $this->updatesBookingTransaction = $updatesBookingTransaction; $this->deletesMultipleBooking = $deletesMultipleBooking; + $this->deletesMultipleTransaction = $deletesMultipleTransaction; + $this->fetchesTransactionDetail = $fetchesTransactionDetail; } /** * @param Request $request * @return JsonResponse - * @throws ErrorException + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException */ public function logic(Request $request) : JsonResponse { - try{ - $transaction_amount = 0; + $transaction_amount = null; + $transaction_original_amount = null; - $booking_ids_to_merge = []; - $booking_update_values = []; + $booking_ids_to_merge = []; + $booking_update_values = []; - $transaction_ids_to_merge = []; - $transaction_update_values = []; + $transaction_ids_to_merge = []; + $transaction_update_values = []; + $transaction_po_delete = []; - $booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids')); + $transaction_details_ids = []; + $transaction_details_values = []; - $this->canMergeBooking->passes($booking_object); + $booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids')); - $booking_main = $this->getBookings->handler(['id'=> $booking_object->getId()])[0]; - $bookings_to_merge = $this->getBookings->handler(['id_in'=> $booking_object->getBookingIds()]); + $this->canMergeBooking->passes($booking_object); - $booking_amount = $booking_main->fix_amount; - $booking_main_transactions = $booking_main->transactions()->get(); + $booking_main = $this->getBookings->handler(['id'=> $booking_object->getId()])[0]; + $bookings_to_merge = $this->getBookings->handler(['id_in'=> $booking_object->getBookingIds()]); - foreach($booking_main_transactions as $transaction) - { - $transaction_amount += $transaction->amount; + $booking_amount = $booking_main->fix_amount; + $booking_main_transaction = $booking_main->transactions()->first(); + + $transaction_amount = $booking_main_transaction->amount; + $transaction_original_amount = $booking_main_transaction->original_amount; + + foreach($bookings_to_merge as $booking) + { + $booking_amount += $booking->fix_amount; + $bookings_to_merge_transaction = $booking->transactions()->first(); + + $transaction_update_values['booking_id']=$booking_main->id; + $transaction_amount += $bookings_to_merge_transaction->amount; + $transaction_original_amount += $bookings_to_merge_transaction->original_amount; + $transaction_ids_to_merge[]=$bookings_to_merge_transaction->id; + + if($bookings_to_merge_transaction->type==7) { + $transaction_po_delete[] = $bookings_to_merge_transaction->id; } - $booking_update_values['status']=1; - $booking_update_values['fix_amount']=$transaction_amount; + $booking_ids_to_merge[]=$booking->id; - foreach($bookings_to_merge as $booking) - { - $booking_amount += $booking->fix_amount; - $bookings_to_merge_transactions = $booking->transactions()->get(); + foreach($bookings_to_merge_transaction->transactionDetails()->get() as $transaction_detail){ + $transaction_details_ids[] = $transaction_detail->id; + $transaction_details_values['transaction_id'] = $booking_main_transaction->id; - foreach($bookings_to_merge_transactions as $transaction) - { - $transaction_amount += $transaction->amount; - $transaction_update_values['status']=0; - $transaction_update_values['booking_id']=$booking_main->id; - $transaction_ids_to_merge[]=$transaction->id; - } - - $booking_ids_to_merge[]=$booking->id; } - - DB::beginTransaction(); - - //Update all transactions - $this->updatesBookingTransaction->execute($booking_main->id,$booking_update_values, $transaction_ids_to_merge, $transaction_update_values); - - //Soft delete merged booking - $this->deletesMultipleBooking->execute($booking_ids_to_merge); - - DB::commit(); - - return $this->response(); - - } catch (\Exception $exception) { - throw new ErrorException($exception->getMessage(), $exception->getCode()); } + $booking_update_values['fix_amount']=$booking_amount; + + //Update all transactions + $this->updatesBookingTransaction->execute( + $booking_main->id,$booking_update_values, + $transaction_ids_to_merge, $transaction_update_values, + $transaction_details_ids, $transaction_details_values + ); + + //Soft delete merged booking + $this->deletesMultipleBooking->execute($booking_ids_to_merge); + + //Soft delete merged transaction with status 7 (purchase order) + if(count($transaction_po_delete)>0) { + $this->deletesMultipleTransaction->execute($transaction_po_delete); + } + + return $this->response(); } } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/DeleteMultipleTransaction.php b/app/Classes/Modules/Bookings/Services/DeleteMultipleTransaction.php new file mode 100644 index 00000000..d0d6d206 --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/DeleteMultipleTransaction.php @@ -0,0 +1,18 @@ +handler(Transaction::query(), $ids); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php index 88b04868..d28bdc62 100644 --- a/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php +++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Bookings\Services; use App\Classes\General\Eloquent\AbstractUpdateMultipleRecord; use App\Models\Booking; use App\Models\Transaction; +use App\Models\TransactionDetail; class UpdatesBookingTransaction extends AbstractUpdateMultipleRecord { @@ -13,14 +14,17 @@ class UpdatesBookingTransaction extends AbstractUpdateMultipleRecord * @param array $booking_values * @param array $transaction_ids * @param array $transaction_values + * @param array $transaction_detail_ids + * @param array $transaction_detail_values * @return mixed * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(int $booking_id, array $booking_values, array $transaction_ids, array $transaction_values) { + public function execute(int $booking_id, array $booking_values, array $transaction_ids, array $transaction_values, array $transaction_detail_ids, array $transaction_detail_values) { $booking_update_success = $this->handler(Booking::query(),[$booking_id],$booking_values); if($booking_update_success) { $booking_update_success = $this->handler(Transaction::query(), $transaction_ids, $transaction_values); + $booking_update_success = $this->handler(TransactionDetail::query(), $transaction_detail_ids, $transaction_detail_values); } return $booking_update_success; diff --git a/database/seeds/FakeBookingTransactions.php b/database/seeds/FakeBookingTransactions.php new file mode 100644 index 00000000..b9d5076a --- /dev/null +++ b/database/seeds/FakeBookingTransactions.php @@ -0,0 +1,291 @@ +environment('local')) { + //Add user to map company, and auth user for bookings + $email = 'bookmaster@cief.com'; + $password = 'bo@k!ng$123'; + $booking_user = [ + 'name' => 'Book Master', + 'email' => $email, + 'password' => bcrypt($password), + 'type' => Constants\RoleTypes::USER, + 'status' => Constants\ApprovalStatus::APPROVED, + ]; + $user = Models\User::updateOrCreate(['email' => $email], $booking_user); + $user_id = $user->id; + + //Add 3 Entity: 2 company + 1 individual + $companies = [ + [ + 'name' => 'Maersk Line SDN BHD', + 'reference' => 'MAERSK-123', + 'type' => Constants\CompanyType::COMPANY_BUSINESS, + 'business_type' => Constants\BusinessType::FREIGHT_FORWARDER, + 'status' => Constants\ApprovalStatus::APPROVED, + ], + [ + 'name' => 'Sunrise Importer SDN BHD', + 'reference' => 'SSMID-E', + 'type' => Constants\CompanyType::COMPANY_BUSINESS, + 'business_type' => Constants\BusinessType::IMPORTER, + 'status' => Constants\ApprovalStatus::APPROVED, + ], + [ + 'name' => 'Han Solo', + 'reference' => '880101-14-6541', + 'type' => Constants\CompanyType::PERSONAL_BUSINESS, + 'business_type' => Constants\BusinessType::IMPORTER, + 'status' => Constants\ApprovalStatus::APPROVED, + ] + ]; + + $addresses = [ + [ + 'company_id' => null, //fill-up later + 'country_id' => 1, + 'state_id' => 15, + 'district_id' => 402, + 'postcode' => '63000', + 'street_one' => 'Vertex Tower, Cybersquare,', + 'street_two' => 'Jalan Teknorat 6, Cyber 5', + 'billing' => 1 + ] + ]; + + $contacts = [ + [ + 'company_id' => null, //fill-up later + 'country_id' => 1, + 'reference' => 'main', + 'phone' => '0123456789', + 'email' => 'email@edomain.com' + ] + ]; + + $banks = [ + [ + 'company_id' => null, //fill-up later + 'reference' => 'CBB', + 'bank_name' => 'Citibank Berhad', + 'holder_name' => '', //fill-up later, use company name + 'account_no' => '0123456789', + 'bank_branch' => 'Menara Citibank Kuala Lumpur', + 'swift' => null, + 'snap' => null, + 'type' => Constants\BankAccountType::EXTERNAL, + 'default' => 0, + 'status' => 2, + 'country_id' => 2, + ] + ]; + + $company_ids = []; + $address_ids = []; + $contact_ids = []; + $bank_ids = []; + + foreach ($companies as $company) { + $check = ['name' => $company['name']]; + $added = Models\Company::updateOrCreate($check, $company); + $company_ids[] = $added->id; + + //Add address + foreach ($addresses as $address) { + $address['company_id'] = $added->id; + $address['street_one'] = $company['name'] . ", " . $address['street_one']; + $check_address = ['street_one' => $address['street_one']]; + $added_address = Models\Address::updateOrCreate($check_address, $address); + $address_ids[$added->id][] = $added_address->id; + } + + //Add contact + foreach ($contacts as $contact) { + $contact['company_id'] = $added->id; + $contact['reference'] = $company['name'] . ", " . $contact['reference']; + $check_contact = ['reference' => $contact['reference']]; + $added_contact = Models\Contact::updateOrCreate($check_contact, $contact); + $contact_ids[$added->id][] = $added_contact->id; + } + + //Add bank + foreach ($banks as $bank) { + $bank['company_id'] = $added->id; + $bank['reference'] = $company['name'] . ", " . $bank['reference']; + $check_bank = ['reference' => $bank['reference']]; + $added_bank = Models\Bank::updateOrCreate($check_bank, $bank); + $bank_ids[$added->id][] = $added_bank->id; + } + + DB::table('employees')->updateOrInsert( + ['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2], + ['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2] + ); + + DB::table('documents')->updateOrInsert( + ['owner_id' => $added->id, 'status' => 2], + [ + 'owner_type' => 'App\Models\Company', + 'owner_id' => $added->id, + 'status' => 2, + 'document_type' => ($company['type'] == Constants\CompanyType::COMPANY_BUSINESS) ? Constants\DocumentType::SSM_REGISTRATION : Constants\DocumentType::IDENTITY_CARD, + 'reference' => $company['reference'], + ] + ); + } + + + //Booking, Transactions require auth user + $user = new Models\User; + $user->email = $email; + $user->password = $password; + auth()->login($user); + + $bookings = [ + [ + 'company_id' => null, //fill-up later + 'marking' => null, //fill-up later + 'service_id' => 1, + 'bank_id' => null, //fill-up later + 'fix_amount' => null, //fill-up later + 'fix_currency_id' => 2, + 'convertible_currency_id' => 2, + 'conversion_currency_id' => 1, + 'status' => Constants\ApprovalStatus::APPROVED, + ], + ]; + + $transactions = [ + [ + 'booking_id' => null, //fill-up later + 'type' => null, //fill-up later + 'issuer' => null, //fill-up later + 'receiver' => 1, + 'recipient_bank_account_id' => 1, + 'payment_method' => 2, + 'payment_reference' => 2, + 'bill_no' => null, //fill-up later + 'amount' => null, //fill-up later + 'original_amount' => null, //fill-up later + 'currency_id' => 2, + 'original_currency_id' => 2, + 'currency_rate' => 1.0, + 'tax' => 1.0, + 'service_charge' => 0.0, + 'expires_on' => null, + 'status' => 0, + ], + ]; + + $transaction_details = [ + [ + 'transaction_id' => null, //fill-up later + 'product_code' => 'MBP15', + 'product_name' => 'Macbook Pro 15"', + 'quantity' => 10, + 'price' => 100, + 'amount' => 1000, + ], + [ + 'transaction_id' => null, //fill-up later + 'product_code' => 'IP12', + 'product_name' => 'iPad Pro 12"', + 'quantity' => 10, + 'price' => 100, + 'amount' => 1000, + ], + [ + 'transaction_id' => null, //fill-up later + 'product_code' => 'IMC24', + 'product_name' => 'iMac', + 'quantity' => 10, + 'price' => 100, + 'amount' => 1000, + ], + ]; + + $booking_ids = []; + $transaction_ids = []; + $transaction_types = [ + Constants\TransactionType::PAYMENT_ATTEMPT, + Constants\TransactionType::PAYMENT, + Constants\TransactionType::INVOICE, + Constants\TransactionType::BILL, + Constants\TransactionType::PERFORMA, + Constants\TransactionType::TOP_UP, + Constants\TransactionType::REFUND, + Constants\TransactionType::PURCHASE_ORDER, + Constants\TransactionType::SUPPLIER_DELIVER, + ]; + + foreach ($company_ids as $company_id) { + foreach ($transaction_types as $transaction_type) { + foreach ($bookings as $booking) { + + $marking = mt_rand(20000, 20100); //Limit marking within 100 for easier to remember + + $booking['company_id'] = $company_id; + $booking['bank_id'] = $bank_ids[$company_id][0]; + $booking['marking'] = $marking; + $booking['fix_amount'] = 1000; + $booking['created_at'] = date('Y-m-d H:i:s'); + $booking['updated_at'] = date('Y-m-d H:i:s'); + + $check_booking = ['marking' => $booking['marking']]; + $added_booking = Models\Booking::updateOrCreate($check_booking, $booking); + $booking_ids[] = $added_booking->id; + $booking_id = $added_booking->id; + + foreach ($transactions as $transaction) { + + $bill_no = $code = mt_rand(100000001, 999999999);; + + $transaction['booking_id'] = $booking_id; + $transaction['type'] = $transaction_type; + $transaction['issuer'] = $company_id; + + $transaction['bill_no'] = $bill_no; + $transaction['amount'] = 1000; + $transaction['original_amount'] = 1000; + + $transaction['created_at'] = date('Y-m-d H:i:s'); + $transaction['updated_at'] = date('Y-m-d H:i:s'); + + $check_transaction = ['bill_no' => $transaction['bill_no']]; + $added_transaction = Models\Transaction::updateOrCreate($check_transaction, $transaction); + $transaction_ids[] = $added_transaction->id; + $transaction_id = $added_transaction->id; + + foreach ($transaction_details as $transaction_detail) { + $transaction_detail['transaction_id'] = $transaction_id; + + $transaction_detail['created_at'] = date('Y-m-d H:i:s'); + $transaction_detail['updated_at'] = date('Y-m-d H:i:s'); + + $check_transaction_details = [ + 'transaction_id' => $transaction_detail['transaction_id'], + 'product_code' => $transaction_detail['product_code'] + ]; + Models\TransactionDetail::updateOrCreate($check_transaction_details, + $transaction_detail); + } + } + } + } + } + } + } +} diff --git a/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue index 05bd5f72..83d2e4fd 100644 --- a/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue @@ -1,7 +1,6 @@