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 @@ + + + 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..d3ca4c28 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingMergeableComponent.vue @@ -0,0 +1,82 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index ce03bcdb..5e9cc914 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -111,7 +111,8 @@
But don't worry you can always merge your transfer orders into one to complete your purchase order successfully and generate your invoice.
- + + Merge Transfer Orders 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..65abfab2 --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/BookingMergeSectionComponent.vue @@ -0,0 +1,245 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/general/elements/ListComponent.vue b/resources/assets/vue/components/general/elements/ListComponent.vue index f2e0cfa4..c11278c5 100644 --- a/resources/assets/vue/components/general/elements/ListComponent.vue +++ b/resources/assets/vue/components/general/elements/ListComponent.vue @@ -1,5 +1,5 @@