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/AbstractDeleteMultipleRecord.php b/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php
new file mode 100644
index 00000000..a6d1b493
--- /dev/null
+++ b/app/Classes/General/Eloquent/AbstractDeleteMultipleRecord.php
@@ -0,0 +1,32 @@
+whereIn('id',$ids)->delete();
+
+ return ($record_deleted == count($ids)) ? true : false;
+
+ } catch (QueryException|\Exception $exception){
+ throw new MalformedRequestException('Unable to delete the record due to unexpected error');
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/Classes/General/Eloquent/AbstractUpdateMultipleRecord.php b/app/Classes/General/Eloquent/AbstractUpdateMultipleRecord.php
new file mode 100644
index 00000000..26b89a30
--- /dev/null
+++ b/app/Classes/General/Eloquent/AbstractUpdateMultipleRecord.php
@@ -0,0 +1,33 @@
+whereIn('id',$ids)->update($values);
+
+ return ($record_updated == count($ids)) ? true : false;
+
+ } catch (QueryException|\Exception $exception){
+ throw new MalformedRequestException('Unable to update the record due to unexpected error');
+ }
+ }
+
+
+
+}
\ 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..70529125
--- /dev/null
+++ b/app/Classes/Modules/Bookings/ControllersLogic/MergeBookingLogic.php
@@ -0,0 +1,146 @@
+ 'Merge Booking',
+ 'message' => 'You have successfully merged Booking'
+ ];
+ }
+
+ /** @var CanMergeBooking */
+ private $canMergeBooking;
+
+ /** @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, 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 \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $transaction_amount = null;
+ $transaction_original_amount = null;
+
+ $booking_ids_to_merge = [];
+ $booking_update_values = [];
+
+ $transaction_ids_to_merge = [];
+ $transaction_update_values = [];
+ $transaction_po_delete = [];
+
+ $transaction_details_ids = [];
+ $transaction_details_values = [];
+
+ $booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids'));
+
+ $this->canMergeBooking->passes($booking_object);
+
+ $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;
+ $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_ids_to_merge[]=$booking->id;
+
+ 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;
+
+ }
+ }
+
+ $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/DataTransferObjects/BookingMergeObject.php b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php
new file mode 100644
index 00000000..03c90e2e
--- /dev/null
+++ b/app/Classes/Modules/Bookings/DataTransferObjects/BookingMergeObject.php
@@ -0,0 +1,82 @@
+id = $id;
+ $this->bookingIds = $bookingIds;
+ }
+
+ /**
+ * @return int
+ */
+ public function getId(): int
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return array
+ */
+ public function getBookingIds(): array
+ {
+ 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/DeleteMultipleBooking.php b/app/Classes/Modules/Bookings/Services/DeleteMultipleBooking.php
new file mode 100644
index 00000000..f35c14db
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Services/DeleteMultipleBooking.php
@@ -0,0 +1,18 @@
+handler(Booking::query(), $ids);
+ }
+}
\ 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/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..d28bdc62
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingTransaction.php
@@ -0,0 +1,32 @@
+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;
+ }
+}
\ 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
new file mode 100644
index 00000000..f348346e
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Standards/Rules/CanMergeBooking.php
@@ -0,0 +1,61 @@
+bookingMergeValidation = $bookingMergeValidation;
+ $this->bookingsAreMergeable = $bookingsAreMergeable;
+ }
+
+ /**
+ * @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 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/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php b/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php
new file mode 100644
index 00000000..8f6bf2a3
--- /dev/null
+++ b/app/Classes/Modules/Bookings/Standards/Validators/BookingMergeValidation.php
@@ -0,0 +1,41 @@
+ $object->getId(),
+ 'booking_ids' => $object->getBookingIds()
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ protected function rules(): array
+ {
+ return [
+ 'id' => 'required|integer',
+ 'booking_ids' => 'required|array|min:1',
+ ];
+ }
+
+ /**
+ * @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/database/seeds/FakeBookingTransactions.php b/database/seeds/FakeBookingTransactions.php
new file mode 100644
index 00000000..08ff95f7
--- /dev/null
+++ b/database/seeds/FakeBookingTransactions.php
@@ -0,0 +1,298 @@
+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;
+ }
+
+ //Model employee have issue: Unknown column 'updated_at' in 'field list'
+ DB::table('employees')->updateOrInsert(
+ ['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2],
+ ['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2]
+ );
+
+ Models\Document::updateOrCreate(
+ ['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'],
+ ]
+ );
+
+ Models\SegmentCompany::updateOrCreate(
+ ['company_id' => $added->id, 'segment_id' => 1],
+ ['company_id' => $added->id, 'segment_id' => 1]
+ );
+ }
+
+
+ //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' => 2,
+ 'price' => 1000,
+ 'amount' => 2000,
+ ],
+ [
+ 'transaction_id' => null, //fill-up later
+ 'product_code' => 'IP12',
+ 'product_name' => 'iPad Pro 12"',
+ 'quantity' => 2,
+ 'price' => 1000,
+ 'amount' => 2000,
+ ],
+ [
+ 'transaction_id' => null, //fill-up later
+ 'product_code' => 'IMC24',
+ 'product_name' => 'iMac',
+ 'quantity' => 2,
+ 'price' => 1000,
+ 'amount' => 2000,
+ ],
+ ];
+
+ $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;
+ $fix_amount = [4000,8000];
+ $booking['fix_amount'] = $fix_amount[array_rand($fix_amount)];;
+ $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'] = 6000;
+ $transaction['original_amount'] = 6000;
+
+ $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
new file mode 100644
index 00000000..83d2e4fd
--- /dev/null
+++ b/resources/assets/vue/components/bookings/elements/BookingMergeModalComponent.vue
@@ -0,0 +1,80 @@
+
+ Merge Transfers
+
Merge multiple transfer orders to generate a single invoice for your purchase order
+Select Transfer Orders to merge with the order above
+