CRM tie invoice to project

This commit is contained in:
Dillon
2023-03-06 15:12:55 +08:00
parent d52131d9df
commit 128c8083c3
6 changed files with 130 additions and 18 deletions
+23 -7
View File
@@ -6,9 +6,12 @@ use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMCustomer;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMInvoice; use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject;
use App\Classes\ValueObjects\Constants\PerfexCRMInvoiceStatus; use App\Classes\ValueObjects\Constants\PerfexCRMInvoiceStatus;
use App\Models\Transaction;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
@@ -20,12 +23,6 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var FetchesPerfexCRMInvoice */
private $FetchesPerfexCRMInvoice;
/** @var FetchesPerfexCRMCustomer */
private $fetchesPerfexCRMCustomer;
/** @var UpdatePerfexCRMInvoiceObject */ /** @var UpdatePerfexCRMInvoiceObject */
private $updatePerfexCRMInvoiceObject; private $updatePerfexCRMInvoiceObject;
@@ -50,14 +47,33 @@ class UpdatePerfexCRMInvoice implements ShouldQueue
$invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $transaction->owner->bill_no); $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $transaction->owner->bill_no);
if(is_null($invoice)){ if(is_null($invoice)){
$result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner); $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner, $this->updatePerfexCRMInvoiceObject->getIsPaid());
$invoiceId = $result->payload['id']; $invoiceId = $result->payload['id'];
} }
else{ else{
$invoiceId = $invoice->id; $invoiceId = $invoice->id;
$invoiceStatus = $invoice->status; $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 = "";
if($transaction->owner instanceof Transaction){
$orderReference = $transaction->owner->owner->owner()->first()->reference;
$packingListReference = $transaction->owner->owner->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$project = (App()->make(FetchesPerfexCRMProject::class))->execute($projectName, $customer->userid);
if(!is_null($project)){
$projectId = $project->id;
}
}
//update invoice
(App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $projectId);
}
} }
//create invoice payment
if($invoiceId != 0 && $invoiceStatus != PerfexCRMInvoiceStatus::PAID){ if($invoiceId != 0 && $invoiceStatus != PerfexCRMInvoiceStatus::PAID){
$date = Carbon::parse($transaction->created_at)->format('Y-m-d'); $date = Carbon::parse($transaction->created_at)->format('Y-m-d');
@@ -14,10 +14,14 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject
/** @var Transaction */ /** @var Transaction */
private $transaction; private $transaction;
public function __construct(string $email, Transaction $transaction) /** @var bool */
private $isPaid;
public function __construct(string $email, Transaction $transaction, bool $isPaid)
{ {
$this->email = $email; $this->email = $email;
$this->transaction = $transaction; $this->transaction = $transaction;
$this->isPaid = $isPaid;
} }
/** /**
@@ -35,4 +39,12 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject
{ {
return $this->transaction; return $this->transaction;
} }
/**
* @return bool
*/
public function getIsPaid(): bool
{
return $this->isPaid;
}
} }
@@ -6,9 +6,11 @@ use App\Models\Transaction;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoice; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoice;
use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoicePayment;
use App\Classes\Modules\PerfexCRM\Services\ConvertsPerfexCRMLeadToCustomer; use App\Classes\Modules\PerfexCRM\Services\ConvertsPerfexCRMLeadToCustomer;
use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMProject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject;
use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject;
use App\Models\PackingList;
use Carbon\Carbon; use Carbon\Carbon;
class CreatePerfexCRMInvoiceProcessor class CreatePerfexCRMInvoiceProcessor
@@ -23,29 +25,35 @@ class CreatePerfexCRMInvoiceProcessor
/** @var ConvertsPerfexCRMLeadToCustomer */ /** @var ConvertsPerfexCRMLeadToCustomer */
private $convertsPerfexCRMLeadToCustomer; private $convertsPerfexCRMLeadToCustomer;
/** @var FetchesPerfexCRMProject */
private $fetchesPerfexCRMProject;
/** /**
* CreatePerfexCRMInvoiceProcessor constructor. * CreatePerfexCRMInvoiceProcessor constructor.
* @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice * @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice
*/ */
public function __construct(CreatesPerfexCRMInvoice $createsPerfexCRMInvoice, public function __construct(CreatesPerfexCRMInvoice $createsPerfexCRMInvoice,
CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment, CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment,
ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer) ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer,
FetchesPerfexCRMProject $fetchesPerfexCRMProject)
{ {
$this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice; $this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice;
$this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment; $this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment;
$this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer;
$this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject;
} }
/** /**
* @param Transaction $transaction * @param Transaction $transaction
* @param bool $isPaid, default: false
* @return null|object * @return null|object
* @throws \App\Classes\Exceptions\MalformedRequestException * @throws \App\Classes\Exceptions\MalformedRequestException
*/ */
public function execute(Transaction $transaction) { public function execute(Transaction $transaction, bool $isPaid = false) {
$clientId = ""; $clientId = "";
$number = $transaction->bill_no; $number = $transaction->bill_no;
$prefix = "INV-"; $prefix = "INV-";
//This will remove the prefix if prefix already exist in the string //This will remove the prefix if prefix already exist in the string
if (substr($number, 0, strlen($prefix)) == $prefix) { if (substr($number, 0, strlen($prefix)) == $prefix) {
$number = substr($number, strlen($prefix)); $number = substr($number, strlen($prefix));
@@ -71,7 +79,6 @@ class CreatePerfexCRMInvoiceProcessor
$billingStreet = $billingStreet.$addresses->state()->first()->name.','; $billingStreet = $billingStreet.$addresses->state()->first()->name.',';
$billingStreet = $billingStreet.$addresses->country()->first()->name; $billingStreet = $billingStreet.$addresses->country()->first()->name;
$projectId = "";
$allowedPaymentModes = []; $allowedPaymentModes = [];
$invoiceItems = []; $invoiceItems = [];
@@ -83,6 +90,20 @@ class CreatePerfexCRMInvoiceProcessor
$clientId = $result->payload['client_id']; $clientId = $result->payload['client_id'];
} }
//get project
$projectId = ""; //Project only exist in CRM if the customer already made payment
if($isPaid){
if($transaction->owner instanceof PackingList){
$orderReference = $transaction->owner->owner->reference;
$packingListReference = $transaction->owner->reference;
$projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference;
$project = (App()->make(FetchesPerfexCRMProject::class))->execute($projectName, $clientId);
if(!is_null($project)){
$projectId = $project->id;
}
}
}
//newitems //newitems
foreach ($transaction->transactionDetails as $key => $transaction_detail){ foreach ($transaction->transactionDetails as $key => $transaction_detail){
$order = $key + 1; $order = $key + 1;
@@ -89,6 +89,7 @@ class TransactionToPerfexCRMProcessor
$updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject( $updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject(
$contactEmail, $contactEmail,
$model, $model,
true
); );
UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject); UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject);
} }
@@ -0,0 +1,67 @@
<?php
namespace App\Classes\Modules\PerfexCRM\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
class UpdatesPerfexCRMInvoice
{
/**
* @param $invoice
* @param string $projectId
* @return null|object
* @throws MalformedRequestException
*/
public function execute($invoice, string $projectId) {
try{
// <p>The Invoice number field is required.<\/p>
// <p>The Invoice date field is required.<\/p>
// <p>The Currency field is required.<\/p>
// <p>The Items field is required.<\/p>
// <p>The Allow Payment Mode field is required.<\/p>
// <p>The Billing Street field is required.<\/p>
// <p>The Sub Total field is required.<\/p>
// <p>The Total field is required.<\/p>
$newInvoiceItems = [];
foreach ($invoice->items as $item) {
$item['itemid'] = $item['id'];
unset($item['id']);
$item['order'] = $item['item_order'];
unset($item['item_order']);
array_push($newInvoiceItems,$item);
}
$data = [
'number' => $invoice->number,
'date' => $invoice->date,
'duedate' => $invoice->date,
'currency' => $invoice->currency,
'subtotal' => $invoice->subtotal,
'total' => $invoice->total,
'billing_street' => $invoice->billing_street,
'shipping_street' => $invoice->billing_street,
'project_id' => $projectId,
'items' => $newInvoiceItems,
'allowed_payment_modes' => $invoice->allowed_payment_modes,
];
$response = Http::asJson()->withHeaders([
'authtoken' => config('perfexcrm.api_key')])
->put(config('perfexcrm.base_url').'/api/invoices/'.$invoice->id, $data);
if($response->successful()){
$data = $response->json();
return (object) $data;
}else{
Log::error($response);
return null;
}
}catch(\Exception $exception){
throw new MalformedRequestException('Unable to get correct response from Perfex CRM server: ' . $exception->getMessage());
}
}
}
@@ -16,7 +16,6 @@ use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument; use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor;
use App\Classes\Jobs\CreatePerfexCRMInvoice; use App\Classes\Jobs\CreatePerfexCRMInvoice;
class ApproveShippingInvoiceTransactionProcessor class ApproveShippingInvoiceTransactionProcessor
@@ -31,21 +30,17 @@ class ApproveShippingInvoiceTransactionProcessor
/** @var CreatesFiles */ /** @var CreatesFiles */
private $createsFiles; private $createsFiles;
/** @var CreatePerfexCRMInvoiceProcessor */
private $createPerfexCRMInvoiceProcessor;
/** /**
* @param UpdatesTransactionStatus $updatesTransactionStatus * @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesDocument $createsDocument * @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles * @param CreatesFiles $createsFiles
* @param CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor
*/ */
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles, CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor) public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{ {
$this->updatesTransactionStatus = $updatesTransactionStatus; $this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsDocument = $createsDocument; $this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles; $this->createsFiles = $createsFiles;
$this->createPerfexCRMInvoiceProcessor = $createPerfexCRMInvoiceProcessor;
} }