Compare commits

...

37 Commits

Author SHA1 Message Date
Dillon e5421f8810 Update condition to update CRM task status 2023-08-20 15:57:51 +08:00
Dillon a413533975 CRM Integration (Part 2 of code sync with Exchange-2.0) 2023-08-20 05:30:54 +08:00
Dillon aceed5f754 Quick fix 2023-08-18 12:13:47 +08:00
Dillon Ngo 761d191c1d Merge branch 'dillon/42-crm-code-sync-with-exchange' into 'master'
Exchange-2.0 code sync for crm changes

See merge request CIEFWorldwideSdnBhd/shipping-portal!166
2023-08-17 13:58:09 +00:00
Dillon d769be137e Exchange-2.0 code sync for crm changes 2023-08-17 21:49:48 +08:00
Dillon d6a5dd56c6 Exchange-2.0 code sync for crm changes 2023-08-17 21:34:18 +08:00
Omair Saleh f279d39ddb fix yd bug 2023-08-15 13:50:22 +08:00
Omair Saleh 2e1e8875b4 fix yd bug 2023-08-15 13:47:53 +08:00
Omair Saleh c30c5a36f2 fix yd bug 2023-08-15 13:46:24 +08:00
Omair Saleh 7d3901ee48 fix yd bug 2023-08-15 13:41:00 +08:00
Omair Saleh 463398945f fix yd bug 2023-08-15 13:40:18 +08:00
Omair Saleh d619862e63 fix yd bug 2023-08-15 13:38:18 +08:00
Omair Saleh 9665a0e242 fix yd bug 2023-08-14 15:43:02 +08:00
Omair Saleh 7ed6c11f37 fix yd bug 2023-08-14 15:40:40 +08:00
Omair Saleh 3eaee0d122 fix yd bug 2023-08-14 15:35:47 +08:00
Omair Saleh b7816873fe fix yd bug 2023-08-14 15:30:05 +08:00
Omair Saleh 8809caa046 Merge remote-tracking branch 'origin/master' 2023-08-14 14:55:35 +08:00
Omair Saleh b8b6910a45 fix yd quantity is not a number bug 2023-08-14 14:55:21 +08:00
edmondlang 64bfbac4f7 update manual generate warehouse packinglist 2023-08-03 14:30:45 +08:00
edmondlang a5b7e79964 manual generate warehouse packinglist 2023-08-03 13:45:07 +08:00
edmondlang 03c9bec256 fix-duplicate-container-reference cron 2023-08-01 00:04:20 +08:00
edmondlang 06134e006c fix deleted packinglist 2023-07-23 15:42:35 +08:00
Omair Saleh 7563b455ba update yd updates link 2023-07-21 12:40:56 +08:00
Omair Saleh 26edb3bebd Merge remote-tracking branch 'origin/master' 2023-07-21 12:34:35 +08:00
Omair Saleh 55e1a6ad02 remove all customer from vt warehouse list 2023-07-21 12:34:19 +08:00
edmondlang 381425c6bc update export mappable transaction 2023-07-18 12:53:00 +08:00
edmondlang 09ab95faf8 update listing mapping transaction 2023-07-18 11:54:27 +08:00
edmondlang 8bb6f0317a update list mappable transactino details log 2023-07-11 17:59:43 +08:00
edmondlang fe95db2605 update list mappable transactino details log 2023-07-11 17:48:09 +08:00
edmondlang 02640e6ae8 update list mappable transactino details log 2023-07-11 17:39:09 +08:00
Omair Saleh 104dd19a6f Merge remote-tracking branch 'origin/master' 2023-07-10 12:52:35 +08:00
Omair Saleh 89117c0706 debug yd api 2023-07-10 12:51:59 +08:00
edmondlang bc650b0816 update public endpoint for exchange to get transaction data for accounting mapping 2023-07-09 22:01:35 +08:00
edmondlang a6a239c489 add public endpoint for exchange to get transaction data for accounting mapping 2023-07-09 21:54:56 +08:00
edmondlang 45b78465da add debtor code in company module resource for exchange accounting mapping purpose 2023-07-07 00:59:48 +08:00
Omair Saleh 71edeca994 Merge remote-tracking branch 'origin/master' 2023-07-05 14:18:02 +08:00
Omair Saleh cd229c6a8f fix the invoice export format 2023-07-05 14:17:43 +08:00
44 changed files with 1346 additions and 280 deletions
+3 -4
View File
@@ -24,12 +24,11 @@ class Helper
return array_slice(get_class_methods($className), 1);
}
/**
/**
* @param $log
* @return none
*/
static function debugLoggerForPerfexCRM($log){
if($log){
static function debugLogger($log){
if($log && isset($log['message'])){
$message = $log['message'];
$substring = 'No data were found';
if (isset($message)) {
+28 -10
View File
@@ -3,6 +3,8 @@
namespace App\Classes\Jobs;
use App\Classes\Modules\PerfexCRM\Processors\UpdatePerfexCRMProcessor;
use App\Classes\Modules\PerfexCRM\Processors\FetchPerfexCRMInvoiceProcessor;
use App\Models\Transaction;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -10,6 +12,8 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\FetchPerfexCRMInvoiceObject;
class UpdatePerfexCRM implements ShouldQueue
{
@@ -18,37 +22,51 @@ class UpdatePerfexCRM implements ShouldQueue
/** @var UpdatePerfexCRMObject */
private $updatePerfexCRMObject;
/** @var UpdatePerfexCRMInvoice */
private $nextJob;
/** @var */
private $transaction;
/** @var bool|null */
private $shouldCreateInvoice;
/**
* UpdatePerfexCRM constructor.
* @param UpdatePerfexCRMObject $updatePerfexCRMObject
* @param UpdatePerfexCRMInvoice $nextJob
* @param $transaction
* @param Transaction $transaction
* @param bool|null $shouldCreateInvoice
*/
public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject, $transaction, $nextJob)
public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject, $transaction, ?bool $shouldCreateInvoice = false)
{
$this->updatePerfexCRMObject = $updatePerfexCRMObject;
$this->nextJob = $nextJob;
$this->transaction = $transaction;
$this->shouldCreateInvoice = $shouldCreateInvoice;
}
public function handle()
{
//To use invoice as a reference to decide whether more tasks should be created
$this->updatePerfexCRMObject->setInvoiceId($this->getInvoiceIdOrCreateInvoice());
$result = (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject);
if($this->nextJob != null && $this->transaction != null){
if($this->transaction != null && $this->shouldCreateInvoice){
$updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject(
$this->updatePerfexCRMObject->getContactEmail(),
$result->projectId,
$this->transaction,
true
);
/** @var UpdatePerfexCRMInvoice $nextJob */
$this->nextJob::dispatch($updatePerfexCRMInvoiceOject);
UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject);
}
}
private function getInvoiceIdOrCreateInvoice(){
if($this->transaction != null){
$fetchPerfexCRMInvoiceObject = new FetchPerfexCRMInvoiceObject(
$this->updatePerfexCRMObject->getContactEmail(),
$this->transaction
);
$invoiceId = (App()->make(FetchPerfexCRMInvoiceProcessor::class))->execute($fetchPerfexCRMInvoiceObject);
return $invoiceId;
}
return 0;
}
}
+3 -4
View File
@@ -30,7 +30,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
/**
* CreatePerfexCRMSingleTask constructor.
* @param UpdatePerfexCRMInvoiceObject $createTaskPerfexCRMObject
* @param UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject
*/
public function __construct(UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject)
{
@@ -47,7 +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));
Log::error('UpdatePerfexCRMInvoice debug bill_no: ' . $transaction->owner->bill_no . ', Project Id: ' . $this->updatePerfexCRMInvoiceObject->getProjectId());
if(is_null($invoice)){
$result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner, $this->updatePerfexCRMInvoiceObject->getIsPaid());
@@ -55,7 +55,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
$invoiceId = $result->payload['id'];
} else {
// Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'));
Helper::debugLoggerForPerfexCRM('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed');
Helper::debugLogger('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed');
}
}
else{
@@ -64,7 +64,6 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
//This only run when invoice already exist and the invoice does not have a PAID status
if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){
Log::error(json_encode('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId()));
//update invoice
(App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId());
}
+7 -14
View File
@@ -27,27 +27,22 @@ class UpdatePerfexCRMPrelude implements ShouldQueue
/** @var UpdatePerfexCRMObject */
private $updatePerfexCRMObject;
/** @var UpdatePerfexCRM */
private $nextJob1;
/** @var UpdatePerfexCRMInvoice */
private $nextJob2;
/** @var bool|null */
private $shouldCreateInvoice;
/**
* UpdatePerfexCRMPrelude constructor.
* @param $packingList
* @param $transaction
* @param Transaction $transaction
* @param UpdatePerfexCRMObject $updatePerfexCRMObject
* @param UpdatePerfexCRM $nextJob1
* @param UpdatePerfexCRMInvoice $nextJob2
* @param bool|null $shouldCreateInvoice
*/
public function __construct($packingList, $transaction, UpdatePerfexCRMObject $updatePerfexCRMObject, $nextJob1, $nextJob2)
public function __construct($packingList, $transaction, UpdatePerfexCRMObject $updatePerfexCRMObject, ?bool $shouldCreateInvoice = false)
{
$this->packingList = $packingList;
$this->transaction = $transaction;
$this->updatePerfexCRMObject = $updatePerfexCRMObject;
$this->nextJob1 = $nextJob1;
$this->nextJob2 = $nextJob2;
$this->shouldCreateInvoice = $shouldCreateInvoice;
}
public function handle()
@@ -69,9 +64,7 @@ class UpdatePerfexCRMPrelude implements ShouldQueue
$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);
UpdatePerfexCRM::dispatch($this->updatePerfexCRMObject, $this->transaction, $this->shouldCreateInvoice);
}
function replacePlaceholders($template, $data, $prefix = '')
@@ -32,7 +32,7 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
'DocNo',
'DocDate',
'DebtorCode',
'DebtorCode',
'Ref',
'ShipInfo',
'AccNo',
'DetailDescription',
@@ -83,11 +83,10 @@ class CreateOrderLogic extends AbstractControllerLogic
} else {
$originWarehouse = $this->fetchesCompanyModule->execute(['id' => $request->input('warehouse_id')]);
if (!in_array($company->companyModules()->importers()->first()->id, WarehouseReferences::YD_EXEMPT_LIST)) {
$originWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU ? WarehouseReferences::YD_GUANG_ZHOU : WarehouseReferences::YD_YIWU]);
}
$originWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU ? WarehouseReferences::YD_GUANG_ZHOU : WarehouseReferences::YD_YIWU]);
// if (!in_array($company->companyModules()->importers()->first()->id, WarehouseReferences::YD_EXEMPT_LIST))
}
if($originWarehouse->reference === WarehouseReferences::YD_YIWU && in_array($address->state_id, [5, 13, 14])) {
throw new RequestValidationException('Our Yiwu warehouse is unable to ship goods to Sabah & Sarawak at the moment. you can select our Guangzhou warehouse as an alternative.');
}
@@ -32,6 +32,7 @@ class FetchesDataFromYDPortal
$content = str_replace("\r",'', $content);
$content = str_replace("\n",'', $content);
$content = str_replace("\t",'', $content);
$content = str_replace('"data":}', '"data":""}', $content);
return json_decode($content);
}
}
@@ -0,0 +1,131 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Processors\CreatePackingListProcessor;
use App\Classes\Modules\PackingLists\Processors\CreatePackageProcessor;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\PackingLists\Services\GeneratesPackingListReferenceNumber;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
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 App\Http\Resources\PackingListResource;
use App\Models\PackingList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;
class CreateWarehouseTransportLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Created Warehouse PackingList',
'message' => 'You have successfully created a Warehouse PackingList'
];
}
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var CreatePackingListProcessor */
private $createPackingListProcessor;
/** @var GeneratesPackingListReferenceNumber */
private $generatesPackingListReferenceNumber;
/** @var CreatesTransport */
private $createsTransport;
/** @var CreatePackageProcessor */
private $createPackageProcessor;
/** @var CreatesSchedule */
private $createsSchedule;
public function __construct(
FetchesPackingList $fetchesPackingList,
CreatePackingListProcessor $createPackingListProcessor,
CreatesTransport $createsTransport,
CreatesSchedule $createsSchedule,
CreatePackageProcessor $createPackageProcessor,
GeneratesPackingListReferenceNumber $generatesPackingListReferenceNumber
) {
$this->fetchesPackingList = $fetchesPackingList;
$this->createPackingListProcessor = $createPackingListProcessor;
$this->createsTransport = $createsTransport;
$this->createsSchedule = $createsSchedule;
$this->createPackageProcessor = $createPackageProcessor;
$this->generatesPackingListReferenceNumber = $generatesPackingListReferenceNumber;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request): JsonResponse
{
$packing_list = $this->fetchesPackingList->execute([
'id' => $request->route('id'),
]);
$count_warehouse_packing_list = PackingList::where('reference', $packing_list->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->count();
if ($count_warehouse_packing_list) {
throw new MalformedRequestException('Warehouse Receive List Exists');
}
$order = $packing_list->owner;
$reference_number = $this->generatesPackingListReferenceNumber->execute();
$packingListObject = new PackingListObject(
$packing_list->reference,
$order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee->id,
PackingListType::WAREHOUSE_RECEIVE_LIST,
ApprovalStatus::PENDING_SUBMISSION
);
$packingList = $this->createPackingListProcessor->execute($packingListObject, $order);
$transportObject = new TransportObject(TransportType::LAND, null, $request->input('tracking'), Carbon::parse($request->input('receive_date')), Carbon::parse($request->input('receive_date')), ApprovalStatus::APPROVED);
$transport = $this->createsTransport->execute($transportObject, $packingList);
$scheduleObject = new ScheduleObject(Carbon::parse($request->input('receive_date')), Carbon::parse($request->input('receive_date')), ApprovalStatus::APPROVED);
$schedule = $this->createsSchedule->execute($transport, $scheduleObject);
$packages = $packing_list->packages;
foreach ($packages as $key => $row) {
$packageObject = new PackageObject(
$row['type'],
$row['description'],
$row['width'],
$row['height'],
$row['length'],
$row['weight'],
$row['quantity'],
ApprovalStatus::APPROVED,
$row['reference'],
);
$this->createPackageProcessor->execute($packageObject, $packingList);
}
return $this->resourceResponse(new PackingListResource($packingList));
}
}
@@ -11,6 +11,7 @@ use App\Classes\Modules\PackingLists\Standards\Rules\CanCreatePackingList;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\PerfexCRMTasksYDStages;
use App\Classes\ValueObjects\Constants\WarehouseReferences;
use App\Models\Order;
use App\Models\PackingList;
@@ -65,7 +66,7 @@ class CreatePackingListProcessor
$this->createsPackingList->execute($object, $packingList);
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList);
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::DEFAULT);
}
return $packingList;
@@ -26,6 +26,7 @@ use App\Classes\Modules\Unity\Processors\AssignContractEntityProcessor;
use App\Classes\Modules\Unity\Processors\CreateContractEntityProcessor;
use App\Classes\Modules\Unity\Services\CreatesContract;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\Modules\PerfexCRM\Processors\PackingListToPerfexCRMProcessor;
use App\Classes\Notifications\ShipmentDepartureEmail;
use App\Classes\Notifications\ShipmentRescheduleEmail;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
@@ -35,6 +36,7 @@ use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Classes\ValueObjects\Constants\WarehouseReferences;
use App\Classes\ValueObjects\Constants\PerfexCRMTasksYDStages;
use App\Models\Container;
use App\Models\Order;
use App\Models\PackingList;
@@ -62,20 +64,25 @@ class FetchContainersFromYdPortalProcessor
/** @var CreateContainerProcessor */
private $createContainerProcessor;
/** @var PackingListToPerfexCRMProcessor */
private $packingListToPerfexCRMProcessor;
/**
* @param FetchesDataFromYDPortal $fetchesDataFRomYDPortal
* @param CreatesTransport $createsTransport
* @param CreatesSchedule $createsSchedule
* @param FetchesContainer $fetchesContainer
* @param CreateContainerProcessor $createContainerProcessor
* @param PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor
*/
public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, FetchesContainer $fetchesContainer, CreateContainerProcessor $createContainerProcessor)
public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, FetchesContainer $fetchesContainer, CreateContainerProcessor $createContainerProcessor, PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor)
{
$this->fetchesDataFRomYDPortal = $fetchesDataFRomYDPortal;
$this->createsTransport = $createsTransport;
$this->createsSchedule = $createsSchedule;
$this->fetchesContainer = $fetchesContainer;
$this->createContainerProcessor = $createContainerProcessor;
$this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor;
}
@@ -137,6 +144,10 @@ class FetchContainersFromYdPortalProcessor
$container->packingLists()->detach($packingList);
$container->packingLists()->attach($packingList);
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::LOAD_CONTAINER);
}
$transport = $container->transports()->first();
if(!$transport){
@@ -8,9 +8,11 @@ use App\Classes\Modules\Orders\Services\FetchesDataFromYDPortal;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\Modules\PerfexCRM\Processors\PackingListToPerfexCRMProcessor;
use App\Classes\Notifications\ShipmentRescheduleEmail;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PerfexCRMTasksYDStages;
use App\Models\Container;
use App\Models\Order;
use App\Models\PackingList;
@@ -27,16 +29,21 @@ class FetchContainersUpdatesFromYdPortalProcessor
/** @var CreatesSchedule */
private $createsSchedule;
/** @var PackingListToPerfexCRMProcessor */
private $packingListToPerfexCRMProcessor;
/**
* @param FetchesDataFromYDPortal $fetchesDataFRomYDPortal
* @param UpdatesContractObligation $updatesContractObligations
* @param CreatesSchedule $createsSchedule
* @param PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor
*/
public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, UpdatesContractObligation $updatesContractObligations, CreatesSchedule $createsSchedule)
public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, UpdatesContractObligation $updatesContractObligations, CreatesSchedule $createsSchedule, PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor)
{
$this->fetchesDataFRomYDPortal = $fetchesDataFRomYDPortal;
$this->updatesContractObligations = $updatesContractObligations;
$this->createsSchedule = $createsSchedule;
$this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor;
}
@@ -65,10 +72,14 @@ class FetchContainersUpdatesFromYdPortalProcessor
$unstuffingDate = null;
$delayDate = null;
$checkShipSailDate = null;
$checkShipArrivalDate = null;
foreach (array_reverse($rows->data) as $trackingRow) {
$rescheduleETD = strpos($trackingRow->remark, '开') || strpos($trackingRow->remark, '到港');
$rescheduleETA = strpos($trackingRow->remark, '到港');
if (($rescheduleETD !== false || $rescheduleETA !== false) && strpos($trackingRow->tracking, '货物装柜完成。') === false) {
preg_match_all('/([0-9]+.{3})/', $trackingRow->remark, $matches);
$dates = collect();
@@ -97,10 +108,12 @@ class FetchContainersUpdatesFromYdPortalProcessor
if ($trackingRow->tracking === '到港') {
$delayDate = Carbon::parse($trackingRow->trackingtime);
$checkShipArrivalDate = Carbon::parse($trackingRow->trackingtime);
}
if ($trackingRow->tracking === '已开船') {
$delayDate = Carbon::parse($trackingRow->trackingtime)->addDays('5');
$checkShipSailDate = Carbon::parse($trackingRow->trackingtime);
}
if ($trackingRow->tracking === '货物已进目的港仓库') {
@@ -110,7 +123,30 @@ class FetchContainersUpdatesFromYdPortalProcessor
dump($delayDate, $unstuffingDate);
if($checkShipSailDate){
//check if ship has sailed
if($checkShipSailDate->isPast()){
foreach ($container->packingLists as $packingList){
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::SHIP_SAILED);
}
}
}
}
if($checkShipArrivalDate){
//check if ship has arrived at destination
if($checkShipArrivalDate->isPast()){
foreach ($container->packingLists as $packingList){
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::SHIP_ARRIVED);
}
}
}
}
if($delayDate){
$delayDate = $delayDate->addDays(2);
$transport = $container->transports()->first();
@@ -126,7 +162,6 @@ class FetchContainersUpdatesFromYdPortalProcessor
}
}
}
}
if($unstuffingDate){
@@ -148,7 +183,9 @@ class FetchContainersUpdatesFromYdPortalProcessor
$this->updatesContractObligations->execute($signature, $step->obligation_hash_id);
$step->update(['status' => ApprovalStatus::COMPLETED]);
}
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::UNSTUFFING);
}
}
}
@@ -8,6 +8,8 @@ use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\Modules\PerfexCRM\Processors\PackingListToPerfexCRMProcessor;
use App\Classes\ValueObjects\Constants\PerfexCRMTasksYDStages;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
@@ -34,16 +36,21 @@ class FetchDeliveryUpdatesFromYdPortalProcessor
/** @var CreatesSchedule */
private $createsSchedule;
/** @var PackingListToPerfexCRMProcessor */
private $packingListToPerfexCRMProcessor;
/**
* @param UpdatesContractObligation $updatesContractObligations
* @param CreatesTransport $createsTransport
* @param CreatesSchedule $createsSchedule
* @param PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor
*/
public function __construct(UpdatesContractObligation $updatesContractObligations, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule)
public function __construct(UpdatesContractObligation $updatesContractObligations, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, PackingListToPerfexCRMProcessor $packingListToPerfexCRMProcessor)
{
$this->updatesContractObligations = $updatesContractObligations;
$this->createsTransport = $createsTransport;
$this->createsSchedule = $createsSchedule;
$this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor;
}
@@ -99,6 +106,9 @@ class FetchDeliveryUpdatesFromYdPortalProcessor
$this->updatesContractObligations->execute($signature, $deliveryStep->obligation_hash_id);
$deliveryStep->update(['status' => ApprovalStatus::COMPLETED]);
if(config('perfexcrm.is_enabled') == 'true'){
$this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::DELIVERY);
}
}
$time_end = microtime(true);
@@ -121,6 +121,7 @@ class FetchPackingListsFromYdPortalProcessor
}
$endDate = Carbon::today()->subDays($x - 1);
$orderRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/GetOrderList.ashx', 'GET', [
'begintime' => $startDate->timestamp,
'endtime' => $endDate->timestamp,
@@ -131,6 +132,7 @@ class FetchPackingListsFromYdPortalProcessor
if(!$rows->data) continue;
foreach($rows->data as $row){
if(!is_numeric($row->goodcount)) continue;
$time_start = microtime(true);
@@ -42,7 +42,10 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
/** @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)
/** @var int */
private $invoiceId;
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, int $invoiceId)
{
$this->email = $email;
$this->name = $name;
@@ -56,6 +59,7 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
$this->department = $department;
$this->priority = $priority;
$this->duedate = $duedate;
$this->invoiceId = $invoiceId;
}
/**
@@ -158,4 +162,12 @@ class CreateTaskPerfexCRMObject implements DataTransferObject
{
return $this->duedate;
}
/**
* @return int
*/
public function getInvoiceId(): int
{
return $this->invoiceId;
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\Classes\Modules\PerfexCRM\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Models\Transaction;
class FetchPerfexCRMInvoiceObject implements DataTransferObject
{
/** @var string */
private $email;
/** @var Transaction */
private $transaction;
public function __construct(string $email, Transaction $transaction)
{
$this->email = $email;
$this->transaction = $transaction;
}
/**
* @return string
*/
public function getEmail(): string
{
return $this->email;
}
/**
* @return Transaction
*/
public function getTransaction(): Transaction
{
return $this->transaction;
}
}
@@ -28,6 +28,9 @@ class UpdatePerfexCRMObject implements DataTransferObject
/** @var int */
private $projectStatus;
/** @var int */
private $invoiceId = 0;
/** @var array */
private $milestoneNames;
@@ -35,7 +38,7 @@ class UpdatePerfexCRMObject implements DataTransferObject
private $tasks;
public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $tasks)
public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, int $invoiceId, array $milestoneNames, array $tasks)
{
$this->companyName = $companyName;
@@ -45,6 +48,7 @@ class UpdatePerfexCRMObject implements DataTransferObject
$this->bookingMarking = $bookingMarking;
$this->projectName = $projectName;
$this->projectStatus = $projectStatus;
$this->$invoiceId = $invoiceId;
$this->milestoneNames = $milestoneNames;
$this->tasks = $tasks;
}
@@ -105,6 +109,14 @@ class UpdatePerfexCRMObject implements DataTransferObject
return $this->projectStatus;
}
/**
* @return int
*/
public function getInvoiceId(): int
{
return $this->invoiceId;
}
/**
* @return array
*/
@@ -125,4 +137,9 @@ class UpdatePerfexCRMObject implements DataTransferObject
{
$this->tasks = $tasks;
}
public function setInvoiceId($invoiceId)
{
$this->invoiceId = $invoiceId;
}
}
@@ -25,19 +25,7 @@ class CreatePerfexCRMTaskProcessor
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(CreateTaskPerfexCRMObject $createTaskPerfexCRMObject) {
$this->createsPerfexCRMTask->execute(
$createTaskPerfexCRMObject->getName(),
$createTaskPerfexCRMObject->getDescription(),
$createTaskPerfexCRMObject->getLeadId(),
$createTaskPerfexCRMObject->getMilestoneId(),
$createTaskPerfexCRMObject->getProjectId(),
$createTaskPerfexCRMObject->getReference(),
$createTaskPerfexCRMObject->getOnTaskCompletion(),
$createTaskPerfexCRMObject->getDepartment(),
$createTaskPerfexCRMObject->getStatus(),
$createTaskPerfexCRMObject->getPriority(),
$createTaskPerfexCRMObject->getDuedate()
);
$this->createsPerfexCRMTask->execute($createTaskPerfexCRMObject);
return true;
}
@@ -0,0 +1,73 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\FetchPerfexCRMInvoiceObject;
use Illuminate\Support\Facades\Log;
use App\Classes\General\Helper;
class FetchPerfexCRMInvoiceProcessor
{
private $fetchesPerfexCRMCustomer;
/** @var FetchesPerfexCRMCustomer */
/** @var FetchesPerfexCRMInvoice */
private $fetchesPerfexCRMInvoice;
/** @var CreatePerfexCRMInvoiceProcessor */
private $createPerfexCRMInvoiceProcessor;
/**
*
* FetchPerfexCRMInvoiceProcessor constructor.
* @param FetchesPerfexCRMCustomer $fetchesPerfexCRMCustomer
* @param FetchesPerfexCRMInvoice $fetchesPerfexCRMInvoice
* @param CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor
*/
public function __construct(FetchesPerfexCRMCustomer $fetchesPerfexCRMCustomer,
FetchesPerfexCRMInvoice $fetchesPerfexCRMInvoice,
CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor)
{
$this->fetchesPerfexCRMCustomer = $fetchesPerfexCRMCustomer;
$this->fetchesPerfexCRMInvoice = $fetchesPerfexCRMInvoice;
$this->createPerfexCRMInvoiceProcessor = $createPerfexCRMInvoiceProcessor;
}
public function execute(FetchPerfexCRMInvoiceObject $fetchPerfexCRMInvoiceObject)
{
//invoiceId to be returned - fetch or create
$invoiceId = 0;
//get the client id
$customer = $this->fetchesPerfexCRMCustomer->execute($fetchPerfexCRMInvoiceObject->getEmail());
$transaction = $fetchPerfexCRMInvoiceObject->getTransaction();
$number = $transaction->bill_no;
$prefix = "INV-";
//This will remove the prefix if prefix already exist in the string
if (substr($number, 0, strlen($prefix)) == $prefix) {
$number = substr($number, strlen($prefix));
}
$invoice = $this->fetchesPerfexCRMInvoice->execute($customer->userid,"INV-", $number);
if(is_null($invoice)){
$result = $this->createPerfexCRMInvoiceProcessor->execute($transaction->owner);
if ($result) {
$invoiceId = $result->payload['id'];
} else {
$log['message'] = 'FetchPerfexCRMInvoiceProcessor failed for transaction > bill_no: '.$number;
Helper::debugLogger($log);
}
}
else{
$invoiceId = $invoice->id;
}
return $invoiceId;
}
}
@@ -7,6 +7,8 @@ use App\Classes\Jobs\CreatePerfexCRMSingleTask;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskPriority;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Models\Company;
use Illuminate\Support\Facades\Log;
class NewLeadTaskToPerfexCRMProcessor
{
@@ -17,26 +19,32 @@ class NewLeadTaskToPerfexCRMProcessor
*/
public function execute(Company $company)
{
$companyModule = $company->companyModules()->first();
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
try {
$companyModule = $company->companyModules()->first();
$employee = $companyModule->employees()->first();
$contactEmail = $employee->email;
$createTaskPerfexCRMObject = new CreateTaskPerfexCRMObject(
$contactEmail,
PerfexCRMTasks::TASK_IDENTIFICATION_1['name'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['description'],
"",
"",
"",
"",
"",
PerfexCRMTasks::TASK_IDENTIFICATION_1['status'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['department'],
PerfexCRMTaskPriority::DEFAULT,
"0"
);
$createTaskPerfexCRMObject = new CreateTaskPerfexCRMObject(
$contactEmail,
PerfexCRMTasks::TASK_IDENTIFICATION_1['name'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['description'],
"",
"",
"",
"",
"",
PerfexCRMTasks::TASK_IDENTIFICATION_1['status'],
PerfexCRMTasks::TASK_IDENTIFICATION_1['department'],
PerfexCRMTaskPriority::DEFAULT,
"0",
0
);
CreatePerfexCRMSingleTask::dispatch($createTaskPerfexCRMObject);
CreatePerfexCRMSingleTask::dispatch($createTaskPerfexCRMObject);
} catch (\Exception $exception){
Log::error($exception);
}
return true;
}
@@ -8,53 +8,157 @@ use App\Classes\Jobs\UpdatePerfexCRM;
use App\Classes\Jobs\UpdatePerfexCRMPrelude;
use App\Models\PackingList;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Classes\ValueObjects\Constants\PerfexCRMTasksYDStages;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus;
use Illuminate\Support\Facades\Log;
class PackingListToPerfexCRMProcessor
{
/**
* @param PackingList $packingList
* @return \Illuminate\Database\Eloquent\Model
* @return bool
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(PackingList $packingList)
public function execute(PackingList $packingList, int $stage = PerfexCRMTasksYDStages::DEFAULT): bool
{
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;
$info = $this->extractInfo($packingList);
$tasks = $this->defineTasks($stage);
$updatePerfexCRMObject = new UpdatePerfexCRMObject(
$companyName,
$companyReference,
$contactName,
$contactEmail,
"",
$projectName,
$info['companyName'],
$info['companyReference'],
$info['contactName'],
$info['contactEmail'],
$info['bookingMarking'], //For Exchange-2.0
$info['projectName'],
PerfexCRMProjectStatus::NOT_STARTED,
0,
[],
[
PerfexCRMTasks::TASK_LOADED_CONTAINER_1,
PerfexCRMTasks::TASK_LOADED_CONTAINER_2,
]
$tasks
);
UpdatePerfexCRMPrelude::dispatch($packingList, null, $updatePerfexCRMObject, UpdatePerfexCRM::class, null);
$this->dispatchUpdateJob($packingList, $updatePerfexCRMObject);
}
} catch (\Exception $exception){
Log::error(json_encode('PackingListToPerfexCRMProcessor debug:'));
Log::error(json_encode($packingList));
Log::error('PackingListToPerfexCRMProcessor: ' . json_encode($packingList));
Log::error($exception);
}
return true;
}
//Level 1
private function extractInfo(PackingList $packingList): array
{
$order = $packingList->owner;
$companyModule = $order->companyModule()->first();
$employee = $companyModule->employees()->first();
$info = [];
$info['companyName'] = $companyModule->name;
$info['companyReference'] = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$info['contactName'] = $employee->name;
$info['contactEmail'] = $employee->email;
$info['bookingMarking'] = ''; //For Exchange-2.0
$info['projectName'] = 'IZYIM | X1 Shipping | '.$packingList->owner->reference.' | '.$packingList->reference;
return $info;
}
private function defineTasks(int $stage): array
{
$tasks = [];
if ($stage === PerfexCRMTasksYDStages::DEFAULT) {
$tasks = $this->defineAllYDStagesTasks();
}
else if ($stage === PerfexCRMTasksYDStages::LOAD_CONTAINER) {
$tasks = $this->updateLoadContainerTasks();
}
else if ($stage === PerfexCRMTasksYDStages::SHIP_SAILED) {
$tasks = $this->updateShipSailedTasks();
}
else if ($stage === PerfexCRMTasksYDStages::SHIP_ARRIVED) {
$tasks = $this->updateShipArrivedTasks();
}
else if ($stage === PerfexCRMTasksYDStages::UNSTUFFING) {
$tasks = $this->updateUnstuffingTasks();
}
else if ($stage === PerfexCRMTasksYDStages::DELIVERY) {
$tasks = $this->updateDeliveryTasks();
}
return $tasks;
}
private function dispatchUpdateJob(PackingList $packingList, UpdatePerfexCRMObject $updatePerfexCRMObject)
{
UpdatePerfexCRMPrelude::dispatch($packingList, null, $updatePerfexCRMObject, false);
}
//Level Others: Nested
private function defineAllYDStagesTasks(): array
{
$tasks = [
PerfexCRMTasks::TASK_YD_LOADED_CONTAINER_1,
PerfexCRMTasks::TASK_YD_LOADED_CONTAINER_2,
PerfexCRMTasks::TASK_YD_LOADED_CONTAINER_3,
PerfexCRMTasks::TASK_YD_SHIPPING_1,
PerfexCRMTasks::TASK_YD_UNSTUFFING_1,
PerfexCRMTasks::TASK_YD_DELIVERY_1,
];
return $tasks;
}
private function updateLoadContainerTasks(): array
{
$tasks = [];
$tasks = $this->completeTask(null, PerfexCRMTasks::TASK_YD_LOADED_CONTAINER_3);
return $tasks;
}
private function updateShipSailedTasks(): array
{
$tasks = [];
$tasks = $this->completeTask(PerfexCRMTasks::TASK_YD_LOADED_CONTAINER_3, PerfexCRMTasks::TASK_YD_SHIPPING_1);
return $tasks;
}
private function updateShipArrivedTasks(): array
{
$tasks = [];
$tasks = $this->completeTask(PerfexCRMTasks::TASK_YD_SHIPPING_1, PerfexCRMTasks::TASK_YD_UNSTUFFING_1);
return $tasks;
}
private function updateUnstuffingTasks(): array
{
$tasks = [];
$tasks = $this->completeTask(PerfexCRMTasks::TASK_YD_UNSTUFFING_1, PerfexCRMTasks::TASK_YD_DELIVERY_1);
return $tasks;
}
private function updateDeliveryTasks(): array
{
$tasks = [];
$tasks = $this->completeTask(PerfexCRMTasks::TASK_YD_DELIVERY_1, null);
return $tasks;
}
private function completeTask($startTask, $endTask) {
$resultArray = [];
if($startTask){
$startTask['status'] = PerfexCRMTaskStatus::COMPLETED;
array_push($resultArray, $startTask);
}
if($endTask){
$endTask['status'] = PerfexCRMTaskStatus::IN_PROGRESS;
array_push($resultArray, $endTask);
}
return $resultArray;
}
}
@@ -1,75 +0,0 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
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
{
/**
* @param Transaction $model
* @param int $status
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Transaction $model, int $status)
{
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 = $order->reference;
$packingListReference = $packingList->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$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,
]
);
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;
}
}
@@ -0,0 +1,145 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Processors;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMTasks;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus;
use App\Classes\Jobs\UpdatePerfexCRMPrelude;
use App\Classes\Jobs\CreatePerfexCRMInvoice;
use App\Models\Booking;
use App\Models\Transaction;
use Illuminate\Support\Facades\Log;
class TransactionToPerfexCRMV2Processor
{
public function execute(Transaction $model, int $status)
{
try {
if($model->owner instanceof \App\Models\Transaction && in_array($model->type, [TransactionType::PAYMENT])) {
//
$transaction = $model;
$info = $this->extractInfo($transaction);
$tasks = $this->defineTasks($model, $status);
//if(count($tasks) > 0) { //commented, otherwise when customer paid, invoice payment will not get created at crm because there is no tasks attached
$updatePerfexCRMObject = new UpdatePerfexCRMObject(
$info['companyName'],
$info['companyReference'],
$info['contactName'],
$info['contactEmail'],
$info['bookingMarking'],
$info['projectName'],
PerfexCRMProjectStatus::IN_PROGRESS,
0, //invoiceId
[], //milestoneNames
$tasks
);
$this->dispatchUpdateJob($transaction, $status, $updatePerfexCRMObject);
//}
}
else if($model->owner instanceof \App\Models\PackingList && $model->status == ApprovalStatus::PENDING_SUBMISSION && $status == ApprovalStatus::APPROVED)
{
CreatePerfexCRMInvoice::dispatch($model);
}
} catch (\Exception $exception) {
Log::error($exception);
}
return true;
}
//Level 1
private function extractInfo(Transaction $model): array
{
$packingList = $model->owner->owner;
$order = $packingList->owner()->first();
$companyModule = $order->companyModule()->first();
$employee = $companyModule->employees()->first();
$info = [];
$info['companyName'] = $companyModule->name;
$info['companyReference'] = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$info['contactName'] = $employee->name;
$info['contactEmail'] = $employee->email;
$info['bookingMarking'] = $packingList->id."-".$packingList->owner->id;
$info['projectName'] = 'IZYIM | X1 Shipping | '.$order->reference.' | '.$packingList->reference;
return $info;
}
private function defineTasks(Transaction $model, int $status): array
{
$tasks = [];
if ($status === ApprovalStatus::PENDING_SUBMISSION) {
$tasks = $this->defineTasks_handlePendingVerificationStatus($model);
} elseif ($status === ApprovalStatus::APPROVED) {
$tasks = $this->defineTasks_handleApprovedStatus($model);
}
return $tasks;
}
private function dispatchUpdateJob(Transaction $model, int $status, UpdatePerfexCRMObject $updatePerfexCRMObject)
{
$withInvoice = ($model->type === TransactionType::PAYMENT && $model->owner instanceof \App\Models\Transaction && $status == ApprovalStatus::APPROVED);
UpdatePerfexCRMPrelude::dispatch(null, $model, $updatePerfexCRMObject, $withInvoice);
}
//Level Others: Nested
private function defineTasks_handlePendingVerificationStatus(Transaction $model): array
{
$tasks = [];
switch($model->type) {
case TransactionType::PAYMENT:
$tasks = $this->definePaymentTasks($model);
break;
}
return $tasks;
}
private function defineTasks_handleApprovedStatus(Transaction $model): array
{
$tasks = [];
switch($model->type) {
case TransactionType::PAYMENT:
$tasks = $this->defineTasks_handleApprovedStatus_handlePaymentApprovedStatus();
break;
}
return $tasks;
}
private function definePaymentTasks(Transaction $model): array //cief todo: to comfirm what tasks need to be created
{
$tasks = [];
return $tasks;
}
private function defineTasks_handleApprovedStatus_handlePaymentApprovedStatus(): array //cief todo: to comfirm what tasks need to be created
{
$tasks = [];
// $tasks = [
// PerfexCRMTasks::TASK_POST_PAYMENT_1,
// PerfexCRMTasks::TASK_POST_PAYMENT_2,
// PerfexCRMTasks::TASK_POST_PAYMENT_3,
// PerfexCRMTasks::TASK_POST_PAYMENT_4,
// ];
return $tasks;
}
private function completeTask($startTask, $endTask) {
$startTask['status'] = PerfexCRMTaskStatus::COMPLETED;
$endTask['status'] = PerfexCRMTaskStatus::IN_PROGRESS;
return [$startTask, $endTask];
}
}
@@ -15,10 +15,11 @@ 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\Modules\PerfexCRM\DataTransferObjects\CreateTaskPerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus;
use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
@@ -207,18 +208,46 @@ class UpdatePerfexCRMProcessor
}
// Get existing or create task
$result = $this->fetchesPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, 'project', $projectId);
$taskName = $tasks[$count]['name'];
$taskReference = $tasks[$count]['reference'];
$taskOnTaskCompletion = $tasks[$count]['on_task_completion'];
$taskIsAllowMultiple = $tasks[$count]['is_allow_multiple'];
$taskIsOnTaskCompletionUpdate = $tasks[$count]['is_on_task_completion_update'];
if($updatePerfexCRMObject->getInvoiceId() != 0 && $taskIsAllowMultiple){
$taskName = $taskName." (".$updatePerfexCRMObject->getInvoiceId().")";
$taskReference = $taskReference."_".$updatePerfexCRMObject->getInvoiceId();
if($taskOnTaskCompletion && $taskIsOnTaskCompletionUpdate){
$taskOnTaskCompletion = $taskOnTaskCompletion."_".$updatePerfexCRMObject->getInvoiceId();
}
}
$result = $this->fetchesPerfexCRMTask->execute($taskName, $milestoneId, 'project', $projectId, $updatePerfexCRMObject->getInvoiceId());
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']);
// }
//Check to make sure that task that is already completed do not get updated again
if($taskStatus != PerfexCRMTaskStatus::NOT_STARTED && $result->payload[0]['status'] != PerfexCRMTaskStatus::COMPLETED && $result->payload[0]['status'] != $taskStatus)
{
$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']);
$createTaskPerfexCRMObject = new CreateTaskPerfexCRMObject(
"",
$taskName,
$tasks[$count]['description'],
"",
$projectId,
$milestoneId,
$taskReference,
$taskOnTaskCompletion,
$taskStatus,
$tasks[$count]['department'],
$tasks[$count]['priority'],
$tasks[$count]['duedate'],
$updatePerfexCRMObject->getInvoiceId()
);
$result = $this->createsPerfexCRMTask->execute($createTaskPerfexCRMObject);
}
}
}
@@ -6,67 +6,47 @@ use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
use App\Classes\ValueObjects\Constants\PerfexCRMCustomFields;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateTaskPerfexCRMObject;
class CreatesPerfexCRMTask
{
/**
* @param string $taskName
* @param string $taskDescription
* @param string $leadId
* @param string $milestoneId
* @param string $projectId
* @param string $reference
* @param string $on_task_completion
* @param string $department
* @param string $status
* @param string $priority
* @param string $duedate
* @param CreateTaskPerfexCRMObject $createTaskPerfexCRMObject
* @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 $department, string $status, string $priority, string $duedate) {
public function execute(CreateTaskPerfexCRMObject $createTaskPerfexCRMObject) {
try{
$custom_fields = [];
if($department != ""){
if($createTaskPerfexCRMObject->getDepartment() != ""){
$custom_fields = [
"tasks" => [
PerfexCRMCustomFields::TASKS_DEPARTMENT => $department
PerfexCRMCustomFields::TASKS_DEPARTMENT => $createTaskPerfexCRMObject->getDepartment()
]
];
}
$data = [
'name' => $taskName,
'description' => $taskDescription,
'milestone' => $milestoneId,
'name' => $createTaskPerfexCRMObject->getName(),
'description' => $createTaskPerfexCRMObject->getDescription(),
'milestone' => $createTaskPerfexCRMObject->getMilestoneId(),
'startdate' => date('Y-m-d'),
'rel_type' => 'project',
'rel_id' => $projectId,
'status' => $status,
'rel_id' => $createTaskPerfexCRMObject->getProjectId(),
'status' => $createTaskPerfexCRMObject->getStatus(),
'is_system_created' => 1,
'reference' => $reference,
'on_task_completion' => $on_task_completion,
'reference' => $createTaskPerfexCRMObject->getReference(),
'on_task_completion' => $createTaskPerfexCRMObject->getOnTaskCompletion(),
'custom_fields' => $custom_fields,
'priority' => $priority,
'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')),
'priority' => $createTaskPerfexCRMObject->getPriority(),
'duedate' => date('Y-m-d', strtotime('+' . $createTaskPerfexCRMObject->getDuedate() . ' days')),
'invoice_id' => $createTaskPerfexCRMObject->getInvoiceId(),
];
if($leadId != '') {
$data = [
'name' => $taskName,
'description' => $taskDescription,
'milestone' => $milestoneId,
'startdate' => date('Y-m-d'),
'rel_type' => 'lead',
'rel_id' => $leadId,
'status' => $status,
'is_system_created' => 1,
'reference' => $reference,
'on_task_completion' => $on_task_completion,
'custom_fields' => $custom_fields,
'priority' => $priority,
'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')),
];
if($createTaskPerfexCRMObject->getLeadId() != '') {
$data['rel_type'] = 'lead';
$data['rel_id'] = $createTaskPerfexCRMObject->getLeadId();
}
$response = Http::asForm()->withHeaders([
@@ -17,7 +17,7 @@ class FetchesPerfexCRMTask
* @return null|object
* @throws MalformedRequestException
*/
public function execute(string $taskName, string $milestoneId, string $relType, string $relId) {
public function execute(string $taskName, string $milestoneId, string $relType, string $relId, string $invoiceId) {
try{
$data = [
'name' => $taskName,
@@ -30,6 +30,11 @@ class FetchesPerfexCRMTask
$data = array_merge($data, $newItem);
}
if($invoiceId != 0) {
$newItem = ['invoice_id' => $invoiceId ];
$data = array_merge($data, $newItem);
}
$response = Http::asForm()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->post(config('perfexcrm.base_url').'/api/tasks/customsearch', $data);
@@ -39,7 +44,7 @@ class FetchesPerfexCRMTask
return (object) $data;
}else{
Helper::debugLoggerForPerfexCRM($response);
Helper::debugLogger($response);
return null;
}
}catch(\Exception $exception){
@@ -38,7 +38,7 @@ class UpdatesPerfexCRMCustomer
$data = $response->json();
return (object) $data;
}else{
Helper::debugLoggerForPerfexCRM($response);
// Helper::debugLogger($response);
return null;
}
}catch(\Exception $exception){
@@ -31,7 +31,7 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
private $createPaymentTransactionProcessor;
public function __construct(
FetchesTransaction $fetchesTransaction,
FetchesTransaction $fetchesTransaction,
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
)
{
@@ -47,6 +47,20 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
$payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'));
//cief todo: at exchange there is a transition step
// if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){
// $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION);
// }
// if(config('perfexcrm.is_enabled') == 'true'){
// $this->transactionToPerfexCRMV2Processor->execute($transaction, $status);
// }
//To use
//ApprovalStatus::PENDING_VERIFICATION;
//use this to trigger $this->transactionToPerfexCRMV2Processor->execute > defineTasks > defineTasks_handlePendingVerificationStatus > definePaymentTasks
return $this->resourceResponse(new TransactionResource($payment_transaction));
}
}
@@ -0,0 +1,56 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Http\Resources\MappableTransactionWithDetailsResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ListMappableTransactionWithDetailsLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Transactions With Details',
'message' => 'You have successfully retrieved a list of transactions'
];
}
/** @var ListsTransactions */
private $listsTransactions;
/**
* ListTransactionsLogic constructor.
* @param ListsTransactions $listsTransactions
*/
public function __construct(ListsTransactions $listsTransactions)
{
$this->listsTransactions = $listsTransactions;
}
public function logic(Request $request) : JsonResponse
{
$filePath = storage_path('logs/list_mappable_transaction_with_details.log');
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $request->input('filters') . PHP_EOL;
file_put_contents($filePath, $textToAppend, FILE_APPEND);
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
return $this->collectionResponse(MappableTransactionWithDetailsResource::collection($query));
}
}
@@ -4,20 +4,20 @@ 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\TransactionToPerfexCRMV2Processor;
class UpdatesTransactionStatus extends AbstractUpdateRecord
{
/** @var TransactionToPerfexCRMProcessor */
private $transactionToPerfexCRMProcessor;
/** @var TransactionToPerfexCRMV2Processor */
private $transactionToPerfexCRMV2Processor;
/**
* UpdatesTransactionStatus constructor.
* @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor
* @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMV2Processor
*/
public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor)
public function __construct(TransactionToPerfexCRMV2Processor $transactionToPerfexCRMV2Processor)
{
$this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor;
$this->transactionToPerfexCRMV2Processor = $transactionToPerfexCRMV2Processor;
}
/**
@@ -33,7 +33,7 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord
$result = $this->handler($model);
if(config('perfexcrm.is_enabled') == 'true'){
$this->transactionToPerfexCRMProcessor->execute($transaction, $status);
$this->transactionToPerfexCRMV2Processor->execute($transaction, $status);
}
return $result;
}
@@ -16,7 +16,9 @@ class PerfexCRMTasks
'department' => '',
'status' => PerfexCRMTaskStatus::COMPLETED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
'duedate' => 0,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_POST_PAYMENT_1 = [
@@ -35,7 +37,9 @@ class PerfexCRMTasks
'department' => 'Accounts',
'status' => PerfexCRMTaskStatus::IN_PROGRESS,
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 0
'duedate' => 0,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_POST_PAYMENT_2 = [
'name' => 'Approve Payment',
@@ -47,7 +51,9 @@ class PerfexCRMTasks
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::HIGH,
'duedate' => 0
'duedate' => 0,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_POST_PAYMENT_3 = [
'name' => 'Issue Shipping Autocount Invoince',
@@ -65,7 +71,9 @@ class PerfexCRMTasks
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::MEDIUM,
'duedate' => 1
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_POST_PAYMENT_3_1 = [
'name' => 'Issue Shipping Autocount OR',
@@ -78,7 +86,9 @@ class PerfexCRMTasks
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
'duedate' => 0,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_POST_PAYMENT_4 = [
'name' => 'Knockoff Invoice',
@@ -96,34 +106,11 @@ class PerfexCRMTasks
'department' => 'Accounts',
'status' => '',
'priority' => PerfexCRMTaskPriority::MEDIUM,
'duedate' => 1
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
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 = [
@@ -142,6 +129,97 @@ class PerfexCRMTasks
'department' => 'Operations',
'status' => PerfexCRMTaskStatus::IN_PROGRESS,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 0
'duedate' => 0,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_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,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_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,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_LOADED_CONTAINER_3 = [
'name' => 'Track 1 - Loaded Container',
'description' => '',
'milestone' => '',
'reference' => 'TASK_YD_SHIPPING_3',
'on_task_completion' => '',
'department' => '',
'status' => PerfexCRMTaskStatus::NOT_STARTED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_SHIPPING_1 = [
'name' => 'Track 2 - Shipping',
'description' => '',
'milestone' => '',
'reference' => 'TASK_YD_SHIPPING_1',
'on_task_completion' => '',
'department' => '',
'status' => PerfexCRMTaskStatus::NOT_STARTED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_UNSTUFFING_1 = [
'name' => 'Track 3 - Unstuffing',
'description' => '',
'milestone' => '',
'reference' => 'TASK_YD_UNSTUFFING_1',
'on_task_completion' => '',
'department' => '',
'status' => PerfexCRMTaskStatus::NOT_STARTED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
public const TASK_YD_DELIVERY_1 = [
'name' => 'Track 4 - Delivery',
'description' => '',
'milestone' => '',
'reference' => 'TASK_YD_DELIVERY_1',
'on_task_completion' => '',
'department' => '',
'status' => PerfexCRMTaskStatus::NOT_STARTED,
'priority' => PerfexCRMTaskPriority::DEFAULT,
'duedate' => 1,
'is_allow_multiple' => false,
'is_on_task_completion_update' => false
];
}
@@ -0,0 +1,17 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class PerfexCRMTasksYDStages {
public const DEFAULT = 0;
public const LOAD_CONTAINER = 10;
public const SHIP_SAILED = 20;
public const SHIP_ARRIVED = 21;
public const UNSTUFFING = 30;
public const DELIVERY = 40;
}
@@ -0,0 +1,77 @@
<?php
namespace App\Console\Commands;
use App\Models\Container;
use App\Models\ContainerPackingList;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class FixDuplicateContainerReference extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fix-duplicate-container-reference';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Fix all duplicated container reference';
/**
* 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() . ' : Started.');
$start = new Carbon();
$duplicatedContainers = Container::select('reference', DB::raw('COUNT(reference) as count'))
->groupBy('reference')
->having('count', '>', 1)
->get();
foreach ($duplicatedContainers as $duplicatedContainer) {
$containers = Container::where('reference', $duplicatedContainer->reference)->get();
$containers = $containers->sortByDesc(function ($container) {
return $container->packingLists->count();
});
$firstContainer = $containers->shift();
foreach ($containers as $container) {
$firstContainer->packingLists()->syncWithoutDetaching($container->packingLists);
$container->packingLists()->detach();
$this->info('Deleted container ' . $container->id);
$container->delete();
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done. ElapsedTime: ' . $elapsedTime);
}
}
+88
View File
@@ -0,0 +1,88 @@
<?php
namespace App\Console\Commands;
use App\Models\PackingList;
use Carbon\Carbon;
use Illuminate\Console\Command;
class FixPackingList extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fix-packinglist';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Fix PackingList';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$packingLists = PackingList::whereDoesntHave('packages')->get();
if ($packingLists->isNotEmpty()) {
$this->info(Carbon::now() . ' : ' . $this->description . ' cron started.');
$start = Carbon::now();
$restoredPackagesCount = 0;
$restoredPackagesIds = [];
// Eager loading packages for all packing lists
$packingLists->load(['packages' => function ($query) {
$query->onlyTrashed();
}]);
foreach ($packingLists as $packingList) {
$deletedPackages = $packingList->packages->filter(function ($package) use ($restoredPackagesIds) {
// Filter out packages that have already been restored
return !in_array($package->id, $restoredPackagesIds);
});
if ($deletedPackages->isNotEmpty()) {
$groupedPackages = $deletedPackages->groupBy(function ($item) {
return $item->only(['type', 'description', 'width', 'height', 'length', 'weight', 'quantity']);
});
foreach ($groupedPackages as $group) {
$latestPackage = $group->sortByDesc('created_at')->first();
// Check if the package ID is already restored before attempting to restore it
if (!in_array($latestPackage->id, $restoredPackagesIds)) {
$latestPackage->restore();
$this->info('Package ID: ' . $latestPackage->id . ' has been restored');
$restoredPackagesCount++;
$restoredPackagesIds[] = $latestPackage->id;
}
}
}
}
$end = Carbon::now();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : Done ' . $this->description . '. ElapsedTime: ' . $elapsedTime . '.');
$this->info('Restored Packages Count: ' . $restoredPackagesCount);
}
}
}
+15 -5
View File
@@ -34,14 +34,24 @@ class Kernel extends ConsoleKernel
->appendOutputTo (storage_path().'/logs/curlvt.log');
$schedule->command('command:curlYdOrderListCommand')
->cron('30 9-18/3 * * *')
->cron('0 9-18/3 * * *')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/curlyd.log');
$schedule->command('command:curlYdOrderListCommand')
->cron('0 9 * * *')
$schedule->command('fix-packinglist')
->cron('30 9-18/3 * * *')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/departure_email.log');
->appendOutputTo (storage_path().'/logs/fix_packinglist.log');
// $schedule->command('command:curlYdOrderListCommand')
// ->cron('0 9 * * *')
// ->withoutOverlapping()
// ->appendOutputTo (storage_path().'/logs/departure_email.log');
$schedule->command('fix-duplicate-container-reference')
->cron('0 1 * * *')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/fix_duplicate_container_reference.log');
$schedule->command('invoice:generate')
->hourly()
@@ -49,7 +59,7 @@ class Kernel extends ConsoleKernel
->appendOutputTo (storage_path().'/logs/auto_generate_invoice.log');
$schedule->command('billplz-failed-callback:fix')
->dailyAt('00:00')
->hourly()
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/fix_failed_callback_from_billplz.log');
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists;
use App\Classes\Modules\PackingLists\ControllersLogic\CreateWarehouseTransportLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateWarehouseTransportController
{
/**
* @param Request $request
* @param CreateContainerLogic $logic
* @return JsonResponse
*/
public function create(Request $request, CreateWarehouseTransportLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Transactions;
use App\Classes\Modules\Transactions\ControllersLogic\ListMappableTransactionWithDetailsLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListMappableTransactionWithDetailsController
{
/**
* @param Request $request
* @return JsonResponse
*/
public function list(Request $request, ListMappableTransactionWithDetailsLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -50,6 +50,7 @@ class CompanyModuleResource extends JsonResource
'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())),
'debtor' => $this->company->debtor,
];
}
@@ -31,6 +31,7 @@ class MappableTransactionResource extends JsonResource
}
return [
'status' => 'success',
'system' => 'SHIPPING_PORTAL',
'type' => $this->type,
'owner_type' => $this->owner_type,
@@ -0,0 +1,69 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Http\Resources\Json\JsonResource;
use Exception;
class MappableTransactionWithDetailsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$data = [
'status' => 'success',
'id' => $this->id,
'updated_at' => $this->updated_at,
'type' => $this->type,
'amount' => $this->amount,
'debtor_code' => null,
'order_reference' => null,
'bill_no' => null,
'marking' => null,
];
if ($this->type === TransactionType::PAYMENT) {
$order = $this->owner->owner->owner;
$data['order_reference'] = $order->reference;
$data['debtor_code'] = $order->companyModule->company->debtor;
} elseif (in_array($this->type, [TransactionType::GROUP_PAYMENT, TransactionType::TOP_UP])) {
$connection = $this->owner->owner->inviters()->withPivot('invitee_reference')->first();
$data['marking'] = $connection ? $connection->pivot->invitee_reference : '';
$data['bill_no'] = $this->bill_no;
} else {
$payments = $this->transactions()
->payments()->where('status', ApprovalStatus::APPROVED)
->get();
if ($payments->count()) {
$data['payment_transactions'] = $payments->map(function ($payment) {
$order = $payment->owner->owner->owner;
return [
'id' => $payment->id,
'updated_at' => $payment->updated_at,
'debtor_code' => $order->companyModule->company->debtor,
'order_reference' => $order->reference,
'bill_no' => null,
'type' => $payment->type,
'marking' => null,
'amount' => $payment->amount,
];
})->toArray();
} else {
$data['status'] = 'error';
$data['amount'] = 'Transaction Type not allowed';
$data['transaction_type'] = $this->type;
$data['payment_transactions'] = null;
}
}
return $data;
}
}
@@ -0,0 +1,78 @@
<template>
<div class="row bg-white padding-40 b-rad-lg" @keyup.enter="submitForm">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h4>Create Warehouse Transport</h4>
</div>
</div>
<div class="row">
<div class="col">
<validation-wrapper-component class="m-b-10" :validator="$v.parameters.receive_date">
<label class="text-primary text-left">Receive Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.receive_date"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col">
<validation-wrapper-component class="m-b-10" :validator="$v.parameters.tracking">
<label class="text-primary text-left">Tracking Number</label>
<input type="text" class="form-control" v-model="parameters.tracking">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-default btn-block bg-master-lighter" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-block b-rad-none btn-success" @click="submitForm">Confrim</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import { required } from "vuelidate/lib/validators";
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
props: {
packinglistId: {
type: Number,
required: true
},
section: {
type: String,
required: true
},
},
data() {
return {
error: '',
parameters: {
receive_date: this.receive_date,
tracking: this.tracking,
}
};
},
validations: {
parameters: {
receive_date: {
required
},
tracking: {
},
}
},
methods: {
submitForm() {
this.submit(this.route('api.packing_list.warehouse_transport.create', this.packinglistId), 'post', this.section, true, true);
}
},
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -61,6 +61,16 @@
</div>
</div>
<div class="col-auto">
<div class="row text-center parentContainer m-b-10" v-if="['Pending Invoice'].includes(invoice_status) && !item.receive_packing_list" >
<div class="col">
<div class="requestModal pointer btn btn-primary btn-xs" data-type="addWarehouseTransport">
Add Warehouse Transport
</div>
<modal-component class="animate_animated animatefast animate_fadeIn" styleType="fill-in" type="addWarehouseTransport">
<create-warehouse-transport-form-component :packinglistId="item.id" :section="section"></create-warehouse-transport-form-component>
</modal-component>
</div>
</div>
<div class="row">
<div class="col">
<div class="btn bg-grey no-border" @click="expanded = !expanded" v-if="['Pending Approval', 'Pending Payment'].includes(invoice_status)">
+1
View File
@@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Route;
Route::group(['middleware' => 'apipub', 'prefix' => 'v1', 'as' => 'apipub.'], function () {
Route::group(['middleware' => 'token.check'], function () {
Route::get('transactions/query', 'Transactions\ListTransactionsController@list')->name('transaction.list');
Route::get('transactions/mappable/query/with-details', 'Transactions\ListMappableTransactionWithDetailsController@list')->name('transaction.mappable.list.with_details');
Route::get('transactions/mappable/query', 'Transactions\ListMappableTransactionsController@list')->name('transaction.mappable.list');
Route::get('groups/query', 'Transactions\ListGroupsController@list')->name('group.list');
});
+1
View File
@@ -20,6 +20,7 @@ Route::group(['namespace' => 'PackingLists', 'as' => 'packing_list.', 'prefix' =
Route::put('/assign-remark/{id}', 'AssignPackingListRemarkController@create')->name('assign.remark');
Route::put('/assign-order/{id}/{reference}', 'AssignPackingListOrderController@assign')->name('assign.order');
Route::post('/{id}/warehouse-transport/create', 'CreateWarehouseTransportController@create')->name('warehouse_transport.create');
Route::group(['namespace' => 'Containers', 'prefix' => 'container', 'as' => 'container.'], function () {
Route::get('/{id}/show', 'FetchContainerController@fetch')->name('show');
+5 -5
View File
@@ -178,7 +178,7 @@ Route::post('/support', function (Request $request) {
$company_module_contact = $company_module->contacts()->first();
$company = $company_module->company;
$company_contact = $company->contacts()->first();
$dataReturn[] = json_encode(
[
'connection' => $connection ? $connection->toArray() : null,
@@ -188,7 +188,7 @@ Route::post('/support', function (Request $request) {
'company_contact' => $company_contact ? $company_contact->toArray() : null,
]
);
}
} else {
$markingNotFound = true;
@@ -376,10 +376,10 @@ Route::group(['prefix' => 'yd', 'as' => 'yd.'], function () {
Route::get('/yd', function (Request $request){
$start = $request->input('start_date') ? Carbon::parse($request->input('start_date')): null;
$end = $request->input('end_date') ? Carbon::parse($request->input('end_date')): null;
// (App()->make(FetchPackingListsFromYdPortalProcessor::class))->execute($start, $end);
// (App()->make(FetchContainersFromYdPortalProcessor::class))->execute();
(App()->make(FetchPackingListsFromYdPortalProcessor::class))->execute($start, $end);
(App()->make(FetchContainersFromYdPortalProcessor::class))->execute();
(App()->make(FetchContainersUpdatesFromYdPortalProcessor::class))->execute();
// (App()->make(FetchDeliveryUpdatesFromYdPortalProcessor::class))->execute();
(App()->make(FetchDeliveryUpdatesFromYdPortalProcessor::class))->execute();
// (App()->make(FetchPackingListFromVTPortalProcessor::class))->execute();
})->name('yd.refresh');