Compare commits

...

137 Commits

Author SHA1 Message Date
edmondlang 76193eeb9f update order v2 2023-04-13 16:09:18 +08:00
edmondlang a696e1dab9 change all order to v2 link 2023-04-13 16:05:20 +08:00
edmondlang c9642bd8f5 update order v2 page 2023-04-13 16:01:12 +08:00
DESKTOP-5I7S92L\nicho a3d26bfb63 uncomment order package code 2023-04-13 12:20:49 +08:00
DESKTOP-5I7S92L\nicho 094f995dcf orde v2 include packages 2023-04-13 12:18:22 +08:00
edmondlang 1a5db25285 update show duplicated invoice logic 2023-04-12 12:15:06 +08:00
edmondlang 2bb4afe426 update show duplicated invoice logic 2023-04-12 11:58:10 +08:00
edmondlang f7a9b2332c enable customer 769SMC summary in 2 different year 2022 and 2023 2023-04-11 11:39:22 +08:00
Dillon Ngo fa0c97b1da Merge branch 'dillon/accounting-bank-mapping' into 'master'
New route, middleware, token table, filters for query to allow  third party to access api

See merge request CIEFWorldwideSdnBhd/shipping-portal!161
2023-04-06 15:19:15 +00:00
Dillon 43cd6f35be New route, middleware, token table, filters for query to allow third party to access api 2023-04-06 22:57:50 +08:00
edmondlang 697c02ac8a delete packing list by package id 2023-04-06 19:22:40 +08:00
edmondlang 3dd9dfe361 Merge branch 'master' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal into delete-packing-list 2023-04-06 18:52:48 +08:00
edmondlang 7c50dfbfc3 update 769SMC summary 2023-04-06 17:30:02 +08:00
edmondlang e77e513bef support page update 2023-04-06 14:24:56 +08:00
DESKTOP-5I7S92L\nicho e173a9ddd3 support update 2023-04-06 14:00:41 +08:00
edmondlang c40d563372 add support at menu 2023-04-06 00:08:06 +08:00
edmondlang 7f0de1c1e4 support page 2023-04-05 23:49:23 +08:00
edmondlang c5477890d6 oder v2 2023-04-05 20:27:22 +08:00
edmondlang 26027f5f3f order profile v2 2023-04-05 19:13:17 +08:00
edmondlang a28f735d8f order v2 2023-04-05 19:12:07 +08:00
DESKTOP-5I7S92L\nicho 225abaacb8 order v2 2023-04-05 16:38:28 +08:00
DESKTOP-5I7S92L\nicho 70fc8285f8 order v2 2023-04-05 16:21:53 +08:00
DESKTOP-5I7S92L\nicho 1f6eaa65a5 order v2 2023-04-05 16:02:10 +08:00
DESKTOP-5I7S92L\nicho 7e2428957e delete packing list 2023-04-05 15:18:46 +08:00
edmondlang 069c3cea35 Showing Billplz payment status 2023-04-02 12:09:44 +08:00
edmondlang 07998c6850 super admin delete invoice/transaction 2023-04-02 11:25:50 +08:00
Dillon Ngo cd3e955f3e Merge branch 'dillon/debug-and-fixes-2' into 'master'
Another attempt to solve invoice without projectId, rewriting job chaining one after another

See merge request CIEFWorldwideSdnBhd/shipping-portal!160
2023-04-01 16:28:55 +00:00
edmondlang 869397056c final-duplicated-invoice-debug 2023-04-01 19:36:43 +08:00
edmondlang c58cdde254 final-duplicated-invoice-debug 2023-04-01 19:35:47 +08:00
edmondlang 982a7c1d44 final-duplicated-invoice-debug 2023-04-01 19:34:30 +08:00
edmondlang c976319521 final-duplicated-invoice-debug 2023-04-01 19:19:48 +08:00
edmondlang 145bf3263a final-duplicated-invoice-debug 2023-04-01 18:51:37 +08:00
edmondlang 57eb1e147d final-duplicated-invoice-debug 2023-04-01 18:48:34 +08:00
edmondlang e1c69f2de4 final-duplicated-invoice-debug 2023-04-01 18:35:15 +08:00
edmondlang 90b2bffd19 final-duplicated-invoice-debug 2023-04-01 18:31:02 +08:00
edmondlang 562815f9fe final-duplicated-invoice-debug 2023-04-01 18:27:04 +08:00
edmondlang 401db91437 final-duplicated-invoice-debug 2023-04-01 18:20:22 +08:00
edmondlang 0d1a623512 final-duplicated-invoice-debug 2023-04-01 17:36:59 +08:00
edmondlang 548a50c14a final-duplicated-invoice-debug 2023-04-01 17:33:51 +08:00
edmondlang 299512ec08 final-duplicated-invoice-debug 2023-04-01 17:29:28 +08:00
edmondlang 7241db7743 final-duplicated-invoice-debug 2023-04-01 17:27:13 +08:00
edmondlang ce24deea18 final-duplicated-invoice-debug 2023-04-01 17:11:07 +08:00
edmondlang c4642c2042 final-duplicated-invoice-debug 2023-04-01 17:06:37 +08:00
edmondlang 3871d8c010 clean up web routes 2023-04-01 16:01:20 +08:00
edmondlang cb65a1f29b fix bug billplz failed callback 2023-03-31 21:24:43 +08:00
edmondlang b1b13d7cbf fix bug billplz failed callback 2023-03-31 21:21:26 +08:00
Omair Saleh f6fa2fcf51 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	routes/web.php
2023-03-31 15:44:13 +08:00
Omair Saleh 6c00a57446 smc summary report 2023-03-31 15:43:04 +08:00
edmondlang 48445020fb adjust warehouse contact ui 2023-03-31 00:41:45 +08:00
edmondlang 46f1368a92 ui and api to update warehouse contact 2023-03-31 00:29:15 +08:00
edmondlang 82a16a5d9d update address 2023-03-30 17:26:19 +08:00
edmondlang 23002f61da update admin role type 2023-03-30 15:13:41 +08:00
edmondlang 2355c74b65 update customer/summary/monthly to 2023 records 2023-03-30 14:22:10 +08:00
edmondlang bd81560c3d remove console.log 2023-03-30 14:21:31 +08:00
edmondlang 575491e500 search admin in settings 2023-03-30 14:18:22 +08:00
edmondlang 1c703489b9 update admin role type 2023-03-30 12:47:02 +08:00
DESKTOP-5I7S92L\nicho 30ef3a7e41 fix call API bug for changeAdminRoleTypeForm 2023-03-30 12:35:30 +08:00
DESKTOP-5I7S92L\nicho f9b1289d28 call api 2023-03-30 12:28:45 +08:00
edmondlang 9fe49d8658 Merge branch 'master' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal into update-admin-role-type 2023-03-30 12:16:04 +08:00
DESKTOP-5I7S92L\nicho e265b069d2 change button color to transparent 2023-03-30 12:12:35 +08:00
edmondlang f90818dbca updates user name and admin type api 2023-03-30 12:06:33 +08:00
DESKTOP-5I7S92L\nicho bfd490854d change admin role type 2023-03-30 11:53:54 +08:00
Dillon 94d96c96ea Another attempt to solve invoice without projectId, rewriting job chaining one after another 2023-03-30 05:58:26 +08:00
edmondlang feaab3cd8e check billplz failed callback 2023-03-30 00:37:09 +08:00
edmondlang 094801abbe check billplz failed callback 2023-03-30 00:35:59 +08:00
edmondlang 275d8880d9 check billplz failed callback 2023-03-30 00:30:12 +08:00
edmondlang 98843d0688 check billplz failed callback 2023-03-30 00:07:21 +08:00
edmondlang 317f4c2351 check billplz failed callback 2023-03-29 23:39:58 +08:00
edmondlang 83c7d70551 check billplz failed callback 2023-03-29 23:29:05 +08:00
Dillon Ngo 20099c416f Merge branch 'dillon/debug-and-fixes-2' into 'master'
New merge request From dillon/debug-and-fixes-2 into master

See merge request CIEFWorldwideSdnBhd/shipping-portal!159
2023-03-29 13:35:13 +00:00
Dillon 03b26e2af9 Typo error a to quick fix for update a CRM project 2023-03-29 13:14:49 +08:00
Dillon Ngo eb399dcbae Merge branch 'dillon/debug-and-fixes-2' into 'master'
New merge request From dillon/debug-and-fixes-2 into master

See merge request CIEFWorldwideSdnBhd/shipping-portal!158
2023-03-28 16:03:34 +00:00
Dillon d602200140 A quick fix 2023-03-29 00:01:48 +08:00
Dillon Ngo 84028b5ed7 Merge branch 'dillon/crm-create-task-3-26' into 'master'
New merge request From dillon/crm-create-task-3-26 into master

See merge request CIEFWorldwideSdnBhd/shipping-portal!157
2023-03-28 15:56:51 +00:00
Dillon 78ceb62dec Sync code fix from exchange 2023-03-28 23:35:49 +08:00
edmondlang 27190868b4 change company type 2023-03-28 16:15:07 +08:00
edmondlang b897b00703 change company type 2023-03-28 15:53:14 +08:00
DESKTOP-5I7S92L\nicho cd93deac26 change company type 2023-03-28 15:35:13 +08:00
edmondlang 0d0e147647 update dummy data seeder generate and approve invoice 2023-03-26 22:48:12 +08:00
edmondlang efba270ea5 update dummy seeder data - postcode 2023-03-26 21:50:14 +08:00
edmondlang 69da484b72 update dummy seeder data - state charges, so the invoice total wont be in 0 2023-03-26 21:37:54 +08:00
Dillon b25adef107 Fix another error from production logs 2023-03-25 14:20:38 +08:00
Dillon 329aa4b496 Minor cleanup 2023-03-25 02:17:51 +08:00
Dillon a05609081b minor code streamline 2023-03-24 15:15:05 +08:00
Dillon 9d442c8cc4 CRM Task with dynamic data 2023-03-24 03:14:57 +08:00
Dillon f5df1adff8 Fix a problem with new registration uploadin documentg 2023-03-23 04:31:35 +08:00
Dillon 119e58c1c9 Added new task, new task details such as priority and due date + some cleanup 2023-03-23 04:18:17 +08:00
Dillon b08ba3e716 Exchange - changes code sync 2023-03-22 22:19:31 +08:00
edmondlang 2169f09ffe billplz failed callback payment 2023-03-22 19:36:26 +08:00
edmondlang 1dfbc71302 billplz failed callback payment 2023-03-22 13:50:11 +08:00
edmondlang 57cdedbdd0 update billplz callback logic 2023-03-21 16:58:12 +08:00
edmondlang fea03de5bd audit billplz invoice 2023-03-21 13:08:05 +08:00
edmondlang 75babc9f38 audit billplz invoice 2023-03-21 13:03:27 +08:00
edmondlang a36f7123e8 audit billplz invoice 2023-03-21 12:56:53 +08:00
Dillon Ngo fad56e30dc Merge branch 'dillon/debug-and-fixes-1' into 'master'
Fix a problem in invoice where rounding issue cause an invoice that is fully...

See merge request CIEFWorldwideSdnBhd/shipping-portal!154
2023-03-20 14:17:04 +00:00
Dillon Ngo 6b56899004 Merge branch 'dillon/crm-invoice-update-23' into 'master'
Dillon/crm invoice update 23

See merge request CIEFWorldwideSdnBhd/shipping-portal!155
2023-03-20 14:16:13 +00:00
edmondlang 37444e6e30 update billing question display position 2023-03-20 18:05:29 +08:00
Dillon 32591273f8 Fix a problem in invoice where rounding issue cause an invoice that is fully paid to appear partially paid 2023-03-19 22:21:10 +08:00
Dillon f73b1d7fe3 Fix a problem at CRM where downloading of invoice in PDF throws errors 2023-03-19 22:20:49 +08:00
Dillon 0d4f7e0ed5 Another attempt to fix an error where invoice created at crm has no project id 2023-03-19 17:34:34 +08:00
Dillon 9786198ca2 Fix Error: BadMethodCallException: Call to undefined method 2023-03-19 16:31:30 +08:00
Dillon 76a9af2dc8 Fix a problem of a mismatch in data update for invoice 2023-03-19 04:50:12 +08:00
Dillon 3dcf3cff10 Update CRM invoice due date 2023-03-19 04:29:50 +08:00
Dillon Ngo 37da620927 Merge branch 'dillon/debug-and-fixes-1' into 'master'
Insert logs for debugging

See merge request CIEFWorldwideSdnBhd/shipping-portal!153
2023-03-18 08:28:57 +00:00
Dillon 64ec76eed6 Insert logs for debugging 2023-03-17 17:28:18 +08:00
edmondlang ef3c738fb1 debug billplz payment 2023-03-15 19:58:05 +08:00
edmondlang 92b6e6dc3a debug billplz payment 2023-03-15 19:48:48 +08:00
Dillon Ngo 0d330447eb Merge branch 'dillon/crm-tasks-department' into 'master'
CRM add department custom field to tasks

See merge request CIEFWorldwideSdnBhd/shipping-portal!152
2023-03-14 12:41:49 +00:00
Omair Saleh daeb376aa5 billplz audit 2023-03-13 16:05:41 +08:00
Omair Saleh f4d81cbde9 Merge remote-tracking branch 'origin/master' 2023-03-13 16:03:18 +08:00
Omair Saleh 0fd3584af2 billplz audit 2023-03-13 16:03:05 +08:00
edmondlang a2f70f266d billplz audit 2023-03-13 06:57:19 +08:00
Omair Saleh 432ce2d14a billplz audit 2023-03-13 01:42:14 +08:00
edmondlang 715384f4a4 audit billplz 2023-03-13 00:42:44 +08:00
edmondlang 8277b9d0fd fix bug unsuccessfull payment can went through 2023-03-13 00:32:59 +08:00
Dillon 4769541535 CRM add department custom field to tasks 2023-03-12 17:37:49 +08:00
Dillon Ngo fe8b6d0518 Merge branch 'dillon/crm-create-task-2' into 'master'
Add in missing update project function

See merge request CIEFWorldwideSdnBhd/shipping-portal!151
2023-03-11 11:45:11 +00:00
Dillon 5934fbcb6c Add in missing update project function 2023-03-11 19:43:30 +08:00
Dillon Ngo c078a879d2 Merge branch 'dillon/crm-feed-improvement-1' into 'master'
Dillon/crm feed improvement 1

See merge request CIEFWorldwideSdnBhd/shipping-portal!150
2023-03-11 08:56:40 +00:00
Dillon Ngo c58f2e55d7 Merge branch 'dillon/crm-create-task-2' into 'master'
Dillon/crm create task 2

See merge request CIEFWorldwideSdnBhd/shipping-portal!149
2023-03-11 08:56:25 +00:00
Dillon 45c94321b1 Fix a problem in invoice item where the amount cannot be 0 2023-03-11 16:32:49 +08:00
Dillon 4fbe771dce Fix a problem with task name in CRM must be unique 2023-03-10 21:12:43 +08:00
edmondlang 9f8ba5163c fix list admin user 2023-03-10 19:23:01 +08:00
Dillon b06cef4045 Feedback from user on crm leads registration 2023-03-10 17:58:13 +08:00
Dillon 1c072d7b96 CRM create all remaining tasks according to documentation 2023-03-10 02:41:41 +08:00
edmondlang eeb7bb77bb delete duplicated invoice 2023-03-09 12:46:00 +08:00
edmondlang 2de60c8262 test delete duplicated invoice 2023-03-09 12:44:36 +08:00
edmondlang c8a2ce71e1 test delete duplicated invoice 2023-03-09 12:39:28 +08:00
edmondlang 7e04580be0 update show duplicated invoice 2023-03-09 12:34:37 +08:00
edmondlang 3d15a8e312 delete duplicate invoice logic 2023-03-09 10:21:40 +08:00
edmondlang 9936e42574 update show duplicated invoice 2023-03-09 10:15:20 +08:00
edmondlang 16ffec01d4 fix missing invoices 2023-03-09 09:28:45 +08:00
edmondlang 7959f8c83c fix missing invoices 2023-03-08 22:02:03 +08:00
edmondlang 16b5660f12 fix duplicated packing list 2023-03-08 15:33:17 +08:00
edmondlang 023954db70 fix duplicated packing list 2023-03-08 14:32:10 +08:00
edmondlang 535b8a59b9 fix invoice drop date 2023-03-08 11:48:38 +08:00
omair saleh dc4d7004a3 Merge branch 'dillon/crm-create-invoice' into 'master'
Dillon/crm create invoice

