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..86017450 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,30 @@ 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'); + $number = 'EXC-'.$number; + $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 +129,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 +212,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/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php index e5e5088b..1ade5453 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -41,7 +41,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, 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; } - }