From 4e3306957489a138892c120e4757b4722c3ae913 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Tue, 18 Jun 2024 22:47:53 +0800 Subject: [PATCH 01/63] test log --- .../Modules/Transactions/ControllersLogic/UpdateGroupLogic.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php index 8e16233b..13c667ab 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php @@ -26,6 +26,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use ErrorException; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf; class UpdateGroupLogic extends AbstractControllerLogic @@ -95,6 +96,7 @@ class UpdateGroupLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + Log::info('update group logic is run'); $group = $this->fetchesGroup->execute(['id' => $request->route('id')]); $transactions = $group->transactions()->get(); From 3f6dde746258c9155c064635590a8f2a1f9f827b Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Tue, 18 Jun 2024 23:25:55 +0800 Subject: [PATCH 02/63] add cancel bill group function --- .../ControllersLogic/CancelBillGroupLogic.php | 66 +++++++++++++++++++ .../CancelBillGroupController.php | 20 ++++++ .../bookings/elements/BillGroupComponent.vue | 16 +++++ .../GeneralConfirmationFormComponent.vue | 2 +- routes/transaction.php | 1 + 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/CancelBillGroupLogic.php create mode 100644 app/Http/Controllers/Transactions/CancelBillGroupController.php diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CancelBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CancelBillGroupLogic.php new file mode 100644 index 00000000..615ae342 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/CancelBillGroupLogic.php @@ -0,0 +1,66 @@ + 'Cancel Bill Group Transaction', + 'message' => 'You have successfully cancelled this Bill Group Transaction' + ]; + } + + /** @var FetchesBillGroup */ + private $fetchesBillGroup; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** + * CancelBillGroupLogic constructor. + * @param FetchesBillGroup $fetchesBillGroup + * @param UpdatesTransactionStatus $updatesTransactionStatus + */ + public function __construct(FetchesBillGroup $fetchesBillGroup, UpdatesTransactionStatus $updatesTransactionStatus) + { + $this->fetchesBillGroup = $fetchesBillGroup; + $this->updatesTransactionStatus = $updatesTransactionStatus; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $billGroup = $this->fetchesBillGroup->execute(['id' => $request->route('id')]); + + $transactions = $billGroup->transactions()->get(); + + foreach($transactions as $transaction) { + if ($transaction->status === ApprovalStatus::APPROVED || $transaction->status === ApprovalStatus::COMPLETED) { + $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); + } + } + + $billGroup->status = ApprovalStatus::PENDING_VERIFICATION; + $billGroup->save(); + + return $this->resourceResponse(new BillGroupResource($billGroup)); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Transactions/CancelBillGroupController.php b/app/Http/Controllers/Transactions/CancelBillGroupController.php new file mode 100644 index 00000000..2eab79c8 --- /dev/null +++ b/app/Http/Controllers/Transactions/CancelBillGroupController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue index 9a309cde..6bde1a01 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue @@ -50,6 +50,22 @@ +
+
+ Cancel +
+ + + + +
diff --git a/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue b/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue index 6d6ad557..0cb9435b 100644 --- a/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue +++ b/resources/assets/vue/components/general/forms/GeneralConfirmationFormComponent.vue @@ -61,7 +61,7 @@ successHandler(){ this.closeModal(); this.formHandler(); - if (this.section && (this.section === 'paymentInProgressBillGroupList' || this.section === 'paymentVerificationBillGroupList')) { + if (this.section && (this.section === 'paymentInProgressBillGroupList' || this.section === 'paymentVerificationBillGroupList' || this.section === 'paidBillGroupList')) { this.$store.dispatch('toggleSection', {name: 'paymentInProgressBillGroupList', status: !this.$store.getters.isShowing('paymentInProgressBillGroupList')}); this.$store.dispatch('toggleSection', {name: 'paymentVerificationBillGroupList', status: !this.$store.getters.isShowing('paymentVerificationBillGroupList')}); this.$store.dispatch('toggleSection', {name: 'paidBillGroupList', status: !this.$store.getters.isShowing('paidBillGroupList')}); diff --git a/routes/transaction.php b/routes/transaction.php index 654b3fb8..51e9ab34 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -41,6 +41,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => Route::post('/transaction/{id}', 'CreateBillGroupPaymentProofDocumentController@create')->name('payment_proof.create'); Route::post('/transaction/{id}/approval/{status}', 'ApproveBillGroupPaymentVerificationController@approve')->where('status', 'approve|reject')->name('payment_proof.approval'); Route::delete('/{id}/delete', 'DeleteBillGroupController@delete')->name('delete'); + Route::put('/{id}/cancel', 'CancelBillGroupController@cancel')->name('cancel'); Route::post('/{id}/pay', 'CreateBillGroupPaymentTransactionController@pay')->name('pay'); // Route::post('/bulk/po', 'CreateBulkPurchaseOrderDocumentController@create')->name('bulk.po'); }); From 4a555afdbf718a42db076ec1b704ff33374134a4 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Tue, 18 Jun 2024 23:29:10 +0800 Subject: [PATCH 03/63] remove log in update group logic --- .../Modules/Transactions/ControllersLogic/UpdateGroupLogic.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php index 13c667ab..b7ca280e 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php @@ -96,7 +96,6 @@ class UpdateGroupLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - Log::info('update group logic is run'); $group = $this->fetchesGroup->execute(['id' => $request->route('id')]); $transactions = $group->transactions()->get(); From 84ff9006297e2d74078eff3c307de47820a59ff8 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Mon, 24 Jun 2024 21:06:05 +0800 Subject: [PATCH 04/63] comment out booking expired command in kernel --- app/Console/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e455eea1..09b96687 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -44,10 +44,10 @@ class Kernel extends ConsoleKernel ->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log') ->withoutOverlapping(); - $schedule->command('booking:expired') - ->dailyAt('02:00') - ->appendOutputTo(storage_path().'/logs/expire-booking.log') - ->withoutOverlapping(); + // $schedule->command('booking:expired') + // ->dailyAt('02:00') + // ->appendOutputTo(storage_path().'/logs/expire-booking.log') + // ->withoutOverlapping(); // $schedule->command('purchaseOrder:autoFill') // ->dailyAt('03:00') From c34bacccfd50b2d9d1733c285a1c8cae3b5f4362 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Mon, 24 Jun 2024 22:45:21 +0800 Subject: [PATCH 05/63] -fix expired booking command to ignore 1688 as 1688 may not have PO initally -create command to revert those fully refunded payment transaction from status EXPIRED to REFUNDED --- .../Commands/ExpiredBookingCommand.php | 5 +- ...gWithRefundedPaymentTransactionCommand.php | 67 +++++++++++++++++++ app/Console/Kernel.php | 8 +-- 3 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 app/Console/Commands/FixExpiredBookingWithRefundedPaymentTransactionCommand.php diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index fe4f260e..17a0158e 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -51,11 +51,12 @@ class ExpiredBookingCommand extends Command // 1. Cancel booking without payment & purchase order (1 month) $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(30)->endOfDay()) + ->where('service_id', '!=', 4) ->where(function ($query) { $query->whereDoesntHave('transactions') ->orWhereDoesntHave('transactions', function($transaction) { return $transaction->where('type', TransactionType::PURCHASE_ORDER)->orWhere(function ($q) { - $q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + $q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]); }); }); })->get(); @@ -78,7 +79,7 @@ class ExpiredBookingCommand extends Command ->where('created_at', '<', now()->subDays(60)->endOfDay()) ->where(function ($query) { $query->whereDoesntHave('transactions', function($transaction) { - return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]); })->whereHas('transactions', function($transaction) { return $transaction->where('type', TransactionType::PURCHASE_ORDER); }); diff --git a/app/Console/Commands/FixExpiredBookingWithRefundedPaymentTransactionCommand.php b/app/Console/Commands/FixExpiredBookingWithRefundedPaymentTransactionCommand.php new file mode 100644 index 00000000..b8e27996 --- /dev/null +++ b/app/Console/Commands/FixExpiredBookingWithRefundedPaymentTransactionCommand.php @@ -0,0 +1,67 @@ +whereHas('transactions', function ($q) { + $q->where('type', TransactionType::PAYMENT)->where('status', ApprovalStatus::EXPIRED)->whereHas('transactions', function ($q2) { + $q2->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + })->get(); + + foreach ($bookings as $booking) { + $payment_transactions = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($q2) { + $q2->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->get(); + + foreach ($payment_transactions as $payment) { + $payment_original_amount = $payment->original_amount; + $refund_original_amount = $payment->transactions()->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('original_amount'); + + if ($payment_original_amount - $refund_original_amount < 0.01) { + $this->info("Updated booking id: $booking->id, payment transaction id: $payment->id, from EXPIRED to REFUNDED"); + + $payment->status = ApprovalStatus::REFUNDED; + $payment->save(); + } + } + } + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 09b96687..e455eea1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -44,10 +44,10 @@ class Kernel extends ConsoleKernel ->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log') ->withoutOverlapping(); - // $schedule->command('booking:expired') - // ->dailyAt('02:00') - // ->appendOutputTo(storage_path().'/logs/expire-booking.log') - // ->withoutOverlapping(); + $schedule->command('booking:expired') + ->dailyAt('02:00') + ->appendOutputTo(storage_path().'/logs/expire-booking.log') + ->withoutOverlapping(); // $schedule->command('purchaseOrder:autoFill') // ->dailyAt('03:00') From a4b09cedb17d02ee89c82a3d5391cefad61717a6 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Sun, 30 Jun 2024 12:18:40 +0800 Subject: [PATCH 06/63] include refund service charges for partial refund --- .../CreateBookingRefundLogic.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index a8df7fce..058e4bc7 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -14,6 +14,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation; +use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject; use App\Classes\Modules\Transactions\ControllersLogic\UpdateRefundTransactionStatusLogic; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; @@ -100,21 +101,45 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $refund = $transaction->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('original_amount'); + $refundInPending = $transaction->transactions()->refunds()->where('status', ApprovalStatus::PENDING_VERIFICATION)->sum('original_amount'); + if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.'); // $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount')); // $transactionRefundCalculationObject->init(); $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); - // refund service charges if is fully refund + + $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; + + $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; - $refundTotal = $isFullyRefund ? $refundAmount + $transaction->service_charge + $transaction->tax : $refundAmount; + + $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(); + + // refund service charges if is fully refund + $refundTotal = $refundAmount + $service_charges_to_refund + $transaction->tax; $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, 1, PaymentMethodType::CASH, $refundTotal, $request->input('amount'), 1, $transaction->original_currency_id, $transaction->currency_rate, - 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); + 0, $service_charges_to_refund, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $refund_transaction = $this->createsTransaction->execute($transaction, $object); From cf17e9bb11116f8457d9c8781fac4d1306bbecc6 Mon Sep 17 00:00:00 2001 From: Jia Sheng Date: Tue, 2 Jul 2024 20:46:53 +0800 Subject: [PATCH 07/63] order export refund by created at --- routes/web.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/web.php b/routes/web.php index 12269a21..7017b1b8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -463,7 +463,7 @@ Route::get('/approve_refunds', function(Request $request){ echo ''; echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -478,7 +478,7 @@ Route::get('/approve_refunds', function(Request $request){ echo ''; echo ''; echo ''; - foreach ($payments->orderBy('updated_at', 'DESC')->get() as $index => $payment){ + foreach ($payments->orderBy('created_at', 'DESC')->get() as $index => $payment){ $booking = $payment->owner; $original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id)); $refunds = $original_refunds / $payment->currency_rate; @@ -511,7 +511,7 @@ Route::get('/approve_refunds', function(Request $request){ echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; From ad06bd4c4cbd12103d152fd1d4818d1edba1d038 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 3 Jul 2024 12:08:57 +0800 Subject: [PATCH 08/63] Fix welcome voucher email out of alignment issue in yahoo mail --- .../views/emails/accounts/welcome_voucher.blade.php | 2 +- resources/views/emails/layout/base.blade.php | 12 ++++++++++-- resources/views/emails/layout/header.blade.php | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/resources/views/emails/accounts/welcome_voucher.blade.php b/resources/views/emails/accounts/welcome_voucher.blade.php index 7cd60aa1..e345ab38 100644 --- a/resources/views/emails/accounts/welcome_voucher.blade.php +++ b/resources/views/emails/accounts/welcome_voucher.blade.php @@ -1,7 +1,7 @@ @extends('emails.layout.base') @section('content') - +

Hello from CIEF! Thanks for signing up with us. Thinking about using our RMB payment transfer services? Use code 【{{$voucher->code}}】 and get a 50% discount on your first order. Why not give it a try?

Any questions? I'm here to help. Start here: {{env('APP_URL').'/dashboard'}}

叮咚!非常感谢您在我们代付网站注册, 您是否对我们的代付服务感兴趣却还在犹豫或者在因为其他因素还没正式使用呢? 如果是首次下单, 不妨使用我们专门为新用户准备的独家优惠, 只需在首次下单时使用代码【{{$voucher->code}}】,就能享有5折的手续费折扣呢! 尝试了一次, 或许你会喜欢我们公司的服务,点击以下网址开始启用吧!

diff --git a/resources/views/emails/layout/base.blade.php b/resources/views/emails/layout/base.blade.php index 0f58c396..81efe937 100644 --- a/resources/views/emails/layout/base.blade.php +++ b/resources/views/emails/layout/base.blade.php @@ -21,6 +21,10 @@ .container { width: 600px; } + .container .header-title { + width: 600px; + padding: 30px 0px; + } .sm-hide { display: block; } @@ -31,12 +35,16 @@ .container { width: 100%; } + .container .header-title { + width: 100%; + padding: 30px 0px; + } .sm-hide { display: none; } } .content { - width: 100%; + /* width: 100%; */ padding: 30px; box-sizing: border-box; } @@ -132,4 +140,4 @@ - \ No newline at end of file + diff --git a/resources/views/emails/layout/header.blade.php b/resources/views/emails/layout/header.blade.php index 572a3f3f..96793dd4 100644 --- a/resources/views/emails/layout/header.blade.php +++ b/resources/views/emails/layout/header.blade.php @@ -1,5 +1,5 @@ -
+

Exchange

Currency Exchange Vendor -
\ No newline at end of file +
From 66c2bb0cca7b007626caa44a92883b6c0f8ce41e Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 3 Jul 2024 14:54:47 +0800 Subject: [PATCH 09/63] 1688 fields changes --- .../elements/BookingConfirmationComponent.vue | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/BookingConfirmationComponent.vue b/resources/assets/vue/components/bookings/elements/BookingConfirmationComponent.vue index 3206b3e5..dc4c01ba 100644 --- a/resources/assets/vue/components/bookings/elements/BookingConfirmationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingConfirmationComponent.vue @@ -1,7 +1,7 @@
No.Updated AtCreated AtMarkingPayment MethodRefunded AmountBank Holder NameNote Remark
'.($index + 1).'.'.$payment->updated_at->format('d-M-y').''.$payment->created_at->format('d-M-y').''.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$payment->currency->short_code.'