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 @@