From a4489215c20b5ea39b40f65b7cb1773e455fca0e Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 18 Dec 2023 23:10:33 +0800 Subject: [PATCH 01/35] create index migration for transactions table --- ...408_create_index_for_transaction_table.php | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 database/migrations/2023_12_18_230408_create_index_for_transaction_table.php diff --git a/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php new file mode 100644 index 00000000..3dc38456 --- /dev/null +++ b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php @@ -0,0 +1,44 @@ +index('status'); + $table->index('type'); + $table->index('payment_method'); + $table->index('payment_reference'); + $table->index('bill_no'); + $table->index('owner_type'); + $table->index('owner_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('transactions', function (Blueprint $table) { + $table->dropIndex('status'); + $table->dropIndex('type'); + $table->dropIndex('payment_method'); + $table->dropIndex('payment_reference'); + $table->dropIndex('bill_no'); + $table->dropIndex('owner_type'); + $table->dropIndex('owner_id'); + }); + } +} From 84e787f05e095d84ffda63fcde1ab2350617eb3c Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 19 Dec 2023 00:02:10 +0800 Subject: [PATCH 02/35] test update --- ...408_create_index_for_transaction_table.php | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php index 3dc38456..12824131 100644 --- a/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php +++ b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php @@ -14,13 +14,27 @@ class CreateIndexForTransactionTable extends Migration public function up() { Schema::table('transactions', function (Blueprint $table) { - $table->index('status'); + $table->index('owner_type'); + $table->index('owner_id'); $table->index('type'); + $table->index('issuer'); + $table->index('receiver'); + $table->index('recipient_bank_account_id'); $table->index('payment_method'); $table->index('payment_reference'); $table->index('bill_no'); - $table->index('owner_type'); - $table->index('owner_id'); + $table->index('amount'); + $table->index('original_amount'); + $table->index('currency_id'); + $table->index('original_currency_id'); + $table->index('currency_rate'); + $table->index('tax'); + $table->index('service_charge'); + $table->index('expires_on'); + $table->index('status'); + $table->index('deleted_at'); + $table->index('created_at'); + $table->index('updated_at'); }); } @@ -32,13 +46,27 @@ class CreateIndexForTransactionTable extends Migration public function down() { Schema::table('transactions', function (Blueprint $table) { - $table->dropIndex('status'); + $table->dropIndex('owner_type'); + $table->dropIndex('owner_id'); $table->dropIndex('type'); + $table->dropIndex('issuer'); + $table->dropIndex('receiver'); + $table->dropIndex('recipient_bank_account_id'); $table->dropIndex('payment_method'); $table->dropIndex('payment_reference'); $table->dropIndex('bill_no'); - $table->dropIndex('owner_type'); - $table->dropIndex('owner_id'); + $table->dropIndex('amount'); + $table->dropIndex('original_amount'); + $table->dropIndex('currency_id'); + $table->dropIndex('original_currency_id'); + $table->dropIndex('currency_rate'); + $table->dropIndex('tax'); + $table->dropIndex('service_charge'); + $table->dropIndex('expires_on'); + $table->dropIndex('status'); + $table->dropIndex('deleted_at'); + $table->dropIndex('created_at'); + $table->dropIndex('updated_at'); }); } } From e72e037ed4d430ece2a4213122e9f7c7acf4c155 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 19 Dec 2023 00:08:53 +0800 Subject: [PATCH 03/35] revert --- ...408_create_index_for_transaction_table.php | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php index 12824131..e343589f 100644 --- a/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php +++ b/database/migrations/2023_12_18_230408_create_index_for_transaction_table.php @@ -14,27 +14,13 @@ class CreateIndexForTransactionTable extends Migration public function up() { Schema::table('transactions', function (Blueprint $table) { - $table->index('owner_type'); - $table->index('owner_id'); + $table->index('status'); $table->index('type'); - $table->index('issuer'); - $table->index('receiver'); - $table->index('recipient_bank_account_id'); $table->index('payment_method'); $table->index('payment_reference'); $table->index('bill_no'); - $table->index('amount'); - $table->index('original_amount'); - $table->index('currency_id'); - $table->index('original_currency_id'); - $table->index('currency_rate'); - $table->index('tax'); - $table->index('service_charge'); - $table->index('expires_on'); - $table->index('status'); - $table->index('deleted_at'); - $table->index('created_at'); - $table->index('updated_at'); + $table->index('owner_type'); + $table->index('owner_id'); }); } From 0abebbe167c2cb2cb6918f56c6a6dd8041f75518 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 19 Dec 2023 00:12:18 +0800 Subject: [PATCH 04/35] comment route_logs migration --- ...2_12_27_165842_create_route_logs_table.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/database/migrations/2022_12_27_165842_create_route_logs_table.php b/database/migrations/2022_12_27_165842_create_route_logs_table.php index bdab0257..78b18b2a 100644 --- a/database/migrations/2022_12_27_165842_create_route_logs_table.php +++ b/database/migrations/2022_12_27_165842_create_route_logs_table.php @@ -13,21 +13,21 @@ class CreateRouteLogsTable extends Migration */ public function up() { - Schema::create('route_logs', function (Blueprint $table) { - $table->id(); - $table->foreignId('user_id')->unsigned(); - $table->string('ip_address'); - $table->string('url', 255); - $table->string('request_method'); - $table->string('browser')->nullable(); - $table->string('platform')->nullable(); - $table->string('longitude')->nullable(); - $table->string('latitude')->nullable(); - $table->string('last_page')->nullable(); - $table->string('countryname')->nullable(); - $table->integer('route_type'); - $table->timestamps(); - }); + // Schema::create('route_logs', function (Blueprint $table) { + // $table->id(); + // $table->foreignId('user_id')->unsigned(); + // $table->string('ip_address'); + // $table->string('url', 255); + // $table->string('request_method'); + // $table->string('browser')->nullable(); + // $table->string('platform')->nullable(); + // $table->string('longitude')->nullable(); + // $table->string('latitude')->nullable(); + // $table->string('last_page')->nullable(); + // $table->string('countryname')->nullable(); + // $table->integer('route_type'); + // $table->timestamps(); + // }); } /** From 9c0f77790c96daad675fb17d743199612402fea7 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Dec 2023 22:31:33 +0800 Subject: [PATCH 05/35] add filters to statement mapping --- .../sections/TransactionsMappingComponent.vue | 74 ++++++++++++------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue index bb19b908..eb12f809 100644 --- a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue +++ b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue @@ -76,26 +76,30 @@ -
-
-
- - - - -
-
- - - - -
-
-
- - Search - -
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+ + Search +
@@ -231,6 +235,7 @@ export default { parameters: { startDate: '', endDate: '', + account: '', }, type: null, stage: null, @@ -252,6 +257,7 @@ export default { endDate: { required }, + account: {}, }, files: { // required // todo-new: set required if is pdf section @@ -300,6 +306,17 @@ export default { this.files = []; this.parameters = {}; }, + getAccountId(){ + if (this.parameters.account) { + if (this.parameters.account.includes('568603010762')) { + return 4; + } + if (this.parameters.account.includes('8881040198515')) { + return 5; + } + } + return false; + }, startMapping(stage){ this.stage = stage; @@ -307,16 +324,17 @@ export default { if(this.type === 1){ switch(this.stage){ case 1: - this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: false, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: false, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} + break; case 2: - this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 3: - this.filter = {min_amount: 0, is_mapped_false_or_mapped_but_status_in: [4], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {min_amount: 0, is_mapped_false_or_mapped_but_status_in: [4], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 4: - this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}}; @@ -328,16 +346,16 @@ export default { if(this.type === 2){ switch(this.stage){ case 1: - this.filter = {max_amount: 0, is_mapped: true, is_mapped_with_multiple: false, statement_transaction_owner_type_in: [3, 5],statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {max_amount: 0, is_mapped: true, is_mapped_with_multiple: false, statement_transaction_owner_type_in: [3, 5],statement_transaction_owner_status_in: [1], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 2: - this.filter = {max_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {max_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [1], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 3: - this.filter = {max_amount: 0, is_mapped: false, per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {max_amount: 0, is_mapped: false, ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, ...this.parameters.startDate && {statement_transaction_posting_start: this.parameters.startDate}, ...this.parameters.endDate && {statement_transaction_posting_end: this.parameters.endDate}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 4: - this.filter = {max_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {max_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [2], ...this.parameters.account && {statement_transaction_account_id: this.getAccountId()}, per_page: 100, order_by: {column: 'posting_date', DESC: true}} if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}}; From ca07fc161e605f9a73afe4d960afc86a441959c0 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Wed, 27 Dec 2023 13:47:12 +0800 Subject: [PATCH 06/35] add reporting for download history import mapped invoice and receipt and with fix bug --- .../Eloquent/Filters/GroupByImportedDate.php | 18 ++ .../Eloquent/Filters/ImportedDateFrom.php | 18 ++ .../Eloquent/Filters/ImportedDateTo.php | 18 ++ .../StatementTransactionInvoiceReference.php | 22 ++ .../StatementTransactionOwnerReference.php | 22 ++ .../StatementTransactionReceiptReference.php | 22 ++ ...portedTransactionMappedControllerLogic.php | 49 ++++ .../Services/ListTransactionMappingLogs.php | 32 +++ .../ExportsImportedInvoiceMappeds.php | 1 - .../ExportsImportedReceiptMappeds.php | 86 +++++++ ...oryImportedTransactionMappedController.php | 20 ++ .../ExportCustomersToExcelController.php | 7 + .../ImportStatementInvoiceController.php | 1 + .../ImportStatementReceiptsController.php | 1 + .../TransactionMappingLogResource.php | 23 ++ app/Models/TransactionMappingLog.php | 2 +- ...type_to_transaction_mapping_logs_table.php | 40 ++++ .../elements/HistoryImportedInvoices.vue | 39 +++ .../elements/HistoryImportedReceipts.vue | 39 +++ .../ImportedInvoiceMappedComponent.vue | 12 +- .../ImportedReceiptMappedComponent.vue | 138 +++++++++++ .../ReportTransactionsMappedComponent.vue | 222 +++++++++++++++++- .../sections/TransactionsMappingComponent.vue | 15 +- routes/accounting.php | 3 + routes/web.php | 1 + 25 files changed, 827 insertions(+), 24 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/GroupByImportedDate.php create mode 100644 app/Classes/General/Eloquent/Filters/ImportedDateFrom.php create mode 100644 app/Classes/General/Eloquent/Filters/ImportedDateTo.php create mode 100644 app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php create mode 100644 app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php create mode 100644 app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php create mode 100644 app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php create mode 100644 app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php create mode 100644 app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php create mode 100644 app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php create mode 100644 app/Http/Resources/TransactionMappingLogResource.php create mode 100644 database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php create mode 100644 resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue create mode 100644 resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue create mode 100644 resources/assets/vue/components/accounting/sections/ImportedReceiptMappedComponent.vue diff --git a/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php b/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php new file mode 100644 index 00000000..25f20fa3 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php @@ -0,0 +1,18 @@ +groupby('imported_date'); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php b/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php new file mode 100644 index 00000000..140bbb20 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php @@ -0,0 +1,18 @@ +whereDate('imported_date', '>=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ImportedDateTo.php b/app/Classes/General/Eloquent/Filters/ImportedDateTo.php new file mode 100644 index 00000000..11bd3857 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ImportedDateTo.php @@ -0,0 +1,18 @@ +whereDate('imported_date', '<=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php new file mode 100644 index 00000000..9e3ba1e9 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('Invoice_reference', $value); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php new file mode 100644 index 00000000..c0a7beaf --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('owner_reference', $value); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php new file mode 100644 index 00000000..f808f784 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('receipt_reference', $value); + }); + } + +} diff --git a/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php new file mode 100644 index 00000000..2f96c613 --- /dev/null +++ b/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php @@ -0,0 +1,49 @@ + 'Retrieved History Imported Invoices', + 'message' => 'You have successfully retrieved history imported invoices' + ]; + } + + /** @var ListTransactionMappingLogs */ + private $listTransactionMappingLogs; + + /** + * UpdateAnnouncementLogic constructor. + * @param ListTransactionMappingLogs $listTransactionMappingLogs + */ + public function __construct( + ListTransactionMappingLogs $listTransactionMappingLogs + ) { + $this->listTransactionMappingLogs = $listTransactionMappingLogs; + } + + /** + * @param Request $request + * @return JsonResponse + */ + public function logic(Request $request): JsonResponse + { + $query = $this->listTransactionMappingLogs->execute($this->listTransactionMappingLogs->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(TransactionMappingLogResource::collection($query)); + } +} diff --git a/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php b/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php new file mode 100644 index 00000000..fdeff835 --- /dev/null +++ b/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php @@ -0,0 +1,32 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php index e629675f..ead22543 100644 --- a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php +++ b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php @@ -59,7 +59,6 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead */ public function map($transaction): array { - // dd($transaction); $this->count += 1; $data = $transaction->data; return [ diff --git a/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php b/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php new file mode 100644 index 00000000..efe95fd3 --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php @@ -0,0 +1,86 @@ +dateTime = $request->input('date').' '.$request->input('time'); + $this->count = 0; + } + + public function headings(): array + { + return [ + 'Check', + 'Doc No', + 'Doc Date', + 'Debtor Code', + 'Company Name', + 'Description', + 'Payment Amount', + 'Created User', + 'Curr.', + 'To Home Rate', + 'Local Payment Amount', + 'Cancelled', + 'Mapped Status', + 'Mapped Reference No', + ]; + } + + /** + * @return \Illuminate\Support\Collection|mixed + */ + public function query() + { + return TransactionMappingLog::where('imported_date', $this->dateTime); + } + + /** + * @param Transaction $transaction + * + * @return array + */ + public function map($transaction): array + { + $this->count += 1; + $data = $transaction->data; + return [ + $this->count, + Arr::get($data,'doc_no'), + Arr::get($data,'doc_date'), + Arr::get($data,'debtor_code'), + Arr::get($data,'company_name'), + Arr::get($data,'description'), + Arr::get($data,'payment_amount'), + Arr::get($data,'created_user'), + Arr::get($data,'curr'), + Arr::get($data,'to_home_rate'), + Arr::get($data,'local_payment_amount'), + Arr::get($data,'cancelled'), + Arr::get($data,'2nd_doc_no'), + Arr::get($data,'mapped_status'), + Arr::get($data,'mapped_result_reference'), + ]; + + } +} diff --git a/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php b/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php new file mode 100644 index 00000000..8b4a2cde --- /dev/null +++ b/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php index 733c84fa..0f351c7d 100644 --- a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php +++ b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php @@ -18,6 +18,7 @@ use Maatwebsite\Excel\Excel; use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds; use App\Models\TransactionMappingLog; use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions; +use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds; class ExportCustomersToExcelController { @@ -91,4 +92,10 @@ class ExportCustomersToExcelController ob_end_clean(); return $response; } + + public function importedReceiptMapped(ExportsImportedReceiptMappeds $exportsImportedReceiptMappeds, Request $request) { + $response = $exportsImportedReceiptMappeds->download($request->input('fileName').'.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']); + ob_end_clean(); + return $response; + } } \ No newline at end of file diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 75953f2b..e4c35eb5 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -100,6 +100,7 @@ class ImportStatementInvoiceController TransactionMappingLog::create([ 'imported_date'=>$importDate, + 'type' => 'invoices', 'data'=>$row, ]); array_push($data, $row); diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index a43f2dda..6c117642 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -69,6 +69,7 @@ class ImportStatementReceiptsController TransactionMappingLog::create([ 'imported_date'=>$importDate, + 'type' => 'receipts', 'data'=>$row, ]); array_push($data, $row); diff --git a/app/Http/Resources/TransactionMappingLogResource.php b/app/Http/Resources/TransactionMappingLogResource.php new file mode 100644 index 00000000..954294f1 --- /dev/null +++ b/app/Http/Resources/TransactionMappingLogResource.php @@ -0,0 +1,23 @@ + $this->id, + 'imported_date' => $this->imported_date, + 'type' => $this->type + ]; + } +} diff --git a/app/Models/TransactionMappingLog.php b/app/Models/TransactionMappingLog.php index d6093f39..e9ddab33 100644 --- a/app/Models/TransactionMappingLog.php +++ b/app/Models/TransactionMappingLog.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class TransactionMappingLog extends Model { - protected $fillable = ['imported_by','data','imported_date']; + protected $fillable = ['imported_by','data','imported_date','type']; protected $casts = [ 'data' => 'array', diff --git a/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php b/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php new file mode 100644 index 00000000..3927920a --- /dev/null +++ b/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php @@ -0,0 +1,40 @@ +string('type',50)->default('invoices')->after('imported_date'); + }); + + foreach (DB::table('transaction_mapping_logs')->get() as $key => $value) { + $data = json_decode($value->data); + DB::table('transaction_mapping_logs')->where('id',$value->id)->update([ + 'type' => (isset($data->description) ? 'receipts' : 'invoices') + ]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('transaction_mapping_logs', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +} diff --git a/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue b/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue new file mode 100644 index 00000000..d3d68cfb --- /dev/null +++ b/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue @@ -0,0 +1,39 @@ + + + diff --git a/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue b/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue new file mode 100644 index 00000000..00138fa5 --- /dev/null +++ b/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue @@ -0,0 +1,39 @@ + + + diff --git a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue index f10f9181..185da370 100644 --- a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue +++ b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue @@ -98,21 +98,17 @@ }, methods: { appendComponentTitle() { - this.componentTitle = this.section == 'importInvoiceMapping' ? 'Imported Invoices Mapped' : 'Imported Receipts Mapped'; + this.componentTitle = 'Imported Invoices Mapped'; }, appendComponentTableHeader() { - if (this.section == 'importInvoiceMapping') { - this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No','Payment Received Date']; - } else { - this.tableHeaders = ['No','OR No','Date','Creditor Code','Creditor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No']; - } + this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No','Payment Received Date']; }, importInvoice(){ this.isLoading = true; this.parameters = { files: this.files }; - this.submit(this.route('api.'+(this.section == 'importInvoiceMapping' ? 'import_invoices' : 'import_receipts')+'.upload'), 'post', this.section, true, false); + this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false); }, successHandler(response){ @@ -128,7 +124,7 @@ downloadInvoiceMapped() { var arrDateTime = this.importedDate.split(" "); - const fileName = this.section == 'importInvoiceMapping' ? 'InvoiceMapped' : 'ReceiptMapped'; + const fileName = 'importInvoiceMapping'; window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank'); }, diff --git a/resources/assets/vue/components/accounting/sections/ImportedReceiptMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ImportedReceiptMappedComponent.vue new file mode 100644 index 00000000..25db762e --- /dev/null +++ b/resources/assets/vue/components/accounting/sections/ImportedReceiptMappedComponent.vue @@ -0,0 +1,138 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/accounting/sections/ReportTransactionsMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ReportTransactionsMappedComponent.vue index e3d4e0d2..86da623c 100644 --- a/resources/assets/vue/components/accounting/sections/ReportTransactionsMappedComponent.vue +++ b/resources/assets/vue/components/accounting/sections/ReportTransactionsMappedComponent.vue @@ -3,19 +3,74 @@
-
-
-
-
Mapped Report
+
+ +
+
+
+
Mapped Report
+
+
+
+
+
History Imported Invoices Report
+
+
+
+
+
History Imported Receipts Report
+
+
-
+
+
+
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+
+ + + + +
+
+ + + + +
+
+
+
Mapped Report
+
+
+
+
@@ -35,7 +90,7 @@
- + @@ -44,22 +99,175 @@
+ + +
+
+
+
+
+
+
+ + + + +
+
+ + + + +
+
+
+
History Imported Invoices Report
+
+
+
+
+
+
+
+
Date
+
+
+
+ + + + +
+
+
+
+ + +
+
+
+
+
+
+
+ + + + +
+
+ + + + +
+
+
+
History Imported Receipts Report
+
+
+
+
+
+
+
+
Date
+
+
+
+ + + + +
+
+
+
\ No newline at end of file diff --git a/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue b/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue new file mode 100644 index 00000000..80ab17b0 --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue @@ -0,0 +1,275 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderItemFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderItemFormComponent.vue index d91d2661..16a10b64 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderItemFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderItemFormComponent.vue @@ -22,7 +22,10 @@
-

{{product.description}}

+ +

{{product.description}}

+
+

{{product.description}}

diff --git a/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue b/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue new file mode 100644 index 00000000..a9afe1d8 --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue @@ -0,0 +1,145 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index a2762ce7..1929aead 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -110,10 +110,15 @@
+
+
+ +
+
-
+
diff --git a/routes/api.php b/routes/api.php index 8b4bada0..715bd9d2 100644 --- a/routes/api.php +++ b/routes/api.php @@ -67,6 +67,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/milestone.php'; + require __DIR__ . '/open1688.php'; + // require __DIR__ . '/rate.php'; // require __DIR__ . '/receipt.php'; diff --git a/routes/open1688.php b/routes/open1688.php new file mode 100644 index 00000000..93250f21 --- /dev/null +++ b/routes/open1688.php @@ -0,0 +1,8 @@ + 'open1688', 'namespace' => 'Open1688', 'as' => 'open1688.'], function () { + Route::get('/', 'Open1688Controller@keywordSearchProduct')->name('keywordSearchProduct'); + Route::get('/{offer_id}', 'Open1688Controller@getProductDetail')->name('getProductDetail'); +}); From d59f19ce5d1538c5e38ce3573bbd8e662d8d51a9 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Thu, 25 Jan 2024 17:27:14 +0800 Subject: [PATCH 16/35] update --- .../forms/AlibabaProductDetailFormComponent.vue | 13 ++++--------- .../sections/AlibabaSiteSectionComponent.vue | 8 +++++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue b/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue index 80ab17b0..95e1c72a 100644 --- a/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/AlibabaProductDetailFormComponent.vue @@ -210,9 +210,11 @@ addToPurchaseOrder() { this.variantInfo = this.productInfo.variantInfo[this.uniqueVariantKey]; if (this.variantInfo && this.quantity > 0) { + const variantdescription = Object.keys(this.selectedVariantAttr).map((variantKey) => `${variantKey}:${this.selectedVariantAttr[variantKey]}`).join(',') + const productDescription = `${this.productInfo.subject}:{${variantdescription}}`; let product = { stockCode: `offerId:${this.productInfo.offerId},skuId:${this.variantInfo.skuId}`, - description: this.productInfo.subject, + description: productDescription, quantity: this.quantity, unit_price: parseFloat((this.variantInfo.price).toString().replaceAll(',', '')), total: this.quantity * parseFloat((this.variantInfo.price).toString().replace(',', '')) @@ -221,12 +223,7 @@ products: [product], pushToExisting: true, }; - - console.log(this.bookingId); - console.log(this.parameters); - console.log(this.isFetchingProduct); - console.log(this.section) - + this.isFetchingProduct = false; this.submit(route('api.transaction.po.create', this.bookingId), 'post', 'bookingDetailSection', true, true); } @@ -239,7 +236,6 @@ this.submit(route('api.open1688.getProductDetail', this.data.offerId), 'get', 'bookingDetailSection', false, true) }, successHandler(response){ - console.log(this.isFetchingProduct) if (this.isFetchingProduct) { this.productInfo = response.payload.data; this.selectedVariantAttr = {}; @@ -256,7 +252,6 @@ }, errorHandler(error){ - console.log(this.isFetchingProduct) if (this.isFetchingProduct) { this.productInfo = null; this.selectedVariantAttr = {}; diff --git a/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue b/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue index a9afe1d8..de9cd26a 100644 --- a/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/AlibabaSiteSectionComponent.vue @@ -125,9 +125,11 @@ this.searchProducts() }, searchProducts(){ - this.showProductList = true; - this.products = []; - this.isLoading = true; + if (this.keyword) { + this.showProductList = true; + this.products = []; + this.isLoading = true; + } this.submit(route('api.open1688.keywordSearchProduct') + '?page=' + this.currentPage + '&keyword=' + this.keyword, 'get', 'alibabaSiteSection', false, true); }, successHandler(response){ From 92f8b19b3e1f05835c512ff780f2c233d1161d3e Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 11 Feb 2024 17:34:46 +0800 Subject: [PATCH 17/35] Test revert merge request --- resources/views/pages/billings.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/pages/billings.blade.php b/resources/views/pages/billings.blade.php index da84f8b9..d1caee2d 100644 --- a/resources/views/pages/billings.blade.php +++ b/resources/views/pages/billings.blade.php @@ -3,7 +3,7 @@
- +
@endsection From 240cda76a5844179c3c52498bca42d68ee54fb26 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 11 Feb 2024 09:41:41 +0000 Subject: [PATCH 18/35] Revert "Merge branch 'dillon/51.2-test-revert-merge-request' into 'development'" This reverts merge request !153 --- resources/views/pages/billings.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/pages/billings.blade.php b/resources/views/pages/billings.blade.php index d1caee2d..da84f8b9 100644 --- a/resources/views/pages/billings.blade.php +++ b/resources/views/pages/billings.blade.php @@ -3,7 +3,7 @@
- +
@endsection From 83448e25df12ddcc4a97d1205930ae69a5eefd39 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 11 Feb 2024 09:47:30 +0000 Subject: [PATCH 19/35] Revert "Merge branch 'revert-c28544c6' into 'development'" This reverts merge request !154 --- resources/views/pages/billings.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/pages/billings.blade.php b/resources/views/pages/billings.blade.php index da84f8b9..d1caee2d 100644 --- a/resources/views/pages/billings.blade.php +++ b/resources/views/pages/billings.blade.php @@ -3,7 +3,7 @@
- +
@endsection From 86cc8bbf9dd105c5eefbd8a6797f75ecd9942d99 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 20 Feb 2024 11:07:35 +0800 Subject: [PATCH 20/35] test ga4 --- resources/assets/vue/app.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/assets/vue/app.js b/resources/assets/vue/app.js index abb7a17e..2fedd45b 100644 --- a/resources/assets/vue/app.js +++ b/resources/assets/vue/app.js @@ -99,6 +99,13 @@ const app = new Vue({ } else { this.render(); } + + // GA4 - push user_id + if (this.$store.getters.getUserId) { + dataLayer.push({ + 'user_id': this.$store.getters.getUserId, + }); + } }, render() { this.captchaId = window.grecaptcha.render('grecaptcha_container', { From db296a511f0b054eec1b9339a1787fe28afb9ad3 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 20 Feb 2024 11:16:38 +0800 Subject: [PATCH 21/35] test ga4 --- resources/assets/vue/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/assets/vue/app.js b/resources/assets/vue/app.js index 2fedd45b..e4fd9d02 100644 --- a/resources/assets/vue/app.js +++ b/resources/assets/vue/app.js @@ -102,6 +102,7 @@ const app = new Vue({ // GA4 - push user_id if (this.$store.getters.getUserId) { + console.log('gtag_push_id: ' + this.$store.getters.getUserId); dataLayer.push({ 'user_id': this.$store.getters.getUserId, }); From da044eb82bf00b8a9912c7388e6c9d57d72601aa Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sun, 17 Mar 2024 15:05:26 +0800 Subject: [PATCH 22/35] Merge branch 'supplier-bill-group-dashboard' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into development # Conflicts: # resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue --- .../bookings/elements/PaymentHistoryComponent.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 15868b10..16b69a40 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -300,7 +300,7 @@
-
+
@@ -445,6 +445,10 @@ TotalRequestedRefund += refunds.status === 2 ? refunds.amount : 0; }); return TotalRequestedRefund; + }, + hasRefundInProgress() { + var refundTransactionsStatus = this.data.transaction_refunds.length > 0 ? this.data.transaction_refunds.map(refund => refund.status) : []; + return refundTransactionsStatus.includes(0) || refundTransactionsStatus.includes(1) } }, methods: { From eb30d4194119fcef71ee1d4657b077a4b7d079de Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 1 Apr 2024 13:56:25 +0800 Subject: [PATCH 23/35] Second voucher (first milestone) for user upon reaching 2 completed bookings --- .../Eloquent/Filters/HasActiveReward.php | 33 +++------- .../Filters/HasActiveRewardForAdmin.php | 26 ++++++++ .../Eloquent/Filters/HasVouchersAll.php | 44 ++++++++++++++ .../General/Eloquent/Filters/RandomName.php | 20 ------- .../CreateMilestoneRewardByTransactionJob.php | 38 ++++++++++++ app/Classes/Jobs/ListDocumentsJob.php | 11 ---- .../ControllersLogic/CreateCustomerLogic.php | 8 +-- .../Processors/AuthenticationProcessor.php | 2 +- .../ControllersLogic/CallbackBillplzLogic.php | 9 ++- .../CheckMilestonesForRewardProcessor.php | 13 +++- .../MilestoneRewardByTransactionProcessor.php | 48 +++++++++++++++ .../Constants/MilestoneCreationOptions.php | 5 +- .../ValueObjects/Constants/Milestones.php | 7 ++- app/Http/Resources/VoucherResource.php | 2 +- .../VouchersNavigationBarComponent.vue | 42 +++++++++++++ .../accounts/forms/LogOutFormComponent.vue | 4 +- .../elements/AvailableVouchersComponent.vue | 9 ++- .../elements/ListVouchersComponent.vue | 9 ++- .../SingleUserRewardItemComponent.vue | 5 +- .../CustomerDashboardSectionComponent.vue | 1 + .../CustomerProfileSectionComponent.vue | 3 +- .../CustomerRewardsAdminSectionComponent.vue | 9 ++- .../CustomerRewardsSectionComponent.vue | 21 +++++-- .../VouchersSummaryAdminComponent.vue | 42 +++++++++++++ .../elements/VouchersSummaryComponent.vue | 26 ++++++++ .../assets/vue/vuex/modules/voucherUpdates.js | 60 +++++++++++++++++++ resources/assets/vue/vuex/store.js | 4 +- resources/views/partials/header.blade.php | 7 ++- routes/api.php | 4 +- 29 files changed, 413 insertions(+), 99 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php create mode 100644 app/Classes/General/Eloquent/Filters/HasVouchersAll.php delete mode 100644 app/Classes/General/Eloquent/Filters/RandomName.php create mode 100644 app/Classes/Jobs/CreateMilestoneRewardByTransactionJob.php create mode 100644 app/Classes/Modules/Milestones/Processors/MilestoneRewardByTransactionProcessor.php create mode 100644 resources/assets/vue/components/accounts/elements/VouchersNavigationBarComponent.vue create mode 100644 resources/assets/vue/components/general/elements/VouchersSummaryAdminComponent.vue create mode 100644 resources/assets/vue/components/general/elements/VouchersSummaryComponent.vue create mode 100644 resources/assets/vue/vuex/modules/voucherUpdates.js diff --git a/app/Classes/General/Eloquent/Filters/HasActiveReward.php b/app/Classes/General/Eloquent/Filters/HasActiveReward.php index 5770ca6e..26385b96 100644 --- a/app/Classes/General/Eloquent/Filters/HasActiveReward.php +++ b/app/Classes/General/Eloquent/Filters/HasActiveReward.php @@ -2,7 +2,6 @@ namespace App\Classes\General\Eloquent\Filters; -use App\Classes\ValueObjects\Constants\RoleTypes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; @@ -12,33 +11,17 @@ class HasActiveReward implements Filter /** * @param Builder $builder * @param $value - * @return mixed + * @return Builder|mixed */ public static function apply(Builder $builder, $value) { - if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){ - // $userId = $value !== 1 ? $value : Auth::user()->id; - $userId = $value; - return $builder->where('user_id', $userId) - ->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); + return $builder->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); }); - } - else{ - return $builder->where('user_id', Auth::user()->id) - ->where(function ($query) { - $query->whereHas('reward', function ($subquery) { - $subquery->where('is_active', true); - }) - ->orWhereDoesntHave('reward'); - }) - ->whereDoesntHave('voucher.redemptions.transaction.owner'); - } + // ->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/HasVouchersAll.php b/app/Classes/General/Eloquent/Filters/HasVouchersAll.php new file mode 100644 index 00000000..d2ff7a2e --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasVouchersAll.php @@ -0,0 +1,44 @@ +type, RoleTypes::ADMIN_ROLES)){ + // $userId = $value !== 1 ? $value : Auth::user()->id; + $userId = $value; + return $builder->where('user_id', $userId) + ->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{ + return $builder->where('user_id', Auth::user()->id) + ->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/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/Jobs/CreateMilestoneRewardByTransactionJob.php b/app/Classes/Jobs/CreateMilestoneRewardByTransactionJob.php new file mode 100644 index 00000000..86208cc9 --- /dev/null +++ b/app/Classes/Jobs/CreateMilestoneRewardByTransactionJob.php @@ -0,0 +1,38 @@ +transaction = $transaction; + $this->milestones = $milestones; + } + + public function handle() + { + (App()->make(MilestoneRewardByTransactionProcessor::class))->execute($this->transaction, $this->milestones); + } +} diff --git a/app/Classes/Jobs/ListDocumentsJob.php b/app/Classes/Jobs/ListDocumentsJob.php index 6e93062b..25247c50 100644 --- a/app/Classes/Jobs/ListDocumentsJob.php +++ b/app/Classes/Jobs/ListDocumentsJob.php @@ -44,17 +44,6 @@ class ListDocumentsJob implements ShouldQueue } $result = (App()->make(ListDocumentsJobProcessor::class))->execute($this->listGenericJobObject); - - //cief todo: Insert into DB: job id, query result, timestamp - // Store the result in the job_results table - - //cief todo: why cannot save data in table like this - // $model = new JobResult(); - // $model->job_id = $this->job->getJobId(); - // $model->result = json_encode($result); - // $model->save(); - - // Log::error(json_encode($model->id)); } public function getJobId(){ diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index 0f7bdb61..e56c0727 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -11,7 +11,6 @@ use App\Classes\Modules\Companies\Processors\AssignEmployeeProcessor; use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; use App\Classes\Modules\Companies\Processors\CreateCompanyProcessor; use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; -use App\Classes\Modules\Milestones\Processors\CheckMilestonesForRewardProcessor; use App\Classes\Modules\Vouchers\Processors\Voucherify\NewCustomerToVoucherifyProcessor; use App\Classes\Modules\Vouchers\Processors\CreateVoucherProcessor; use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject; @@ -69,9 +68,6 @@ class CreateCustomerLogic extends AbstractControllerLogic /** @var CreatesSeasonalSegment */ private $createsSeasonalSegment; - /** @var CheckMilestonesForRewardProcessor */ - private $checkMilestonesForRewardProcessor; - /** @var NewCustomerToVoucherifyProcessor */ private $newCustomerToVoucherifyProcessor; @@ -88,12 +84,11 @@ class CreateCustomerLogic extends AbstractControllerLogic * @param AuthenticationProcessor $authenticationProcessor * @param GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor * @param CreatesSeasonalSegment $createsSeasonalSegment - * @param CheckMilestonesForRewardProcessor $checkMilestonesForRewardProcessor * @param NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor * @param CreateVoucherProcessor $createVoucherProcessor */ public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateContactProcessor $createContactProcessor, AssignEmployeeProcessor $assignEmployeeProcessor, AssignSegmentProcessor $assignSegmentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor, - CreatesSeasonalSegment $createsSeasonalSegment, CheckMilestonesForRewardProcessor $checkMilestonesForRewardProcessor, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor, CreateVoucherProcessor $createVoucherProcessor) + CreatesSeasonalSegment $createsSeasonalSegment, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor, CreateVoucherProcessor $createVoucherProcessor) { $this->createUserProcessor = $createUserProcessor; $this->createCompanyProcessor = $createCompanyProcessor; @@ -103,7 +98,6 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->authenticationProcessor = $authenticationProcessor; $this->generateEmailVerificationAttemptProcessor = $generateEmailVerificationAttemptProcessor; $this->createsSeasonalSegment = $createsSeasonalSegment; - $this->checkMilestonesForRewardProcessor = $checkMilestonesForRewardProcessor; $this->newCustomerToVoucherifyProcessor = $newCustomerToVoucherifyProcessor; $this->createVoucherProcessor = $createVoucherProcessor; } diff --git a/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php b/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php index 707369e9..7e5fca53 100644 --- a/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php +++ b/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php @@ -82,7 +82,7 @@ class AuthenticationProcessor } //cief todo: case study 1 - //$this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_1]); + //$this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_DEMO_1]); return ['access_token' => $this->generatesAuthenticationToken->execute($user), 'redirect_url' => $this->authenticationRedirect->url($user)]; } diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index 186ef3b6..a4b80fc4 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -26,6 +26,8 @@ use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance; +use App\Classes\Jobs\CreateMilestoneRewardByTransactionJob; +use App\Classes\ValueObjects\Constants\Milestones; class CallbackBillplzLogic { @@ -55,7 +57,9 @@ class CallbackBillplzLogic * @param FetchesTransaction $fetchesTransaction * @param UpdatesTransactionStatus $updatesTransactionStatus * @param UpdatesWalletBalance $updatesWalletBalance + * @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor * @param RecalculatesWalletBalance $recalculatesWalletBalance + * @param CreateMilestoneRewardJob $createMilestoneRewardJob */ public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWalletBalance $updatesWalletBalance, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance) { @@ -87,7 +91,8 @@ class CallbackBillplzLogic if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.'); $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]); - + CreateMilestoneRewardByTransactionJob::dispatch($transaction, [Milestones::MILESTONE_1]); + if($billPlz->state === 'paid') { $status = ApprovalStatus::APPROVED; } @@ -117,4 +122,4 @@ class CallbackBillplzLogic return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking ?? null, 'transaction' => $transaction, 'status' => $status]); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Milestones/Processors/CheckMilestonesForRewardProcessor.php b/app/Classes/Modules/Milestones/Processors/CheckMilestonesForRewardProcessor.php index 597fa8bc..1a138dfa 100644 --- a/app/Classes/Modules/Milestones/Processors/CheckMilestonesForRewardProcessor.php +++ b/app/Classes/Modules/Milestones/Processors/CheckMilestonesForRewardProcessor.php @@ -81,9 +81,12 @@ class CheckMilestonesForRewardProcessor try{ foreach($milestone_constants as $constant) { - //update milestone progress - /** @var Milestone $milestone */ - $milestone = $this->fetchesMilestone->execute(['name' => $constant]); + //update milestone progres + $milestone = Milestone::where('name', $constant)->first(); + if(!$milestone) { + Log::error("{$constant} NOT FOUND!"); + continue; + } $result = null; if($user->milestoneProgress->count() > 0){ $result = $user->milestoneProgress->where('milestone_id', $milestone->id)->first(); @@ -130,6 +133,10 @@ class CheckMilestonesForRewardProcessor //Voucherify - Create Voucher $result = $this->createsVoucherifyVoucher->execute($user, intval($reward->value)); } + else if($reward->type == RewardType::REWARD_CODE){ + //Voucherify - Get Voucher + $result = $this->fetchesVoucherifyVoucher->execute($user, $reward->value); + } else{ //Voucherify - Validates Voucher $ValidateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject(0, $reward->value, 0.00, $user); diff --git a/app/Classes/Modules/Milestones/Processors/MilestoneRewardByTransactionProcessor.php b/app/Classes/Modules/Milestones/Processors/MilestoneRewardByTransactionProcessor.php new file mode 100644 index 00000000..ea9abf9c --- /dev/null +++ b/app/Classes/Modules/Milestones/Processors/MilestoneRewardByTransactionProcessor.php @@ -0,0 +1,48 @@ +checkMilestonesForRewardProcessor = $checkMilestonesForRewardProcessor; + } + + + /** + * @param Transaction $transaction + * @param array $milestones + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(Transaction $transaction, array $milestones) + { + $company = $transaction->owner instanceof Booking ? $transaction->owner()->first()->company : null; + if($company){ + $completedBookingCount = count($company->bookings()->where('status', ApprovalStatus::COMPLETED)->get()); + Log::info("Number of completed bookings completed for company ".$company->reference. ": " .$completedBookingCount); + if (in_array(Milestones::MILESTONE_1, $milestones)) { + if($completedBookingCount === 2){ + $user = $company->employees()->first(); + $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_1]); + } + } + } + } +} diff --git a/app/Classes/ValueObjects/Constants/MilestoneCreationOptions.php b/app/Classes/ValueObjects/Constants/MilestoneCreationOptions.php index 4631b25b..6e94e610 100644 --- a/app/Classes/ValueObjects/Constants/MilestoneCreationOptions.php +++ b/app/Classes/ValueObjects/Constants/MilestoneCreationOptions.php @@ -6,8 +6,9 @@ class MilestoneCreationOptions { const OPTIONS_MILESTONE_NAME= [ ['text' => 'MILESTONE 1', 'id' => Milestones::MILESTONE_1], - ['text' => 'MILESTONE 2', 'id' => Milestones::MILESTONE_2], - ['text' => 'MILESTONE 3', 'id' => Milestones::MILESTONE_3], + // ['text' => 'MILESTONE DEMO 1', 'id' => Milestones::MILESTONE_DEMO_1], + // ['text' => 'MILESTONE 2', 'id' => Milestones::MILESTONE_2], + // ['text' => 'MILESTONE 3', 'id' => Milestones::MILESTONE_3], // ['text' => 'MILESTONE 4', 'id' => Milestones::MILESTONE_4], // ['text' => 'MILESTONE 5', 'id' => Milestones::MILESTONE_5], // ['text' => 'MILESTONE 6', 'id' => Milestones::MILESTONE_6], diff --git a/app/Classes/ValueObjects/Constants/Milestones.php b/app/Classes/ValueObjects/Constants/Milestones.php index 19961d68..6a85abbe 100644 --- a/app/Classes/ValueObjects/Constants/Milestones.php +++ b/app/Classes/ValueObjects/Constants/Milestones.php @@ -4,9 +4,10 @@ namespace App\Classes\ValueObjects\Constants; class Milestones { - public const MILESTONE_1 = 'MILESTONE 1'; //Authentication (Sign in) or CreateCustomerLogic (Sign up) - public const MILESTONE_2 = 'MILESTONE 2'; //Create Identification Document - public const MILESTONE_3 = 'MILESTONE 3'; //Assign Company to Segment Logic -segment.assign when accept 1688 + public const MILESTONE_1 = 'MILESTONE 1'; //Has 2 successful bookings + // public const MILESTONE_DEMO_1 = 'MILESTONE_DEMO_1 1'; //Authentication (Sign in) or CreateCustomerLogic (Sign up) + // public const MILESTONE_2 = 'MILESTONE 2'; //Create Identification Document + // public const MILESTONE_3 = 'MILESTONE 3'; //Assign Company to Segment Logic -segment.assign when accept 1688 // public const MILESTONE_4 = 'MILESTONE 4'; //Create Bank Logic (Transfer Now from dashboard) // public const MILESTONE_5 = 'MILESTONE 5'; //Create Booking Logic // public const MILESTONE_6 = 'MILESTONE 6'; //Create Address Logic (At transfer page before create booking) diff --git a/app/Http/Resources/VoucherResource.php b/app/Http/Resources/VoucherResource.php index 3f3112bb..031cf39f 100644 --- a/app/Http/Resources/VoucherResource.php +++ b/app/Http/Resources/VoucherResource.php @@ -16,7 +16,7 @@ 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_vouchers_all")) { $filteredRedemptions = new ArrayObject([]); } else{ diff --git a/resources/assets/vue/components/accounts/elements/VouchersNavigationBarComponent.vue b/resources/assets/vue/components/accounts/elements/VouchersNavigationBarComponent.vue new file mode 100644 index 00000000..60947cb9 --- /dev/null +++ b/resources/assets/vue/components/accounts/elements/VouchersNavigationBarComponent.vue @@ -0,0 +1,42 @@ + + + diff --git a/resources/assets/vue/components/accounts/forms/LogOutFormComponent.vue b/resources/assets/vue/components/accounts/forms/LogOutFormComponent.vue index 4956260f..5843111c 100644 --- a/resources/assets/vue/components/accounts/forms/LogOutFormComponent.vue +++ b/resources/assets/vue/components/accounts/forms/LogOutFormComponent.vue @@ -68,11 +68,13 @@ }, successHandler(){ this.$store.dispatch('userAuthentication', {access_token: '', redirect_url: this.route('login')}); + this.$store.dispatch('clearVoucher'); }, errorHandler(){ this.$store.dispatch('userAuthentication', {access_token: '', redirect_url: this.route('login')}); + this.$store.dispatch('clearVoucher'); } } } - \ No newline at end of file + diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index 89a56b0f..9b08e7f3 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -12,11 +12,14 @@ {{ item.voucher.code }}
- + + This voucher has expired. + + Valid till {{ item.voucher.end_date }} - No expiry date + Non-expired
@@ -62,7 +65,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_vouchers_all': 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..0de8b692 100644 --- a/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/ListVouchersComponent.vue @@ -26,11 +26,14 @@

RM{{ item.voucher.value/100 }} Discount

{{ item.voucher.value }}% Discount

-
+
+ This voucher has expired. +
+
Valid till {{ item.voucher.end_date }}
- No expiry date + Non-expired
@@ -76,7 +79,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_vouchers_all': this.employee.id} ), 'get', this.section, false, false); } }, successHandler(response){ diff --git a/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue b/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue index 9cc2409a..164c98c1 100644 --- a/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue +++ b/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue @@ -17,11 +17,14 @@

Voucher claimed

+

+ This voucher has expired. +

Valid till {{ item.voucher.end_date }}

- - + Non-expired

diff --git a/resources/assets/vue/components/companies/sections/CustomerDashboardSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerDashboardSectionComponent.vue index 5a0766cb..074354ca 100644 --- a/resources/assets/vue/components/companies/sections/CustomerDashboardSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerDashboardSectionComponent.vue @@ -201,6 +201,7 @@
+ diff --git a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue index bd646426..76c28e1d 100644 --- a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue @@ -141,6 +141,7 @@
+
@@ -213,4 +214,4 @@ } } } - \ No newline at end of file + diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue index 9429593a..aba22978 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsAdminSectionComponent.vue @@ -52,7 +52,7 @@
- + @@ -69,10 +69,15 @@
- + + +
diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue index 83567aaf..d781d66e 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 @@
- + +
@@ -108,5 +113,9 @@ diff --git a/resources/assets/vue/components/general/elements/VouchersSummaryAdminComponent.vue b/resources/assets/vue/components/general/elements/VouchersSummaryAdminComponent.vue new file mode 100644 index 00000000..dc4a2a54 --- /dev/null +++ b/resources/assets/vue/components/general/elements/VouchersSummaryAdminComponent.vue @@ -0,0 +1,42 @@ + + + + diff --git a/resources/assets/vue/components/general/elements/VouchersSummaryComponent.vue b/resources/assets/vue/components/general/elements/VouchersSummaryComponent.vue new file mode 100644 index 00000000..e90748af --- /dev/null +++ b/resources/assets/vue/components/general/elements/VouchersSummaryComponent.vue @@ -0,0 +1,26 @@ + + + + diff --git a/resources/assets/vue/vuex/modules/voucherUpdates.js b/resources/assets/vue/vuex/modules/voucherUpdates.js new file mode 100644 index 00000000..a9fd08a5 --- /dev/null +++ b/resources/assets/vue/vuex/modules/voucherUpdates.js @@ -0,0 +1,60 @@ +const initialState = { + vouchersCount: localStorage.getItem('voucher-count') || 0, + latestVoucherTimestamp: localStorage.getItem('latest-voucher-timestamp') || null, + lastSeenVoucherTimestamp: localStorage.getItem('last-seen-voucher-timestamp') || null, +}; + +export default { + state: { ...initialState }, + getters: { + getVouchersCount: state => { + return state.vouchersCount; + }, + showVoucherUpdateIndicator: state => { + if (!state.lastSeenVoucherTimestamp && state.voucherCount > 0) { + return true; + } + if (!state.latestVoucherTimestamp) { + return false; + } + const latestTime = new Date(state.latestVoucherTimestamp).getTime(); + const lastSeenTime = new Date(state.lastSeenVoucherTimestamp).getTime(); + return latestTime > lastSeenTime; + } + }, + mutations: { + SET_VOUCHER_LATEST_TIMESTAMP(state, timestamp) { + state.latestVoucherTimestamp = timestamp; + }, + SET_VOUCHER_LAST_SEEN_TIMESTAMP(state, timestamp) { + state.lastSeenVoucherTimestamp = timestamp; + }, + SET_VOUCHER_COUNT(state, count) { + state.vouchersCount = count; + }, + RESET_VOUCHER_STATE(state) { + Object.assign(state, initialState); + } + }, + actions: { + updateLatestVoucherTimestamp(store, timestamp){ + localStorage.setItem('latest-voucher-timestamp', timestamp); + store.commit('SET_VOUCHER_LATEST_TIMESTAMP', timestamp); + }, + markVouchersAsSeen(store) { + const latestVoucherTimestamp = store.state.latestVoucherTimestamp; + localStorage.setItem('last-seen-voucher-timestamp', latestVoucherTimestamp); + store.commit('SET_VOUCHER_LAST_SEEN_TIMESTAMP', latestVoucherTimestamp); + }, + updateVoucherCount(store, count){ + localStorage.setItem('voucher-count', count); + store.commit('SET_VOUCHER_COUNT', count); + }, + clearVoucher(store, count){ + localStorage.removeItem('voucher-count'); + localStorage.removeItem('latest-voucher-timestamp'); + localStorage.removeItem('last-seen-voucher-timestamp'); + store.commit('RESET_VOUCHER_STATE'); + }, + } +} diff --git a/resources/assets/vue/vuex/store.js b/resources/assets/vue/vuex/store.js index ff10c673..ab554e8a 100644 --- a/resources/assets/vue/vuex/store.js +++ b/resources/assets/vue/vuex/store.js @@ -7,6 +7,7 @@ import crudRequest from './modules/crudRequest' import crudRequestV2 from './modules/crudRequestV2' import authentication from './modules/authentication' import loadRequestQueue from './modules/loadRequestQueue' +import voucherUpdates from './modules/voucherUpdates' Vue.use(Vuex); @@ -18,6 +19,7 @@ export default new Vuex.Store({ createNotification, crudRequest, crudRequestV2, - authentication + authentication, + voucherUpdates } }) diff --git a/resources/views/partials/header.blade.php b/resources/views/partials/header.blade.php index b618e334..e04131ac 100644 --- a/resources/views/partials/header.blade.php +++ b/resources/views/partials/header.blade.php @@ -61,9 +61,10 @@ - +
+ + +
diff --git a/routes/api.php b/routes/api.php index 460bd772..9d67e62c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -60,15 +60,13 @@ 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'; require __DIR__ . '/milestone.php'; - // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed - require __DIR__ . '/job.php'; // require __DIR__ . '/rate.php'; From 19ef720bc5db03a8b3489f4cf8ad9a8677cc9a50 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 2 Apr 2024 20:25:57 +0800 Subject: [PATCH 24/35] Small fix on UX when applying voucher --- .../bookings/forms/BookingPaymentQuotationComponent.vue | 3 ++- .../companies/sections/CustomerRewardsSectionComponent.vue | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 10246745..8ba9833e 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -260,7 +260,8 @@
{{ voucherCodeFailedReason }} - Voucher applied + Voucher applied + No voucher applied
diff --git a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue index d781d66e..b1f2a5f9 100644 --- a/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerRewardsSectionComponent.vue @@ -69,7 +69,7 @@
- - -
@yield('content') diff --git a/resources/views/vendor/head.blade.php b/resources/views/vendor/head.blade.php index 21aa971e..c3502429 100644 --- a/resources/views/vendor/head.blade.php +++ b/resources/views/vendor/head.blade.php @@ -1,11 +1,3 @@ - - - - Exchange - Overseas Money Transfers From 06a0fb5aec204878dcf3fc6b38e67c931bb7a6c8 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sun, 9 Jun 2024 22:19:03 +0800 Subject: [PATCH 33/35] remove testing code --- resources/assets/vue/app.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/assets/vue/app.js b/resources/assets/vue/app.js index 82945ab5..0479ab13 100644 --- a/resources/assets/vue/app.js +++ b/resources/assets/vue/app.js @@ -119,14 +119,6 @@ const app = new Vue({ } else { this.render(); } - - // GA4 - push user_id - if (this.$store.getters.getUserId) { - console.log('gtag_push_id: ' + this.$store.getters.getUserId); - dataLayer.push({ - 'user_id': this.$store.getters.getUserId, - }); - } }, render() { this.captchaId = window.grecaptcha.render('grecaptcha_container', { From 9a4dba7fdd1d8d0e8296f2f92c3ad15e203afdd4 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 12 Jun 2024 10:16:31 +0800 Subject: [PATCH 34/35] fix the error mock up white form cannot be created --- resources/views/pages/pdfs/currency_vendor_order.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/pages/pdfs/currency_vendor_order.blade.php b/resources/views/pages/pdfs/currency_vendor_order.blade.php index 10707369..881ca2ca 100644 --- a/resources/views/pages/pdfs/currency_vendor_order.blade.php +++ b/resources/views/pages/pdfs/currency_vendor_order.blade.php @@ -59,7 +59,7 @@ Transfer fee: @php - $transfer_fee = number_format(((float)$transferFeeTransactions->sum('service_charge') + (float)$groupTransferFeeOriginalAmount), 2, '.', ''); + $transfer_fee = number_format(((float)$transferFeeTransactions->sum('service_charge') + (float)($groupTransferFeeOriginalAmount ?? 0)), 2, '.', ''); @endphp {{$transaction->original_currency->short_code}} {{$transfer_fee}} From b31d592e4a2801dd46d8aad8e89a4fc23ff11eaa Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sun, 16 Jun 2024 11:50:29 +0800 Subject: [PATCH 35/35] update command logic --- ...eBillGroupAndGroupToIncludeTransferFee.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/app/Console/Commands/UpdateBillGroupAndGroupToIncludeTransferFee.php b/app/Console/Commands/UpdateBillGroupAndGroupToIncludeTransferFee.php index 3712f8a7..72a1c8f2 100644 --- a/app/Console/Commands/UpdateBillGroupAndGroupToIncludeTransferFee.php +++ b/app/Console/Commands/UpdateBillGroupAndGroupToIncludeTransferFee.php @@ -103,23 +103,8 @@ class UpdateBillGroupAndGroupToIncludeTransferFee extends Command continue; } - // get the groups - $payments = $billGroup->groups; - - $totalOriginalTransferFee = 0; - $totalTransferFee = 0; - // for each group - foreach ($payments as $group) { - $group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first(); - - if ($group_transfer_fee) { - $totalOriginalTransferFee += $group_transfer_fee->original_amount; - $totalTransferFee = $totalTransferFee + ($group_transfer_fee->original_amount / $group->currency_rate); - } - } - - $totalOriginal = $billGroup->original_amount + $totalOriginalTransferFee; - $total = $billGroup->amount + $totalTransferFee; + $totalOriginal = $billGroup->groups()->sum('original_amount'); + $total = $billGroup->groups()->sum('amount'); // update bill group payment transaction amount if there is only 1 payment transaction $payment_transactions = $billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();