From 13ba4e5c1254ffe1e335c9a3af67a9eb09353584 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 20 Jan 2023 01:23:03 +0800 Subject: [PATCH 01/32] Edit book recipient bank details --- .../UpdateBookingRecipientLogic.php | 94 ++++++++++++ .../UpdateBookingRecipientController.php | 20 +++ .../banks/forms/BankAccountFormComponent.vue | 25 +++- .../banks/forms/PhoneAccountFormComponent.vue | 27 +++- .../BookingRecipientEditComponent.vue | 141 ++++++++++++++++++ .../BookingPaymentQuotationComponent.vue | 33 +++- .../bookings/forms/UpdateBookingComponent.vue | 41 +++++ routes/booking.php | 3 +- 8 files changed, 371 insertions(+), 13 deletions(-) create mode 100644 app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php create mode 100644 app/Http/Controllers/Bookings/UpdateBookingRecipientController.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue create mode 100644 resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php new file mode 100644 index 00000000..8bdee9e3 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php @@ -0,0 +1,94 @@ + 'Updated Booking', + 'message' => 'You have successfully updated the Booking' + ]; + } + + /** @var CanUpdateBooking */ + private $canUpdateBooking; + + /** @var UpdatesBooking */ + private $updatesBooking; + + /** @var FetchesBooking */ + private $fetchesBooking; + + + /** + * UpdateBookingRecipientLogic constructor. + * @param CanUpdateBooking $canUpdateBooking + * @param UpdatesBooking $updatesBooking + * @param FetchesBooking $fetchesBooking + */ + public function __construct( + CanUpdateBooking $canUpdateBooking, + UpdatesBooking $updatesBooking, + FetchesBooking $fetchesBooking + ) + { + $this->canUpdateBooking = $canUpdateBooking; + $this->updatesBooking = $updatesBooking; + $this->fetchesBooking = $fetchesBooking; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + try { + DB::beginTransaction(); + + $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); + + + $booking_object = new BookingObject( + $booking->service_id, + $request->input('transferable_bank_id', $booking->transferable_bank_id), + $booking->marking, + $booking->fix_amount, + $booking->fix_currency_id, + $booking->convertible_currency_id, + $booking->conversion_currency_id + ); + $this->canUpdateBooking->passes($booking_object); + $booking = $this->updatesBooking->execute($booking, $booking_object); + + DB::commit(); + + return $this->resourceResponse(new BookingResource($booking)); + + } catch (\Exception $exception){ + throw new ErrorException($exception->getMessage(), $exception->getCode()); + } + } + +} diff --git a/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php new file mode 100644 index 00000000..670db6da --- /dev/null +++ b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue index 6e9518d9..e1fd6f0d 100644 --- a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue @@ -136,9 +136,12 @@
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
-
+
Add Account
+
+
Update Details
+
@@ -179,6 +182,10 @@ type: String, required: false, default: 'RMB' + }, + isEditing: { + type: Boolean, + default: false } }, data(){ @@ -224,10 +231,22 @@ }, methods: { submitForm(){ - this.submit(route('api.bank.create'), 'post', this.section, true, false); + if(this.isEditing){ + this.parameters.company_id = this.company_id; + this.parameters.account_type = this.type; + this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); + } + else{ + this.submit(route('api.bank.create'), 'post', this.section, true, false); + } }, successHandler(response){ - this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + if(this.isEditing){ + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + } + else{ + this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + } this.formHandler(); this.resetForm(); }, diff --git a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue index 76401d2b..aea24179 100644 --- a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue @@ -42,9 +42,12 @@
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
-
+
+
+ +
@@ -80,6 +83,10 @@ type: Object, required: false, default: null + }, + isEditing: { + type: Boolean, + default: false } }, data(){ @@ -115,10 +122,22 @@ submitForm(){ this.parameters.account_type = 3; this.parameters.bank_name = '-'; - this.submit(route('api.bank.create'), 'post', this.section, true, false); + if(this.isEditing){ + this.parameters.company_id = this.company_id; + this.parameters.account_type = this.type; + this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); + } + else{ + this.submit(route('api.bank.create'), 'post', this.section, true, false); + } }, successHandler(response){ - this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + if(this.isEditing){ + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + } + else{ + this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + } this.formHandler(); this.resetForm(); }, @@ -140,4 +159,4 @@ mixins: [FormHandler] } - \ No newline at end of file + diff --git a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue new file mode 100644 index 00000000..ffdbece2 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue @@ -0,0 +1,141 @@ + + + diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 37a51a43..e2f5dfad 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -81,6 +81,14 @@ +
+
+
EDIT
+
+ + + +
@@ -540,12 +548,26 @@ id: '', status: false }, - onlinePayment: { + onlinePayment: { id: '', status: false }, amount: (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2), - calculation: null + calculation: null, + recipientBanks: { + company: this.data.company, + serviceType: { + status: false, + id: this.data.service.id, + name: this.data.service.name, + currencies: this.data.service.configurations.currencies, + selectedCurrency: this.data.service.configurations.currencies[0] + }, + bankAccount: this.data.bank, + bankAccountDefault: this.data.bank, + recipientBanks: this.data.company.recipient_banks.accounts, + bookingId: this.data.id + } } }, validations () { @@ -575,14 +597,12 @@ id: bankCode, status: true, } - }, submitForm(){ this.parameters = { payment_method: this.paymentMethod.id, amount: this.amount }; - this.submit(route('api.booking.payment.quotation', this.item.id), 'post', this.section, false, false) this.calculation = null; }, @@ -600,9 +620,12 @@ cancelQuotation(){ this.calculation = null; this.expandPayment = false; + }, + updatedBankDetails(bank){ + this.item.bank = bank; } }, mixins: [componentHandler], directives: {money: VMoney} } - \ No newline at end of file + diff --git a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue new file mode 100644 index 00000000..73d6d51f --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue @@ -0,0 +1,41 @@ + + + diff --git a/routes/booking.php b/routes/booking.php index 0cbeca76..e54ba278 100644 --- a/routes/booking.php +++ b/routes/booking.php @@ -7,6 +7,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::get('/list', 'ListBookingsController@list')->name('list'); Route::post('/create', 'CreateBookingController@create')->name('create'); Route::put('/update/{id}', 'UpdateBookingController@update')->name('update'); + Route::put('/recipient/update/{id}', 'UpdateBookingRecipientController@update')->name('update.recipient'); Route::put('/cancel/{id}', 'CancelBookingController@cancel')->name('cancel'); Route::put('/restore/{id}', 'RestoreBookingController@restore')->name('restore'); Route::delete('/delete/{id}', 'DeleteBookingController@delete')->name('delete'); @@ -33,4 +34,4 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::post('{id}/proforma/create', 'CreateProformaInvoiceTransaction@create')->name('proforma.create'); -}); \ No newline at end of file +}); From 0b37cf6e7275c5f5d18f4e8d51715b1b976a92f7 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 20 Jan 2023 23:47:22 +0800 Subject: [PATCH 02/32] Edit recipient details do not allow empty --- .../bookings/elements/BookingRecipientEditComponent.vue | 1 + .../vue/components/bookings/forms/UpdateBookingComponent.vue | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue index ffdbece2..6240b629 100644 --- a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue @@ -129,6 +129,7 @@ this.createBank = false; this.isEditing = false; this.account_no = ''; + this.parameters.bankAccount = {}; }, cancelUpdate(){ this.parameters.bankAccount = this.parameters.bankAccountDefault; diff --git a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue index 73d6d51f..16cae41c 100644 --- a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue +++ b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue @@ -3,7 +3,7 @@
-
+
From 3bd708ed0e9e297635354f9289977f6041e8eb2e Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 7 Aug 2024 06:46:17 +0800 Subject: [PATCH 03/32] Recipient Bank Details to follow payment overriding the default attached to Booking --- app/Classes/Jobs/UpdatePerfexCRMPrelude.php | 6 +- .../Accounts/Services/DeletesKeyValuePair.php | 19 ++ .../ControllersLogic/UpdateBankLogic.php | 40 ++-- .../UpdateBankMetadataLogic.php | 67 ++++++ .../BankMetadataObject.php | 29 +++ .../Banks/Processors/UpdateBankProcessor.php | 97 +++++++++ .../Banks/Services/CreatesOrUpdateBank.php | 44 ++++ .../Standards/Rules/CanUpdateBankMetadata.php | 66 ++++++ .../Validators/BankMetadataValidation.php | 38 ++++ .../ExportsAnalyticBillingTransactions.php | 8 +- .../Banks/UpdateBankMetadataController.php | 19 ++ app/Http/Resources/CompanyResource.php | 2 +- .../Resources/ListTransactionJobResource.php | 14 +- .../Resources/PaymentTransactionResource.php | 14 +- app/Http/Resources/TransactionResource.php | 17 +- app/Http/Resources/V2/CompanyV2Resource.php | 2 +- app/Models/Bank.php | 35 ++- app/Models/KeyValuePair.php | 6 +- app/Models/Transaction.php | 24 +- ...ted_by_and_creator_type_to_banks_table.php | 35 +++ ...2359_add_deleted_at_to_key_value_pairs.php | 32 +++ .../seeds/AdminUserPermissionsTableSeeder.php | 1 + .../banks/forms/BankAccountFormComponent.vue | 20 +- .../banks/forms/PhoneAccountFormComponent.vue | 20 +- .../BookingPaymentRecipientEditComponent.vue | 177 +++++++++++++++ .../BookingRecipientEditComponent.vue | 44 +++- .../BookingPaymentQuotationComponent.vue | 67 +++--- ...itPaymentRecipientBankDetailsComponent.vue | 205 ++++++++++++++++++ .../forms/RecipientBankDetailsComponent.vue | 83 +++++++ .../bookings/forms/UpdateBookingComponent.vue | 2 +- .../GeneralConfirmationFormComponent.vue | 2 +- .../pdfs/currency_vendor_order.blade.php | 16 +- .../currency_vendor_order_inner.blade.php | 10 +- routes/api.php | 4 +- routes/bank.php | 4 +- routes/web.php | 40 ++-- 36 files changed, 1193 insertions(+), 116 deletions(-) create mode 100644 app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php create mode 100644 app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php create mode 100644 app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php create mode 100644 app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php create mode 100644 app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php create mode 100644 app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php create mode 100644 app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php create mode 100644 app/Http/Controllers/Banks/UpdateBankMetadataController.php create mode 100644 database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php create mode 100644 database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingPaymentRecipientEditComponent.vue create mode 100644 resources/assets/vue/components/bookings/forms/EditPaymentRecipientBankDetailsComponent.vue create mode 100644 resources/assets/vue/components/bookings/forms/RecipientBankDetailsComponent.vue diff --git a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php index 3b05ac63..1bf9dede 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php +++ b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php @@ -41,7 +41,11 @@ class UpdatePerfexCRMPrelude implements ShouldQueue { $serviceTypeName = $this->transaction->owner->company->services()->where('id', $this->transaction->owner->service_id)->first()->name; $booking = $this->transaction->booking; - $bankDetails = $this->generateBankDetails($booking->bank); + $bank = $booking->bank; //cief todo: 66 + if($this->transaction->bank){ + $bank = $this->transaction->bank; + } + $bankDetails = $this->generateBankDetails($bank); $data = [ 'amount' => number_format($this->transaction->amount, 2, '.', ''), diff --git a/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php b/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php new file mode 100644 index 00000000..a52288af --- /dev/null +++ b/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php @@ -0,0 +1,19 @@ +handler($model); + } +} diff --git a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php index 8509ed6b..88172f47 100644 --- a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php +++ b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php @@ -3,21 +3,17 @@ namespace App\Classes\Modules\Banks\ControllersLogic; use App\Http\Resources\BankResource; - use App\Classes\General\Abstracts\AbstractControllerLogic; - use App\Classes\Modules\Banks\Services\FetchesBank; - use App\Classes\Modules\Banks\Standards\Rules\CanUpdateBank; use App\Classes\Modules\Banks\Services\UpdatesBank; +use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank; use App\Classes\Modules\Banks\Services\CreatesBankLog; - +use App\Classes\Modules\Banks\Processors\UpdateBankProcessor; use App\Classes\Modules\Banks\DataTransferObjects\BankObject; - -use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; + class UpdateBankLogic extends AbstractControllerLogic { @@ -44,24 +40,36 @@ class UpdateBankLogic extends AbstractControllerLogic /** @var CreatesBankLog */ private $createsBankLog; + /** @var CreatesOrUpdateBank */ + private $createsOrUpdateBank; + + /** @var UpdateBankProcessor */ + private $updateBankProcessor; + /** * UpdateBankLogic constructor. * @param CanUpdateBank $canUpdateBank * @param UpdatesBank $updatesBank * @param FetchesBank $fetchesBank * @param CreatesBankLog $createsBankLog + * @param CreatesOrUpdateBank $createsOrUpdateBank + * @param UpdateBankProcessor $updateBankProcessor */ public function __construct( CanUpdateBank $canUpdateBank, UpdatesBank $updatesBank, FetchesBank $fetchesBank, - CreatesBankLog $createsBankLog + CreatesBankLog $createsBankLog, + CreatesOrUpdateBank $createsOrUpdateBank, + UpdateBankProcessor $updateBankProcessor ) { $this->canUpdateBank = $canUpdateBank; $this->updatesBank = $updatesBank; $this->fetchesBank = $fetchesBank; $this->createsBankLog = $createsBankLog; + $this->createsOrUpdateBank = $createsOrUpdateBank; + $this->updateBankProcessor = $updateBankProcessor; } /** @@ -74,15 +82,15 @@ class UpdateBankLogic extends AbstractControllerLogic public function logic(Request $request) : JsonResponse { $bankObject = new BankObject( - $request->input('company_id'), + $request->input('company_id'), $request->input('account_type'), $request->input('bank_name'), - $request->input('holder_name'), + $request->input('holder_name'), $request->input('account_no'), - $request->input('bank_branch'), - $request->input('swift'), + $request->input('bank_branch'), + $request->input('swift'), $request->input('snap'), - $request->input('country_id'), + $request->input('country_id'), $request->input('reference') ); @@ -90,12 +98,10 @@ class UpdateBankLogic extends AbstractControllerLogic $this->canUpdateBank->passes($bankObject); - $bank_query = $this->updatesBank->execute($bank, $bankObject); - -// $bankLog = $this->createsBankLog->execute($bank_query); + $bank_query = $this->updateBankProcessor->execute($bankObject, $bank, $request->input('bill_no') ?? '', (int) $request->input('transaction_id') ?? 0 ); return $this->resourceResponse(new BankResource($bank_query)); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php new file mode 100644 index 00000000..1dc79f1a --- /dev/null +++ b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php @@ -0,0 +1,67 @@ + 'Update Bank Metadata', + 'message' => 'You have successfully updated the Bank metadata' + ]; + } + + /** @var CanUpdateBankMetadata */ + private $canUpdateBankMetadata; + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** + * UpdateBankMetadataLogic constructor. + * @param CanUpdateBankMetadata $canUpdateBankMetadata + * @param FetchesTransaction $fetchesTransaction + */ + public function __construct( + CanUpdateBankMetadata $canUpdateBankMetadata, + FetchesTransaction $fetchesTransaction + ) + { + $this->canUpdateBankMetadata = $canUpdateBankMetadata; + $this->fetchesTransaction = $fetchesTransaction; + } + + /** + * @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 + { + $bankMetadataObject = new BankMetadataObject( + $request->input('transactionId'), + ); + + $this->canUpdateBankMetadata->passes($bankMetadataObject); + + $transaction = $this->fetchesTransaction->execute(['id' => $request->input('transactionId')]); + $transaction->attributes()->delete(); + + return $this->response([]); + } + +} diff --git a/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php b/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php new file mode 100644 index 00000000..dae7a61e --- /dev/null +++ b/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php @@ -0,0 +1,29 @@ +transaction_id = $transaction_id; + } + + /** + * @return int + */ + public function getTransactionId(): int + { + return $this->transaction_id; + } +} diff --git a/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php new file mode 100644 index 00000000..a646cb95 --- /dev/null +++ b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php @@ -0,0 +1,97 @@ +updatesBank = $updatesBank; + $this->createsOrUpdateBank = $createsOrUpdateBank; + $this->createsKeyValuePair = $createsKeyValuePair; + $this->fetchesTransaction = $fetchesTransaction; + } + + /** + * @param BankObject $bankObject + * @param Bank $bank + * @param string $billNo + * @param int $transactionId + * @return Model + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(BankObject $bankObject, Bank $bank, string $billNo, int $transactionId) { + $result = null; + if($billNo && $transactionId){ + $transaction = $this->fetchesTransaction->execute(['id' => $transactionId]); + //If payment transaction do not have a bank yet, create one + if(!$transaction->bank){ + $result = $this->createsOrUpdateBank->execute($bankObject); + + // if ($result->wasRecentlyCreated) { + //Key #1 for Bank + $kvp = $bank->attributes()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first(); + if(!$kvp){ + $keyValuePairObject = new KeyValuePairObject( + "App\Models\Bank", + $result->id + ); + $this->createsKeyValuePair->execute($bank, $keyValuePairObject); + } + + //Key #2 for Payment Transaction (owner type: booking) + $keyValuePairObject = new KeyValuePairObject( + "App\Models\Bank", + $result->id + ); + $this->createsKeyValuePair->execute($transaction, $keyValuePairObject); + // } + + } + else{ + $result = $this->updatesBank->execute($transaction->bank, $bankObject); + } + } + else{ + $result = $this->updatesBank->execute($bank, $bankObject); + } + + return $result; + } +} diff --git a/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php b/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php new file mode 100644 index 00000000..1c582229 --- /dev/null +++ b/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php @@ -0,0 +1,44 @@ + $object->getCompanyId(), + 'account_no' => $object->getAccountNo(), + 'reference' => $object->getReference(), + 'bank_name' => $object->getBankName(), + 'holder_name' => $object->getHolderName(), + 'bank_branch' => $object->getBankBranch(), + 'type' => $object->getType(), + 'country_id' => $object->getCountryId(), + 'created_by' => Auth::id(), + 'creator_type' => in_array($user->type, RoleTypes::ADMIN_ROLES) ? RoleTypes::ADMIN : RoleTypes::USER, + ]; + + $values = [ + 'swift' => $object->getSwift(), + 'snap' => $object->getSnap(), + ]; + + $model = Bank::updateOrCreate($attributes, $values); //Bank::firstOrCreate($attributes, $values); + + return $model; + } +} diff --git a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php new file mode 100644 index 00000000..7d4de3aa --- /dev/null +++ b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php @@ -0,0 +1,66 @@ +validation = $validation; + } + + /** + * @return bool + */ + protected function authorized(): bool + { + //cief todo: 66 - temporary workaround + // if (!Auth::user()->can('update bank_metadata')) { + // return false; + // } + + // return true; + + if (in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)) { + return true; + } + + return false; + } + + /** + * @param BankMetadataObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->validation->validate($object); + } + + /** + * @param BankMetadataObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php b/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php new file mode 100644 index 00000000..37e134c4 --- /dev/null +++ b/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php @@ -0,0 +1,38 @@ + $object->getTransactionId(), + ]; + } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'transaction_id' => 'required', + ]; + } + + /** + * @return array + */ + protected function messages(): array + { + return []; + } +} diff --git a/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php b/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php index af4c88c4..d368574f 100644 --- a/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php @@ -65,8 +65,12 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings $bill = $transaction; $payment = $transaction->owner; $booking = $payment->owner; + $bank = $booking->bank; //cief todo: 66 + if($payment->bank){ + $bank = $payment->bank; + } $company = $booking->company; - $ecommerce = str::contains($booking->bank->bank_name, ['浙江网商银行']); + $ecommerce = str::contains($bank->bank_name, ['浙江网商银行']); return [ $booking->id, @@ -88,4 +92,4 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings $bill->created_at ]; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Banks/UpdateBankMetadataController.php b/app/Http/Controllers/Banks/UpdateBankMetadataController.php new file mode 100644 index 00000000..3b89c1ff --- /dev/null +++ b/app/Http/Controllers/Banks/UpdateBankMetadataController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index a8103e8b..82b4cf3e 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -56,7 +56,7 @@ class CompanyResource extends JsonResource 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', 'personal_banks' => BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), 'recipient_banks' => [ - 'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])), + 'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])->whereIn('creator_type', [null])), 'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) ], 'segments' => SegmentResource::collection($this->segments), diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/ListTransactionJobResource.php index 6c4c0ece..b8908ee6 100644 --- a/app/Http/Resources/ListTransactionJobResource.php +++ b/app/Http/Resources/ListTransactionJobResource.php @@ -16,8 +16,16 @@ class ListTransactionJobResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank ?? $booking->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank ?? $booking->bank; + } $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ @@ -27,7 +35,7 @@ class ListTransactionJobResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, diff --git a/app/Http/Resources/PaymentTransactionResource.php b/app/Http/Resources/PaymentTransactionResource.php index 456ece3d..d0549c38 100644 --- a/app/Http/Resources/PaymentTransactionResource.php +++ b/app/Http/Resources/PaymentTransactionResource.php @@ -18,8 +18,16 @@ class PaymentTransactionResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank ?? $booking->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank ?? $booking->bank; + } $booking_marking = ''; switch ($this->owner_type) { @@ -38,7 +46,7 @@ class PaymentTransactionResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index d259d777..f8620f05 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -19,8 +19,16 @@ class TransactionResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank; + } $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ @@ -30,7 +38,7 @@ class TransactionResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('amount') : $this->amount), @@ -54,7 +62,8 @@ class TransactionResource extends JsonResource 'duration' => $days->diff(Carbon::now())->format('%d'), ], 'remarks' => RemarkResource::collection($this->remarks), - 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) + 'redemption' => new VoucherRedemptionResource($this->voucherRedemption), + 'bank' => ((int) $this->type === TransactionType::PAYMENT) ? new BankResource($bank) : null, //When a transaction (of type payment) has an override recipient bank details on booking, this is NOT null ]; } } diff --git a/app/Http/Resources/V2/CompanyV2Resource.php b/app/Http/Resources/V2/CompanyV2Resource.php index 64fca7c7..3f2cb4c2 100644 --- a/app/Http/Resources/V2/CompanyV2Resource.php +++ b/app/Http/Resources/V2/CompanyV2Resource.php @@ -82,7 +82,7 @@ class CompanyV2Resource extends JsonResource 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', 'personal_banks' => V1\BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), 'recipient_banks' => [ - 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)), + 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)->whereIn('creator_type', [null])), 'default' => new V1\BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) ], 'segments' => V1\SegmentResource::collection($this->segments), diff --git a/app/Models/Bank.php b/app/Models/Bank.php index 3b0bb915..30a429ae 100644 --- a/app/Models/Bank.php +++ b/app/Models/Bank.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use App\Classes\General\Interfaces\KeyValueInterface; /** * Class Bank @@ -21,10 +23,29 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property int default * @property int status */ -class Bank extends AbstractModel +class Bank extends AbstractModel implements KeyValueInterface { use SoftDeletes; - + + /** + * + * @var array + */ + protected $fillable = [ + 'company_id', + 'reference', + 'bank_name', + 'holder_name', + 'account_no', + 'bank_branch', + 'swift', + 'snap', + 'type', + 'country_id', + 'created_by', + 'creator_type', + ]; + protected $table = 'banks'; /** @@ -42,7 +63,7 @@ class Bank extends AbstractModel { return $this->BelongsTo(Company::class, 'company_id', 'id'); } - + /** * @return HasMany */ @@ -50,4 +71,12 @@ class Bank extends AbstractModel { return $this->HasMany(Transaction::class, 'recipient_bank_account_id'); } + + /** + * @return MorphMany + */ + public function attributes(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } } diff --git a/app/Models/KeyValuePair.php b/app/Models/KeyValuePair.php index 3ad6d6cd..8f8ddec8 100644 --- a/app/Models/KeyValuePair.php +++ b/app/Models/KeyValuePair.php @@ -2,10 +2,14 @@ namespace App\Models; use Illuminate\Database\Eloquent\Relations\MorphTo; - +use Illuminate\Database\Eloquent\SoftDeletes; class KeyValuePair extends AbstractModel { + use SoftDeletes; + + protected $dates = ['deleted_at']; + protected $table = 'key_value_pairs'; public function owner(): MorphTo diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 31b67e69..dc18faa1 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\General\Interfaces\Documentable; +use App\Classes\General\Interfaces\KeyValueInterface; use App\Classes\General\Interfaces\Remarkable; use App\Classes\General\Interfaces\Transactionable; use App\Classes\General\Interfaces\Voucherifiable; @@ -22,7 +23,7 @@ use Staudenmeir\EloquentHasManyDeep\HasTableAlias; use App\Models\StatementTransactionOwner; -class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable +class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable, KeyValueInterface { use HasTableAlias; use SoftDeletes; @@ -268,4 +269,25 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $this->morphMany(Remark::class, 'owner'); } + /** + * @return MorphMany + */ + public function attributes(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } + + /** + * + * @return Model|null + */ + public function getBankAttribute() + { + $keyValuePairs = $this->attributes()->where('key', 'App\Models\Bank')->latest()->first(); + if($keyValuePairs){ + $bank = Bank::where('id', $keyValuePairs->value)->first(); + return $bank; + } + return null; + } } diff --git a/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php b/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php new file mode 100644 index 00000000..1d99906f --- /dev/null +++ b/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php @@ -0,0 +1,35 @@ +unsignedBigInteger('created_by')->nullable()->after('country_id'); + $table->unsignedInteger('creator_type')->nullable()->after('created_by'); // 'admin' or 'customer', see RoleTypes.php for more + $table->foreign('created_by')->references('id')->on('users')->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('banks', function (Blueprint $table) { + $table->dropForeign(['created_by']); + $table->dropColumn(['created_by', 'creator_type']); + }); + } +} diff --git a/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php b/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php new file mode 100644 index 00000000..df64b4a8 --- /dev/null +++ b/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php @@ -0,0 +1,32 @@ +softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('key_value_pairs', function (Blueprint $table) { + $table->dropSoftDeletes(); + }); + } +} diff --git a/database/seeds/AdminUserPermissionsTableSeeder.php b/database/seeds/AdminUserPermissionsTableSeeder.php index 0c3d5acf..c111ab6a 100644 --- a/database/seeds/AdminUserPermissionsTableSeeder.php +++ b/database/seeds/AdminUserPermissionsTableSeeder.php @@ -71,6 +71,7 @@ class AdminUserPermissionsTableSeeder extends Seeder ['name' => 'delete milestone', 'guard_name' => 'web'], ['name' => 'delete reward', 'guard_name' => 'web'], + ['name' => 'update bank_metadata', 'guard_name' => 'web'], ]; foreach ($permissions as $permission){ diff --git a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue index 80a3c94d..3bf4f46a 100644 --- a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue @@ -133,7 +133,7 @@
-
+
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
@@ -186,6 +186,18 @@ isEditing: { type: Boolean, default: false + }, + isCancelButtonHidden: { + type: Boolean, + default: false + }, + billNo: { + type: String, + default: '' + }, + transactionId: { + type: Number, + default: 0 } }, data(){ @@ -201,6 +213,8 @@ swift: '', snap: '', country_id: this.country_id, + bill_no: this.billNo, + transaction_id: this.transactionId, } } }, @@ -234,6 +248,8 @@ if(this.isEditing){ this.parameters.company_id = this.company_id; this.parameters.account_type = this.type; + this.parameters.bill_no = this.billNo; + this.parameters.transaction_id = this.transactionId; this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); } else{ @@ -242,7 +258,7 @@ }, successHandler(response){ if(this.isEditing){ - this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data, this.transactionId); } else{ this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); diff --git a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue index cf589b25..dde77e9c 100644 --- a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue @@ -39,7 +39,7 @@
-
+
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
@@ -87,6 +87,18 @@ isEditing: { type: Boolean, default: false + }, + isCancelButtonHidden: { + type: Boolean, + default: false + }, + billNo: { + type: String, + default: '' + }, + transactionId: { + type: Number, + default: 0 } }, data(){ @@ -100,6 +112,8 @@ account_no: '', bank_branch: '', country_id: this.country_id, + bill_no: this.billNo, + transaction_id: this.transactionId, }, englishTextWarning: false, confirmProceedEnglishText: false, @@ -125,6 +139,8 @@ if(this.isEditing){ this.parameters.company_id = this.company_id; this.parameters.account_type = this.type; + this.parameters.bill_no = this.billNo; + this.parameters.transaction_id = this.transactionId; this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); } else{ @@ -133,7 +149,7 @@ }, successHandler(response){ if(this.isEditing){ - this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data, this.transactionId); } else{ this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); diff --git a/resources/assets/vue/components/bookings/elements/BookingPaymentRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingPaymentRecipientEditComponent.vue new file mode 100644 index 00000000..12b673af --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingPaymentRecipientEditComponent.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue index 6240b629..8690d262 100644 --- a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue @@ -3,9 +3,12 @@
-
-
-
Recipient Details
+
+
+
Edit Recipient Bank Details ({{ data.billNo }})
+
+
+
Edit Recipient Bank Details (Default)
@@ -64,8 +67,31 @@
- - + + + +
@@ -84,9 +110,9 @@ diff --git a/resources/assets/vue/components/bookings/forms/RecipientBankDetailsComponent.vue b/resources/assets/vue/components/bookings/forms/RecipientBankDetailsComponent.vue new file mode 100644 index 00000000..a58a6fd5 --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/RecipientBankDetailsComponent.vue @@ -0,0 +1,83 @@ + + diff --git a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue index 16cae41c..1634e9d9 100644 --- a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue +++ b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue @@ -4,7 +4,7 @@
- +
diff --git a/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue b/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue index 0cb9435b..85526d4e 100644 --- a/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue +++ b/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue @@ -33,7 +33,7 @@ required: true }, params: { - type: Array, + type: Object, required: false }, modalType: { diff --git a/resources/views/pages/pdfs/currency_vendor_order.blade.php b/resources/views/pages/pdfs/currency_vendor_order.blade.php index df445998..7638f5c5 100644 --- a/resources/views/pages/pdfs/currency_vendor_order.blade.php +++ b/resources/views/pages/pdfs/currency_vendor_order.blade.php @@ -46,12 +46,18 @@ {{$transaction->currency_rate}} {{$transaction->currency->short_code}} {{number_format((float)$transaction->amount, 2, '.', '')}} - Account Holder Name: {{$transaction->owner->owner->bank->holder_name}} -
{{$transaction->owner->owner->bank->bank_name}}: {{$transaction->owner->owner->bank->account_no}} -
Branch: {{$transaction->owner->owner->bank->bank_branch}} + @php + $bank = $transaction->owner->owner->bank; + if($transaction->owner->bank){ + $bank = $transaction->owner->bank; + } + @endphp + Account Holder Name: {{$bank->holder_name}} +
{{$bank->bank_name}}: {{$bank->account_no}} +
Branch: {{$bank->bank_branch}} @if($transaction->original_currency->short_code === 'USD') -
Account Holder Address: {{$transaction->owner->owner->bank->reference}} -
Swift Code: {{$transaction->owner->owner->bank->swift}} +
Account Holder Address: {{$bank->reference}} +
Swift Code: {{$bank->swift}} @endif
Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}} @if ($order_reference_no) diff --git a/resources/views/pages/pdfs/currency_vendor_order_inner.blade.php b/resources/views/pages/pdfs/currency_vendor_order_inner.blade.php index e477c538..2d0c486f 100644 --- a/resources/views/pages/pdfs/currency_vendor_order_inner.blade.php +++ b/resources/views/pages/pdfs/currency_vendor_order_inner.blade.php @@ -19,12 +19,18 @@ @foreach($transactions as $transaction) + @php + $bank = $transaction->owner->owner->bank; + if($transaction->owner->bank){ + $bank = $transaction->owner->bank; + } + @endphp {{$transaction->owner->owner->marking}} {{$transaction->owner->owner->company->reference}} {{$transaction->currency_rate}} {{$transaction->currency->short_code}} {{number_format((float)$transaction->amount, 2, '.', '')}} - Account Holder Name: {{$transaction->owner->owner->bank->holder_name}}
{{$transaction->owner->owner->bank->bank_name}}: {{$transaction->owner->owner->bank->account_no}} -
Branch: {{$transaction->owner->owner->bank->bank_branch}}@if($transaction->original_currency->short_code === 'USD')
Swift Code: {{$transaction->owner->owner->bank->swift}}@endif
Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}} + Account Holder Name: {{$bank->holder_name}}
{{$bank->bank_name}}: {{$bank->account_no}} +
Branch: {{$bank->bank_branch}}@if($transaction->original_currency->short_code === 'USD')
Swift Code: {{$bank->swift}}@endif
Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}} @endforeach diff --git a/routes/api.php b/routes/api.php index 2d52b3ea..23adace3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -60,7 +60,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/wallet.php'; require __DIR__ . '/voucher.php'; - + require __DIR__ . '/accounting.php'; require __DIR__ . '/reward.php'; @@ -69,8 +69,6 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__.'/remark.php'; - // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed - require __DIR__ . '/job.php'; // require __DIR__ . '/rate.php'; diff --git a/routes/bank.php b/routes/bank.php index 03c719e6..b7c7e96e 100644 --- a/routes/bank.php +++ b/routes/bank.php @@ -10,4 +10,6 @@ Route::group(['prefix' => 'bank', 'as' => 'bank.', 'namespace' => 'Banks'], func Route::delete('/delete/{id}', 'DeleteBankController@delete')->name('delete'); Route::put('/update/{id}/status', 'UpdateBankStatusController@update')->name('status.update'); -}); \ No newline at end of file + + Route::post('/metadata/update/{id}', 'UpdateBankMetadataController@delete')->name('update.metadata'); +}); diff --git a/routes/web.php b/routes/web.php index a7c87263..23c4239e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -406,16 +406,18 @@ Route::get('/pending_orders', function(){ $i = 0; foreach ($payments as $payment){ $booking = $payment->owner; + $bank = $payment->bank ?? $booking->bank; //cief todo: 66 + $original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id)); $refunds = $original_refunds / $payment->currency_rate; if(!$booking instanceof Booking){ dd($payment); } - $bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str::length($bank->holder_name) > 4 ? 'Company' : 'Personal'; - if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name)) + if (!preg_match('/[^A-Za-z0-9]/', $bank->holder_name)) { - $bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str_word_count($bank->holder_name) > 4 ? 'Company' : 'Personal'; } echo ''; @@ -432,7 +434,7 @@ Route::get('/pending_orders', function(){ echo ''.$booking->service->name.''; echo ''.$payment->updated_at->diffForHumans().''; echo ''.$bankType.''; - echo ''.$booking->bank->holder_name.''; + echo ''.$bank->holder_name.''; echo ''; } echo ''; @@ -509,14 +511,16 @@ Route::get('/approve_refunds', function(Request $request){ foreach ($approve_refunds->orderBy('created_at', 'DESC')->get() as $index => $refund){ $payment = $refund->owner; $booking = $refund->owner->owner; + $bank = $payment->bank ?? $booking->bank; //cief todo: 66 + if(!$booking instanceof Booking){ dd($refund); } - $bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str::length($bank->holder_name) > 4 ? 'Company' : 'Personal'; - if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name)) + if (!preg_match('/[^A-Za-z0-9]/', $bank->holder_name)) { - $bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str_word_count($bank->holder_name) > 4 ? 'Company' : 'Personal'; } $remark = $refund->original_amount === $refund->owner->original_amount ? 'Fully Refund' : 'Partial Refund'; @@ -545,7 +549,7 @@ Route::get('/approve_refunds', function(Request $request){ echo ''.$booking->service->name.''; echo ''.$payment->updated_at->diffForHumans().''; echo ''.$bankType.''; - echo ''.$booking->bank->holder_name.''; + echo ''.$bank->holder_name.''; echo ''.$noteRemark.''; echo ''; } @@ -563,10 +567,12 @@ Route::get('/group/text/{id}', function($id){ foreach ($group->transactions as $transaction){ $i++; $booking = $transaction->owner->owner; + $bank = $transaction->owner->bank ?? $booking->bank; //cief todo: 66 + echo 'No.'.$i.'
'; - echo 'Bank Details:'.$booking->bank->holder_name.'
'; - echo $booking->bank->bank_name.' '.$booking->bank->bank_branch.'
'; - echo 'Bank Account Number:'.$booking->bank->account_no.'
'; + echo 'Bank Details:'.$bank->holder_name.'
'; + echo $bank->bank_name.' '.$bank->bank_branch.'
'; + echo 'Bank Account Number:'.$bank->account_no.'
'; echo 'Order Amount:'.$transaction->original_currency->short_code.' '.(round($transaction->original_amount, 2) + 0).'

