From 15f07f553b0e281969b7f00201e058ccc9c97611 Mon Sep 17 00:00:00 2001 From: Dillon Date: Sat, 18 Mar 2023 02:11:50 +0800 Subject: [PATCH 1/4] Update business logic of when invoice at CRM should be generated --- app/Classes/Jobs/UpdatePerfexCRMInvoice.php | 103 ++++++++++++ .../UpdatePerfexCRMInvoiceObject.php | 62 +++++++ .../CreatePerfexCRMInvoiceProcessor.php | 154 +++++++++++------- .../TransactionToPerfexCRMProcessor.php | 11 +- .../CreateInvoiceTransactionProcessor.php | 10 +- .../Services/UpdatesTransactionStatus.php | 15 +- 6 files changed, 281 insertions(+), 74 deletions(-) create mode 100644 app/Classes/Jobs/UpdatePerfexCRMInvoice.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php new file mode 100644 index 00000000..dae4cdc9 --- /dev/null +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -0,0 +1,103 @@ +updatePerfexCRMInvoiceObject = $updatePerfexCRMInvoiceObject; + } + + public function handle() + { + //get the client id + $customer = (App()->make(FetchesPerfexCRMCustomer::class))->execute($this->updatePerfexCRMInvoiceObject->getEmail()); + $transaction = $this->updatePerfexCRMInvoiceObject->getTransaction(); + + //get the invoice id + $invoiceId = 0; + $invoiceStatus = 0; + + $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)); + } + + $number = 'EXC-'.$number; + $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $number); + + if(is_null($invoice)){ + $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction, null, null, $this->updatePerfexCRMInvoiceObject->getIsPaid()); + $invoiceId = $result->payload['id']; + } + else{ + $invoiceId = $invoice->id; + $invoiceStatus = $invoice->status; + + //This only run when invoice already exist and the invoice does not have a PAID status + if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){ + //get project + $projectId = ""; + $project = (App()->make(FetchesPerfexCRMProject::class))->execute($this->updatePerfexCRMInvoiceObject->getProjectName(), $customer->userid); + if(!is_null($project)){ + $projectId = $project->id; + } + + if($projectId == ""){ + Log::error(json_encode('UpdatePerfexCRMInvoice debug: '.$this->updatePerfexCRMInvoiceObject->getProjectName())); + Log::error(json_encode($transaction->owner)); + } + + //update invoice + (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $projectId); + } + } + + //create invoice payment + if($invoiceId != 0 && $invoiceStatus != PerfexCRMInvoiceStatus::PAID){ + + $date = Carbon::parse($transaction->created_at)->format('Y-m-d'); + + $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject( + $invoiceId, + "$transaction->amount", + $date, + 1, + "", + "" + ); + (App()->make(CreatesPerfexCRMInvoicePayment::class))->execute($invoicePaymentPerfexCRMObject); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php new file mode 100644 index 00000000..ff2c2080 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php @@ -0,0 +1,62 @@ +email = $email; + $this->transaction = $transaction; + $this->isPaid = $isPaid; + $this->projectName = $projectName; + } + + /** + * @return string + */ + public function getEmail(): string + { + return $this->email; + } + + /** + * @return Transaction + */ + public function getTransaction(): Transaction + { + return $this->transaction; + } + + /** + * @return bool + */ + public function getIsPaid(): bool + { + return $this->isPaid; + } + + /** + * @return string + */ + public function getProjectName(): string + { + return $this->projectName; + } +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 767bd894..8c505014 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -8,10 +8,12 @@ use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment; use App\Classes\Modules\PerfexCRM\Services\ConvertsPerfexCRMLeadToCustomer; use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerProject; +use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject; use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; +use App\Classes\ValueObjects\Constants\TransactionType; use Carbon\Carbon; class CreatePerfexCRMInvoiceProcessor @@ -32,6 +34,9 @@ class CreatePerfexCRMInvoiceProcessor /** @var CreatesPerfexCRMCustomerProject */ private $createsPerfexCRMCustomerProject; + /** @var FetchesCompany */ + private $fetchesCompany; + /** * CreatePerfexCRMInvoiceProcessor constructor. * @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice @@ -40,13 +45,15 @@ class CreatePerfexCRMInvoiceProcessor CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment, ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer, FetchesPerfexCRMProject $fetchesPerfexCRMProject, - CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject) + CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject, + FetchesCompany $fetchesCompany) { $this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice; $this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment; $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; + $this->fetchesCompany = $fetchesCompany; } /** @@ -57,19 +64,31 @@ class CreatePerfexCRMInvoiceProcessor * @throws \App\Classes\Exceptions\MalformedRequestException */ public function execute($transaction, $purchaseOrder, $supplier) { + $booking = $transaction->booking; + + if(is_null($supplier)){ + $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); + } + if(is_null($purchaseOrder)){ + $purchaseOrder = $booking->transactions() + ->where('type', TransactionType::PURCHASE_ORDER) + ->complete() + ->first(); + } $clientId = ""; $number = $transaction->bill_no; - $prefix = "INV-"; + $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)); } + $number = 'EXC-'.$number; - $date = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); - $dueDate = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); + $date = Carbon::parse($booking->created_at)->format('Y-m-d'); + $dueDate = Carbon::parse($booking->created_at)->format('Y-m-d'); $currency = 1; //cief TODO: To look into Malaysia and Chinese currency $subTotal = 0.00; $total = 0.00; @@ -111,47 +130,67 @@ class CreatePerfexCRMInvoiceProcessor } } - //newitems - foreach ($purchaseOrder->transactionDetails as $key => $transaction_detail){ - $order = $key + 1; - $stockCode = $transaction_detail->product_code; - $description = $transaction_detail->product_name; - $quantity = $transaction_detail->quantity; - $unitPrice = 0.00; - if($transaction->booking()->first()->fix_currency_id !== 1) - $unitPrice = (1/$transaction->currency_rate) * $transaction_detail->price; - else - $unitPrice = $transaction_detail->price; - - //$totalAmount = 0.00; - if($transaction->booking()->first()->fix_currency_id !== 1){ - - //$totalAmount = (float)number_format( (1/$transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity; - $subTotal += number_format((1/$transaction->currency_rate) * $transaction_detail->price, 2,'.','') * $transaction_detail->quantity; - } - else - { - //$totalAmount = (float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity; - $subTotal += number_format($transaction_detail->price, 2,'.','') * $transaction_detail->quantity; - } - - //string $description, string $longDescription, int $qty, int $rate, int $order, string $unit - $invoiceSingleItem = new InvoiceSingleItemPerfexCRMObject( - $description, + if(is_null($purchaseOrder)){ + $extraInvoiceSingleItem = new InvoiceSingleItemPerfexCRMObject( + 'Refer to booking: '.$booking->marking, "", - $quantity, - $unitPrice, - $order, + 1.00, + $transaction->amount, + 1, "" ); - array_push($invoiceItems, $invoiceSingleItem); - } - - if($transaction->booking()->first()->fix_currency_id !== 1){ - $total = ((1/$transaction->currency_rate) * $transaction->amount) + $transaction->service_charge + $transaction->tax; + $subTotal += number_format($transaction->amount, 2,'.','') * 1; + array_push($invoiceItems, $extraInvoiceSingleItem); } else{ - $total = $transaction->amount + $transaction->service_charge + $transaction->tax; + foreach ($purchaseOrder->transactionDetails as $key => $transaction_detail){ + $order = $key + 1; + $stockCode = $transaction_detail->product_code; + $description = $transaction_detail->product_name; + $quantity = $transaction_detail->quantity; + $unitPrice = 0.00; + if($booking->first()->fix_currency_id !== 1) + $unitPrice = (1/$transaction->currency_rate) * $transaction_detail->price; + else + $unitPrice = $transaction_detail->price; + + //$totalAmount = 0.00; + if($booking->first()->fix_currency_id !== 1){ + + //$totalAmount = (float)number_format( (1/$transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity; + $subTotal += number_format((1/$transaction->currency_rate) * $transaction_detail->price, 2,'.','') * $transaction_detail->quantity; + } + else + { + //$totalAmount = (float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity; + $subTotal += number_format($transaction_detail->price, 2,'.','') * $transaction_detail->quantity; + } + + //string $description, string $longDescription, int $qty, int $rate, int $order, string $unit + $invoiceSingleItem = new InvoiceSingleItemPerfexCRMObject( + $description, + "", + $quantity, + $unitPrice, + $order, + "" + ); + array_push($invoiceItems, $invoiceSingleItem); + } + } + + //When this transaction is of TransactionType::PAYMENT, the amount is actually in the currecy user choose to pay (RM) + //So there is no need to convert it + if ($transaction->type == TransactionType::PAYMENT){ + $total = $transaction->amount; + } + else{ + if($booking->first()->fix_currency_id !== 1){ + $total = ((1/$transaction->currency_rate) * $transaction->amount) + $transaction->service_charge + $transaction->tax; + } + else{ + $total = $transaction->amount + $transaction->service_charge + $transaction->tax; + } } //This setting is similar to Setup > Leads > Sources, Setup > Leads > Statuses @@ -174,25 +213,26 @@ class CreatePerfexCRMInvoiceProcessor $result = $this->createsPerfexCRMInvoice->execute($invoicePerfexCRMObject); - if(!is_null($result)) - { - if($result->payload['id']){ - $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject( - $result->payload['id'], - $total, - $date, - 1, - "", - "" - ); - $this->createsPerfexCRMInvoicePayment->execute($invoicePaymentPerfexCRMObject); - } - } + //cief todo: When invoices need to be regenerated, need to ensure payment do not get double created + + // if(!is_null($result)) + // { + // if($result->payload['id']){ + // $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject( + // $result->payload['id'], + // $total, + // $date, + // 1, + // "", + // "" + // ); + // $this->createsPerfexCRMInvoicePayment->execute($invoicePaymentPerfexCRMObject); + // } + // } //else: logs will record the following: //"status":false,"error":{"number":"The Invoice number is already in use"},"message":"

The Invoice number is already in use<\/p>"} - - return true; + return $result; } - } + diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index cd7ba6b0..6d9a558c 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -7,7 +7,8 @@ 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\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject; +use App\Classes\Jobs\UpdatePerfexCRMInvoice; use App\Classes\Jobs\UpdatePerfexCRM; use App\Models\Transaction; @@ -93,6 +94,14 @@ class TransactionToPerfexCRMProcessor ); UpdatePerfexCRM::dispatch($updatePerfexCRMObject); } + + $updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject( + $contactEmail, + $model, + true, + $projectName + ); + UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject); } else if($status == ApprovalStatus::PENDING_VERIFICATION){ if($model->type == TransactionType::PURCHASE_ORDER){ diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index d48d4d5b..985d45ea 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -194,11 +194,11 @@ class CreateInvoiceTransactionProcessor // supply deliver order $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER); - // update perfex crm - if(config('perfexcrm.is_enabled') == 'true'){ - CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); - } - $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); + + // update perfex crm + // if(config('perfexcrm.is_enabled') == 'true'){ + // CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); + // } } } diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index 2843e0c2..cdd8c81c 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -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,12 +28,11 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord */ public function execute(Transaction $model, int $status) { + $model->status = $status; + $result = $this->handler($model); if(config('perfexcrm.is_enabled') == 'true'){ $this->transactionToPerfexCRMProcessor->execute($model, $status); - // $this->newLeadTaskToPerfexCRMProcessor->execute(); } - $model->status = $status; - return $this->handler($model); + return $result; } - } From ee4521a071679e5f0b71f927ccef7d950169e868 Mon Sep 17 00:00:00 2001 From: Dillon Date: Sat, 18 Mar 2023 02:39:01 +0800 Subject: [PATCH 2/4] Update due date for invoice --- .../PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 8c505014..384bfbb1 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -86,9 +86,8 @@ class CreatePerfexCRMInvoiceProcessor } $number = 'EXC-'.$number; - $date = Carbon::parse($booking->created_at)->format('Y-m-d'); - $dueDate = Carbon::parse($booking->created_at)->format('Y-m-d'); + $dueDate = Carbon::parse($booking->created_at)->addDays(6)->startOfDay()->format('Y-m-d'); $currency = 1; //cief TODO: To look into Malaysia and Chinese currency $subTotal = 0.00; $total = 0.00; From 5a226d18e10cb06422f44e788e132b6aa101993b Mon Sep 17 00:00:00 2001 From: Dillon Date: Sun, 19 Mar 2023 04:32:01 +0800 Subject: [PATCH 3/4] Undo a change that was meant for shipping portal --- .../PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 384bfbb1..86017450 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -87,7 +87,7 @@ class CreatePerfexCRMInvoiceProcessor $number = 'EXC-'.$number; $date = Carbon::parse($booking->created_at)->format('Y-m-d'); - $dueDate = Carbon::parse($booking->created_at)->addDays(6)->startOfDay()->format('Y-m-d'); + $dueDate = Carbon::parse($booking->created_at)->format('Y-m-d'); $currency = 1; //cief TODO: To look into Malaysia and Chinese currency $subTotal = 0.00; $total = 0.00; From 4a4c53e3883f7053057a2f908ef3e51435b14f48 Mon Sep 17 00:00:00 2001 From: Dillon Date: Sun, 19 Mar 2023 04:55:54 +0800 Subject: [PATCH 4/4] Fix a problem of a mismatch in data update for invoice --- .../Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php index 5240d931..21a79a96 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -38,7 +38,7 @@ class UpdatesPerfexCRMInvoice $data = [ 'number' => $invoice->number, 'date' => $invoice->date, - 'duedate' => $invoice->date, + 'duedate' => $invoice->duedate, 'currency' => $invoice->currency, 'subtotal' => $invoice->subtotal, 'total' => $invoice->total,