See merge request CIEFWorldwideSdnBhd/shipping-portal!148
2023-03-07 15:16:46 +00:00
120 changed files with 4693 additions and 620 deletions
+4
View File
@@ -55,3 +55,7 @@ EXCHANGE_URL=https://dev.exchange.cief-malaysia.com/
MIX_EXCHANGE_URL="${EXCHANGE_URL}"
YD_API_CODE=''
PERFEXCRM_BASE_URL=""
PERFEXCRM_API_KEY=""
PERFEXCRM_IS_ENABLED="false"
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class AmountExceed implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('amount', '>', $value);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class AmountShort implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('amount', '<', $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
class CreatedBefore implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('created_at', '<', Carbon::parse($value));
}
}
@@ -15,7 +15,7 @@ class DoesNotHaveTransactionType implements Filter
public static function apply(Builder $builder, $value)
{
return $builder->whereDoesntHave('transactions', function (Builder $query) use($value) {
$query->where('type', $value);
$query->where('type', $value)->whereIn('status', [0,1,2,3]);
})->whereHas('containers', function ($query){
return $query->whereDate('loading_date', '>=', Carbon::parse('20-09-2022'));
});
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class EmailLike implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('email', 'LIKE', '%'.$value.'%');
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class PaymentMethod implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('payment_method', $value);
}
}
+9 -1
View File
@@ -3,6 +3,8 @@
namespace App\Classes\Jobs;
use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMLeadProcessor;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMLead;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMLead;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -28,6 +30,12 @@ class CreatePerfexCRMCustomer implements ShouldQueue
public function handle()
{
(App()->make(CreatePerfexCRMLeadProcessor::class))->execute($this->createLeadPerfexCRMObject);
$lead = (App()->make(FetchesPerfexCRMLead::class))->execute($this->createLeadPerfexCRMObject->getEmail());
if(!is_null($lead)){
(App()->make(UpdatesPerfexCRMLead::class))->execute($lead, $this->createLeadPerfexCRMObject->getCompanyReference());
}
else{
(App()->make(CreatePerfexCRMLeadProcessor::class))->execute($this->createLeadPerfexCRMObject);
}
}
}
-33
View File
@@ -1,33 +0,0 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\PerfexCRM\Processors\InitializePerfexCRMProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject;
class InitializePerfexCRM implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var InitialPerfexCRMObject */
private $initialPerfexCRMObject;
/**
* InitializePerfexCRM constructor.
* @param InitialPerfexCRMObject $initialPerfexCRMObject
*/
public function __construct(InitialPerfexCRMObject $initialPerfexCRMObject)
{
$this->initialPerfexCRMObject = $initialPerfexCRMObject;
}
public function handle()
{
(App()->make(InitializePerfexCRMProcessor::class))->execute($this->initialPerfexCRMObject);
}
}
+23 -2
View File
@@ -9,6 +9,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
class UpdatePerfexCRM implements ShouldQueue
{
@@ -17,17 +18,37 @@ class UpdatePerfexCRM implements ShouldQueue
/** @var UpdatePerfexCRMObject */
private $updatePerfexCRMObject;
/** @var UpdatePerfexCRMInvoice */
private $nextJob;
/** @var */
private $transaction;
/**
* UpdatePerfexCRM constructor.
* @param UpdatePerfexCRMObject $updatePerfexCRMObject
* @param UpdatePerfexCRMInvoice $nextJob
* @param $transaction
*/
public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject)
public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject, $transaction, $nextJob)
{
$this->updatePerfexCRMObject = $updatePerfexCRMObject;
$this->nextJob = $nextJob;
$this->transaction = $transaction;
}
public function handle()
{
(App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject);
$result = (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject);
if($this->nextJob != null && $this->transaction != null){
$updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject(
$this->updatePerfexCRMObject->getContactEmail(),
$result->projectId,
$this->transaction,
true
);
/** @var UpdatePerfexCRMInvoice $nextJob */
$this->nextJob::dispatch($updatePerfexCRMInvoiceOject);
}
}
}
+12 -13
View File
@@ -18,6 +18,8 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class UpdatePerfexCRMInvoice implements ShouldQueue
{
@@ -45,6 +47,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
$invoiceId = 0;
$invoiceStatus = 0;
$invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $transaction->owner->bill_no);
Log::error(json_encode('UpdatePerfexCRMInvoice debug $transaction->owner->bill_no: '.$transaction->owner->bill_no));
if(is_null($invoice)){
$result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner, $this->updatePerfexCRMInvoiceObject->getIsPaid());
@@ -56,20 +59,9 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
//This only run when invoice already exist and the invoice does not have a PAID status
if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){
//get project
$projectId = "";
if($transaction->owner instanceof Transaction){
$orderReference = $transaction->owner->owner->owner()->first()->reference;
$packingListReference = $transaction->owner->owner->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$project = (App()->make(FetchesPerfexCRMProject::class))->execute($projectName, $customer->userid);
if(!is_null($project)){
$projectId = $project->id;
}
}
Log::error(json_encode('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId()));
//update invoice
(App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $projectId);
(App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId());
}
}
@@ -89,4 +81,11 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
(App()->make(CreatesPerfexCRMInvoicePayment::class))->execute($invoicePaymentPerfexCRMObject);
}
}
public function delay($delay)
{
// Add delay in seconds to the job
$this->delay = $delay;
return $this;
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
use App\Models\PackingList;
use App\Models\Transaction;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class UpdatePerfexCRMPrelude implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var */
private $packingList;
/** @var */
private $transaction;
/** @var UpdatePerfexCRMObject */
private $updatePerfexCRMObject;
/** @var UpdatePerfexCRM */
private $nextJob1;
/** @var UpdatePerfexCRMInvoice */
private $nextJob2;
/**
* UpdatePerfexCRMPrelude constructor.
* @param $packingList
* @param $transaction
* @param UpdatePerfexCRMObject $updatePerfexCRMObject
* @param UpdatePerfexCRM $nextJob1
* @param UpdatePerfexCRMInvoice $nextJob2
*/
public function __construct($packingList, $transaction, UpdatePerfexCRMObject $updatePerfexCRMObject, $nextJob1, $nextJob2)
{
$this->packingList = $packingList;
$this->transaction = $transaction;
$this->updatePerfexCRMObject = $updatePerfexCRMObject;
$this->nextJob1 = $nextJob1;
$this->nextJob2 = $nextJob2;
}
public function handle()
{
if(is_null($this->packingList)){
$this->packingList = $this->transaction->owner->owner;
}
$amount = 0.00;
if(!is_null($this->transaction)){
$amount = $this->transaction->amount;
}
$data = [
'amount' => number_format($amount, 2, '.', ''),
'link_order' => config('app.url').'/order/show/'.$this->packingList->owner->reference,
'link_autocount_or' => 'https://docs.google.com/spreadsheets/d/1Q3rJBGQ9Bo04HZp5WR9zbLp7pIW2kfDYsabxG7JON-4/edit#gid=2013983170',
'link_perfex' => 'https://perfex.cief-malaysia.com/admin/projects/view/89',
];
$result = $this->replacePlaceholders($this->updatePerfexCRMObject->getTasks(), $data);
$this->updatePerfexCRMObject->setTasks($result);
/** @var UpdatePerfexCRM $nextJob1 */
/** @var UpdatePerfexCRMInvoice $nextJob2 */
$this->nextJob1::dispatch($this->updatePerfexCRMObject, $this->transaction, $this->nextJob2);
}
function replacePlaceholders($template, $data, $prefix = '')
{
foreach ($template as $key => $value) {
foreach ($data as $dataKey => $dataValue) {
if (is_array($dataValue)) {
$template[$key] = $this->replacePlaceholders($template[$key], $dataValue, $dataKey);
} else {
if ($prefix != '') {
$template[$key] = str_replace('{' .$prefix. "." .$dataKey . '}', $dataValue, $template[$key]);
} else {
$template[$key] = str_replace('{' . $dataKey . '}', $dataValue, $template[$key]);
}
}
}
}
return $template;
}
}
@@ -161,7 +161,8 @@ class CreateCustomerLogic extends AbstractControllerLogic
$request->input('name'),
$request->input('email'),
$request->input('phone'),
$request->input('type') === CompanyType::COMPANY_BUSINESS ? $request->input('company_name') : $request->input('name')
$request->input('type') === CompanyType::COMPANY_BUSINESS ? $request->input('company_name') : $request->input('name'),
$connection->invitee_reference
);
CreatePerfexCRMCustomer::dispatch($createLeadPerfexCRMObject);
}
@@ -4,7 +4,7 @@ namespace App\Classes\Modules\Accounts\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounts\Services\UpdatesUser;
use App\Classes\Modules\Accounts\Services\UpdatesUserFullName;
use App\Classes\Modules\Accounts\Services\FetchesUser;
use App\Classes\Modules\Accounts\Standards\Rules\CanUpdateUser;
use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject;
@@ -29,8 +29,8 @@ class UpdateUserLogic extends AbstractControllerLogic
/** @var CanUpdateUser */
private $canUpdateUser;
/** @var UpdatesUser */
private $updatesUser;
/** @var UpdatesUserFullName */
private $updatesUserFullName;
/** @var FetchesUser */
private $fetchesUser;
@@ -38,13 +38,13 @@ class UpdateUserLogic extends AbstractControllerLogic
/**
* UpdateAddressLogic constructor.
* @param CanUpdateUser $canUpdateUser
* @param UpdatesUser $updatesUser
* @param UpdatesUserFullName $updatesUserFullName
* @param FetchesUser $fetchesUSer
*/
public function __construct(CanUpdateUser $canUpdateUser, UpdatesUser $updatesUser, FetchesUser $fetchesUser)
public function __construct(CanUpdateUser $canUpdateUser, UpdatesUserFullName $updatesUserFullName, FetchesUser $fetchesUser)
{
$this->canUpdateUser = $canUpdateUser;
$this->updatesUser = $updatesUser;
$this->updatesUserFullName = $updatesUserFullName;
$this->fetchesUser = $fetchesUser;
}
@@ -64,7 +64,7 @@ class UpdateUserLogic extends AbstractControllerLogic
$query = $this->fetchesUser->execute(['id' => $request->route('id')]);
$query = $this->updatesUser->execute($query, $object);
$query = $this->updatesUserFullName->execute($query, $object);
return $this->resourceResponse(new UserResource($query));
@@ -0,0 +1,71 @@
<?php
namespace App\Classes\Modules\Accounts\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounts\Services\UpdatesUser;
use App\Classes\Modules\Accounts\Services\FetchesUser;
use App\Classes\Modules\Accounts\Standards\Rules\CanUpdateUser;
use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject;
use App\Classes\Modules\Accounts\DataTransferObjects\UserObject;
use App\Http\Resources\UserResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateUserRoleLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Admin Role',
'message' => 'You have successfully updated the Admin Role'
];
}
/** @var CanUpdateUser */
private $canUpdateUser;
/** @var UpdatesUser */
private $updatesUser;
/** @var FetchesUser */
private $fetchesUser;
/**
* UpdateAddressLogic constructor.
* @param CanUpdateUser $canUpdateUser
* @param UpdatesUser $updatesUser
* @param FetchesUser $fetchesUSer
*/
public function __construct(CanUpdateUser $canUpdateUser, UpdatesUser $updatesUser, FetchesUser $fetchesUser)
{
$this->canUpdateUser = $canUpdateUser;
$this->updatesUser = $updatesUser;
$this->fetchesUser = $fetchesUser;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$query = $this->fetchesUser->execute(['id' => $request->route('id')]);
$object = new UserObject($query->name, $request->input('type'));
$this->canUpdateUser->passes($object);
$query = $this->updatesUser->execute($query, $object);
return $this->resourceResponse(new UserResource($query));
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Classes\Modules\Accounts\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class UserObject implements DataTransferObject
{
/** @var string */
private $name;
/** @var int */
private $type;
/**
* FullNameObject constructor.
* @param string $name
*/
public function __construct(string $name, int $type)
{
$this->name = $name;
$this->type = $type;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return int
*/
public function getType(): int
{
return $this->type;
}
}
@@ -3,7 +3,7 @@
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject;
use App\Classes\Modules\Accounts\DataTransferObjects\UserObject;
use App\Models\User;
class UpdatesUser extends AbstractUpdateRecord
@@ -11,13 +11,14 @@ class UpdatesUser extends AbstractUpdateRecord
/**
* @param User $model
* @param FullNameObject $object
* @param UserObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(User $model, FullNameObject $object) {
public function execute(User $model, UserObject $object) {
$model->name = $object->getName();
$model->type = $object->getType();
return $this->handler($model);
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject;
use App\Models\User;
class UpdatesUserFullName extends AbstractUpdateRecord
{
/**
* @param User $model
* @param FullNameObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(User $model, FullNameObject $object) {
$model->name = $object->getName();
return $this->handler($model);
}
}
@@ -23,6 +23,7 @@ use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@@ -101,9 +102,11 @@ class CallbackBillplzLogic
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
$this->updatesTransactionStatus->execute($transaction, $status);
if(($invoice->amount - $transaction->amount) < 0.01) {
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if(($invoice->amount - $totalPaidAmount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
@@ -0,0 +1,69 @@
<?php
namespace App\Classes\Modules\Companies\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\UpdatesCompany;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Companies\Standards\Rules\CanUpdateCompany;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
use App\Http\Resources\CompanyResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyTypeLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Company Type',
'message' => 'You have successfully updated the Company Tyoe'
];
}
/** @var CanUpdateCompany */
private $canUpdateCompany;
/** @var UpdatesCompany */
private $updatesCompany;
/** @var FetchesCompany */
private $fetchesCompany;
/**
* UpdateCompanyControllersLogic constructor.
* @param CanUpdateCompany $canUpdateCompany
* @param UpdatesCompany $updatesCompany
* @param FetchesCompany $fetchesCompany
*/
public function __construct(CanUpdateCompany $canUpdateCompany, UpdatesCompany $updatesCompany, FetchesCompany $fetchesCompany)
{
$this->canUpdateCompany = $canUpdateCompany;
$this->updatesCompany = $updatesCompany;
$this->fetchesCompany = $fetchesCompany;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$query = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$object = new CompanyObject($query->name, $query->reference, $request->input('type'));
$this->canUpdateCompany->passes($object);
$query = $this->updatesCompany->execute($query, $object);
return $this->resourceResponse(new CompanyResource($query));
}
}
@@ -0,0 +1,69 @@
<?php
namespace App\Classes\Modules\Contacts\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Contacts\Services\UpdatesContact;
use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject;
use App\Classes\Modules\Contacts\Services\FetchesContact;
use App\Http\Resources\ContactResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateContactLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Contact',
'message' => 'You have successfully updated the Contact'
];
}
/** @var UpdatesContact */
private $updatesContact;
/** @var FetchesContact */
private $fetchesContact;
/**
* UpdateContactLogic constructor.
* @param UpdatesContact $updatesContact
* @param FetchesContact $fetchesContact
*/
public function __construct(UpdatesContact $updatesContact, FetchesContact $fetchesContact)
{
$this->updatesContact = $updatesContact;
$this->fetchesContact = $fetchesContact;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$object = new ContactObject(
$request->input('reference'),
$request->input('phone'),
$request->input('email'),
$request->input('wechat_id')
);
// $this->canUpdateContact->passes($object);
$query = $this->fetchesContact->execute(['id' => $request->route('id')]);
$query = $this->updatesContact->execute($query, $object);
return $this->resourceResponse(new ContactResource($query));
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Contacts\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Contact;
class FetchesContact extends AbstractFetchRecord
{
/** @var Contact */
private $repository;
/**
* FetchesContact constructor.
* @param Contact $repository
*/
public function __construct(Contact $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\Modules\Contacts\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject;
use App\Models\Contact;
class UpdatesContact extends AbstractUpdateRecord
{
/**
* @param Contact $model
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Contact $model, ContactObject $object)
{
$model->reference = $object->getReference();
$model->phone = $object->getPhone();
$model->email = $object->getEmail();
$model->wechat_id = $object->getWechatId();
return $this->handler($model);
}
}
@@ -7,6 +7,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Addresses\Services\FetchesAddress;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Companies\Services\FetchesCompanyModule;
use App\Classes\Modules\PerfexCRM\Processors\NewLeadTaskToPerfexCRMProcessor;
use App\Classes\Modules\Orders\Processors\CreateOrderProcessor;
use App\Classes\Modules\Orders\Services\GeneratesOrderNumber;
use App\Classes\ValueObjects\Constants\WarehouseReferences;
@@ -39,6 +40,8 @@ class CreateOrderLogic extends AbstractControllerLogic
/** @var GeneratesOrderNumber */
private $generatesOrderNumber;
/** @var NewLeadTaskToPerfexCRMProcessor */
private $newLeadTaskToPerfexCRMProcessor;
/**
* CreateOrderLogic constructor.
* @param FetchesCompany $fetchesCompany
@@ -46,22 +49,24 @@ class CreateOrderLogic extends AbstractControllerLogic
* @param CreateOrderProcessor $createOrderProcessor
* @param FetchesCompanyModule $fetchesCompanyModule
* @param GeneratesOrderNumber $generatesOrderNumber
* @param NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesAddress $fetchesAddress, CreateOrderProcessor $createOrderProcessor, FetchesCompanyModule $fetchesCompanyModule, GeneratesOrderNumber $generatesOrderNumber)
public function __construct(FetchesCompany $fetchesCompany, FetchesAddress $fetchesAddress, CreateOrderProcessor $createOrderProcessor, FetchesCompanyModule $fetchesCompanyModule, GeneratesOrderNumber $generatesOrderNumber, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesAddress = $fetchesAddress;
$this->createOrderProcessor = $createOrderProcessor;
$this->fetchesCompanyModule = $fetchesCompanyModule;
$this->generatesOrderNumber = $generatesOrderNumber;
$this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor;
}
public function logic(Request $request) : JsonResponse {
$company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]);
$address = $this->fetchesAddress->execute(['id' => $request->input('address_id')]);
$originWarehouse = $this->fetchesCompanyModule->execute(['id' => $request->input('warehouse_id')]);
@@ -76,6 +81,10 @@ class CreateOrderLogic extends AbstractControllerLogic
$order = $this->createOrderProcessor->execute($company, $originWarehouse, $address, $this->generatesOrderNumber->execute());
if(config('perfexcrm.is_enabled') == 'true'){
$this->newLeadTaskToPerfexCRMProcessor->execute($company);
}
return $this->resourceResponse(new OrderResource($order));
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Modules\Orders\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Orders\Standards\Rules\CanFetchOrder;
use App\Http\Resources\OrderV2Resource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchOrderV2Logic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Order',
'message' => 'You have successfully retrieved an order'
];
}
/** @var CanFetchOrder */
private $canFetchOrder;
/** @var FetchesOrder */
private $fetchesOrder;
/**
* FetchOrderLogic constructor.
* @param CanFetchOrder $canFetchOrder
* @param FetchesOrder $fetchesOrder
*/
public function __construct(CanFetchOrder $canFetchOrder, FetchesOrder $fetchesOrder)
{
$this->canFetchOrder = $canFetchOrder;
$this->fetchesOrder = $fetchesOrder;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
$this->canFetchOrder->passes();
$query = $this->fetchesOrder->execute(['reference' => $request->route('id'), 'with_packing_lists' => true]);
return $this->resourceResponse(new OrderV2Resource($query));
}
}
@@ -0,0 +1,81 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\DeletesPackingList;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\PackingLists\Services\Packages\FetchesPackage;
use App\Classes\Modules\PackingLists\Standards\Rules\CanDeletePackingList;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Models\PackingList;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeletePackingListByPackageIdLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Deleted PackingList',
'message' => 'You have successfully deleted a PackingList'
];
}
/** @var CanDeletePackingList */
private $canDeletePackingList;
/** @var DeletesPackingList */
private $deletesPackingList;
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var FetchesPackage */
private $fetchesPackage;
/**
* DeletePackingListByPackageIdLogic constructor.
* @param CanDeletePackingList $canDeletePackingList
* @param DeletesPackingList $deletesPackingList
* @param FetchesPackingList $fetchesPackingList
* @param FetchesPackage $fetchesPackage
*/
public function __construct(CanDeletePackingList $canDeletePackingList, DeletesPackingList $deletesPackingList, FetchesPackingList $fetchesPackingList, FetchesPackage $fetchesPackage)
{
$this->canDeletePackingList = $canDeletePackingList;
$this->deletesPackingList = $deletesPackingList;
$this->fetchesPackingList = $fetchesPackingList;
$this->fetchesPackage = $fetchesPackage;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$this->canDeletePackingList->passes();
$package = $this->fetchesPackage->execute(['id' => $request->route('id')]);
$packingList = $package->packingList;
$packingList = PackingList::where('reference', $packingList->reference)->get();
$childPackingList = PackingList::where('owner_type', PackingList::class)->whereIn('owner_id', $packingList->pluck('id'))->get();
$packingList->each->delete();
$childPackingList->each->delete();
return $this->response([]);
}
}
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\General\Interfaces\Packable;
use App\Classes\Modules\PerfexCRM\Processors\PackingListToPerfexCRMProcessor;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\Modules\PackingLists\Services\CreatesPackingList;
use App\Classes\Modules\PackingLists\Standards\Rules\CanCreatePackingList;
@@ -25,16 +26,20 @@ class CreatePackingListProcessor
/** @var CreatesPackingList */
private $createsPackingList;
/** @var PackingListToPerfexCRMProcessor */
private $packingListToPerfexCRMProcessor;
/**
* CreatePackingListProcessor constructor.
* @param CanCreatePackingList $canCreatePackingList
* @param CreatesPackingList $createsPackingList
* @param PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor
*/
public function __construct(CanCreatePackingList $canCreatePackingList, CreatesPackingList $createsPackingList)
public function __construct(CanCreatePackingList $canCreatePackingList, CreatesPackingList $createsPackingList, PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor)
{
$this->canCreatePackingList = $canCreatePackingList;
$this->createsPackingList = $createsPackingList;
$this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor;
}
/**
@@ -59,6 +64,10 @@ class CreatePackingListProcessor
$object = new PackingListObject($object->getReference().'_01', $appointee_id, $type, ApprovalStatus::PENDING_SUBMISSION);
$this->createsPackingList->execute($object, $packingList);
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList);
}
return $packingList;
}
@@ -19,13 +19,17 @@ class CreateLeadPerfexCRMObject implements DataTransferObject
/** @var string */
private $companyName;
public function __construct(string $name, string $email, string $phone, string $companyName)
/** @var string */
private $companyReference;
public function __construct(string $name, string $email, string $phone, string $companyName, string $companyReference)
{
$this->name = $name;
$this->email = $email;
$this->phone = $phone;
$this->companyName = $companyName;
$this->companyReference = $companyReference;
}
/**
@@ -60,4 +64,11 @@ class CreateLeadPerfexCRMObject implements DataTransferObject
return $this->companyName;
}
/**
* @return string
*/
public function getCompanyReference(): string
{
return $this->companyReference;
}
}
@@ -33,8 +33,16 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
/** @var string */
private $status;
/** @var string */
private $department;
public function __construct(string $email, string $name, string $description, string $leadId, string $projectId, string $milestoneId, string $reference, string $onTaskCompletion, string $status)
/** @var string */
private $priority;
/** @var string */
private $duedate;
public function __construct(string $email, string $name, string $description, string $leadId, string $projectId, string $milestoneId, string $reference, string $onTaskCompletion, string $status, string $department, string $priority, string $duedate)
{
$this->email = $email;
$this->name = $name;
@@ -45,6 +53,9 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
$this->reference = $reference;
$this->onTaskCompletion = $onTaskCompletion;
$this->status = $status;
$this->department = $department;
$this->priority = $priority;
$this->duedate = $duedate;
}
/**
@@ -124,4 +135,27 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
return $this->status;
}
/**
* @return string
*/
public function getDepartment(): string
{
return $this->department;
}
/**
* @return string
*/
public function getPriority(): string
{
return $this->priority;
}
/**
* @return string
*/
public function getDuedate(): string
{
return $this->duedate;
}
}
@@ -25,6 +25,9 @@ class InitialPerfexCRMObject implements DataTransferObject
/** @var string */
private $projectName;
/** @var int */
private $projectStatus;
/** @var array */
private $milestoneNames;
@@ -32,7 +35,7 @@ class InitialPerfexCRMObject implements DataTransferObject
private $taskNames;
public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, array $milestoneNames, array $taskNames)
public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $taskNames)
{
$this->companyName = $companyName;
@@ -41,6 +44,7 @@ class InitialPerfexCRMObject implements DataTransferObject
$this->contactEmail = $contactEmail;
$this->bookingMarking = $bookingMarking;
$this->projectName = $projectName;
$this->projectStatus = $projectStatus;
$this->milestoneNames = $milestoneNames;
$this->taskNames = $taskNames;
}
@@ -93,6 +97,14 @@ class InitialPerfexCRMObject implements DataTransferObject
return $this->projectName;
}
/**
* @return string
*/
public function getProjectStatus(): int
{
return $this->projectStatus;
}
/**
* @return array
*/
@@ -17,11 +17,15 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject
/** @var bool */
private $isPaid;
public function __construct(string $email, Transaction $transaction, bool $isPaid)
/** @var string */
private $projectId;
public function __construct(string $email, string $projectId, Transaction $transaction, bool $isPaid)
{
$this->email = $email;
$this->transaction = $transaction;
$this->isPaid = $isPaid;
$this->projectId = $projectId;
}
/**
@@ -32,6 +36,14 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject
return $this->email;
}
/**
* @return string
*/
public function getProjectId(): string
{
return $this->projectId;
}
/**
* @return Transaction
*/
@@ -13,6 +13,9 @@ class UpdatePerfexCRMObject implements DataTransferObject
/** @var string */
private $companyReference;
/** @var string */
private $contactName;
/** @var string */
private $contactEmail;
@@ -22,23 +25,28 @@ class UpdatePerfexCRMObject implements DataTransferObject
/** @var string */
private $projectName;
/** @var string */
private $milestoneName;
/** @var int */
private $projectStatus;
/** @var string */
private $taskName;
/** @var array */
private $milestoneNames;
/** @var array */
private $tasks;
public function __construct(string $companyName, string $companyReference, string $contactEmail, string $bookingMarking, string $projectName, string $milestoneName, string $taskName)
public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $tasks)
{
$this->companyName = $companyName;
$this->companyReference = $companyReference;
$this->contactName = $contactName;
$this->contactEmail = $contactEmail;
$this->bookingMarking = $bookingMarking;
$this->projectName = $projectName;
$this->milestoneName = $milestoneName;
$this->taskName = $taskName;
$this->projectStatus = $projectStatus;
$this->milestoneNames = $milestoneNames;
$this->tasks = $tasks;
}
/**
@@ -57,6 +65,14 @@ class UpdatePerfexCRMObject implements DataTransferObject
return $this->companyReference;
}
/**
* @return string
*/
public function getContactName(): string
{
return $this->contactName;
}
/**
* @return string
*/
@@ -82,19 +98,31 @@ class UpdatePerfexCRMObject implements DataTransferObject
}
/**
* @return string
* @return int
*/
public function getMilestoneName(): string
public function getProjectStatus(): int
{
return $this->milestoneName;
return $this->projectStatus;
}
/**
* @return string
* @return array
*/
public function getTaskName(): string
public function getMilestoneNames(): array
{
return $this->taskName;
return $this->milestoneNames;
}
/**
* @return array
*/
public function getTasks(): array
{
return $this->tasks;
}
public function setTasks($tasks)
{
$this->tasks = $tasks;
}
}
@@ -10,8 +10,11 @@ use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerProject;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Models\PackingList;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class CreatePerfexCRMInvoiceProcessor
{
@@ -28,6 +31,9 @@ class CreatePerfexCRMInvoiceProcessor
/** @var FetchesPerfexCRMProject */
private $fetchesPerfexCRMProject;
/** @var CreatesPerfexCRMCustomerProject */
private $createsPerfexCRMCustomerProject;
/**
* CreatePerfexCRMInvoiceProcessor constructor.
* @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice
@@ -35,12 +41,14 @@ class CreatePerfexCRMInvoiceProcessor
public function __construct(CreatesPerfexCRMInvoice $createsPerfexCRMInvoice,
CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment,
ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer,
FetchesPerfexCRMProject $fetchesPerfexCRMProject)
FetchesPerfexCRMProject $fetchesPerfexCRMProject,
CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject)
{
$this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice;
$this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment;
$this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer;
$this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject;
$this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject;
}
/**
@@ -60,8 +68,8 @@ class CreatePerfexCRMInvoiceProcessor
}
$date = Carbon::parse($transaction->created_at)->format('Y-m-d');
$dueDate = Carbon::parse($transaction->created_at)->format('Y-m-d');
$currency = 1; //cief TODO: To look into Malaysia and Chinese currency
$dueDate = Carbon::parse($transaction->created_at)->addDays(6)->startOfDay()->format('Y-m-d');
$currency = 1;
$subTotal = 0.00;
$total = 0.00;
@@ -72,12 +80,17 @@ class CreatePerfexCRMInvoiceProcessor
->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)
->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first();
$billingStreet = $billingStreet.$addresses->street_one;
$billingStreet = $billingStreet.$addresses->street_two.',';
$billingStreet = $billingStreet.$addresses->district()->first()->name.',';
$billingStreet = $billingStreet.$addresses->postcode;
$billingStreet = $billingStreet.$addresses->state()->first()->name.',';
$billingStreet = $billingStreet.$addresses->country()->first()->name;
if ($addresses !== null) {
$billingStreet = $billingStreet.$addresses->street_one;
$billingStreet = $billingStreet.$addresses->street_two.',';
$billingStreet = $billingStreet.$addresses->district()->first()->name.',';
$billingStreet = $billingStreet.$addresses->postcode;
$billingStreet = $billingStreet.$addresses->state()->first()->name.',';
$billingStreet = $billingStreet.$addresses->country()->first()->name;
}
else{
$billingStreet = "[Pending Billing Details by user]";
}
$allowedPaymentModes = [];
$invoiceItems = [];
@@ -92,15 +105,28 @@ class CreatePerfexCRMInvoiceProcessor
//get project
$projectId = ""; //Project only exist in CRM if the customer already made payment
$projectName = "";
if($isPaid){
if($transaction->owner instanceof PackingList){
$orderReference = $transaction->owner->owner->reference;
$packingListReference = $transaction->owner->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$project = (App()->make(FetchesPerfexCRMProject::class))->execute($projectName, $clientId);
if(!is_null($project)){
$projectId = $project->id;
$result = $this->fetchesPerfexCRMProject->execute($projectName, $clientId);
if(isset($result->payload)){
$project = $result->payload[0];
$projectId = $project['id'];
}
else{
$result = $this->createsPerfexCRMCustomerProject->execute($projectName, PerfexCRMProjectStatus::NOT_STARTED, $clientId);
if(isset($result->payload)){ //Here means project creation successful
$projectId = $result->payload['project_id'];
}
}
}
if($projectId == ""){
Log::error(json_encode('CreatePerfexCRMInvoiceProcessor debug: '.$projectName));
Log::error(json_encode($transaction->owner));
}
}
@@ -111,8 +137,7 @@ class CreatePerfexCRMInvoiceProcessor
$quantity = $transaction_detail->quantity;
$unitPrice = $transaction_detail->price;
$subTotal = $transaction_detail->amount;
$subTotal = $subTotal + $transaction_detail->amount;
//string $description, string $longDescription, int $qty, int $rate, int $order, string $unit
$invoiceSingleItem = new InvoiceSingleItemPerfexCRMObject(
@@ -33,7 +33,10 @@ class CreatePerfexCRMTaskProcessor
$createTaskPerfexCRMObject->getProjectId(),
$createTaskPerfexCRMObject->getReference(),
$createTaskPerfexCRMObject->getOnTaskCompletion(),
$createTaskPerfexCRMObject->getDepartment(),
$createTaskPerfexCRMObject->getStatus(),
$createTaskPerfexCRMObject->getPriority(),
$createTaskPerfexCRMObject->getDuedate()
);
return true;
}
@@ -1,192 +0,0 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\Services\ConvertsPerfexCRMLeadToCustomer;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerProject;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMMilestone;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMTask;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMMilestone;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMTask;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerContact;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\CustomerContactObject;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMMilestones;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Classes\ValueObjects\Constants\PerfexCRMStatus;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
class InitializePerfexCRMProcessor
{
/** @var ConvertsPerfexCRMLeadToCustomer */
private $convertsPerfexCRMLeadToCustomer;
/** @var CreatesPerfexCRMCustomerProject */
private $createsPerfexCRMCustomerProject;
/** @var CreatesPerfexCRMMilestone */
private $createsPerfexCRMMilestone;
/** @var CreatesPerfexCRMTask */
private $createsPerfexCRMTask;
/** @var FetchesPerfexCRMProject */
private $fetchesPerfexCRMProject;
/** @var FetchesPerfexCRMMilestone */
private $fetchesPerfexCRMMilestone;
/** @var FetchesPerfexCRMTask */
private $fetchesPerfexCRMTask;
/** @var CreatesPerfexCRMCustomer */
private $createsPerfexCRMCustomer;
/** @var CreatesPerfexCRMCustomerContact */
private $createsPerfexCRMCustomerContact;
/** @var UpdatesPerfexCRM */
private $updatePerfexCRM;
/** @var UpdatesPerfexCRMCustomer */
private $updatesPerfexCRMCustomer;
/**
* @param ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer
* @param CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject
* @param CreatesPerfexCRMMilestone $createsPerfexCRMMilestone
* @param CreatesPerfexCRMTask $createsPerfexCRMTask
* @param FetchesPerfexCRMProject $fetchesPerfexCRMProject
* @param FetchesPerfexCRMMilestone $fetchesPerfexCRMMilestone
* @param FetchesPerfexCRMTask $fetchesPerfexCRMTask
* @param CreatesPerfexCRMCustomer $createsPerfexCRMCustomer
* @param CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact
* @param UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer
*/
public function __construct(ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer,
CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject,
CreatesPerfexCRMMilestone $createsPerfexCRMMilestone,
CreatesPerfexCRMTask $createsPerfexCRMTask,
FetchesPerfexCRMProject $fetchesPerfexCRMProject,
FetchesPerfexCRMMilestone $fetchesPerfexCRMMilestone,
FetchesPerfexCRMTask $fetchesPerfexCRMTask,
CreatesPerfexCRMCustomer $createsPerfexCRMCustomer,
CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact,
UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer)
{
$this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer;
$this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject;
$this->createsPerfexCRMMilestone = $createsPerfexCRMMilestone;
$this->createsPerfexCRMTask = $createsPerfexCRMTask;
$this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject;
$this->fetchesPerfexCRMMilestone = $fetchesPerfexCRMMilestone;
$this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask;
$this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer;
$this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact;
$this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer;
}
/**
* @param InitialPerfexCRMObject $initialPerfexCRMObject
* @return null|object
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(InitialPerfexCRMObject $initialPerfexCRMObject) {
// Customer has to exist first before Project can appear under it
// Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer
$crmCompany = $initialPerfexCRMObject->getCompanyName();
$result = $this->convertsPerfexCRMLeadToCustomer->execute($initialPerfexCRMObject->getContactEmail());
if(isset($result->payload)){
$crmClientId = $result->payload['client_id'];
if (isset($result->payload['company'])) {
$crmCompany = $result->payload['company'];
}
}
else{
//if reach this point, this means this user is not a official customer nor is a lead in crm
//Create Customer has 2 parts: Create Company (client), Create Contact
$result = $this->createsPerfexCRMCustomer->execute($crmCompany);
if(is_null($result)){
$crmCompany = $crmCompany." 2";
$result = $this->createsPerfexCRMCustomer->execute($crmCompany);
}
$crmClientId = $result->payload['clientId'];
$customerContactObject = new CustomerContactObject(
$crmClientId,
$initialPerfexCRMObject->getContactName(),
$initialPerfexCRMObject->getContactName(),
$initialPerfexCRMObject->getContactEmail(),
"pU^T@sC#9Q",
"on",
"on"
);
$result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject);
}
//Update custom fields to identify company reference from exchange or shipping portal
$value_exists = false;
if (isset($result->payload['customfields'])) {
foreach ($result->payload['customfields'] as $element) {
if ($element['value'] === $initialPerfexCRMObject->getCompanyReference()) {
$value_exists = true;
break;
}
}
}
if(!$value_exists);
{
$result = $this->updatesPerfexCRMCustomer->execute($crmClientId, $crmCompany, $initialPerfexCRMObject->getCompanyReference());
}
// Get existing or create project, project has to exist first before milestone can appear under it
$result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId);
if(isset($result->payload)){ //Here means project creation successful
$projectId = $result->payload['project_id'];
}
else{
$projectId = $this->fetchesPerfexCRMProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId)->id;
}
if(!is_null($result)){
$tasks = $initialPerfexCRMObject->getTaskNames();
//Create tasks with milestone
for($count=0; $count < count($tasks); $count++) {
$milestoneId = 0; //By default milestoneId is 0, having this set at individual task is optional
if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined
{
// Get existing or create milestone, milestone has to exist first before task can appear under it
$result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count);
if(isset($result->payload)){
$milestoneId = $result->payload['milestone_id'];
}
else{
$milestone = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId);
$array = json_decode(json_encode($milestone), true);
$milestoneId = $array[0]['id'];
}
}
$taskStatus = PerfexCRMStatus::NOT_STARTED;
if($tasks[$count]['status'] != ''){
$taskStatus = $tasks[$count]['status'];
}
// Get existing or create task
$result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $taskStatus);
}
}
return true;
}
}
@@ -3,28 +3,37 @@
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateTaskPerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMStatus;
use App\Classes\Jobs\CreatePerfexCRMSingleTask;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskPriority;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Models\Company;
class NewLeadTaskToPerfexCRMProcessor
{
/**
* @param None
* @param Company $company
* @return true
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute()
public function execute(Company $company)
{
$companyModule = $company->companyModules()->first();
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
$createTaskPerfexCRMObject = new CreateTaskPerfexCRMObject(
"dillontest1@gmail.com",
"test is the name of the task",
"this is the description of the task",
$contactEmail,
PerfexCRMTasks::TASK_IDENTIFICATION_1['name'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['description'],
"",
"",
"",
"",
"",
PerfexCRMStatus::NOT_STARTED
PerfexCRMTasks::TASK_IDENTIFICATION_1['status'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['department'],
PerfexCRMTaskPriority::DEFAULT,
"0"
);
CreatePerfexCRMSingleTask::dispatch($createTaskPerfexCRMObject);
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Classes\Jobs\UpdatePerfexCRM;
use App\Classes\Jobs\UpdatePerfexCRMPrelude;
use App\Models\PackingList;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use Illuminate\Support\Facades\Log;
class PackingListToPerfexCRMProcessor
{
/**
* @param PackingList $packingList
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(PackingList $packingList)
{
try {
if($packingList->owner instanceof \App\Models\Order) {
$order = $packingList->owner;
$companyModule = $order->companyModule()->first();
$connection = $companyModule->inviters()->withPivot('invitee_reference')->first();
$companyName = $companyModule->name;
$companyReference = $connection ? $connection->pivot->invitee_reference:'';
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
$contactName = $employee->name;
$orderReference = $packingList->owner->reference;
$packingListReference = $packingList->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$updatePerfexCRMObject = new UpdatePerfexCRMObject(
$companyName,
$companyReference,
$contactName,
$contactEmail,
"",
$projectName,
PerfexCRMProjectStatus::NOT_STARTED,
[],
[
PerfexCRMTasks::TASK_LOADED_CONTAINER_1,
PerfexCRMTasks::TASK_LOADED_CONTAINER_2,
]
);
UpdatePerfexCRMPrelude::dispatch($packingList, null, $updatePerfexCRMObject, UpdatePerfexCRM::class, null);
}
} catch (\Exception $exception){
Log::error(json_encode('PackingListToPerfexCRMProcessor debug:'));
Log::error(json_encode($packingList));
Log::error($exception);
}
return true;
}
}
@@ -2,47 +2,19 @@
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\Processors\UpdatePerfexCRMProcessor;
use App\Classes\Modules\PerfexCRM\Processors\InitializePerfexCRMProcessor;
use App\Classes\Modules\PerfexCRM\Services\Init;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\ValueObjects\Constants\PerfexCRMMilestones;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Jobs\InitializePerfexCRM;
use App\Classes\Jobs\UpdatePerfexCRMInvoice;
use App\Classes\Jobs\UpdatePerfexCRM;
use App\Classes\Jobs\UpdatePerfexCRMPrelude;
use App\Classes\Jobs\CreatePerfexCRMInvoice;
use App\Models\Transaction;
use Illuminate\Support\Facades\Log;
class TransactionToPerfexCRMProcessor
{
/** @var FetchesCompany */
private $fetchesCompany;
/** @var UpdatePerfexCRMProcessor */
private $updatePerfexCRMProcessor;
/** @var InitializePerfexCRMProcessor */
private $initializePerfexCRMProcessor;
/**
* TransactionToPerfexCRMProcessor constructor.
* @param UpdatePerfexCRMProcessor $updatePerfexCRMProcessor
* @param InitializePerfexCRMProcessor $initializePerfexCRMProcessor
* @param FetchesCompany $fetchesCompany
*/
public function __construct(UpdatePerfexCRMProcessor $updatePerfexCRMProcessor, InitializePerfexCRMProcessor $initializePerfexCRMProcessor, FetchesCompany $fetchesCompany)
{
$this->updatePerfexCRMProcessor = $updatePerfexCRMProcessor;
$this->initializePerfexCRMProcessor = $initializePerfexCRMProcessor;
$this->fetchesCompany = $fetchesCompany;
}
/**
* @param Transaction $model
* @param int $status
@@ -51,49 +23,53 @@ class TransactionToPerfexCRMProcessor
*/
public function execute(Transaction $model, int $status)
{
if($model->owner instanceof \App\Models\Transaction && $status == ApprovalStatus::APPROVED){
//dd(json_encode($packingList->owner()->first()->companyModule()->first()->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference));
//dd(json_encode($model->owner->owner->owner()->first()->companyModule()->first()->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference));
$companyModule = $model->owner->owner->owner()->first()->companyModule()->first();
$companyName = $companyModule->name;
$companyReference = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
$contactName = $employee->name;
try
{
if($model->owner instanceof \App\Models\Transaction && $status == ApprovalStatus::APPROVED)
{
$packingList = $model->owner->owner;
$order = $packingList->owner()->first();
$companyModule = $order->companyModule()->first();
$companyName = $companyModule->name;
$companyReference = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
$contactName = $employee->name;
$orderReference = $model->owner->owner->owner()->first()->reference;
$packingListReference = $model->owner->owner->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$orderReference = $order->reference;
$packingListReference = $packingList->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$bookingMarking = $model->owner->owner->id."-".$model->owner->owner->owner->id;
$initialPerfexCRMObject = new InitialPerfexCRMObject(
$companyName,
$companyReference,
$contactName,
$contactEmail,
$bookingMarking,
$projectName,
[],
[
PerfexCRMTasks::TASK_1,
PerfexCRMTasks::TASK_POST_PAYMENT_1,
PerfexCRMTasks::TASK_POST_PAYMENT_2,
PerfexCRMTasks::TASK_POST_PAYMENT_3,
PerfexCRMTasks::TASK_POST_PAYMENT_4,
]
);
$bookingMarking = $packingList->id."-".$packingList->owner->id;
$updatePerfexCRMObject = new UpdatePerfexCRMObject(
$companyName,
$companyReference,
$contactName,
$contactEmail,
$bookingMarking,
$projectName,
PerfexCRMProjectStatus::IN_PROGRESS,
[],
[
PerfexCRMTasks::TASK_1,
PerfexCRMTasks::TASK_POST_PAYMENT_1,
PerfexCRMTasks::TASK_POST_PAYMENT_2,
PerfexCRMTasks::TASK_POST_PAYMENT_3,
PerfexCRMTasks::TASK_POST_PAYMENT_4,
]
);
//$this->initializePerfexCRMProcessor->execute($initialPerfexCRMObject);
InitializePerfexCRM::dispatch($initialPerfexCRMObject);
$updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject(
$contactEmail,
$model,
true
);
UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject);
UpdatePerfexCRMPrelude::dispatch(null, $model, $updatePerfexCRMObject, UpdatePerfexCRM::class, UpdatePerfexCRMInvoice::class);
}
else if($model->owner instanceof \App\Models\PackingList && $model->status == ApprovalStatus::PENDING_SUBMISSION && $status == ApprovalStatus::APPROVED)
{
CreatePerfexCRMInvoice::dispatch($model);
}
}
catch (\Exception $exception) {
Log::error('TransactionToPerfexCRMProcessor debug:');
Log::error($exception);
}
return true;
}
}
@@ -12,10 +12,13 @@ use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMTask;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerContact;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMTask;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\CustomerContactObject;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMStatus;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
@@ -52,8 +55,13 @@ class UpdatePerfexCRMProcessor
/** @var UpdatesPerfexCRMTask */
private $updatesPerfexCRMTask;
/** @var UpdatesPerfexCRMCustomer */
private $updatesPerfexCRMCustomer;
/**
/** @var UpdatesPerfexCRMProject */
private $updatesPerfexCRMProject;
/**
* @param ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer
* @param CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject
* @param CreatesPerfexCRMMilestone $createsPerfexCRMMilestone
@@ -64,17 +72,21 @@ class UpdatePerfexCRMProcessor
* @param CreatesPerfexCRMCustomer $createsPerfexCRMCustomer
* @param CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact
* @param UpdatesPerfexCRMTask $updatesPerfexCRMTask
* @param UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer
* @param UpdatesPerfexCRMProject $updatesPerfexCRMProject
*/
public function __construct(ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer,
CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject,
CreatesPerfexCRMMilestone $createsPerfexCRMMilestone,
CreatesPerfexCRMTask $createsPerfexCRMTask,
FetchesPerfexCRMProject $fetchesPerfexCRMProject,
FetchesPerfexCRMMilestone $fetchesPerfexCRMMilestone,
FetchesPerfexCRMTask $fetchesPerfexCRMTask,
CreatesPerfexCRMCustomer $createsPerfexCRMCustomer,
CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact,
UpdatesPerfexCRMTask $updatesPerfexCRMTask)
CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject,
CreatesPerfexCRMMilestone $createsPerfexCRMMilestone,
CreatesPerfexCRMTask $createsPerfexCRMTask,
FetchesPerfexCRMProject $fetchesPerfexCRMProject,
FetchesPerfexCRMMilestone $fetchesPerfexCRMMilestone,
FetchesPerfexCRMTask $fetchesPerfexCRMTask,
CreatesPerfexCRMCustomer $createsPerfexCRMCustomer,
CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact,
UpdatesPerfexCRMTask $updatesPerfexCRMTask,
UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer,
UpdatesPerfexCRMProject $updatesPerfexCRMProject)
{
$this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer;
$this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject;
@@ -86,54 +98,134 @@ class UpdatePerfexCRMProcessor
$this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer;
$this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact;
$this->updatesPerfexCRMTask = $updatesPerfexCRMTask;
}
$this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer;
$this->updatesPerfexCRMProject = $updatesPerfexCRMProject;
}
/**
* @param PerfexCRMObject $perfexCRMObject
* @param UpdatePerfexCRMObject $updatePerfexCRMObject
* @return null|object
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(UpdatePerfexCRMObject $updatePerfexCRMObject) {
public function execute(UpdatePerfexCRMObject $updatePerfexCRMObject) {
$projectId = "";
// Customer has to exist first before Project can appear under it
// Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer
$crmCompany = $updatePerfexCRMObject->getCompanyName();
$result = $this->convertsPerfexCRMLeadToCustomer->execute($updatePerfexCRMObject->getContactEmail());
if(isset($result->payload)){
$crmClientId = $result->payload['client_id'];
if (isset($result->payload['company'])) {
$crmCompany = $result->payload['company'];
}
}
else{
//if reach this point, this means this user is not a official customer nor is a lead in crm
//Create Customer has 2 parts: Create Company (client), Create Contact
$result = $this->createsPerfexCRMCustomer->execute($crmCompany);
if(is_null($result)){
$crmCompany = $crmCompany." 2";
$result = $this->createsPerfexCRMCustomer->execute($crmCompany);
}
$crmClientId = $result->payload['clientId'];
$customerContactObject = new CustomerContactObject(
$crmClientId,
$updatePerfexCRMObject->getContactName(),
$updatePerfexCRMObject->getContactName(),
$updatePerfexCRMObject->getContactEmail(),
"pU^T@sC#9Q",
"on",
"on"
);
$result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject);
}
//Update custom fields to identify company reference from exchange or shipping portal
$value_exists = false;
if (isset($result->payload['customfields'])) {
foreach ($result->payload['customfields'] as $element) {
if ($element['value'] === $updatePerfexCRMObject->getCompanyReference()) {
$value_exists = true;
break;
}
}
}
if(!$value_exists);
{
$result = $this->updatesPerfexCRMCustomer->execute($crmClientId, $crmCompany, $updatePerfexCRMObject->getCompanyReference());
}
// Get existing or create project, project has to exist first before milestone can appear under it
$result = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId);
// Customer has to exist first before Project can appear under it
// Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer
$result = $this->convertsPerfexCRMLeadToCustomer->execute($updatePerfexCRMObject->getContactEmail());
if(isset($result->payload)){
$crmClientId = $result->payload['client_id'];
$project = $result->payload[0];
$projectId = $project['id'];
//if the project status is anything but PerfexCRMProjectStatus::NOT_STARTED, update the project
if($updatePerfexCRMObject->getProjectStatus() != PerfexCRMProjectStatus::NOT_STARTED && $project['status'] == PerfexCRMProjectStatus::NOT_STARTED)
{
$this->updatesPerfexCRMProject->execute($project, $updatePerfexCRMObject->getProjectStatus());
}
}
else{
$result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $updatePerfexCRMObject->getProjectStatus(), $crmClientId);
if(isset($result->payload)){ //Here means project creation successful
$projectId = $result->payload['project_id'];
}
}
// Get existing or create project, project has to exist first before milestone can appear under it
$result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId);
if(isset($result->payload)){
$projectId = $result->payload['project_id'];
}
else{
$projectId = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId)->id;
}
// Get existing or create milestone, milestone has to exist first before task can appear under it
$result = $this->createsPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId);
if(isset($result->payload)){
$milestoneId = $result->payload['milestone_id'];
}
else{
$milestone = $this->fetchesPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId);
$array = json_decode(json_encode($milestone), true);
$milestoneId = $array[0]['id'];
}
$tasks = $updatePerfexCRMObject->getTasks();
if(count($tasks) > 0){
// Get existing or create task
$result = $this->createsPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId);
if(isset($result->payload)){
$taskId = $result->payload['task_id'];
}
else{
$taskId = $this->fetchesPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId)->id;
}
//Create tasks with milestone
for($count=0; $count < count($tasks); $count++) {
$milestoneId = 0; //By default milestoneId is 0, having this set at individual task is optional
if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined
{
// Get existing or create milestone, milestone has to exist first before task can appear under it
$result = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId);
if(isset($result->payload)){
$array = json_decode(json_encode($result->payload[0]), true);
$milestoneId = $array['id'];
}
else{
$result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count);
if(isset($result->payload)){
$milestoneId = $result->payload['milestone_id'];
}
}
}
$this->updatesPerfexCRMTask->execute($taskId, $updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId, PerfexCRMStatus::COMPLETED);
$taskStatus = PerfexCRMTaskStatus::NOT_STARTED;
if($tasks[$count]['status'] != ''){
$taskStatus = $tasks[$count]['status'];
}
return null;
}
// Get existing or create task
$result = $this->fetchesPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, 'project', $projectId);
if(isset($result->payload)){
break; //Breaking the rest of the tasks in array assuming that they are all created as a batch previously
//The following are code not needed at Shipping Portal, Exchange need certain task's status to be updated dynamically
// if($taskStatus != PerfexCRMTaskStatus::NOT_STARTED && $result->payload[0]['status'] == PerfexCRMTaskStatus::NOT_STARTED)
// {
// $task = $result->payload[0];
// $result = $this->updatesPerfexCRMTask->execute($task['id'], $task['name'], $task['milestone'], $task['rel_id'], $taskStatus, $task['startdate'], is_null($task['duedate']) ? '': $task['duedate']);
// }
}
else{
$result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $tasks[$count]['department'], $taskStatus, $tasks[$count]['priority'], $tasks[$count]['duedate']);
}
}
}
$payload = [];
$payload['projectId'] = $projectId;
return (object) $payload;
}
}
@@ -14,7 +14,7 @@ class CreatesPerfexCRMCustomerProject
* @return null|object
* @throws MalformedRequestException
*/
public function execute(string $projectName, string $clientId) {
public function execute(string $projectName, int $status, string $clientId) {
try{
$data = [
'name' => $projectName,
@@ -22,7 +22,7 @@ class CreatesPerfexCRMCustomerProject
'billing_type' => 1,
'clientid' => $clientId,
'start_date' => date('Y-m-d'),
'status' => 1
'status' => $status
];
$response = Http::asForm()->withHeaders([
@@ -16,14 +16,17 @@ class CreatesPerfexCRMInvoice
*/
public function execute(InvoicePerfexCRMObject $invoicePerfexCRMObject) {
try{
$subtotal = floor($invoicePerfexCRMObject->getSubTotal() * 100) / 100;
$total = floor($invoicePerfexCRMObject->getTotal() * 100) / 100;
$data = [
'clientid' => $invoicePerfexCRMObject->getClientId(),
'number' => $invoicePerfexCRMObject->getNumber(),
'date' => $invoicePerfexCRMObject->getDate(),
'duedate' => $invoicePerfexCRMObject->getDueDate(),
'currency' => $invoicePerfexCRMObject->getCurrency(),
'subtotal' => number_format($invoicePerfexCRMObject->getSubTotal(), 2, '.', ''),
'total' => number_format($invoicePerfexCRMObject->getTotal(), 2, '.', ''),
'subtotal' => number_format($subtotal, 2, '.', ''),
'total' => number_format($total, 2, '.', ''),
'billing_street' => $invoicePerfexCRMObject->getBillingStreet(),
'project_id' => $invoicePerfexCRMObject->getProjectId(),
'allowed_payment_modes[0]' => 1,
@@ -16,13 +16,20 @@ class CreatesPerfexCRMLead
*/
public function execute(CreateLeadPerfexCRMObject $createLeadPerfexCRMObject) {
try{
$custom_fields = [
"leads" => [
4 => $createLeadPerfexCRMObject->getCompanyReference()
]
];
$data = [
'name' => $createLeadPerfexCRMObject->getName(),
'email' => $createLeadPerfexCRMObject->getEmail(),
'phonenumber' => $createLeadPerfexCRMObject->getPhone(),
'company' => $createLeadPerfexCRMObject->getCompanyName(),
'source' => 2, //1: Exchange, 2: Shipping Portal
'status' => 2 //2: Lead, 1: Customer
'status' => 2, //2: Lead, 1: Customer
'custom_fields' => $custom_fields
];
$response = Http::asForm()->withHeaders([
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\PerfexCRM\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\PerfexCRMCustomFields;
class CreatesPerfexCRMTask
{
@@ -14,14 +15,26 @@ class CreatesPerfexCRMTask
* @param string $leadId
* @param string $milestoneId
* @param string $projectId
* @param string $reference, default: ''
* @param string $on_task_completion, default: ''
* @param string $status, default: 1
* @param string $reference
* @param string $on_task_completion
* @param string $department
* @param string $status
* @param string $priority
* @param string $duedate
* @return null|object
* @throws MalformedRequestException
*/
public function execute(string $taskName, string $taskDescription, string $leadId, string $milestoneId, string $projectId, string $reference = '', string $on_task_completion = '', string $status = "1") {
public function execute(string $taskName, string $taskDescription, string $leadId, string $milestoneId, string $projectId, string $reference, string $on_task_completion, string $department, string $status, string $priority, string $duedate) {
try{
$custom_fields = [];
if($department != ""){
$custom_fields = [
"tasks" => [
PerfexCRMCustomFields::TASKS_DEPARTMENT => $department
]
];
}
$data = [
'name' => $taskName,
'description' => $taskDescription,
@@ -32,7 +45,10 @@ class CreatesPerfexCRMTask
'status' => $status,
'is_system_created' => 1,
'reference' => $reference,
'on_task_completion' => $on_task_completion
'on_task_completion' => $on_task_completion,
'custom_fields' => $custom_fields,
'priority' => $priority,
'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')),
];
if($leadId != '') {
@@ -46,7 +62,10 @@ class CreatesPerfexCRMTask
'status' => $status,
'is_system_created' => 1,
'reference' => $reference,
'on_task_completion' => $on_task_completion
'on_task_completion' => $on_task_completion,
'custom_fields' => $custom_fields,
'priority' => $priority,
'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')),
];
}
@@ -16,9 +16,14 @@ class FetchesPerfexCRMMilestone
*/
public function execute(string $milestoneName, string $projectId) {
try{
$response = Http::withHeaders([
'authtoken' => config('perfexcrm.api_key'),])
->get(config('perfexcrm.base_url').'/api/milestones/bynameandprojectid/'.rawurlencode($milestoneName).'/'.$projectId);
$data = [
'name' => $milestoneName,
'project_id' => $projectId,
];
$response = Http::asForm()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->post(config('perfexcrm.base_url').'/api/milestones/bynameandprojectid', $data);
if($response->successful()){
$data = $response->json();
@@ -11,14 +11,27 @@ class FetchesPerfexCRMTask
/**
* @param string $taskName
* @param string $milestoneId
* @param string $relType
* @param string $relId
* @return null|object
* @throws MalformedRequestException
*/
public function execute(string $taskName, string $milestoneId) {
public function execute(string $taskName, string $milestoneId, string $relType, string $relId) {
try{
$response = Http::withHeaders([
'authtoken' => config('perfexcrm.api_key'),])
->get(config('perfexcrm.base_url').'/api/tasks/bynameandmilestoneid/'.rawurlencode($taskName).'/'.$milestoneId);
$data = [
'name' => $taskName,
'rel_type' => $relType,
'rel_id' => $relId,
];
if($milestoneId != '') {
$newItem = ['milestone' => $milestoneId ];
$data = array_merge($data, $newItem);
}
$response = Http::asForm()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->post(config('perfexcrm.base_url').'/api/tasks/customsearch', $data);
if($response->successful()){
$data = $response->json();
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\PerfexCRM\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\PerfexCRMCustomFields;
class UpdatesPerfexCRMCustomer
{
@@ -19,7 +20,7 @@ class UpdatesPerfexCRMCustomer
try{
$custom_fields = [
"customers" => [
2 => $companyReference
PerfexCRMCustomFields::CUSTOMERS_SHIPPING_PORTAL_REFERENCE => $companyReference
]
];
@@ -35,10 +35,13 @@ class UpdatesPerfexCRMInvoice
array_push($newInvoiceItems,$item);
}
$allowedPaymentModes = [];
array_push($allowedPaymentModes, 1, 2);
$data = [
'number' => $invoice->number,
'date' => $invoice->date,
'duedate' => $invoice->date,
'duedate' => $invoice->duedate,
'currency' => $invoice->currency,
'subtotal' => $invoice->subtotal,
'total' => $invoice->total,
@@ -46,7 +49,7 @@ class UpdatesPerfexCRMInvoice
'shipping_street' => $invoice->billing_street,
'project_id' => $projectId,
'items' => $newInvoiceItems,
'allowed_payment_modes' => $invoice->allowed_payment_modes,
'allowed_payment_modes' => $allowedPaymentModes,
];
$response = Http::asJson()->withHeaders([
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\PerfexCRMCustomFields;
class UpdatesPerfexCRMLead
{
/**
* @param $lead
* @param string $companyReference
* @return null|object
* @throws MalformedRequestException
*/
public function execute($lead, string $companyReference) {
try{
$custom_fields = [
"leads" => [
PerfexCRMCustomFields::LEADS_SHIPPING_PORTAL_REFERENCE => $companyReference
]
];
$data = [
'name' => $lead->name,
'email' => $lead->email,
'phonenumber' => $lead->phonenumber,
'company' => $lead->company,
'custom_fields' => $custom_fields,
'source' => $lead->source,
'status' => $lead->status,
];
$response = Http::asJson()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->put(config('perfexcrm.base_url').'/api/leads/'.$lead->id, $data);
if($response->successful()){
$data = $response->json();
return (object) $data;
}else{
Log::error($response);
return null;
}
}catch(\Exception $exception){
throw new MalformedRequestException('Unable to get correct response from Perfex CRM server: ' . $exception->getMessage());
}
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
class UpdatesPerfexCRMProject
{
/**
* @param $project
* @param int $status
* @return null|object
* @throws MalformedRequestException
*/
public function execute($project, int $status) {
try{
$data = [
'name' => $project['name'],
'clientid' => $project['clientid'],
// 'rel_type' => 'customer',
'billing_type' => 1,
'start_date' => $project['start_date'],
'status' => $status
];
$response = Http::asJson()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->put(config('perfexcrm.base_url').'/api/projects/'.$project['id'], $data);
if($response->successful()){
$data = $response->json();
return (object) $data;
}else{
Log::error($response);
return null;
}
}catch(\Exception $exception){
throw new MalformedRequestException('Unable to get correct response from Perfex CRM server: ' . $exception->getMessage());
}
}
}
@@ -5,17 +5,8 @@ namespace App\Classes\Modules\Segments\ControllersLogic;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\ConstantResource;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Classes\Modules\Segments\Services\UpdatesConstant;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\AddItemToConstantValueArray;
use App\Classes\Modules\Segments\Services\RemoveItemFromConstantValueArray;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Segments\Services\CreatesConstant;
use App\Classes\Modules\Segments\Processors\UpdatePostcodeSegmentProcessor;
class UpdateConstantPostcodeLogic extends AbstractControllerLogic
{
@@ -30,54 +21,17 @@ class UpdateConstantPostcodeLogic extends AbstractControllerLogic
];
}
/** @var CanUpdateConstant */
private $canUpdateConstant;
/** @var UpdatesConstant */
private $updatesConstant;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var FetchesConstant */
private $fetchesConstant;
/** @var AddItemToConstantValueArray */
private $addItemToConstantValueArray;
/** @var RemoveItemFromConstantValueArray */
private $removeItemFromConstantValueArray;
/** @var CreatesConstant */
private $createsConstant;
/** @var UpdatePostcodeSegmentProcessor */
private $updatePostcodeSegmentProcessor;
/**
* UpdateConstantLogic constructor.
* @param CanUpdateConstant $canUpdateConstant
* @param UpdatesConstant $updatesConstant
* @param FetchesSegment $fetchesSegment
* @param FetchesConstant $fetchesConstant
* @param AddItemToConstantValueArray $addItemToConstantValueArray
* @param CreatesConstant $createsConstant
* @param RemoveItemFromConstantValueArray $removeItemFromConstantValueArray
* @param UpdatePostcodeSegmentProcessor $updatePostcodeSegmentProcessor
*/
public function __construct(
CanUpdateConstant $canUpdateConstant,
UpdatesConstant $updatesConstant,
FetchesSegment $fetchesSegment,
FetchesConstant $fetchesConstant,
AddItemToConstantValueArray $addItemToConstantValueArray,
RemoveItemFromConstantValueArray $removeItemFromConstantValueArray,
CreatesConstant $createsConstant
)
UpdatePostcodeSegmentProcessor $updatePostcodeSegmentProcessor)
{
$this->canUpdateConstant = $canUpdateConstant;
$this->updatesConstant = $updatesConstant;
$this->fetchesSegment = $fetchesSegment;
$this->fetchesConstant = $fetchesConstant;
$this->addItemToConstantValueArray = $addItemToConstantValueArray;
$this->removeItemFromConstantValueArray = $removeItemFromConstantValueArray;
$this->createsConstant = $createsConstant;
$this->updatePostcodeSegmentProcessor = $updatePostcodeSegmentProcessor;
}
/**
* @param Request $request
@@ -88,44 +42,9 @@ class UpdateConstantPostcodeLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$segment = $this->fetchesSegment->execute(['id' => $request->route('id')]);
try {
$constant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $request->input('reference')]);
$constantValue = $this->addItemToConstantValueArray->execute($constant->value, $request->input('postcode'));
$object = new ConstantObject($request->input('reference'), $constantValue);
} catch (ResourceNotFoundException $exception){
$constantObject = [$request->input('postcode')];
$object = new ConstantObject(
$request->input('reference'),
$constantObject
);
$constant = $this->createsConstant->execute($segment, $object);
}
try {
// check if postcode exist in the opposite constant, and delete it
$oppositeConstant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $request->input('reference') == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE]);
$oppositeConstantValue = $this->removeItemFromConstantValueArray->execute($oppositeConstant->value, $request->input('postcode'));
$oppositeObject = new ConstantObject($request->input('reference') == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE, $oppositeConstantValue);
$this->updatesConstant->execute($oppositeConstant, $oppositeObject);
} catch (ResourceNotFoundException $exception){
// if opposite constant does not exist, do nothing
}
$constant = $this->updatesConstant->execute($constant, $object);
$constant = $this->updatePostcodeSegmentProcessor->execute($request->route('id'), $request->input('reference'), $request->input('postcode'));
return $this->resourceResponse(new ConstantResource($constant));
}
}
}
@@ -0,0 +1,122 @@
<?php
namespace App\Classes\Modules\Segments\Processors;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\ConstantResource;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Classes\Modules\Segments\Services\UpdatesConstant;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\AddItemToConstantValueArray;
use App\Classes\Modules\Segments\Services\RemoveItemFromConstantValueArray;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Segments\Services\CreatesConstant;
class UpdatePostcodeSegmentProcessor
{
/** @var CanUpdateConstant */
private $canUpdateConstant;
/** @var UpdatesConstant */
private $updatesConstant;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var FetchesConstant */
private $fetchesConstant;
/** @var AddItemToConstantValueArray */
private $addItemToConstantValueArray;
/** @var RemoveItemFromConstantValueArray */
private $removeItemFromConstantValueArray;
/** @var CreatesConstant */
private $createsConstant;
/**
* UpdatePostcodeSegmentProcessor constructor.
* @param CanUpdateConstant $canUpdateConstant
* @param UpdatesConstant $updatesConstant
* @param FetchesSegment $fetchesSegment
* @param FetchesConstant $fetchesConstant
* @param AddItemToConstantValueArray $addItemToConstantValueArray
* @param CreatesConstant $createsConstant
* @param RemoveItemFromConstantValueArray $removeItemFromConstantValueArray
*/
public function __construct(
CanUpdateConstant $canUpdateConstant,
UpdatesConstant $updatesConstant,
FetchesSegment $fetchesSegment,
FetchesConstant $fetchesConstant,
AddItemToConstantValueArray $addItemToConstantValueArray,
RemoveItemFromConstantValueArray $removeItemFromConstantValueArray,
CreatesConstant $createsConstant
)
{
$this->canUpdateConstant = $canUpdateConstant;
$this->updatesConstant = $updatesConstant;
$this->fetchesSegment = $fetchesSegment;
$this->fetchesConstant = $fetchesConstant;
$this->addItemToConstantValueArray = $addItemToConstantValueArray;
$this->removeItemFromConstantValueArray = $removeItemFromConstantValueArray;
$this->createsConstant = $createsConstant;
}
/**
* @param string $name
* @param int $companyModuleId
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function execute($segment_id, $reference, $postcode){
$segment = $this->fetchesSegment->execute(['id' => $segment_id]);
try {
$constant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $reference]);
$constantValue = $this->addItemToConstantValueArray->execute($constant->value, $postcode);
$object = new ConstantObject($reference, $constantValue);
} catch (ResourceNotFoundException $exception){
$constantObject = [$postcode];
$object = new ConstantObject(
$reference,
$constantObject
);
$constant = $this->createsConstant->execute($segment, $object);
}
try {
// check if postcode exist in the opposite constant, and delete it
$oppositeConstant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $reference == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE]);
$oppositeConstantValue = $this->removeItemFromConstantValueArray->execute($oppositeConstant->value, $postcode);
$oppositeObject = new ConstantObject($reference == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE, $oppositeConstantValue);
$this->updatesConstant->execute($oppositeConstant, $oppositeObject);
} catch (ResourceNotFoundException $exception){
// if opposite constant does not exist, do nothing
}
$constant = $this->updatesConstant->execute($constant, $object);
return $constant;
}
}
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeleteTransactionLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Delete Transaction',
'message' => 'You have successfully deleted the transaction'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/**
* SuspendTransactionLogic constructor.
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
}
public function logic(Request $request) : JsonResponse
{
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$transaction->delete();
return $this->response([]);
}
}
@@ -75,11 +75,6 @@ class ApproveShippingInvoiceTransactionProcessor
$user->notify(new InvoiceIssuedEmail($user, $packingList));
}
// update perfex crm
if(config('perfexcrm.is_enabled') == 'true'){
CreatePerfexCRMInvoice::dispatch($invoice_transaction);
}
return;
}
@@ -5,25 +5,19 @@ namespace App\Classes\Modules\Transactions\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Transaction;
use App\Classes\Modules\PerfexCRM\Processors\TransactionToPerfexCRMProcessor;
use App\Classes\Modules\PerfexCRM\Processors\NewLeadTaskToPerfexCRMProcessor;
class UpdatesTransactionStatus extends AbstractUpdateRecord
{
/** @var TransactionToPerfexCRMProcessor */
private $transactionToPerfexCRMProcessor;
/** @var NewLeadTaskToPerfexCRMProcessor */
private $newLeadTaskToPerfexCRMProcessor;
/**
* UpdatesTransactionStatus constructor.
* @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor
* @param NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor
*/
public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor)
public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor)
{
$this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor;
$this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor;
}
/**
@@ -34,11 +28,13 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord
*/
public function execute(Transaction $model, int $status)
{
if(config('perfexcrm.is_enabled') == 'true'){
$this->transactionToPerfexCRMProcessor->execute($model, $status);
// $this->newLeadTaskToPerfexCRMProcessor->execute();
}
$transaction = clone($model);
$model->status = $status;
return $this->handler($model);
$result = $this->handler($model);
if(config('perfexcrm.is_enabled') == 'true'){
$this->transactionToPerfexCRMProcessor->execute($transaction, $status);
}
return $result;
}
}
@@ -8,4 +8,9 @@ final class CompanyType {
public const COMPANY_BUSINESS = 1;
public const COMPANY_TYPE_ID = [
self::PERSONAL_BUSINESS => "Personal Business",
self::COMPANY_BUSINESS => "Company Business",
];
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class PerfexCRMCustomFields {
public const CUSTOMERS_EXCHANGE_REFERENCE = 1;
public const CUSTOMERS_SHIPPING_PORTAL_REFERENCE = 2;
public const LEADS_EXCHANGE_REFERENCE = 3;
public const LEADS_SHIPPING_PORTAL_REFERENCE = 4;
public const TICKETS_CUSTOM_TAGS = 5;
public const TASKS_DEPARTMENT = 6;
}
@@ -0,0 +1,16 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class PerfexCRMProjectStatus {
public const NOT_STARTED = 1;
public const IN_PROGRESS = 2;
public const ON_HOLD = 3;
public const FINISHED = 4;
public const CANCELLED = 5;
}
@@ -0,0 +1,17 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class PerfexCRMTaskPriority {
public const DEFAULT = 0;
public const LOW = 1;
public const MEDIUM = 2;
public const HIGH = 3;
public const URGENT = 4;
}
@@ -2,7 +2,7 @@
namespace App\Classes\ValueObjects\Constants;
final class PerfexCRMStatus {
final class PerfexCRMTaskStatus {
public const NOT_STARTED = 1;
@@ -11,7 +11,7 @@ final class PerfexCRMStatus {
public const TESTING = 3;
public const IN_PROGRESS = 4;
public const COMPLETED = 5;
}
@@ -4,13 +4,19 @@ namespace App\Classes\ValueObjects\Constants;
class PerfexCRMTasks
{
//IMPORTANT NOTE: TASK NAME MUST BE UNIQUE ACCORDING TO REL_TYPE
//e.g. rel_type: lead, project
public const TASK_1 = [
'name' => 'Customer Paid',
'description' => '',
'milestone' => 'MILESTONE 1 - Customer Paid',
'reference' => '',
'on_task_completion' => '',
'status' => PerfexCRMStatus::COMPLETED
'department' => '',
'status' => PerfexCRMTaskStatus::COMPLETED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
];
public const TASK_POST_PAYMENT_1 = [
@@ -26,22 +32,22 @@ class PerfexCRMTasks
'milestone' => '',
'reference' => 'TASK_POST_PAYMENT_1',
'on_task_completion' => 'TASK_POST_PAYMENT_2',
'status' => PerfexCRMStatus::IN_PROGRESS
'department' => 'Accounts',
'status' => PerfexCRMTaskStatus::IN_PROGRESS,
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 0
];
public const TASK_POST_PAYMENT_2 = [
'name' => 'Approve Payment',
'description' => '○ Purpose: To verify and approve the customer\'s payment on IZYIM<br>
Initial Status: Not Started<br>
○ Deadline:Same day<br>
○ Responsible department: Accounts<br>
○ Next step: Change the status of the Issue Shipping Autocount Invoice operation to "In Progress"<br>
○ Additional details: When the payment method is FPX or Wallet this task is performed automatically by the system.<br>
○ Dependencies: Map Transaction operation must be completed before this operation can begin.<br>
○ Outcomes: The payment will be approved in IZYIM, which will release the customers goods for delivery.<br>',
Amount To be Approve: RM {amount}<br>',
'milestone' => '',
'reference' => 'TASK_POST_PAYMENT_2',
'on_task_completion' => 'TASK_POST_PAYMENT_3',
'status' => ''
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 0
];
public const TASK_POST_PAYMENT_3 = [
'name' => 'Issue Shipping Autocount Invoince',
@@ -56,7 +62,23 @@ class PerfexCRMTasks
'milestone' => '',
'reference' => 'TASK_POST_PAYMENT_3',
'on_task_completion' => 'TASK_POST_PAYMENT_4',
'status' => ''
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::MEDIUM,
'duedate' => 1
];
public const TASK_POST_PAYMENT_3_1 = [
'name' => 'Issue Shipping Autocount OR',
'description' => '○ Purpose: To issue an invoice for the customer\'s payment in accounting software.<br>
○ Note: Customer Actually Upload Bank Slip or Not, If not, Invoice Will Not be Exported<br>
○ {link_autocount_or}<br>',
'milestone' => '',
'reference' => 'TASK_POST_PAYMENT_3_1',
'on_task_completion' => 'TASK_POST_PAYMENT_4',
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
];
public const TASK_POST_PAYMENT_4 = [
'name' => 'Knockoff Invoice',
@@ -71,6 +93,55 @@ class PerfexCRMTasks
'milestone' => '',
'reference' => 'TASK_POST_PAYMENT_4',
'on_task_completion' => '',
'status' => ''
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::MEDIUM,
'duedate' => 1
];
public const TASK_LOADED_CONTAINER_1 = [
'name' => 'Generate Shipping Invoices',
'description' => '○ Purpose: -<br>
○ Link to order page: {link_order}<br>',
'milestone' => '',
'reference' => 'TASK_LOADED_CONTAINER_1',
'on_task_completion' => 'TASK_LOADED_CONTAINER_2',
'department' => 'Operations',
'status' => PerfexCRMTaskStatus::IN_PROGRESS,
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 1
];
public const TASK_LOADED_CONTAINER_2 = [
'name' => 'Approve Shipping Invoices',
'description' => '○ Purpose: -<br>
○ Link to refer Pay On Behalf or Any extra charge: : {link_perfex}<br>',
'milestone' => '',
'reference' => 'TASK_LOADED_CONTAINER_2',
'on_task_completion' => '',
'department' => 'Customer Services',
'status' => '',
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 1
];
public const TASK_IDENTIFICATION_1 = [
'name' => 'Approve Identification Verification (Shipping)',
'description' => '○ Purpose: To ensure the customer submit information matches the information in their identification document.<br>
○ Initial Status: In Progress<br>
○ Deadline: Same Day<br>
○ Responsible department: Operation<br>
○ Next step: None<br>
○ Additional details: ** Any specific requirements or notes for the operation.**<br>
○ Dependencies: None<br>
○ Outcomes: Customer account identification is verified<br>',
'milestone' => '',
'reference' => 'TASK_IDENTIFICATION_1',
'on_task_completion' => '',
'department' => 'Operations',
'status' => PerfexCRMTaskStatus::IN_PROGRESS,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
];
}
@@ -16,4 +16,10 @@ final class RoleTypes
public const USER = 3;
public const USER_TYPE_ID = [
self::SHADOW_ADMIN => "Shadow Admin",
self::SUPER_ADMIN => "Super Admin",
self::ADMIN => "Admin",
self::USER => "User",
];
}
@@ -27,4 +27,9 @@ final class TransactionType {
// public const SHIPPING_COST = 9;
public const TRANSACTION_TYPE_ID = [
self::SHIPPING_INVOICE => "Shipping Invoice",
self::PAYMENT => "Payment",
];
}
@@ -0,0 +1,75 @@
<?php
namespace App\Console\Commands;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class AuditBillplzInvoice extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billplz-invoice:audit';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all unpaid invoice but marked paid at our system';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Audit Billplz Invoice cron started.');
$start = new Carbon();
$transactions = Transaction::where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::COMPLETED)->whereHas('transactions', function($query){
return $query->where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->where('status', ApprovalStatus::REJECTED);
})->get();
$totalTransactions = count($transactions);
$counter = 1;
$totalAmount = 0;
foreach ($transactions as $transaction){
$payment_transaction = $transaction->transactions->sortByDesc('created_at')->first();
if ($payment_transaction->status === ApprovalStatus::REJECTED) {
$this->info($counter . ' of ' . $totalTransactions . '. Order Marking: '. $payment_transaction->owner->owner->owner->reference . '. Transaction Id: '. $payment_transaction->id . '. Invoice Id: '. $transaction->id . ' - Date: '.$payment_transaction->created_at->format('d-m-Y').' - Amount: '. $payment_transaction->amount);
$totalAmount += $transaction->amount;
$counter++;
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Audit Billplz. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
@@ -0,0 +1,77 @@
<?php
namespace App\Console\Commands;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class AuditBillplzPayment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billplz-payment:audit';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all failed payment in billplz, but marked at success at our system';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Audit Billplz Payment cron started.');
$start = new Carbon();
$transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->get();
$totalTransactions = count($transactions);
$counter = 1;
$totalAmount = 0;
foreach ($transactions as $transaction){
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference);
if($response->successful()){
$data = $response->json();
if($data['paid']){
} else {
$totalAmount += $transaction->amount;
$this->info($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount);
}
}else{
$this->info("billplz error</br>");
}
$counter++;
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Audit Billplz. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
@@ -0,0 +1,86 @@
<?php
namespace App\Console\Commands;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Http;
class CheckDeletedInvoiceButPaid extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'check-deleted-paid-invoice';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all deleted invoice but has completed payment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Start Check all deleted invoice but has completed payment.');
$start = new Carbon();
$totalAmount = 0;
$softDeletedTransactions = Transaction::onlyTrashed()->where('type', TransactionType::SHIPPING_INVOICE)->whereHas('transactions', function (Builder $query) {
$query->where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY);
})->get();
foreach ($softDeletedTransactions as $invoice) {
$invoice_payments = $invoice->transactions()->payments()->get();
foreach($invoice_payments as $invoice_payment) {
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$invoice_payment->payment_reference);
if($response->successful()){
$data = $response->json();
$orderReference = $invoice->owner->owner->reference ?? null;
if($data['paid']){
$this->info('Invoice id: ' . $invoice->id. '. Payment id: ' . $invoice_payment->id . '. Order: ' . $orderReference);
} else {
}
}else{
$this->info("billplz error</br>");
}
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Check all deleted invoice but has completed payment. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
@@ -0,0 +1,185 @@
<?php
namespace App\Console\Commands;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class FixBillplzFailedCallbackPayment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billplz-failed-callback:fix';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all failled callback from billplz';
protected $output = null;
protected $outputArray = [];
/** @var GetBillplzBill */
private $getBillplzBill;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor ;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
{
parent::__construct();
$this->getBillplzBill = $getBillplzBill;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Billplz Failled Callback cron started.');
$this->outputArray = [];
$start = new Carbon();
$approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;
$transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
$totalTransactions = count($transactions);
$counter = 1;
$totalAmount = 0;
foreach ($transactions as $transaction){
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference);
if($response->successful()){
$data = $response->json();
if($data['paid']){
$totalAmount += $transaction->amount;
$invoiceStatus = null;
switch($transaction->owner->status) {
case 3:
$invoiceStatus = 'Payment Completed';
break;
case 5:
$invoiceStatus = 'Dispute in progress';
break;
case 6:
$invoiceStatus = 'Cancelled Invoice';
break;
default:
$invoiceStatus = 'Pending Payment';
}
$order = $transaction->owner->owner->owner;
if (in_array($invoiceStatus , ['Pending Payment', 'Payment Completed'])) {
// code here
// $billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId());
// if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.');
// $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]);
$invoice = $transaction->owner;
$packingList = $invoice->owner;
$order = $packingList->owner;
$status = ApprovalStatus::PENDING_VERIFICATION;
if($data['state'] === 'paid') {
$status = ApprovalStatus::APPROVED;
}
// if($data->state === 'due') {
// $status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
// }
// $token = Auth::fromUser(User::find(1));
// $request->headers->set('Authorization', 'Bearer '.$token);
$this->updatesTransactionStatus->execute($transaction, $status);
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if(($invoice->amount - $totalPaidAmount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
$this->info('Updated invoice ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
} else {
$this->info('Failed to update invoice due to unsufficeint payment ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
}
} else {
if(!$order instanceof Order) {
$this->info("Error transaction id:" . $transaction->id . 'Type: ' . get_class($order));
} else {
$this->info($counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
}
}
} else {
// $totalAmount += $transaction->amount;
// $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount);
}
}else{
$this->info("billplz error</br>");
}
$counter++;
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
@@ -0,0 +1,69 @@
<?php
namespace App\Console\Commands;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class ShowBillplzPaymentStatus extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billplz-payment-status {billplz_id}` ';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show Billplz payment status';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Show Billplz payment status started.');
$start = new Carbon();
$billplz_id = $this->argument('billplz_id');
$billplz_id = explode(",", $billplz_id);
foreach ($billplz_id as $payment) {
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$payment);
if($response->successful()){
$data = $response->json();
dump($data);
}else{
$this->info("billplz error</br>");
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Showing Billplz payment status. ElapsedTime: ' . $elapsedTime);
}
}
@@ -0,0 +1,136 @@
<?php
namespace App\Console\Commands;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class ShowFixBillplzFailedCallbackPayment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billplz-failed-callback:show';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all failled callback from billplz';
protected $output = null;
protected $outputArray = [];
/** @var GetBillplzBill */
private $getBillplzBill;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor ;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
{
parent::__construct();
$this->getBillplzBill = $getBillplzBill;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Billplz Failled Callback cron started.');
$this->outputArray = [];
$start = new Carbon();
$approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;
$transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
$totalTransactions = count($transactions);
$counter = 1;
$totalAmount = 0;
foreach ($transactions as $transaction){
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference);
if($response->successful()){
$data = $response->json();
if($data['paid']){
$totalAmount += $transaction->amount;
$invoiceStatus = null;
switch($transaction->owner->status) {
case 3:
$invoiceStatus = 'Payment Completed';
break;
case 5:
$invoiceStatus = 'Dispute in progress';
break;
case 6:
$invoiceStatus = 'Cancelled Invoice';
break;
default:
$invoiceStatus = 'Pending Payment';
}
$order = $transaction->owner->owner->owner;
if(!$order instanceof Order) {
$this->info("Error transaction id:" . $transaction->id . 'Type: ' . get_class($order));
} else {
$this->info($counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
}
} else {
// $totalAmount += $transaction->amount;
// $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount);
}
}else{
$this->info("billplz error</br>");
}
$counter++;
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
@@ -0,0 +1,138 @@
<?php
namespace App\Console\Commands;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Http;
class SuccessUpdatePaymentStatusButFailedCallback extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fix-invoice-status';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Success Updated Payment Status But Inoie stat';
protected $output = null;
protected $outputArray = [];
/** @var GetBillplzBill */
private $getBillplzBill;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor ;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
{
parent::__construct();
$this->getBillplzBill = $getBillplzBill;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ' : Billplz Failled Callback cron started.');
$this->outputArray = [];
$start = new Carbon();
$approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;
$transactions = Transaction::where('type', TransactionType::PAYMENT)
->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->get();
foreach ($transactions as $payment) {
$invoice = $payment->owner ?? null;
if (!$invoice) {
$this->info('Payment has no owner. Payment ID: ' . $payment->id);
continue;
}
$packingList = $invoice->owner ?? null;
if (!$packingList) {
$this->info('Invoice has no owner. Invoice ID: ' . $invoice->id);
continue;
}
$order = $packingList->owner;
if (!$invoice) {
$this->info('PackingList has no owner. PackingList ID: ' . $packingList->id);
continue;
}
if ($invoice->status == ApprovalStatus::APPROVED) {
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if(($invoice->amount - $totalPaidAmount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
dump('Updated invoice ' . $invoice->id . '. Order: '. $order->reference);
} else {
$this->info('Failed Update invoice ' . $invoice->id . ' because payment not enough. Invoice Amount: ' . $invoice->amount . ' . Paid Amount: ' . $totalPaidAmount . ' . Order: '. $order->reference);
}
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime );
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\Accounts;
use App\Classes\Modules\Accounts\ControllersLogic\UpdateUserRoleLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateUserRoleController
{
/**
* @param Request $request
* @param UpdateUserLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateUserRoleLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Companies;
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyTypeLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyTypeController
{
/**
* @param Request $request
* @param AddNewMemberLogic $execute
* @return JsonResponse
*/
public function create(Request $request, UpdateCompanyTypeLogic $execute) : JsonResponse
{
return $execute->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Contacts;
use App\Classes\Modules\Contacts\ControllersLogic\UpdateContactLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateContactController
{
/**
* @param Request $request
* @param UpdateCompanyLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateContactLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Orders;
use App\Classes\Modules\Orders\ControllersLogic\FetchOrderV2Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchOrderV2Controller
{
/**
* @param Request $request
* @param FetchOrderLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, FetchOrderV2Logic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists;
use App\Classes\Modules\PackingLists\ControllersLogic\DeletePackingListByPackageIdLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeletePackingListByPackageIdController
{
/**
* @param Request $request
* @param DeletePackingListLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, DeletePackingListByPackageIdLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\DeleteTransactionLogic;
class DeleteTransactionController
{
/**
* @param Request $request
* @param DeleteTransactionLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, DeleteTransactionLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+7 -1
View File
@@ -44,6 +44,11 @@ class Kernel extends HttpKernel
'throttle:300,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'apipub' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
@@ -63,6 +68,7 @@ class Kernel extends HttpKernel
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'valid.token' => ValidateToken::class
'valid.token' => ValidateToken::class,
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
];
}
@@ -0,0 +1,56 @@
<?php
namespace App\Http\Middleware;
use App\Models\PersonalAccessTokens;
use Closure;
use Illuminate\Http\Request;
class TokenCheckerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
//Method 1: Token pass via query parameter
// Check if the api_key query parameter is present
if (!$request->query('api-key')) {
return response()->json(['message' => 'Invalid API key.'], 401);
}
// Check if the api_key is valid
$apiKey = $request->query('api-key');
$personalAccessToken = PersonalAccessTokens::where('token', $apiKey)->first();
if (!$personalAccessToken) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $next($request);
//Method 2: Token pass via request header
/*
$authHeader = $request->header('Authorization');
if (preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
$token = $matches[1];
// validate the token here
$personalAccessToken = PersonalAccessToken::where('token', $token)->first();
if (!$personalAccessToken) {
return response()->json(['error' => 'Unauthorized'], 401);
}
// if the token is valid, you can attach it to the request
$request->attributes->add(['bearerToken' => $token]);
return $next($request);
}
return response()->json(['error' => 'Unauthorized'], 401);
*/
}
}
@@ -49,6 +49,7 @@ class CompanyModuleResource extends JsonResource
'marking' => $marking,
'warehouseCharges' => array_key_exists($this->id, $segmentConstant) ? $segmentConstant[$this->id] : null,
'connections' => $this->connections,
'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())),
];
}
+4
View File
@@ -4,6 +4,7 @@ namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\CompanyType;
use App\Classes\ValueObjects\Constants\DocumentType;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Crypt;
@@ -19,6 +20,8 @@ class CompanyResource extends JsonResource
public function toArray($request)
{
$companyModule = $this->companyModules()->first();
$companyTypeArray = CompanyType::COMPANY_TYPE_ID;
return [
'id' => $this->id,
'hash_id' => Crypt::encryptString($this->id),
@@ -26,6 +29,7 @@ class CompanyResource extends JsonResource
'debtor' => $this->debtor,
'reference' => $this->reference,
'type' => (int) $this->type,
'type_name' => ($companyTypeArray[(int) $this->type]),
'business_type' => (int) $this->business_type,
'status' => (int) $this->status,
'segments' => SegmentResource::collection($companyModule->connections()->first()->segments),
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class OrderV2Resource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'reference' => $this->reference,
'reference_contract' => (int) $this->type,
'type' => (int) $this->type,
'status' => (int) $this->status,
'company_module' => new CompanyModuleResource($this->companyModule),
'warehouse' => new CompanyModuleResource($this->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee),
'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()),
'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()),
'invoices' => $this->whenLoaded('packingLists', function() {
return TransactionResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->get());
}),
'remarks' => RemarkResource::collection($this->remarks),
'created_at' => $this->created_at->format('d-m-Y')
];
}
}
+3
View File
@@ -2,6 +2,7 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
@@ -14,11 +15,13 @@ class UserResource extends JsonResource
*/
public function toArray($request)
{
$userTypeArray = RoleTypes::USER_TYPE_ID;
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'type' => (int) $this->type,
'type_name' => ($userTypeArray[(int) $this->type]),
'status' => (int) $this->status
];
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace App\Models;
class PersonalAccessTokens extends AbstractModel
{
protected $table = 'personal_access_tokens';
}
+5
View File
@@ -43,6 +43,11 @@ class RouteServiceProvider extends ServiceProvider
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::prefix('public/api')
->middleware('apipub')
->namespace($this->namespace)
->group(base_path('routes/apipub.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
// $table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}
+30
View File
@@ -46,19 +46,23 @@ use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Classes\Modules\Segments\Processors\UpdatePostcodeSegmentProcessor;
use App\Models\Address;
use App\Models\Company;
use App\Models\CompanyModule;
use App\Models\Container;
use App\Models\Document;
use App\Models\PackingList;
use App\Models\SegmentConstant;
use App\Models\Transport;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\Artisan;
class DummyDataSeeder extends Seeder
{
@@ -583,6 +587,32 @@ class DummyDataSeeder extends Seeder
// 3. overweight cbm
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
// Generate and Approve Dummmy Invoice //
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
ini_set('memory_limit', '-1');
$randomCompanyModule = CompanyModule::latest('id')->take(5)->get();
$centerPostcodeConstantObject = SegmentConstant::where('reference', SegmentConstants::CENTER_POSTCODE)->get();
$centerPostcodeConstant = $centerPostcodeConstantObject->isEmpty() ? [] : (array)$centerPostcodeConstantObject->first()->value;
foreach($randomCompanyModule as $companyModule) {
foreach($companyModule->addresses as $address) {
$postcode = $address->postcode;
$postcodeArea = in_array($postcode, $centerPostcodeConstant) ? 'CENTER_POSTCODE' : null;
if (!$postcodeArea) {
$random = rand(0, 1);
$postcodeArray = ['OUTSTATION_POSTCODE', 'CENTER_POSTCODE'];
(App()->make(UpdatePostcodeSegmentProcessor::class))->execute('1', $postcodeArray[$random],$postcode);
$this->command->info($postcodeArray[$random]);
}
}
}
Artisan::call('invoice:generate');
Artisan::call('approve:invoice');
}
}
@@ -38,7 +38,7 @@ class SegmentConstantsTableSeeder extends Seeder
Segmentconstant::create( [
'segment_id'=>1,
'reference'=>'STATE_RATE',
'value'=>'[{"state_id":1,"center":"10.00","outstation":"2.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"50.00","outstation":"0.00"},{"center":"0.00","outstation":"0.00"},{"center":"345.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"10.00","outstation":"0.00"},{"center":"0.00","outstation":"0.00"},{"center":"185.00","outstation":"0.00"},{"center":"185.00","outstation":"0.00"},{"center":"0.00","outstation":"0.00"},{"center":"50.00","outstation":"0.00"}]',
'value'=>'[{"state_id":1,"center":"10.00","outstation":"2.00"},{"center":"10.00","outstation":"10.00"},{"center":"10.00","outstation":"10.00"},{"center":"50.00","outstation":"50.00"},{"center":"12.00","outstation":"12.00"},{"center":"345.00","outstation":"345.00"},{"center":"10.00","outstation":"10.00"},{"center":"10.00","outstation":"10.00"},{"center":"10.00","outstation":"30.00"},{"center":"10.00","outstation":"20.00"},{"center":"10.00","outstation":"10.00"},{"center":"10.00","outstation":"10.00"},{"center":"15.00","outstation":"15.00"},{"center":"185.00","outstation":"23.00"},{"center":"185.00","outstation":"185.00"},{"center":"30.00","outstation":"30.00"},{"center":"50.00","outstation":"50.00"}]',
'deleted_at'=>NULL,
'created_at'=>NULL,
'updated_at'=>'2022-09-27 01:18:15'
@@ -71,7 +71,7 @@ class SegmentConstantsTableSeeder extends Seeder
Segmentconstant::create( [
'segment_id'=>1,
'reference'=>'OUTSTATION_POSTCODE',
'value'=>'["93250","93350","94200","94300","94600","78556","78557","94700","94750","94760","93050","93250","94000","94500","93050","93350","93350","79466","93050","94100","94500","93050","93050","93250","93350","93050","94200","94200","93010","93010","94700","94800","94807","94809","93250","94000","93050","93050","93250","86900","82300","86800","86810","81600","86800","71600","71650","72400","71600","72200","72300","71750","71770","69000","26800","26810","26820","39000","39007","39009","39010","33300","33310","33320","33100"]',
'value'=>'["93250","93350","94200","94300","94600","78556","78557","94700","94750","94760","93050","93250","94000","94500","93050","93350","93350","79466","93050","94100","94500","93050","93050","93250","93350","93050","94200","94200","93010","93010","94700","94800","94807","94809","93250","94000","93050","93050","93250","86900","82300","86800","86810","81600","86800","71600","71650","72400","71600","72200","72300","71750","71770","69000","26800","26810","26820","39000","39007","39009","39010","33300","33310","33320","33100","42425","42500","42507","42509","42800","45500","43950","47507","47600","47610","47620","47640","47650","47200","40000","40100","40470","40500","40502","40503","40505","40512","40517","40520","40529","40542","40548","40550","40551","40560","40564","40570","40572","40576","40578","40582","40590","40592","40594","40596","40598","40604","40607","40608","40610","40612","40620","40622","40626","40632","40646","40648","40660","40664","40670","40672","40673","40674","40675","40676","40680","40690","40700","40702","40704","40706","40708","40710","40712","40714","40716","40718","40720","40722","40724","40726","40728","40730","40732","40800","40802","40804","40806","40808","40810","40990"]',
'deleted_at'=>NULL,
'created_at'=>NULL,
'updated_at'=>'2022-09-21 03:35:19'
+4
View File
@@ -23,5 +23,9 @@ server {
fastcgi_intercept_errors on;
fastcgi_keep_conn on;
fastcgi_param PHP_VALUE "auto_prepend_file= \n allow_url_include=Off \n output_buffering=Off \n output_buffering=4096";
proxy_send_timeout 3600;
proxy_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_read_timeout 3600;
}
}
@@ -0,0 +1,76 @@
<template>
<div class="row m-b-10 parentContainer">
<div class="col">
<div class="row">
<div class="col-auto">
<div class="row">
<div class="col">
<h6 class="no-margin fs-12 text-black">{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}</h6>
</div>
</div>
</div>
<div class="col-auto">
<div class="row">
<!-- <div class="col-auto p-r-5">
<i class="fa m-r-10" data-type="defaultAddress" :class="{'fa-star': item.default, 'requestModal': !item.default, 'fa-star-o': !item.default, 'pointer': !item.default, 'text-warning': item.default}" ></i>
</div> -->
<div class="col-auto no-padding p-r-5 p-l-5 pointer">
<i class="fa fa-pencil-square-o text-complete m-r-10" @click="expanded = !expanded"></i>
</div>
<!-- <div class="col-auto p-l-5">
<i class="fa fa-trash-o text-danger requestModal" data-type="deleteAddress"></i>
</div> -->
</div>
</div>
</div>
<div class="row" v-if="expanded">
<div class="col">
<warehouse-address-form-component :company_module_id="company_module_id" :data="item" :section="section" @input="updateAddress($event)"></warehouse-address-form-component>
</div>
</div>
<!-- <modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteAddress">
<delete-address-form-component :data="item" :section="section" class="text-center"></delete-address-form-component>
</modal-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="defaultAddress">
<set-default-address-form-component :data="item" :section="section" class="text-center"></set-default-address-form-component>
</modal-component> -->
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props: {
company_module_id: {
type: Number,
required: true
},
section: {
type: String,
required: true
}
},
data(){
return {
expanded: false
}
},
watch: {
value: function(value){
this.value = value;
if(value !== this.item.id){
this.expanded = false;
}
}
},
methods: {
updateAddress(id){
this.expanded = false;
this.$emit('input', id);
}
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,230 @@
<template>
<div class="row p-t-25 text-left">
<div class="col">
<div class="row" v-if="![7,8].includes($store.getters.getCompanyModuleType)">
<div class="col">
<!-- <div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.reference">
<label>Address Reference/Label</label>
<input class="form-control" name="reference" v-model="parameters.reference">
</validation-wrapper-component>
</div>
</div> -->
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.street_one">
<label>Address Line 1</label>
<input class="form-control" name="street_one" v-model="parameters.street_one">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.street_two">
<label>Address Line 2</label>
<input class="form-control" name="street_two" v-model="parameters.street_two">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col-12 col-md pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component selectable :validator="$v.parameters.district_id">
<label>District</label>
<selectable-component :endpoint="route('api.address.district.list')" section="districtListSection" valueColumn="id" :labelColumn="['city']" v-model="parameters.district_id"></selectable-component>
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.post_code">
<label>Post Code</label>
<input class="form-control" name="post_code" v-model="parameters.post_code">
</validation-wrapper-component>
</div>
</div>
<!-- <div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="row m-b-15">
<div class="col-12 col-md pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component :validator="$v.parameters.person_in_charge">
<label>Person In Charge</label>
<input class="form-control" name="person_in_charge" v-model="parameters.person_in_charge">
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.phone">
<label>Phone</label>
<input class="form-control" name="phone" v-model="parameters.phone">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.remark">
<label>Delivery Remark</label>
<input class="form-control" name="remark" v-model="parameters.remark">
</validation-wrapper-component>
</div>
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
<div class="row" v-if="[7,8].includes($store.getters.getCompanyModuleType)">
<div class="col">
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.reference">
<label>Company Name</label>
<input class="form-control" name="reference" v-model="parameters.reference">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col-12 col-md pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component :validator="$v.parameters.person_in_charge">
<label>Name</label>
<input class="form-control" name="person_in_charge" v-model="parameters.person_in_charge">
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.phone">
<label>Phone</label>
<input class="form-control" name="phone" v-model="parameters.phone">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col-12 col-md-3 pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component :validator="$v.parameters.street_one">
<label>Unit No.</label>
<input class="form-control" name="street_one" v-model="parameters.street_one">
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.street_two">
<label>Street Address</label>
<input class="form-control" name="street_two" v-model="parameters.street_two">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col-12 col-md pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component selectable :validator="$v.parameters.district_id">
<label>City/Town</label>
<selectable-component :endpoint="route('api.address.district.list')" section="districtListSection" valueColumn="id" :labelColumn="['city']" v-model="parameters.district_id"></selectable-component>
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.post_code">
<label>Post Code</label>
<input class="form-control" name="post_code" v-model="parameters.post_code">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.remark">
<label>Remark</label>
<input class="form-control" name="remark" v-model="parameters.remark">
</validation-wrapper-component>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<div class="col"></div>
<div class="col-auto">
<button type="button" class="btn btn-sm btn-complete b-rad-none" @click="submitForm()">{{ this.data ? "Update" : "Save" }} Address</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required, requiredIf, numeric } from "vuelidate/lib/validators";
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props: {
company_module_id: {
type: Number,
required: true
},
type: {
type: Number,
default: 2
},
data: {
type: Object,
default: null
},
section:{
type: String,
required: true
},
},
data() {
return {
parameters : {
company_module_id: this.company_module_id,
street_one: '',
street_two: '',
district_id: '',
post_code: '',
type: this.type,
// reference: null,
// remark: null,
// phone: null,
// person_in_charge: null,
}
}
},
created(){
if(this.data){
this.parameters.reference = this.data.reference;
this.parameters.street_one = this.data.street_one;
this.parameters.street_two = this.data.street_two;
this.parameters.district_id = this.data.district.id;
this.parameters.post_code = this.data.post_code;
this.parameters.type = this.data.type;
this.parameters.phone = this.data.contact ? this.data.contact.phone : '';
this.parameters.person_in_charge = this.data.contact ? this.data.contact.reference : '';
this.parameters.remark = this.data.remark ? this.data.remark.content : '';
}
},
validations: {
parameters: {
// reference: {
// required: requiredIf(function(){
// return ![7,8].includes(this.$store.getters.getCompanyModuleType);
// })
// },
street_one: { required },
street_two: {
required: requiredIf(function(){
return [7,8].includes(this.$store.getters.getCompanyModuleType);
})
},
district_id: { required },
post_code: { required },
// remark: {},
// phone: {required, numeric},
// person_in_charge: { required },
}
},
methods:{
submitForm(){
this.submit(this.data ? (this.route('api.address.update', this.data.id)) : (this.route('api.address.create')), this.data ? 'put' : 'post', this.section, true, true);
},
},
}
</script>
@@ -16,8 +16,9 @@
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="changeCustomerName">
<change-customer-name-form-component :section="'customerProfileSection'" :data="item"></change-customer-name-form-component>
</modal-component>
<div class="font-heading fs-20 light">{{item.name}}
<div class="btn btn-xs b-rad-none pointer requestModal d-inline rounded no-border hover-primary" data-type="changeCustomerName" >
<div class="font-heading fs-20 light">
{{item.name}}
<div class="btn btn-xs b-rad-none pointer requestModal d-inline rounded no-border hover-primary bg-transparent" data-type="changeCustomerName" >
<i class="fa fa-edit pointer fa-fw fs-15 m-l-5"></i>
</div>
</div>
@@ -92,10 +93,24 @@
<h6 class="no-margin">{{item.contact.phone}}</h6>
</div>
</div>
<!-- <div class="row align-items-center">
<div class="col">
<h6 class="no-margin fs-12">WeChat ID</h6>
<h6 class="no-margin">{{item.contact.wechat_id}}</h6>
</div>
</div> -->
<div class="row align-items-center">
<div class="col">
<h6 class="no-margin fs-12">WeChat ID</h6>
<h6 class="no-margin">{{item.contact.wechat_id}}</h6>
<h6 class="no-margin fs-12">Company Type </h6>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="changeBusinessType">
<change-business-type-form-component :section="'customerProfileSection'" :data="item"></change-business-type-form-component>
</modal-component>
<h6 class="no-margin">
{{item.type_name}}
<div class="btn btn-xs b-rad-none pointer requestModal d-inline rounded no-border hover-primary bg-transparent" data-type="changeBusinessType" v-if="$store.getters.isAdmin">
<i class="fa fa-edit pointer fa-fw fs-15 m-l-5"></i>
</div>
</h6>
</div>
</div>
</div>
@@ -0,0 +1,89 @@
<template>
<div class="row" style="width: 450px; margin: auto;" @keyup.enter="submitForm">
<div class="col bg-white padding-40 b-rad-lg">
<div class="row m-b-10">
<div class="col text-center">
<h3>Edit Contact</h3>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.reference">
<label>Reference</label>
<input class="form-control" name="street_one" v-model="parameters.reference">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.phone">
<label>Phone</label>
<input class="form-control" name="street_one" v-model="parameters.phone">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.email">
<label>Email</label>
<input class="form-control" name="street_one" v-model="parameters.email">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.wechat_id">
<label>Wechat ID</label>
<input class="form-control" name="street_one" v-model="parameters.wechat_id">
</validation-wrapper-component>
</div>
</div>
<div class="row m-t-15">
<div class="col-auto p-r-5">
<div class="btn btn-lg btn-default b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-primary w-100 btn-lg" @click="submitForm">Confirm</div>
</div>
</div>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required } from "vuelidate/lib/validators";
export default {
props: {
company_module_id: {
type: Number,
required: true
},
},
data() {
return {
parameters: {
reference: this.data.reference,
phone: this.data.phone,
email: this.data.email,
wechat_id: this.data.wechat_id,
}
};
},
methods: {
submitForm() {
this.submit(this.route('api.contact.update', this.data.id), 'put', this.section, true, true)
},
},
validations: {
parameters: {
reference: { },
phone: { },
email: { },
wechat_id: { },
}
},
mixins: [modalFormHandler]
}
</script>
@@ -0,0 +1,126 @@
<template>
<div class="row align-items-center justify-content-center w-100">
<div class="col">
<div class='tetrominos'>
<div class='tetromino box1'></div>
<div class='tetromino box2'></div>
<div class='tetromino box3'></div>
<div class='tetromino box4'></div>
</div>
</div>
</div>
</template>
<style>
.tetrominos {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-112px, -96px);
}
.tetromino {
width: 96px;
height: 112px;
position: absolute;
transition: all ease 0.3s;
background: url('data:image/svg+xml;utf-8,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 684"%3E%3Cpath fill="%23010101" d="M305.7 0L0 170.9v342.3L305.7 684 612 513.2V170.9L305.7 0z"/%3E%3Cpath fill="%23fff" d="M305.7 80.1l-233.6 131 233.6 131 234.2-131-234.2-131"/%3E%3C/svg%3E') no-repeat top center;
}
.box1 {
animation: tetromino1 1.5s ease-out infinite;
}
.box2 {
animation: tetromino2 1.5s ease-out infinite;
}
.box3 {
animation: tetromino3 1.5s ease-out infinite;
z-index: 2;
}
.box4 {
animation: tetromino4 1.5s ease-out infinite;
}
@keyframes tetromino1 {
/* compose logo */
/* 1 on 3 */
/* L-shape */
0%,
40% {
transform: translate(0, 0);
}
50% {
/* pre-box */
transform: translate(48px, -27px);
}
60%,
100% {
/* box */
/* compose logo */
transform: translate(96px, 0);
}
}
@keyframes tetromino2 {
/* compose logo */
/* 1 on 3 */
0%,
20% {
transform: translate(96px, 0px);
}
40%,
100% {
/* L-shape */
/* box */
/* compose logo */
transform: translate(144px, 27px);
}
}
@keyframes tetromino3 {
/* compose logo */
0% {
transform: translate(144px, 27px);
}
20%,
60% {
/* 1 on 3 */
/* L-shape */
/* box */
transform: translate(96px, 54px);
}
90%,
100% {
/* compose logo */
transform: translate(48px, 27px);
}
}
@keyframes tetromino4 {
/* compose logo */
/* 1 on 3 */
/* L-shape */
/* box */
0%,
60% {
transform: translate(48px, 27px);
}
90%,
100% {
/* compose logo */
transform: translate(0, 0);
}
}
</style>
@@ -0,0 +1,83 @@
<template>
<div class="row parentContainer" @keyup.enter="search">
<div class="col">
<div class="row">
<div class="col p-r-0">
<div class="row">
<!-- <div class="col">
<div class="form-group no-margin form-group-default b-rad-none">
<label class="text-primary">Customer Marking</label>
<input type="text" class="form-control" v-model="parameters.customerMarking"
@click="clearAll('customerMarking')" />
</div>
</div>
<div class="col">
<div class="form-group no-margin form-group-default b-rad-none">
<label class="text-primary">Email</label>
<input type="text" class="form-control" v-model="parameters.email"
@click="clearAll('email')" />
</div>
</div> -->
<div class="col">
<div class="form-group no-margin form-group-default b-rad-none">
<label class="text-primary">Order No</label>
<input type="text" class="form-control" v-model="parameters.orderNo"
@click="clearAll('orderNo')" />
</div>
</div>
</div>
</div>
<div class="col-auto p-l-0">
<div class="btn btn-primary b-rad-none" @click="search">
<i class="fa fa-search lh-40"></i>
</div>
<div class="btn btn-default b-rad-none lh-40" @click="reset">
Reset
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
section: {
default: 'addressList'
},
},
data() {
return {
isLoading: false,
parameters: {
customerMarking: null,
email: null,
orderNo: null,
}
}
},
methods: {
clearAll(input) {
var parameters = this.parameters;
$.each(this.parameters, function (key, value) {
if (key != input) {
parameters[key] = null;
}
});
this.parameters = parameters;
},
reset() {
this.parameters.customerMarking = null;
this.parameters.email = null;
this.parameters.orderNo = null;
},
search() {
if (this.parameters.orderNo) {
window.location.href = this.route('order.show', this.parameters.orderNo);
return;
}
}
},
}
</script>
@@ -1,5 +1,5 @@
<template>
<div class="row">
<div class="row parentContainer">
<div class="col">
<div class="row align-items-center p-t-5 p-b-5">
<div class="col-auto p-r-0" v-if="!$store.getters.isAdmin">
@@ -38,6 +38,14 @@
<div class="col-auto text-right">
<div class="btn btn-xs btn-default" @click="expanded = !expanded"><i class="fa" :class="{'fa-angle-up': expanded, 'fa-angle-down': !expanded}"></i></div>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
<span class="d-inline-block m-r-15 pointer requestModal bg-white btn-xs" data-type="deleteParcel">
<i class="fa fa-close"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteParcel">
<delete-parcel-form-component :data="item" :section="section"></delete-parcel-form-component>
</modal-component>
</div>
</div>
</div>
</div>
@@ -104,6 +112,12 @@
expanded: false
}
},
props: {
section:{
type: String,
default: null,
}
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,62 @@
<template>
<div class="row" style="width: 450px; margin: auto;" @keyup.enter="submitForm">
<div class="col bg-white padding-40 b-rad-lg">
<div class="row m-b-10">
<div class="col text-center">
<h3>Edit Role Type</h3>
</div>
</div>
<div class="row">
<div class="col">
<div class="row m-t-15 m-b-15">
<div class="col p-r-5">
<div class="b-grey b-a w-100 text-center p-l-15 p-r-15 p-t-10 p-b-10 pointer fs-15" :class="[{'b-primary': parameters.type === 2}]" @click="updateRoleType(2)">Admin</div>
</div>
<div class="col p-l-5">
<div class="b-grey b-a w-100 text-center p-l-15 p-r-15 p-t-10 p-b-10 pointer fs-15" :class="[{'b-primary': parameters.type === 1}]" @click="updateRoleType(1)">Super Admin</div>
</div>
</div>
</div>
</div>
<div class="row m-t-15">
<div class="col-auto p-r-5">
<div class="btn btn-lg btn-default b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-primary w-100 btn-lg" @click="submitForm">Confirm</div>
</div>
</div>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required, minLength } from "vuelidate/lib/validators";
export default {
props: {
data:{
type: Object,
required: true,
}
},
data() {
return {
parameters: {
type: this.data.type,
}
};
},
methods: {
submitForm() {
this.submit(this.route('api.account.user.update.role', this.data.id), 'put', this.section, true, true)
},
updateRoleType(type){
this.parameters.type=type;
}
},
mixins: [modalFormHandler]
}
</script>
@@ -0,0 +1,49 @@
<template>
<div class="row" style="width: 450px; margin: auto;" @keyup.enter="submitForm">
<div class="col bg-white padding-40 b-rad-lg">
<div class="row m-b-10">
<div class="col text-center">
<h3>Edit Company Type</h3>
</div>
</div>
<div class="row m-t-15 m-b-15">
<div class="col p-r-5">
<div class="b-grey b-a w-100 text-center p-l-15 p-r-15 p-t-10 p-b-10 pointer fs-15" :class="[{'b-primary': parameters.type === 0}]" @click="updateType(0)">Personal<br>Business</div>
</div>
<div class="col p-l-5">
<div class="b-grey b-a w-100 text-center p-l-15 p-r-15 p-t-10 p-b-10 pointer fs-15" :class="[{'b-primary': parameters.type === 1}]" @click="updateType(1)">Company<br>Business</div>
</div>
</div>
<div class="row m-t-15">
<div class="col-auto p-r-5">
<div class="btn btn-lg btn-default b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-primary w-100 btn-lg" @click="submitForm">Confirm</div>
</div>
</div>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
data() {
return {
parameters: {
type: this.data.type,
}
};
},
methods: {
submitForm() {
this.submit(this.route('api.company.update.type', this.data.id), 'put', this.section, true, true)
},
updateType(type) {
this.parameters.type = type;
},
},
mixins: [modalFormHandler]
}
</script>
@@ -60,9 +60,6 @@
}
},
methods: {
successHandler(response) {
window.location.replace(this.route('customers', response.payload.data.reference));
},
submitForm() {
this.submit(this.route('api.company.update.nameAndDebtor', this.data.id), 'put', this.section, true, true)
}
File diff suppressed because one or more lines are too long
@@ -301,7 +301,7 @@
</div>
<div class="row">
<div class="col">
<parcel-component v-for="parcel in order.parcels.received_packages.flatMap(packing_list => packing_list.packages)" :data="parcel" :key="parcel.id"></parcel-component>
<parcel-component :section="section" v-for="parcel in order.parcels.received_packages.flatMap(packing_list => packing_list.packages)" :data="parcel" :key="parcel.id"></parcel-component>
</div>
</div>
</div>
@@ -0,0 +1,203 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 200px; top: 0;" v-if="isLoading"></loading-component>
<div class="row flex-wrap" v-if="!isLoading && order">
<div class="col">
<div class="row m-b-30">
<div class="col bg-master-lightest padding-25">
<div class="row align-items-center">
<div class="col-12 col-lg-3">
<div class="row justify-content-center">
<div class="col-10">
<a :href="route('order.qr.download', order.id)" target="_blank">
<div class="peelable-corner overflow-hidden relative">
<img :src="'https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl={id:'+order.id+'}'" class="w-100">
</div>
</a>
</div>
</div>
</div>
<div class="col">
<div class="row m-b-20">
<div class="col-auto">
<h3 class="no-margin"><b>Order No.</b> {{order.reference}}</h3>
</div>
<div class="col d-flex">
<div class="btn btn-xs btn-outline-danger b-rad-none pointer requestModal align-items-center d-flex" data-type="changeOrderNo" v-if="$store.getters.isSuperAdmin">Change Order Number</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="changeOrderNo">
<change-order-number-form-component :section="section" :data="order"></change-order-number-form-component>
</modal-component>
</div>
</div>
<div class="row m-b-20">
<div class="col-12">
<div class="row">
<div class="col-auto d-flex align-items-center">
<h6 class="no-margin"><b>Remark:</b></h6>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="orderRemark">
<remark-form-component module_type="Order" :data="order" :section="section"></remark-form-component>
</modal-component>
</div>
<div class="col-auto p-l-0" v-if="order.remarks.length == 0">
<div class="btn btn-xs btn-outline-info b-rad-none pointer requestModal" data-type="orderRemark">Add a Remark</div>
</div>
<div class="col d-flex align-items-center pl-3 pl-md-0" v-if="order.remarks.length >= 1">
<h6 class="no-margin">{{ order.remarks[0].content }}</h6>
<span class="btn btn-md btn-default m-l-10 requestModal" data-type="orderRemark">
<i class="fa fa-edit"></i>
</span>
<span class="btn btn-md btn-default m-l-5 requestModal" data-type="deleteOrderRemark">
<i class="fa fa-trash"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="deleteOrderRemark">
<delete-remark-form-component :section="section" :data="order.remarks[0]"></delete-remark-form-component>
</modal-component>
</div>
</div>
</div>
</div>
<div class="row m-b-20">
<div class="col-12 col-sm-auto">
<h6 class="no-margin"><b>Order Date:</b> {{order.created_at}}</h6>
</div>
<div class="col-12 col-sm-auto">
<h6 class="no-margin"><b>Warehouse:</b> {{order.warehouse.name}} {{$store.getters.isAdmin ? order.warehouse.reference : ''}}</h6>
</div>
<div class="col col-sm" v-if="$store.getters.isAdmin">
<a :href="route('customer.profile', order.company_module.marking)">
<h6 class="no-margin"><b>Customer Marking:</b> {{order.company_module.marking}}</h6>
</a>
</div>
</div>
<div class="row m-b-10 align-items-center parentContainer" >
<div class="col-auto">
<h6 class="no-margin">
<div class="row">
<div class="col-12 col-sm-auto pr-sm-0"><b>Delivery Address:</b>&nbsp;</div>
<div class="col-12 col-sm-auto pl-sm-0">{{order.address.reference}} <i class="fa fa-info-circle m-l-10" v-tooltip:right="order.address.street_one+' '+(order.address.street_two ? order.address.street_two : '')+', '+ order.address.district.name+', '+order.address.post_code+' '+order.address.state.name+', '+order.address.country.name" ></i></div>
</div>
</h6>
</div>
<div class="col">
<div class="row" v-if="!order.address_change_request">
<div class="col">
<div class="btn btn-xs btn-outline-danger b-rad-none pointer requestModal m-t-10 mt-sm-0" data-type="updateDeliveryAddress">Change Delivery Address</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="stick-up" type="updateDeliveryAddress" size="large">
<change-order-address-form-component :data="order" :section="section" class="text-center"></change-order-address-form-component>
</modal-component>
</div>
</div>
<div class="row parentContainer" v-if="order.address_change_request">
<div class="col-auto p-r-0">
<div class="p-t-10 p-b-10 p-l-15 p-r-15 b-a b-danger fs-10 text-danger requestModal" data-type="updateDeliveryAddress"><i class="fa fa-exclamation-circle m-r-10"></i>Your Delivery address change request is being reviewed</div>
</div>
<div class="col-auto bg-danger-light pointer requestModal" data-type="cancelAddressChangeRequest">
<i class="fa fa-times text-white lh-38"></i>
</div>
<modal-component small type="cancelAddressChangeRequest">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col text-center">
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Cancel Address Change Request</h5>
<div class="fs-11">Are you sure you want to cancel your order delivery address change request?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div data-dismiss="modal" class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.order.address.status.update', order.address_change_request.id, 6), 'put', section, true, true)">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</modal-component>
</div>
</div>
</div>
<div class="row align-items-center">
<div class="col-10">
<h6 class="text-info"><span class="text-danger bold">Gentle reminder:</span> You need to send the QR code to your supplier to print and stick on your packages, this QR code is required for us to identify your packages when they arrives at our warehouse!</h6>
<a :href="route('order.qr.download', order.id)" target="_blank">
<button class="btn btn-sm btn-success bg-master b-rad-none all-caps">Download QR Code Pdf</button>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row m-b-30" v-if="order.invoices.length">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h4 class="bold">Invoices</h4>
<p>You can view your invoices here and make payment.</p>
</div>
</div>
<div class="row bg-master-lightest p-t-15" v-for="invoice in order.invoices">
<div class="col">
<customer-payments-billing-component :data="invoice" invoice_status="Pending Payment" :section="section"></customer-payments-billing-component>
</div>
</div>
</div>
</div>
</div>
</div>
<order-package-v2-section-component v-if="!isLoading" :order_number="order_number"></order-package-v2-section-component>
</div>
</div>
</template>
<script>
export default {
props: {
order_number: {
type: Number,
required: true,
}
},
data(){
return {
section: 'orderProfileV2Section',
isLoading: true,
order: null,
addComment: false,
}
},
computed: {
pendingQueue () {
return this.$store.getters.isInCompleteQueue(this.section);
}
},
watch: {
pendingQueue(inComplete){
if(inComplete){
this.fetchCompany();
}
}
},
created(){
this.$store.dispatch('updateListQueue', {'name': this.section});
},
methods: {
fetchCompany(){
this.isLoading = true;
this.submit(route('api.order.v2.show', this.order_number), 'get', this.section, false, false)
},
successHandler(response){
this.$store.dispatch('completeList', {'name': this.section, 'data': []});
this.isLoading = false;
this.order = response.payload.data;
}
}
}
</script>

Some files were not shown because too many files have changed in this diff Show More