'; } @@ -576,7 +582,7 @@ Route::get('/group/invoice/{id}', function ($id) { $group = Group::findOrFail($id); - $supplier = $group->issuerCompany; + $supplier = $group->issuerCompany; $transferFeeTransactions = $group->transactions() ->with(['transactions' => function ($transaction) { @@ -588,8 +594,8 @@ Route::get('/group/invoice/{id}', function ($id) { $html = view('pages.pdfs.supplier_deliver_order_group_invoice', [ 'group'=> $group, - 'transactions' => $group->transactions, - 'transferFeeTransactions' => $transferFeeTransactions, + 'transactions' => $group->transactions, + 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier ])->render(); @@ -597,7 +603,7 @@ Route::get('/group/invoice/{id}', function ($id) { $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); - + return $dompdf->stream("invoice_pdf_{$supplier->name}.pdf"); })->name('group.invoice'); @@ -1167,7 +1173,7 @@ Route::get('check-duplicate-refunds', function () { foreach ($results as $result) { $booking_ref_arr = explode(' ', $result->payment_reference); $booking_ref = end($booking_ref_arr); - + echo ''; echo "$result->owner_type"; echo "$result->owner_id"; @@ -1204,7 +1210,7 @@ Route::get('check-duplicate-refunds', function () { echo "" . ($refund ? $refund : '') . ""; echo ''; - + } echo ''; echo ''; From 32833064b33d1eda60065d7b313a34ab2aa3b540 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 7 Aug 2024 06:56:49 +0800 Subject: [PATCH 04/32] Fix some breaking changes that is already deployed to master branch --- .../Banks/ControllersLogic/UpdateBankMetadataLogic.php | 2 +- app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php | 2 +- app/Models/Bank.php | 2 +- app/Models/Transaction.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php index 1dc79f1a..e73d051a 100644 --- a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php +++ b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php @@ -59,7 +59,7 @@ class UpdateBankMetadataLogic extends AbstractControllerLogic $this->canUpdateBankMetadata->passes($bankMetadataObject); $transaction = $this->fetchesTransaction->execute(['id' => $request->input('transactionId')]); - $transaction->attributes()->delete(); + $transaction->attributesKVP()->delete(); return $this->response([]); } diff --git a/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php index a646cb95..6030c11d 100644 --- a/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php +++ b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php @@ -66,7 +66,7 @@ class UpdateBankProcessor // if ($result->wasRecentlyCreated) { //Key #1 for Bank - $kvp = $bank->attributes()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first(); + $kvp = $bank->attributesKVP()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first(); if(!$kvp){ $keyValuePairObject = new KeyValuePairObject( "App\Models\Bank", diff --git a/app/Models/Bank.php b/app/Models/Bank.php index 30a429ae..42cdf3df 100644 --- a/app/Models/Bank.php +++ b/app/Models/Bank.php @@ -75,7 +75,7 @@ class Bank extends AbstractModel implements KeyValueInterface /** * @return MorphMany */ - public function attributes(): MorphMany + public function attributesKVP(): MorphMany { return $this->morphMany(KeyValuePair::class, 'owner'); } diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index dc18faa1..c84c0238 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -272,7 +272,7 @@ class Transaction extends AbstractModel implements Documentable, Transactionable /** * @return MorphMany */ - public function attributes(): MorphMany + public function attributesKVP(): MorphMany { return $this->morphMany(KeyValuePair::class, 'owner'); } @@ -283,7 +283,7 @@ class Transaction extends AbstractModel implements Documentable, Transactionable */ public function getBankAttribute() { - $keyValuePairs = $this->attributes()->where('key', 'App\Models\Bank')->latest()->first(); + $keyValuePairs = $this->attributesKVP()->where('key', 'App\Models\Bank')->latest()->first(); if($keyValuePairs){ $bank = Bank::where('id', $keyValuePairs->value)->first(); return $bank; From 039d8deeea2e0a8847780275c5fafc149ba28b72 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 7 Aug 2024 07:23:45 +0800 Subject: [PATCH 05/32] Fix some breaking changes that is already deployed to master branch --- .../Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php index 7d4de3aa..d102a763 100644 --- a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php +++ b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php @@ -28,7 +28,7 @@ class CanUpdateBankMetadata extends AbstractRule /** * @return bool */ - protected function authorized(): bool + protected function authorized($object): bool { //cief todo: 66 - temporary workaround // if (!Auth::user()->can('update bank_metadata')) { From 7013dd4256f517f1d5a67c7c6bbf00a0867f33f8 Mon Sep 17 00:00:00 2001 From: Aqqil Azman Date: Wed, 7 Aug 2024 09:58:39 +0800 Subject: [PATCH 06/32] added table headers due to account oversight on the database structure, mixing Marking and Ref No up --- routes/web.php | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/routes/web.php b/routes/web.php index e5743ed5..c4ab51f7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -402,8 +402,25 @@ Route::get('/pending_orders', function(){ }) ->orderBy('updated_at', 'desc') ->get(); - - echo ''; + + echo '
'; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; $i = 0; foreach ($payments as $payment){ $booking = $payment->owner; @@ -422,14 +439,12 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; - echo ''; - echo ''; + echo ''; echo ''; echo ''; - echo ''; echo ''; echo ''; echo ''; From ea06152dbf86ca417bd1f3d1ccaa7ab92aae75bf Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 7 Aug 2024 10:51:27 +0800 Subject: [PATCH 07/32] update pending_orders table header --- routes/web.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/routes/web.php b/routes/web.php index c4ab51f7..a66457a6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -406,16 +406,16 @@ Route::get('/pending_orders', function(){ echo '
Client Booking DatePayment TypeMarkingCustomer Payment CurrencyCustomer Payment AmountReference No.Booking Amount CurrencyCNYServiceDaysCust Supplier Acc TypeCust Supplier Acc Name
'.$payment->updated_at->format('d-M-y').''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$booking->company->reference.''.$booking->marking.''.$payment->currency->short_code.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->marking.''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.'
'; echo ''; echo ''; - echo ''; + echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; From 764f242e871c1b346e777b246684f66a41bd0b58 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 7 Aug 2024 13:13:26 +0800 Subject: [PATCH 08/32] fix pending_orders table header --- routes/web.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/web.php b/routes/web.php index a66457a6..e912b49d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -411,9 +411,11 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -442,9 +444,11 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; From 8a0005aa175ecee0185230117fe446a49e7de482 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 7 Aug 2024 15:40:24 +0800 Subject: [PATCH 09/32] fix pending_orders table header --- routes/web.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/routes/web.php b/routes/web.php index e912b49d..1a654013 100644 --- a/routes/web.php +++ b/routes/web.php @@ -403,16 +403,22 @@ Route::get('/pending_orders', function(){ ->orderBy('updated_at', 'desc') ->get(); - echo '
Client Booking DateBooking Updated DatePayment TypeMarkingCustomer Payment CurrencyCustomer Payment AmountReference No.Booking Amount CurrencyCNYBookingPayment CurrencyPayment AmountCustomerBooking CurrencyBooking AmountServiceDaysPayment UpdatedCust Supplier Acc TypeCust Supplier Acc Name
BookingPayment CurrencyPayment AmountCustomerBooking CurrencyBooking AmountServicePayment UpdatedCust Supplier Acc Type'.$booking->marking.''.$payment->currency->short_code.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.'
'; + echo ' + '; + echo '
'; echo ''; echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -440,12 +446,12 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; From f58dea32ac8bb39a67b9b9820eef8668da229806 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 7 Aug 2024 18:27:58 +0800 Subject: [PATCH 10/32] revert fixed pending_orders table --- routes/web.php | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/routes/web.php b/routes/web.php index 1a654013..76446093 100644 --- a/routes/web.php +++ b/routes/web.php @@ -403,32 +403,24 @@ Route::get('/pending_orders', function(){ ->orderBy('updated_at', 'desc') ->get(); - echo ' - '; - echo '
Booking Updated DatePayment TypeBookingPayment TypePayment CurrencyPayment AmountCustomerBooking CurrencyBooking Amount
'.$payment->updated_at->format('d-M-y').''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$payment->currency->short_code.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').'
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo '
Booking Updated DateBookingPayment TypePayment CurrencyPayment AmountCustomerBooking CurrencyBooking AmountServicePayment UpdatedCust Supplier Acc TypeCust Supplier Acc Name
'; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; + // echo ''; $i = 0; foreach ($payments as $payment){ $booking = $payment->owner; @@ -446,15 +438,13 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; - echo ''; echo ''; echo ''; - echo ''; echo ''; echo ''; echo ''; From 602b69dcba132823ed294998218916377b3fdf04 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 9 Aug 2024 19:47:58 +0800 Subject: [PATCH 11/32] show payment method and date --- .../bookings/elements/PaymentHistoryComponent.vue | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 370092cd..939865b1 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -33,6 +33,12 @@
{{ item.status === 2 ? 'Received' : item.status === 4 ? 'Rejected' : 'Submitted'}} On: {{item.updated_at}}
+
+
+
Payment Method: {{ convertPaymentMethod(item.payment_method) }}
+
Payment Date: {{ item.created_at }}
+
+
Bill Number: {{ item.bill_no }}
@@ -456,6 +462,15 @@ clickExpandRefundTransactions(){ this.expandRefundTransactions = !this.expandRefundTransactions; }, + convertPaymentMethod(paymentMethod){ + var paymentMethodArray = []; + paymentMethodArray[1] = 'Cash'; + paymentMethodArray[2] = 'Cheque'; + paymentMethodArray[3] = 'ba'; + paymentMethodArray[4] = 'Wallet'; + paymentMethodArray[5] = 'Payment Gateway'; + return paymentMethodArray[paymentMethod]; + }, }, mixins: [componentHandler] } From cfcc5fbe26c364ec7fcc7f3c86f76b570b196930 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 12 Aug 2024 09:34:45 +0800 Subject: [PATCH 12/32] Fix an error with refund for transaction that used a voucher earlier, get discount amount for voucher so to get details breakdown --- .../CreateBookingRefundLogic.php | 10 +++-- .../Services/FetchesBookingQuotation.php | 44 +++++++++++++------ .../FetchesVoucherifyRedemption.php | 38 ++++++++++++++++ .../BookingPaymentQuotationComponent.vue | 2 +- 4 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 8c492eb1..6a7510c2 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -117,16 +117,18 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; $voucherCode = null; + $redemptionId = null; if ($transaction->voucherRedemption) { - $voucherCode = $transaction->voucherRedemption->voucher->code; + // $voucherCode = $transaction->voucherRedemption->voucher->code; + $redemptionId = $transaction->voucherRedemption->redemption_id; } - + $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode); + $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode); @@ -179,4 +181,4 @@ class CreateBookingRefundLogic extends AbstractControllerLogic } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php index 1d3d7acc..e5535e2a 100644 --- a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php +++ b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php @@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidatedVoucherObject; use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherObject; use App\Classes\Modules\Currencies\Services\FetchesCurrency; use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher; +use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyRedemption; use App\Models\Company; use App\Models\Currency; use Illuminate\Support\Facades\Log; @@ -27,27 +28,34 @@ class FetchesBookingQuotation /** @var ValidatesVoucherifyVoucher */ private $validatesVoucherifyVoucher; + /** @var FetchesVoucherifyRedemption */ + private $fetchesVoucherifyRedemption; + /** * FetchesBookingQuotation constructor. * @param FetchesCompanyServiceSettings $fetchesCompanyServiceSettings * @param FetchesCurrency $fetchesCurrency + * @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher + * @param FetchesVoucherifyRedemption $fetchesVoucherifyRedemption */ - public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher) + public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, FetchesVoucherifyRedemption $fetchesVoucherifyRedemption) { $this->fetchesCompanyServiceSettings = $fetchesCompanyServiceSettings; $this->fetchesCurrency = $fetchesCurrency; $this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher; + $this->fetchesVoucherifyRedemption = $fetchesVoucherifyRedemption; } /** * @param Company $company * @param CurrencyConversionObject $conversionObject - * @param string $voucherCode + * @param null|string $voucherCode + * @param null|string $redemptionId * @return CalculationObject * @throws MalformedRequestException */ - public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null){ + public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null, ?string $redemptionId = null){ if($conversionObject->getAmount() <= 0) throw new MalformedRequestException('Your transfer must be greater than zero.'); $configurations = $this->fetchesCompanyServiceSettings->execute($company, $conversionObject); @@ -58,27 +66,37 @@ class FetchesBookingQuotation $calculationObject = new CalculationObject($conversionObject, $configurations, null); + $voucher = null; + //Voucherify if($voucherCode){ $employee = $company->employees()->first(); $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employee); $result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject); - - // //A minimum charge of RM5 applies when voucher used make price to be paid by customer RM0 - // if(isset($result->order->total_amount) && $result->order->total_amount === 0){ - // // $result->order->cief_original_total_amount = $result->order->total_amount; - // $result->order->total_amount = 500; - // $result->order->total_discount_amount = $result->order->total_discount_amount - $result->order->total_amount; - // Log::info('FetchesBookingQuotation order total_amount RM0 (voucher applied) for company id ' . $company->id. ' with original amount ' . $calculationObject->getSubTotal()); - // } - $voucher = [ "code" => $result->code, "discount" => property_exists($result, 'discount') ? $result->discount : null, "metadata" => $result->metadata, "order" => $result->order, ]; - $validatedVoucherObject = new ValidatedVoucherObject(isset($voucher['metadata']->name) ? $voucher['metadata']->name: "", $voucher['code'], $voucher['discount']->type ?? 'AMOUNT', $voucher['order']->total_discount_amount, $voucher['order']->total_amount); + } + else if($redemptionId){ + $result = $this->fetchesVoucherifyRedemption->execute($redemptionId); + $voucher = [ + "code" => $result->voucher->code ?? null, + "discount" => null, + "metadata" => null, + "order" => $result->order ?? null, + ]; + } + + if($voucher){ + $validatedVoucherObject = new ValidatedVoucherObject( + isset($voucher['metadata']->name) ? $voucher['metadata']->name : "", + $voucher['code'], + $voucher['discount']->type ?? 'AMOUNT', + $voucher['order']->total_discount_amount, + $voucher['order']->total_amount); $calculationObject = new CalculationObject($conversionObject, $configurations, $validatedVoucherObject); } diff --git a/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php b/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php new file mode 100644 index 00000000..03966926 --- /dev/null +++ b/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php @@ -0,0 +1,38 @@ +voucherifyClient = createVoucherifyClient(); + } + + /** + * @param string $redemptionId + * @return null|object + * @throws \Voucherify\ClientException + */ + public function execute(string $redemptionId) + { + try { + $result = $this->voucherifyClient->redemptions->get($redemptionId); + return $result; + } catch (\Voucherify\ClientException $e) { + Log::error('FetchesVoucherifyRedemption '.$e); + return null; + } + } +} diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index f0528dbd..ba2d7893 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -116,7 +116,7 @@
{{this.data.fixed_currency.short_code}} {{(Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
-
+
From 77e314c52b3211fe6ac24ffa4217a617f91e7fd2 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 12 Aug 2024 10:25:57 +0800 Subject: [PATCH 13/32] Quick fix on recipient_bank_account is null error on frontend --- app/Http/Resources/TransactionResource.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index f8620f05..595ce443 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -23,11 +23,11 @@ class TransactionResource extends JsonResource $bank = null; if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){ $booking = $this->owner->owner; - $bank = $this->owner->bank; + $bank = $this->owner->bank ?? $booking->bank; } else{ $booking = $this->owner; - $bank = $this->bank; + $bank = $this->bank ?? $booking->bank; } $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); From a36b6f5e57d3c2010b53213c3ad16a9f71fa6ece Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 12 Aug 2024 10:48:35 +0800 Subject: [PATCH 14/32] Comments on code --- app/Http/Resources/ListTransactionJobResource.php | 2 ++ app/Http/Resources/PaymentTransactionResource.php | 2 ++ app/Http/Resources/TransactionResource.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/ListTransactionJobResource.php index b8908ee6..1547c09e 100644 --- a/app/Http/Resources/ListTransactionJobResource.php +++ b/app/Http/Resources/ListTransactionJobResource.php @@ -18,6 +18,7 @@ class ListTransactionJobResource extends JsonResource { $booking = null; //cief todo: 66 $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ $booking = $this->owner->owner; $bank = $this->owner->bank ?? $booking->bank; @@ -26,6 +27,7 @@ class ListTransactionJobResource extends JsonResource $booking = $this->owner; $bank = $this->bank ?? $booking->bank; } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ diff --git a/app/Http/Resources/PaymentTransactionResource.php b/app/Http/Resources/PaymentTransactionResource.php index d0549c38..01da84b2 100644 --- a/app/Http/Resources/PaymentTransactionResource.php +++ b/app/Http/Resources/PaymentTransactionResource.php @@ -20,6 +20,7 @@ class PaymentTransactionResource extends JsonResource { $booking = null; //cief todo: 66 $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ $booking = $this->owner->owner; $bank = $this->owner->bank ?? $booking->bank; @@ -28,6 +29,7 @@ class PaymentTransactionResource extends JsonResource $booking = $this->owner; $bank = $this->bank ?? $booking->bank; } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $booking_marking = ''; switch ($this->owner_type) { diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index 595ce443..e14c32c0 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -21,6 +21,7 @@ class TransactionResource extends JsonResource { $booking = null; //cief todo: 66 $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){ $booking = $this->owner->owner; $bank = $this->owner->bank ?? $booking->bank; @@ -29,6 +30,7 @@ class TransactionResource extends JsonResource $booking = $this->owner; $bank = $this->bank ?? $booking->bank; } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ From a6174c61bf1399fd22e24a63a2ce8f5ff99962a5 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 12 Aug 2024 14:10:35 +0800 Subject: [PATCH 15/32] revert update on pending_orders --- routes/web.php | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/routes/web.php b/routes/web.php index b2067c6e..32038ed2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -400,27 +400,10 @@ Route::get('/pending_orders', function(){ ->whereDoesntHave('transactions', function ($query) { return $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); }) - ->orderBy('updated_at', 'desc') + // ->orderBy('updated_at', 'desc') ->get(); - - echo '
Client Booking DatePayment TypeMarkingCustomer Payment CurrencyCustomer Payment AmountReference No.Booking Amount CurrencyCNYServiceDaysCust Supplier Acc TypeCust Supplier Acc Name
'.$payment->updated_at->format('d-M-y').''.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$booking->marking.''.$payment->currency->short_code.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.'
'; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; - // echo ''; + + echo '
Client Booking DatePayment TypeMarkingCustomer Payment CurrencyCustomer Payment AmountReference No.Booking Amount CurrencyCNYServiceDaysCust Supplier Acc TypeCust Supplier Acc Name
'; $i = 0; foreach ($payments as $payment){ $booking = $payment->owner; @@ -440,17 +423,19 @@ Route::get('/pending_orders', function(){ echo ''; echo ''; - echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; - echo ''; + echo ''; echo ''; } echo '
'.$payment->updated_at->format('d-M-y').''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$payment->currency->short_code.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.''.$bank->holder_name.''.$booking->bank->holder_name.'
'; From 08e56acc2438ad88503df9504a2d82b6cbfe37e7 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 12 Aug 2024 14:17:07 +0800 Subject: [PATCH 16/32] update pending_orders, order by updated_at desc --- routes/web.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index 32038ed2..112dee31 100644 --- a/routes/web.php +++ b/routes/web.php @@ -400,7 +400,7 @@ Route::get('/pending_orders', function(){ ->whereDoesntHave('transactions', function ($query) { return $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); }) - // ->orderBy('updated_at', 'desc') + ->orderBy('updated_at', 'desc') ->get(); echo ''; From 03472dc6be8969b84750a43ab5e7220a0938ec05 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Mon, 12 Aug 2024 21:25:48 +0800 Subject: [PATCH 17/32] fix fully refund oustanding --- .../CreateBookingRefundLogic.php | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 8c492eb1..6c2ab63a 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -108,29 +108,34 @@ class CreateBookingRefundLogic extends AbstractControllerLogic // $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount')); // $transactionRefundCalculationObject->init(); - $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); + if ((float)$request->input('amount') === (float)$transaction->original_amount) { + $refundAmount = $transaction->original_amount / $transaction->currency_rate; + $service_charges_to_refund = $transaction->service_charge; + } else { + $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); - $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; - - $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); - - $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; - - $voucherCode = null; - - if ($transaction->voucherRedemption) { - $voucherCode = $transaction->voucherRedemption->voucher->code; + $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; + + $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); + + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; + + $voucherCode = null; + + if ($transaction->voucherRedemption) { + $voucherCode = $transaction->voucherRedemption->voucher->code; + } + + $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode); + + $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode); + + $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); } - - $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode); - - $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode); - - $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); // refund service charges if booking is not E2E $refundTotal = $refundAmount; From 13dd19d0a1348c979022de494fdd583813c431ae Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 12 Aug 2024 22:29:04 +0800 Subject: [PATCH 18/32] Fix an error with refund for transaction that used a voucher earlier, get discount amount for voucher so to get details breakdown --- .../Bookings/ControllersLogic/CreateBookingRefundLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 6a7510c2..6e6b2233 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -130,7 +130,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); - $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode); + $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); From 1d5b5f78658687a65aa8be5814204ef1233879da Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Mon, 12 Aug 2024 22:41:39 +0800 Subject: [PATCH 19/32] fix group with currency rate more than 100 --- .../Commands/UpdateWrongGroupCurrencyRate.php | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 app/Console/Commands/UpdateWrongGroupCurrencyRate.php diff --git a/app/Console/Commands/UpdateWrongGroupCurrencyRate.php b/app/Console/Commands/UpdateWrongGroupCurrencyRate.php new file mode 100644 index 00000000..fbe7245b --- /dev/null +++ b/app/Console/Commands/UpdateWrongGroupCurrencyRate.php @@ -0,0 +1,126 @@ +createsDocument = $createsDocument; + $this->createsFile = $createsFile; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $groups = Group::where('currency_rate', '>', 100)->get(); + + foreach ($groups as $group) { + $transactions = $group->transactions()->get(); + + $rate = DB::table('transaction_logs')->where('transaction_id', $transactions->first()->id)->latest('updated_at')->first()->currency_rate; + + $supplier = $group->issuerCompany; + + foreach ($transactions as $transaction) { + $transaction->currency_rate = $rate; + $transaction->amount = $transaction->original_amount / $rate; + $transaction->save(); + + $supplierRefundTransactions = $transaction->owner->transactions()->supplierRefunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->get(); + + foreach ($supplierRefundTransactions as $supplierRefundTransaction) { + $claimBefore = $supplierRefundTransaction->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->exists(); + + if (!$claimBefore) { + $supplierRefundTransaction->currency_rate = $rate; + $supplierRefundTransaction->amount = $supplierRefundTransaction->original_amount / $rate; + $supplierRefundTransaction->save(); + } + } + } + + $group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first(); + + $group_transfer_fee_original_amount = 0; + + if ($group_transfer_fee) { + $group_transfer_fee_original_amount = $group_transfer_fee->original_amount; + } + + $transferFeeTransactions = $group->transactions()->with([ + 'transactions' => function ($transaction) { + return $transaction->where('type', TransactionType::TRANSFER_FEE); + } + ])->get()->pluck('transactions')->flatten(); + + $group->original_amount = $group->transactions()->sum('original_amount') + ((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount); + $group->amount = $group->transactions()->sum('amount') + (((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount) / $rate) + $group->transactions()->sum('service_charge'); + $group->currency_rate = $rate; + $group->tax = $group->transactions()->sum('tax'); + $group->service_charge = $group->transactions()->sum('service_charge'); + + $group->save(); + + $group->documents()->delete(); + + $pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $group->transactions, 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier, 'groupTransferFeeOriginalAmount' => $group_transfer_fee_original_amount]); + + $object = new DocumentObject( + DocumentType::CURRENCY_VENDOR_ORDER, + [chunk_split('data:application/pdf;base64,' . base64_encode($pdf->output()))], + '', + ApprovalStatus::COMPLETED, + 'currency_vendor_order' + ); + + /** @var Document $document */ + $document = $this->createsDocument->execute($group, $object); + $this->createsFile->execute($document, $object); + + $this->info("Group ID: {$group->id} updated to currency rate {$rate}"); + } + } +} From 204ebf04ca6e52443ed7cc64449df9865395b8b8 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 12 Aug 2024 23:19:12 +0800 Subject: [PATCH 20/32] fix merge code error --- .../CreateBookingRefundLogic.php | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index e6bf4f1c..fbafb659 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -113,32 +113,32 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $service_charges_to_refund = $transaction->service_charge; } else { $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); - - $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; - - $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); - - $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; - - $voucherCode = null; - $redemptionId = null; - - if ($transaction->voucherRedemption) { - // $voucherCode = $transaction->voucherRedemption->voucher->code; - $redemptionId = $transaction->voucherRedemption->redemption_id; - } - - $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); - - $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); - - $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); } + $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; + + $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); + + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; + + $voucherCode = null; + $redemptionId = null; + + if ($transaction->voucherRedemption) { + // $voucherCode = $transaction->voucherRedemption->voucher->code; + $redemptionId = $transaction->voucherRedemption->redemption_id; + } + + $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); + + $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); + + $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); + // refund service charges if booking is not E2E $refundTotal = $refundAmount; From ca1d36bac697ef04372d5a55f36fa875c168b2cc Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 12 Aug 2024 23:39:17 +0800 Subject: [PATCH 21/32] fix code merging --- .../CreateBookingRefundLogic.php | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index fbafb659..e6bf4f1c 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -113,32 +113,32 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $service_charges_to_refund = $transaction->service_charge; } else { $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); + + $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; + + $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); + + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; + + $voucherCode = null; + $redemptionId = null; + + if ($transaction->voucherRedemption) { + // $voucherCode = $transaction->voucherRedemption->voucher->code; + $redemptionId = $transaction->voucherRedemption->redemption_id; + } + + $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); + + $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); + + $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); } - $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; - - $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); - - $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; - - $voucherCode = null; - $redemptionId = null; - - if ($transaction->voucherRedemption) { - // $voucherCode = $transaction->voucherRedemption->voucher->code; - $redemptionId = $transaction->voucherRedemption->redemption_id; - } - - $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); - - $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); - - $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); - // refund service charges if booking is not E2E $refundTotal = $refundAmount; From 45533c9179d55f2aa1053fd777b5051e7a91c59f Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 13 Aug 2024 14:55:05 +0800 Subject: [PATCH 22/32] Quick fix on error when lock booking info forwarded to voucherify --- .../Voucherify/BookingToVoucherifyProcessor.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php index dd17e76c..6f89916b 100644 --- a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php +++ b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php @@ -18,6 +18,7 @@ use App\Classes\ValueObjects\Constants\VoucherifyEntityType; use App\Models\User; use App\Models\Transaction; use App\Models\Voucher; +use App\Models\VoucherCampaign; use Illuminate\Support\Facades\Log; class BookingToVoucherifyProcessor @@ -98,7 +99,7 @@ class BookingToVoucherifyProcessor $voucherify_customer_id = $redeemVoucherResult->customer->id; } - $voucher = $this->recordVoucherInfo($redeemedVoucher, $transaction); + $voucher = $this->recordVoucherInfo($redeemedVoucher); $this->createsVoucherRedemption->execute($transaction, $voucher, $redemptionId, $voucherDiscountAmount); $this->recordVoucherForUserInfo($user, $voucher); } @@ -126,9 +127,14 @@ class BookingToVoucherifyProcessor //Create records at 3 tables $voucherValue = isset($redeemedVoucher->discount->amount_off) ? $redeemedVoucher->discount->amount_off : $redeemedVoucher->discount->percent_off; $voucherType = $redeemedVoucher->discount ? $redeemedVoucher->discount->type : null; - $voucherCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null; + $voucherifyCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null; - $voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->name) ? $redeemedVoucher->metadata->name : "", $voucherType, $voucherValue, $voucherCampaignId); + $voucherCampaign = null; + if($voucherifyCampaignId){ + $voucherCampaign = VoucherCampaign::where('campaign_id', $voucherifyCampaignId)->first(); + } + + $voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->displayname) ? $redeemedVoucher->metadata->displayname : "", $voucherType, $voucherValue, $voucherCampaign ? $voucherCampaign->id : null); $voucher = $this->createsVoucher->execute($voucherObject); if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]); From de008d593e38bd7ed6e768827d64e2f9612c2c52 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 13 Aug 2024 15:59:07 +0800 Subject: [PATCH 23/32] Minor UI update to show Terms requested by KS --- .../elements/AvailableVouchersComponent.vue | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index bcfd7219..a5fb4e3b 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -14,12 +14,43 @@ -->
- - Valid till {{ item.voucher.end_date }} - - - No expiry date - +
+ + Valid till {{ item.voucher.end_date }} + + + No expiry date + +
+
+ Terms +
+ +
+
+
+ Terms & Conditions +
+
+
    +
  1. Vouchers are only valid for purchases made on https://exchange.cief-malaysia.com/.
  2. +
  3. Each voucher is applicable for a single transaction (unless stated otherwise).
  4. +
  5. Each voucher is only applicable for new orders.
  6. +
  7. Voucher codes are to be entered at the checkout or cart page (unless stated otherwise).
  8. +
  9. Vouchers are not valid for promotions or discounted products (unless stated otherwise).
  10. +
  11. Customers should take note of the expiry dates of the voucher(s) that they wish to redeem. Any voucher(s) which have expired will be invalid.
  12. +
  13. Individual vouchers are only valid during its respective promotion period. This guideline overrides any individual voucher policy (unless stated otherwise).
  14. +
  15. CIEF reserves the right to cancel any order if a customer’s purchasing behavior appears to be suspicious or potentially fraudulent.
  16. +
  17. CIEF vouchers are not exchangeable for cash at https://exchange.cief-malaysia.com/.
  18. +
  19. This voucher can only be used and redeemed by a registered customer who has already logged into their account during purchase.
  20. +
  21. CIEF reserves the right to amend the terms & conditions or cancel any vouchers/promotions without prior notice.
  22. +
  23. Additional terms & conditions are stated on the respective promotion banners (e.g., duration, discount amounts, validity for campaigns/promotions or certain services).
  24. +
+ +
+
+
+
From 78c4b4db63950ff1519b5eb19bddf914c5471ccf Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 14 Aug 2024 09:44:19 +0800 Subject: [PATCH 24/32] delete refund --- .../DeleteRefundTransactionLogic.php | 113 ++++++++++++++++++ .../DeleteRefundTransactionController.php | 14 +++ .../elements/PaymentHistoryComponent.vue | 18 +++ routes/transaction.php | 2 + 4 files changed, 147 insertions(+) create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php create mode 100644 app/Http/Controllers/Transactions/DeleteRefundTransactionController.php diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php new file mode 100644 index 00000000..ca8e0af3 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php @@ -0,0 +1,113 @@ + 'Deleted Refund Transaction', + 'message' => 'You have successfully deleted a transaction' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var DeletesTransaction */ + private $deletesTransaction; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + + /** @var CalculatesBookingPaidAmount */ + private $calculatesBookingPaidAmount; + + /** @var UpdateBookingAmountLogic */ + private $updateBookingAmountLogic; + + /** + * CreatePaymentVerificationDocumentLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param DeletesTransaction $deletesTransaction + * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount + * @param UpdateBookingAmountLogic $updateBookingAmountLogic + * @param calculatesBookingPaidAmount $calculatesBookingPaidAmount + */ + public function __construct(FetchesTransaction $fetchesTransaction, DeletesTransaction $deletesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic, CalculatesBookingPaidAmount $calculatesBookingPaidAmount) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->deletesTransaction = $deletesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; + $this->updateBookingAmountLogic = $updateBookingAmountLogic; + $this->calculatesBookingPaidAmount = $calculatesBookingPaidAmount; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request): JsonResponse + { + // delete refund transaction + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + $this->deletesTransaction->execute($transaction); + + // Update payment_transaction status + $payment_transaction = $transaction->owner; + $this->updatesTransactionStatus->execute($payment_transaction, ApprovalStatus::APPROVED); + + // delete wallet top up transaction + $booking = $transaction->owner->owner; + Transaction::where('type', TransactionType::CREDIT_NOTE) + ->where('amount', $transaction->amount) + ->where('payment_reference', 'like', '%' . $booking->marking . '%') + ->delete(); + + // update back the latest booking amount + $request['fix_amount'] = $this->calculatesBookingPaidAmount->execute($booking); + $request->route()->setParameter('id', $booking->id); + $this->updateBookingAmountLogic->execute($request); + + // if have SUPPLIER_REFUND transaction + $bookingInWhiteForm = $payment_transaction->transactions()->bills()->first(); + if ($bookingInWhiteForm) { + + $whiteFormTransaction = Transaction::where('type', TransactionType::SUPPLIER_REFUND) + ->where('payment_reference', $transaction->payment_reference) + ->first(); + + + Log::info($whiteFormTransaction->id); + + $whiteFormTransaction->delete(); + } + + return $this->response([]); + } +} diff --git a/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php b/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php new file mode 100644 index 00000000..0940ce49 --- /dev/null +++ b/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php @@ -0,0 +1,14 @@ +execute($request); + } +} \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 939865b1..0d893096 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -392,6 +392,24 @@ +
+
+ + + + + +
+
diff --git a/routes/transaction.php b/routes/transaction.php index 51e9ab34..b9f70aa3 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -14,6 +14,8 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => Route::put('/{id}/bill/{status}', 'UpdatePaymentTransactionStatusController@update')->where('status', 'pending|complete')->name('bill.status'); Route::put('/{id}/refund/status/update/{status}', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update'); + Route::delete('/refund/{id}/delete', 'DeleteRefundTransactionController@delete')->name('refund.delete'); + route::delete('{id}/bill/delete', 'DeletePaymentProofDocumentController@delete')->name('bill.delete'); Route::post('booking/{id}/details/update', 'CreatePurchaseOrderTransactionController@create')->name('po.create'); From 886a7b2767e4ccc3c9a1b635aea77ab4fe1af1b2 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 14 Aug 2024 09:48:51 +0800 Subject: [PATCH 25/32] delete refund --- .../ControllersLogic/DeleteRefundTransactionLogic.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php index ca8e0af3..65446adf 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php @@ -102,8 +102,7 @@ class DeleteRefundTransactionLogic extends AbstractControllerLogic ->where('payment_reference', $transaction->payment_reference) ->first(); - - Log::info($whiteFormTransaction->id); + // Log::info($whiteFormTransaction->id); $whiteFormTransaction->delete(); } From 6093ce896ef207c1c8b41cb4db848ddcc72e0250 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 20 Aug 2024 17:21:00 +0800 Subject: [PATCH 26/32] Allow user account to see and use all vouchers that belongs to all employees under the same company in checkout --- .../Filters/HasActiveRewardWithCompany.php | 53 +++++++++++++++++++ ...Reward.php => HasActiveRewardWithUser.php} | 2 +- .../Services/FetchesBookingQuotation.php | 20 ++++++- .../ControllersLogic/ValidateVoucherLogic.php | 21 +++++++- .../ValidateVoucherifyVoucherObject.php | 4 +- .../BookingToVoucherifyProcessor.php | 21 +++++++- app/Http/Resources/VoucherResource.php | 4 +- .../elements/AvailableVouchersComponent.vue | 2 +- .../elements/ListVouchersComponent.vue | 2 +- .../CustomerRewardsAdminSectionComponent.vue | 2 +- .../CustomerRewardsSectionComponent.vue | 2 +- 11 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php rename app/Classes/General/Eloquent/Filters/{HasActiveReward.php => HasActiveRewardWithUser.php} (96%) diff --git a/app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php b/app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php new file mode 100644 index 00000000..c9ff1f53 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php @@ -0,0 +1,53 @@ +type, RoleTypes::ADMIN_ROLES)){ + // $userId = $value !== 1 ? $value : Auth::user()->id; + $userId = $value; + $user = User::where('id', $userId)->first(); + $users = $user->company()->first()->employees; + $userIds = $users->pluck('id'); + + return $builder->whereIn('user_id', $userIds) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) { + $query->where('user_id', $userId); + }); + } + else{ + $user = User::where('id', Auth::user()->id)->first(); + $users = $user->company()->first()->employees; + $userIds = $users->pluck('id'); + + return $builder->whereIn('user_id', $userIds) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.owner'); + } + } +} diff --git a/app/Classes/General/Eloquent/Filters/HasActiveReward.php b/app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php similarity index 96% rename from app/Classes/General/Eloquent/Filters/HasActiveReward.php rename to app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php index 5770ca6e..72d0d6e2 100644 --- a/app/Classes/General/Eloquent/Filters/HasActiveReward.php +++ b/app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php @@ -6,7 +6,7 @@ use App\Classes\ValueObjects\Constants\RoleTypes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; -class HasActiveReward implements Filter +class HasActiveRewardWithUser implements Filter { /** diff --git a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php index e5535e2a..feafba19 100644 --- a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php +++ b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php @@ -70,8 +70,24 @@ class FetchesBookingQuotation //Voucherify if($voucherCode){ - $employee = $company->employees()->first(); - $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employee); + $employeeWhoOwnsTheVoucher = null; + + $employees = $company->first()->employees; + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $voucherCode) { + Log::info('1. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $company->employees()->first(); + } + + $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employeeWhoOwnsTheVoucher); $result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject); $voucher = [ "code" => $result->code, diff --git a/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php b/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php index 30e7fe12..4530292f 100644 --- a/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php +++ b/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php @@ -10,6 +10,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherOb use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Models\Booking; +use Illuminate\Support\Facades\Log; class ValidateVoucherLogic extends AbstractControllerLogic { @@ -42,11 +43,27 @@ class ValidateVoucherLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + $employeeWhoOwnsTheVoucher = null; $booking = Booking::find($request->input('itemId')); - $employee = $booking->company->employees()->first(); + $employees = $booking->company->employees()->get(); + + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $request->input('voucherCode')) { + Log::info('2. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $request->input('voucherCode')); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $booking->company->employees()->first(); + } + $amount = $this->floatvalue($request->input('amount')); - $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employee); + $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employeeWhoOwnsTheVoucher); $result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject); return $this->response(['data' => $result]); } diff --git a/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php b/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php index b48bee16..956afc00 100644 --- a/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php +++ b/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php @@ -17,8 +17,8 @@ class ValidateVoucherifyVoucherObject implements DataTransferObject /** @var float */ private $amount; - /** @var User */ - private $user; + /** @var User */ + private $user; //this will affect certain voucher that limit user redemption e.g. one user one redemption per campaign /** * ValidateVoucherifyVoucherObject constructor. diff --git a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php index 6f89916b..90fba55a 100644 --- a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php +++ b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php @@ -83,7 +83,24 @@ class BookingToVoucherifyProcessor $voucherify_customer_id = ""; $voucherify_order_id = ""; if($voucherCode){ - $redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $user); + $employeeWhoOwnsTheVoucher = null; + + $employees = $user->company()->first()->employees; + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $voucherCode) { + Log::info('3. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $user; + } + + $redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $employeeWhoOwnsTheVoucher); $redeemVoucherResult = $this->redeemsVoucherifyVoucher->execute($redeemVoucherifyVoucherObject); // Log::info('redeemVoucherResult: '.json_encode($redeemVoucherResult)); @@ -101,7 +118,7 @@ class BookingToVoucherifyProcessor $voucher = $this->recordVoucherInfo($redeemedVoucher); $this->createsVoucherRedemption->execute($transaction, $voucher, $redemptionId, $voucherDiscountAmount); - $this->recordVoucherForUserInfo($user, $voucher); + $this->recordVoucherForUserInfo($employeeWhoOwnsTheVoucher, $voucher); } else{ $createVoucherifyOrderObject = new CreateVoucherifyOrderObject($user, $companyId, $transaction->id, $amount, true, $transaction->type == TransactionType::TOP_UP); diff --git a/app/Http/Resources/VoucherResource.php b/app/Http/Resources/VoucherResource.php index 3f3112bb..7e372d5f 100644 --- a/app/Http/Resources/VoucherResource.php +++ b/app/Http/Resources/VoucherResource.php @@ -4,6 +4,7 @@ namespace App\Http\Resources; use ArrayObject; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Log; class VoucherResource extends JsonResource { @@ -16,7 +17,8 @@ class VoucherResource extends JsonResource public function toArray($request) { $filteredRedemptions = new ArrayObject([]); - if ($request->has('filters') && str_contains($request->input('filters'), "has_active_reward")) { + if ($request->has('filters') && (str_contains($request->input('filters'), "has_active_reward_with_user") )) { + //|| str_contains($request->input('filters'), "has_active_reward_with_company") $filteredRedemptions = new ArrayObject([]); } else{ diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index a5fb4e3b..3fff52e8 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -95,7 +95,7 @@ fetchVouchers(){ this.isLoading = true; if(this.employee){ - this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward': this.employee.id} ), 'get', this.section, false, false); + this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward_with_company': this.employee.id} ), 'get', this.section, false, false); } }, successHandler(response){ diff --git a/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue index e55e5151..3b2eb5a0 100644 --- a/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue @@ -76,7 +76,7 @@ fetchVouchers(){ this.isLoading = true; if(this.employee){ - this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward': this.employee.id} ), 'get', this.section, false, false); + this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward_with_company': this.employee.id} ), 'get', this.section, false, false); } }, successHandler(response){ diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue index f28c88dd..7300f3ba 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue @@ -57,7 +57,7 @@
- + diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue index 83567aaf..7a97f22f 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue @@ -52,7 +52,7 @@
- + From 2905edef5e2d3b831b22cf8f5037bd2d1d8ff3a8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 21 Aug 2024 22:04:09 +0800 Subject: [PATCH 27/32] Amendment meant to resolve merge conflict in development branch from branch dillon/63.6-company-with-multiple-employees --- .../Eloquent/Filters/HasActiveReward.php | 27 +++++++++++++++++++ .../Filters/HasActiveRewardForAdmin.php | 26 ++++++++++++++++++ ...pany.php => HasVouchersAllWithCompany.php} | 2 +- ...ithUser.php => HasVouchersAllWithUser.php} | 2 +- app/Http/Resources/VoucherResource.php | 4 +-- .../elements/AvailableVouchersComponent.vue | 2 +- .../elements/ListVouchersComponent.vue | 2 +- .../CustomerRewardsAdminSectionComponent.vue | 9 +++++-- .../CustomerRewardsSectionComponent.vue | 15 +++++++---- 9 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/HasActiveReward.php create mode 100644 app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php rename app/Classes/General/Eloquent/Filters/{HasActiveRewardWithCompany.php => HasVouchersAllWithCompany.php} (97%) rename app/Classes/General/Eloquent/Filters/{HasActiveRewardWithUser.php => HasVouchersAllWithUser.php} (96%) diff --git a/app/Classes/General/Eloquent/Filters/HasActiveReward.php b/app/Classes/General/Eloquent/Filters/HasActiveReward.php new file mode 100644 index 00000000..26385b96 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasActiveReward.php @@ -0,0 +1,27 @@ +where('user_id', Auth::user()->id) //cief todo: should not use Auth::user()->id + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }); + // ->orWhereDoesntHave('reward'); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php b/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php new file mode 100644 index 00000000..5d69aa4b --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php @@ -0,0 +1,26 @@ +where('user_id', $value) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }); + // ->orWhereDoesntHave('reward'); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php similarity index 97% rename from app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php rename to app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php index c9ff1f53..be4d335b 100644 --- a/app/Classes/General/Eloquent/Filters/HasActiveRewardWithCompany.php +++ b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php @@ -7,7 +7,7 @@ use App\Models\User; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; -class HasActiveRewardWithCompany implements Filter +class HasVouchersAllWithCompany implements Filter { /** diff --git a/app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php similarity index 96% rename from app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php rename to app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php index 72d0d6e2..79a02914 100644 --- a/app/Classes/General/Eloquent/Filters/HasActiveRewardWithUser.php +++ b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php @@ -6,7 +6,7 @@ use App\Classes\ValueObjects\Constants\RoleTypes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; -class HasActiveRewardWithUser implements Filter +class HasVouchersAllWithUser implements Filter { /** diff --git a/app/Http/Resources/VoucherResource.php b/app/Http/Resources/VoucherResource.php index 7e372d5f..55cc2b56 100644 --- a/app/Http/Resources/VoucherResource.php +++ b/app/Http/Resources/VoucherResource.php @@ -17,8 +17,8 @@ class VoucherResource extends JsonResource public function toArray($request) { $filteredRedemptions = new ArrayObject([]); - if ($request->has('filters') && (str_contains($request->input('filters'), "has_active_reward_with_user") )) { - //|| str_contains($request->input('filters'), "has_active_reward_with_company") + if ($request->has('filters') && (str_contains($request->input('filters'), "has_vouchers_all_with_user") )) { + //|| str_contains($request->input('filters'), "has_vouchers_all_with_company") $filteredRedemptions = new ArrayObject([]); } else{ diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index 3fff52e8..0d52ff13 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -95,7 +95,7 @@ fetchVouchers(){ this.isLoading = true; if(this.employee){ - this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward_with_company': this.employee.id} ), 'get', this.section, false, false); + this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_vouchers_all_with_company': this.employee.id} ), 'get', this.section, false, false); } }, successHandler(response){ diff --git a/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue index 3b2eb5a0..cc8afbf2 100644 --- a/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue @@ -76,7 +76,7 @@ fetchVouchers(){ this.isLoading = true; if(this.employee){ - this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward_with_company': this.employee.id} ), 'get', this.section, false, false); + this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_vouchers_all_with_company': this.employee.id} ), 'get', this.section, false, false); } }, successHandler(response){ diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue index 7300f3ba..d41c2b63 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue @@ -57,7 +57,7 @@
- + @@ -74,10 +74,15 @@
- + + +
diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue index 7a97f22f..f6143340 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue @@ -19,7 +19,7 @@
-
+
@@ -52,7 +52,7 @@
- + @@ -69,11 +69,16 @@
- + +
From 8963d5ff28013da00d984e29135687b1fd52e95f Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 23 Aug 2024 11:04:38 +0800 Subject: [PATCH 28/32] fix Proforma Invoice --- .../pages/pdfs/proforma_invoice.blade.php | 94 +------------------ 1 file changed, 2 insertions(+), 92 deletions(-) diff --git a/resources/views/pages/pdfs/proforma_invoice.blade.php b/resources/views/pages/pdfs/proforma_invoice.blade.php index d2b3977b..da5e8238 100644 --- a/resources/views/pages/pdfs/proforma_invoice.blade.php +++ b/resources/views/pages/pdfs/proforma_invoice.blade.php @@ -69,100 +69,10 @@

-
- - - - - - - - - - - - @php - $subtotal = 0; - @endphp - @foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail) - - - - - - - - - @endforeach - - - - - - - - - - - - - - - - - - @if($invoice_transaction->tax > 0) - - - - - - @endif - - - - - - -
NoStock CodeDescriptionQuantityUnit Price (RM)Total Amount
(RM)
{{ $key + 1 }}{{ $transaction_detail->product_code }}{{ $transaction_detail->product_name }}{{ $transaction_detail->quantity }} - @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2) }} - @else - {{ number_format($transaction_detail->price, 2) }} - @endif - - @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) + + @include('pages.pdfs.purchase_order_table') - {{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }} - - @php - $subtotal += number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.',''); - @endphp - @else - {{ number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }} - - @php - $subtotal += number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.',''); - @endphp - @endif -
Subtotal - {{ number_format($subtotal, 2) }} -
Service Charges - {{ number_format($invoice_transaction->service_charge, 2) }} -
Adjustment - @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }} - @else - {{ number_format((float)number_format($invoice_transaction->amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }} - @endif -
Tax{{ number_format($invoice_transaction->tax, 2) }}
Total - @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format( ((1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount) + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }} - @else - {{ number_format($invoice_transaction->amount + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }} - @endif -
From bef54204ff6f3765022bb8ed45a09605caa4e07d Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 23 Aug 2024 11:38:38 +0800 Subject: [PATCH 29/32] fix proforma invoice --- ...ateProformaInvoiceTransactionProcessor.php | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php index 8dab2d24..1a48fc31 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php @@ -118,14 +118,20 @@ class CreateProformaInvoiceTransactionProcessor $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + $transaction = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->first(); - $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, - $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), - $configurations->getTotal(), $configurations->getForeignTotal(), 1, - $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL); + if (!$transaction) { + $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, + $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), + $configurations->getTotal(), $configurations->getForeignTotal(), 1, + $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), + $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL + ); - $this->createsTransaction->execute($booking, $object); + $this->createsTransaction->execute($booking, $object); + } $billNumber = $this->generatesTransactionBillNumber->execute('PROFORMA-'); @@ -160,6 +166,11 @@ class CreateProformaInvoiceTransactionProcessor ->whereIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED]) ->sum('tax'); + // delete prev proforma transactions + $booking->transactions() + ->where('type', TransactionType::PROFORMA) + ->delete(); + $transaction_object = new TransactionObject( $billNumber, TransactionType::PROFORMA, @@ -178,11 +189,11 @@ class CreateProformaInvoiceTransactionProcessor ApprovalStatus::APPROVED ); - $perofrma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object); + $proforma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object); $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); - $purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $perofrma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]); + $purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $proforma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]); $document_object = new DocumentObject( DocumentType::PROFORMA_INVOICE, [chunk_split('data:application/pdf;base64,'.base64_encode($purchase_order_pdf->output()))], From bedee606bc0c0970a77729eeaf9a587d59846867 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 23 Aug 2024 11:48:03 +0800 Subject: [PATCH 30/32] fix proforma invoice --- .../components/bookings/forms/PurchaseOrderFormComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index b9a0f2d6..035e37e1 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -173,7 +173,7 @@ - +
From 8c9264b26a015d9b17723e65f29f103eea846b84 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 23 Aug 2024 12:24:18 +0800 Subject: [PATCH 31/32] Solve a problem where voucher cannot be added to a user account if user does not exist at Voucherify --- .../General/Eloquent/Filters/RandomName.php | 20 ------------------- .../ControllersLogic/CreateVoucherLogic.php | 14 ++++++++++++- .../CreateVoucherifyCustomerObject.php | 6 +++--- .../NewCustomerToVoucherifyProcessor.php | 4 +++- 4 files changed, 19 insertions(+), 25 deletions(-) delete mode 100644 app/Classes/General/Eloquent/Filters/RandomName.php diff --git a/app/Classes/General/Eloquent/Filters/RandomName.php b/app/Classes/General/Eloquent/Filters/RandomName.php deleted file mode 100644 index 54024e96..00000000 --- a/app/Classes/General/Eloquent/Filters/RandomName.php +++ /dev/null @@ -1,20 +0,0 @@ -where('is_active', $value); - } - -} diff --git a/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php b/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php index 5c85895a..e345ebcf 100644 --- a/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php +++ b/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php @@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher; use App\Classes\Modules\Vouchers\Services\Voucherify\CreatesVoucherifyVoucherInACampaign; use App\Classes\Modules\Vouchers\Services\Voucherify\ListsVoucherifyVouchers; use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyCampaign; +use App\Classes\Modules\Vouchers\Processors\Voucherify\NewCustomerToVoucherifyProcessor; use App\Classes\Modules\Vouchers\Services\CreatesVoucher; use App\Classes\Modules\Vouchers\Services\FetchesVoucher; use App\Classes\Modules\Vouchers\Services\UpdatesVoucherCampaign; @@ -75,6 +76,9 @@ class CreateVoucherLogic extends AbstractControllerLogic /** @var UpdatesVoucherCampaign */ private $updatesVoucherCampaign; + /** @var NewCustomerToVoucherifyProcessor */ + private $newCustomerToVoucherifyProcessor; + /** * CreateVoucherLogic constructor. * @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher @@ -87,8 +91,9 @@ class CreateVoucherLogic extends AbstractControllerLogic * @param CreatesKeyValuePair $createsKeyValuePair * @param UpdatesKeyValuePair $updatesKeyValuePair * @param UpdatesVoucherCampaign $updatesVoucherCampaign + * @param NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor */ - public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign) + public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor) { $this->createsUserReward = $createsUserReward; $this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher; @@ -100,6 +105,7 @@ class CreateVoucherLogic extends AbstractControllerLogic $this->createsKeyValuePair = $createsKeyValuePair; $this->updatesKeyValuePair = $updatesKeyValuePair; $this->updatesVoucherCampaign = $updatesVoucherCampaign; + $this->newCustomerToVoucherifyProcessor = $newCustomerToVoucherifyProcessor; } /** @@ -129,6 +135,12 @@ class CreateVoucherLogic extends AbstractControllerLogic $user = $userParam ? $userParam : $user; } + //Voucherify - To check if user exist at Voucherify, create if not exist + $voucherify_entity = $user->voucherifyEntities()->first(); + if(!$voucherify_entity){ + $this->newCustomerToVoucherifyProcessor->execute($user->company()->first()->id, $user, false); + } + //Voucherify - creates new voucher at voucherify if ($voucherCodeInput === Vouchers::SORRY_50 || $voucherCodeInput === Vouchers::SORRY_100 || $voucherCodeInput === Vouchers::SORRY_200 ) { $result = $this->newVoucherifyVoucherIssuanceHandler($voucherCodeInput); diff --git a/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php b/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php index 9678dafe..e61d1d00 100644 --- a/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php +++ b/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php @@ -65,9 +65,9 @@ class CreateVoucherifyCustomerObject implements DataTransferObject */ public function getAcquisitionChannel(): string { - if(!$this->isNew){ - return ""; - } + // if(!$this->isNew){ + // return ""; + // } return $this->acquisitionChannel; } diff --git a/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php b/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php index 006bcd94..3fd2ccee 100644 --- a/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php +++ b/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php @@ -44,7 +44,9 @@ class NewCustomerToVoucherifyProcessor $createVoucherifyCustomerObject = new CreateVoucherifyCustomerObject($companyId, $user, $isNew); $result = $this->createsVoucherifyCustomer->execute($createVoucherifyCustomerObject); - if($result && isset($result->id)){ + $voucherify_entity = $user->voucherifyEntities()->get(); + + if($result && isset($result->id) && count($voucherify_entity) === 0){ $voucherEntityObject = new VoucherEntityObject($result->id, VoucherifyEntityType::CUSTOMER); $this->createsVoucherEntityMapping->execute($createVoucherifyCustomerObject->getUser(), $voucherEntityObject); } From eecb351fb38d03e3de188fe4fee245ee98b271dc Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 23 Aug 2024 16:59:05 +0800 Subject: [PATCH 32/32] fix proforma invoice --- ...ateProformaInvoiceTransactionProcessor.php | 63 +++++++++++-------- .../pages/pdfs/proforma_invoice.blade.php | 5 ++ 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php index 1a48fc31..28a34057 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php @@ -24,6 +24,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Booking; use App\Models\Document; use Carbon\Carbon; +use Illuminate\Support\Facades\Log; use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf; class CreateProformaInvoiceTransactionProcessor @@ -102,32 +103,44 @@ class CreateProformaInvoiceTransactionProcessor */ public function execute(Booking $booking) { - $po_order_transaction = $booking->transactions() ->where('type', TransactionType::PURCHASE_ORDER) ->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]) ->first(); - $outstanding = $this->calculatesBookingOutstanding->execute($booking); - - $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::CASH); - - $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject); - - $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); - - $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); - $transaction = $booking->transactions() ->where('type', TransactionType::PAYMENT) ->first(); if (!$transaction) { - $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, - $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), - $configurations->getTotal(), $configurations->getForeignTotal(), 1, - $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL + $outstanding = $this->calculatesBookingOutstanding->execute($booking); + + $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0 : 1, PaymentMethodType::CASH); + + $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject); + + $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); + + $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + + $object = new TransactionObject( + $billNumber, + TransactionType::PAYMENT, + 1, + $booking->company->id, + $configurations->getConfigurations()->getBankId(), + $configurations->getConversionObject()->getPaymentMethod(), + $configurations->getTotal(), + $configurations->getForeignTotal(), + 1, + $configurations->getConversionObject()->getCurrencyId(), + $configurations->getConfigurations()->getRate(), + $configurations->getTax(), + $configurations->getServiceCharge(), + Carbon::now()->addMinutes($paymentAttemptLimit), + ApprovalStatus::PENDING_SUBMISSION, + [], + isset($billPlzBill) ? $billPlzBill->id : NULL ); $this->createsTransaction->execute($booking, $object); @@ -135,10 +148,10 @@ class CreateProformaInvoiceTransactionProcessor $billNumber = $this->generatesTransactionBillNumber->execute('PROFORMA-'); - $payable_amount = $booking->transactions()->payments()->where(function($query){ - return $query->where(function($query){ + $payable_amount = $booking->transactions()->payments()->where(function ($query) { + return $query->where(function ($query) { return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString()); - })->orWhere(function($query){ + })->orWhere(function ($query) { return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); })->sum('amount'); @@ -148,14 +161,16 @@ class CreateProformaInvoiceTransactionProcessor ->where('type', TransactionType::PAYMENT) ->first(); - $booking_currency_average_rate = $booking_amount / $booking->transactions()->payments()->where(function($query){ - return $query->where(function($query){ + $paymentAmount = $booking->transactions()->payments()->where(function ($query) { + return $query->where(function ($query) { return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString()); - })->orWhere(function($query){ + })->orWhere(function ($query) { return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); })->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); + $booking_currency_average_rate = $booking_amount / $paymentAmount; + $total_service_charge = $booking->transactions() ->where('type', TransactionType::PAYMENT) ->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED]) @@ -196,7 +211,7 @@ class CreateProformaInvoiceTransactionProcessor $purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $proforma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]); $document_object = new DocumentObject( DocumentType::PROFORMA_INVOICE, - [chunk_split('data:application/pdf;base64,'.base64_encode($purchase_order_pdf->output()))], + [chunk_split('data:application/pdf;base64,' . base64_encode($purchase_order_pdf->output()))], '', ApprovalStatus::COMPLETED, 'proforma_invoices' @@ -205,7 +220,5 @@ class CreateProformaInvoiceTransactionProcessor /** @var Document $document */ $document = $this->createsDocument->execute($po_order_transaction->booking, $document_object); $this->createsFile->execute($document, $document_object); - - } } diff --git a/resources/views/pages/pdfs/proforma_invoice.blade.php b/resources/views/pages/pdfs/proforma_invoice.blade.php index da5e8238..6d25b5ba 100644 --- a/resources/views/pages/pdfs/proforma_invoice.blade.php +++ b/resources/views/pages/pdfs/proforma_invoice.blade.php @@ -70,6 +70,11 @@

+ + @include('pages.pdfs.purchase_order_table')