diff --git a/app/Classes/Jobs/UpdatePerfexCRM.php b/app/Classes/Jobs/UpdatePerfexCRM.php index 059779e1..833fb365 100644 --- a/app/Classes/Jobs/UpdatePerfexCRM.php +++ b/app/Classes/Jobs/UpdatePerfexCRM.php @@ -10,7 +10,8 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject; - +use Illuminate\Support\Facades\Log; +use PhpOffice\PhpSpreadsheet\Calculation\Logical\Boolean; class UpdatePerfexCRM implements ShouldQueue { @@ -19,38 +20,39 @@ class UpdatePerfexCRM implements ShouldQueue /** @var UpdatePerfexCRMObject */ private $updatePerfexCRMObject; - /** @var UpdatePerfexCRMInvoice */ - private $nextJob; - - /** @var */ + /** @var */ private $transaction; + /** @var Boolean|null */ + private $shouldCreateInvoice; + /** - * UpdatePerfexCRM constructor. * @param UpdatePerfexCRMObject $updatePerfexCRMObject - * @param UpdatePerfexCRMInvoice $nextJob * @param $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() { $result = (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject); - /** @var UpdatePerfexCRMInvoice $nextJob*/ - if($this->nextJob != null && $this->transaction != null){ - $updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject( + if($this->transaction != null && $this->shouldCreateInvoice){ + $updatePerfexCRMInvoiceObject = new UpdatePerfexCRMInvoiceObject( $this->updatePerfexCRMObject->getContactEmail(), $this->updatePerfexCRMObject->getProjectName(), $result->projectId, $this->transaction, - true, + true ); - $this->nextJob::dispatch($updatePerfexCRMInvoiceOject); + + UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceObject); + } } } diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 0d7b093e..ee395033 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -30,7 +30,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue /** * CreatePerfexCRMSingleTask constructor. - * @param UpdatePerfexCRMInvoiceObject $createTaskPerfexCRMObject + * @param UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject */ public function __construct(UpdatePerfexCRMInvoiceObject $updatePerfexCRMInvoiceObject) { @@ -65,7 +65,8 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $invoiceId = $result->payload['id']; } else { // Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed')); - Helper::debugLoggerForPerfexCRM('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'); + $log['message'] = 'UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'; + Helper::debugLoggerForPerfexCRM($log); } } else{ diff --git a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php index 25afdc4d..3b05ac63 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php +++ b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php @@ -21,50 +21,28 @@ class UpdatePerfexCRMPrelude implements ShouldQueue /** @var UpdatePerfexCRMObject */ private $updatePerfexCRMObject; - /** @var UpdatePerfexCRM */ - private $nextJob1; - - /** @var UpdatePerfexCRMInvoice */ - private $nextJob2; + /** @var Boolean|null */ + private $shouldCreateInvoice; /** - * UpdatePerfexCRMPrelude constructor. * @param Transaction $transaction * @param UpdatePerfexCRMObject $updatePerfexCRMObject - * @param UpdatePerfexCRM $nextJob1 - * @param UpdatePerfexCRMInvoice $nextJob2 + * @param bool|null $shouldCreateInvoice */ - public function __construct(Transaction $transaction, UpdatePerfexCRMObject $updatePerfexCRMObject, $nextJob1, $nextJob2) + public function __construct(Transaction $transaction, UpdatePerfexCRMObject $updatePerfexCRMObject, ?bool $shouldCreateInvoice = false) { $this->transaction = $transaction; $this->updatePerfexCRMObject = $updatePerfexCRMObject; - $this->nextJob1 = $nextJob1; - $this->nextJob2 = $nextJob2; + $this->shouldCreateInvoice = $shouldCreateInvoice; } + public function handle() { $serviceTypeName = $this->transaction->owner->company->services()->where('id', $this->transaction->owner->service_id)->first()->name; $booking = $this->transaction->booking; - $bank = $booking->bank; - $bankDetails = $this->transaction->owner->service_id == 4 ? - [ - '1688_username' => $bank->account_no, - '1688_password' => $bank->holder_name, - 'payment_pin' => $bank->bank_branch, - ]: - [ - 'id' => $bank->id, - 'type' => $bank->type, - 'reference' => $bank->reference, - 'bank_name' => $bank->bank_name, - 'bank_branch' => $bank->bank_branch, - 'holder_name' => $bank->holder_name, - 'account_no' => $bank->account_no, - 'country_id' => $bank->country_id, - 'default' => $bank->default, - 'status' => $bank->status, - ]; + $bankDetails = $this->generateBankDetails($booking->bank); + $data = [ 'amount' => number_format($this->transaction->amount, 2, '.', ''), 'currency' => $this->transaction->currency_id == 1 ? "MYR" : "CNY", @@ -75,14 +53,36 @@ class UpdatePerfexCRMPrelude implements ShouldQueue 'link_autocount_or' => 'https://docs.google.com/spreadsheets/d/1Q3rJBGQ9Bo04HZp5WR9zbLp7pIW2kfDYsabxG7JON-4/edit#gid=2013983170', ]; - $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); } + + private function generateBankDetails($bank): array + { + return $this->transaction->owner->service_id == 4 ? + [ + '1688_username' => $bank->account_no, + '1688_password' => $bank->holder_name, + 'payment_pin' => $bank->bank_branch, + ]: + [ + 'id' => $bank->id, + 'type' => $bank->type, + 'reference' => $bank->reference, + 'bank_name' => $bank->bank_name, + 'bank_branch' => $bank->bank_branch, + 'holder_name' => $bank->holder_name, + 'account_no' => $bank->account_no, + 'country_id' => $bank->country_id, + 'default' => $bank->default, + 'status' => $bank->status, + ]; + } + + function replacePlaceholders($template, $data, $prefix = '') { foreach ($template as $key => $value) { diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php index 0fbf2519..a93a3654 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php @@ -17,6 +17,7 @@ use App\Classes\Modules\PerfexCRM\Processors\BookingToPerfexCRMProcessor; use App\Http\Resources\BookingResource; +use App\Models\Booking; use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -82,6 +83,7 @@ class CreateBookingLogic extends AbstractControllerLogic $this->canCreateBooking->passes($object); + /** @var Booking $booking */ $booking = $this->createsBooking->execute($company, $object); if(config('perfexcrm.is_enabled') == 'true'){ diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index 77d8252d..b0e4da51 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -5,27 +5,29 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; use App\Classes\Exceptions\MalformedRequestException; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Modules\Bookings\DataTransferObjects\CalculationObject; use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding; use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation; use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; +use App\Classes\Modules\Vouchers\DataTransferObjects\VoucherObject; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\CreatesTransaction; -use App\Classes\Modules\Transactions\Services\UpdatesTransaction; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use App\Classes\Modules\Vouchers\Services\FetchesVoucher; +use App\Classes\Modules\Vouchers\Services\CreatesVoucher; +use App\Classes\Modules\Vouchers\Services\CreatesVoucherRedemption; +use App\Classes\Modules\Vouchers\Services\RedeemsVoucher; use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Http\Resources\TransactionResource; -use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor; - use App\Models\Booking; use App\Models\Transaction; -use App\Models\Wallet; use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -34,6 +36,7 @@ use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance; class CreateBookingPaymentLogic extends AbstractControllerLogic { + /** * @return array */ @@ -68,14 +71,24 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic /** @var UpdatesTransactionStatus */ private $updatesTransactionStatus; - /** @var CreateCashBackTransactionProcessor */ - private $createCashBackTransactionProcessor; /** @var RecalculatesWalletBalance */ private $recalculatesWalletBalance; + /** @var FetchesVoucher */ + private $fetchesVoucher; + + /** @var CreatesVoucher */ + private $createsVoucher; + + /** @var CreatesVoucherRedemption */ + private $createsVoucherRedemption; + + /** @var RedeemsVoucher */ + private $redeemsVoucher; + + /** - * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation * @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber @@ -84,10 +97,13 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic * @param CreatesBillplzBill $createsBillplzBill * @param UpdatesWalletBalance $updatesWalletBalance * @param UpdatesTransactionStatus $updatesTransactionStatus - * @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor * @param RecalculatesWalletBalance $recalculatesWalletBalance + * @param FetchesVoucher $fetchesVoucher + * @param CreatesVoucher $createsVoucher + * @param CreatesVoucherRedemption $createsVoucherRedemption + * @param RedeemsVoucher $redeemsVoucher */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, RecalculatesWalletBalance $recalculatesWalletBalance, FetchesVoucher $fetchesVoucher, CreatesVoucher $createsVoucher, CreatesVoucherRedemption $createsVoucherRedemption, RedeemsVoucher $redeemsVoucher) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; @@ -97,75 +113,146 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $this->createsBillplzBill = $createsBillplzBill; $this->updatesWalletBalance = $updatesWalletBalance; $this->updatesTransactionStatus = $updatesTransactionStatus; - $this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor; $this->recalculatesWalletBalance = $recalculatesWalletBalance; + $this->fetchesVoucher = $fetchesVoucher; + $this->createsVoucher = $createsVoucher; + $this->createsVoucherRedemption = $createsVoucherRedemption; + $this->redeemsVoucher = $redeemsVoucher; } - /** - * @param Request $request - * @return JsonResponse - * @throws MalformedRequestException - */ public function logic(Request $request) : JsonResponse { $booking = Booking::find($request->route('id')); - $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]); + $conversionObject = $this->createConversionObject($request, $booking); - $outstanding = $this->calculatesBookingOutstanding->execute($booking); + $this->validatePayment($request, $booking, $conversionObject); - if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); - - $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject); - - $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); + $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $request->input('voucher_code')); $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); - $paymentReference = null; + $paymentReference = $this->handlePaymentMethods($request, $booking, $configurations, $billNumber); - $amount = $configurations->getTotal(); - - if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ - $billPlzBill = $this->createsBillplzBill->execute($booking->company->name, $request->user()->email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $request->input('bank_code')); - $paymentReference = $billPlzBill->id; - } - - if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){ - /** @var Wallet $wallet */ - $wallet = $booking->company->wallets()->first(); - - if((float) number_format(($wallet->amount - $amount),2) < 0){ - throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); - } - - $transaction_object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], ''); - $transaction = $this->createsTransaction->execute($wallet, $transaction_object); - - $paymentReference = $billNumber; - - $walletBalance = $this->recalculatesWalletBalance->execute($wallet); - $this->updatesWalletBalance->execute($wallet, $walletBalance); - } - - $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); - - $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, - $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), - $configurations->getTotal(), $configurations->getForeignTotal(), 1, - $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference); + $object = $this->createTransactionObject($booking, $configurations, $billNumber, $paymentReference); /** @var Transaction $transaction */ $transaction = $this->createsTransaction->execute($booking, $object); -// $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction); - if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){ - $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ + $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); } + // $this->handleVoucherCode($request, $booking, $configurations, $transaction); //todo-important: uncomment this for voucherify + return $this->resourceResponse(new TransactionResource($transaction)); } + private function createConversionObject(Request $request, Booking $booking): CurrencyConversionObject + { + return new CurrencyConversionObject( + floatval(str_replace(',', '', $request->input('amount'))), + $booking->convertible_currency_id, + $booking->service_id, + $booking->fix_currency_id === 1 ? 0:1, + PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] + ); + } + private function validatePayment(Request $request, Booking $booking, CurrencyConversionObject $conversionObject): void + { + $outstanding = $this->calculatesBookingOutstanding->execute($booking); + + if($conversionObject->getAmount() > round($outstanding, 2)) + throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); + } + + private function handlePaymentMethods(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): ?string + { + $paymentReference = null; + + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY) + $paymentReference = $this->handlePaymentGateway($request, $booking, $configurations, $billNumber); + + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET) + $paymentReference = $this->handleWalletPayment($request, $booking, $configurations, $billNumber); + + return $paymentReference; + } + + private function handlePaymentGateway(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): string + { + $billPlzBill = $this->createsBillplzBill->execute( + $booking->company->name, + $request->user()->email, + 'This payment is made for transfer ref. '.$booking->marking, + $configurations->getTotal(), + $billNumber, + $request->input('bank_code') + ); + + return $billPlzBill->id; + } + + private function handleWalletPayment(Request $request, Booking $booking, CalculationObject $configurations, string $billNumber): string + { + $wallet = $booking->company->wallets()->first(); + + $amount = $configurations->getTotal(); + if((float) number_format(($wallet->amount - $amount),2) < 0) + throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); + + $transactionObject = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], ''); + $this->createsTransaction->execute($wallet, $transactionObject); + + $walletBalance = $this->recalculatesWalletBalance->execute($wallet); + $this->updatesWalletBalance->execute($wallet, $walletBalance); + + return $billNumber; + } + + private function createTransactionObject(Booking $booking, CalculationObject $configurations, string $billNumber, ?string $paymentReference): TransactionObject + { + return new TransactionObject( + $billNumber, + TransactionType::PAYMENT, + 1, + $booking->company->id, + $configurations->getConfigurations()->getBankId(), + $configurations->getConversionObject()->getPaymentMethod(), + $configurations->getTotal(), + $configurations->getForeignTotal(), + 1, + $configurations->getConversionObject()->getCurrencyId(), + $configurations->getConfigurations()->getRate(), + $configurations->getTax(), + $configurations->getServiceCharge(), + Carbon::now()->addMinutes($this->fetchesCompanyPaymentAttemptLimit->execute($booking->company)), + ApprovalStatus::PENDING_SUBMISSION, + [], + $paymentReference + ); + } + + private function handleVoucherCode(Request $request, Booking $booking, CalculationObject $configurations, Transaction $transaction): void + { + $voucherCode = $request->input('voucher_code'); + if($voucherCode){ + $employee = $booking->company->employees()->first(); + + $result = $this->redeemsVoucher->execute($voucherCode, $configurations->getSubTotal(), $employee); + $voucher = $result->voucher; + $redemptionId = $result->id; + + $voucherValue = $voucher->discount->amount_off ?? ($voucher->discount->percent_off ?? 0.00); + $voucherObject = new VoucherObject($voucher->code, $voucher->metadata->name ?? "", $voucher->discount->type, $voucherValue); + $voucher = $this->createsVoucher->execute($voucherObject); + + if(!$voucher) + $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]); + + $this->createsVoucherRedemption->execute($redemptionId, $voucher->id, $employee->id, $configurations->getVoucherDiscountAmount()); + } + } } + diff --git a/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php index 76b01825..930d3765 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php @@ -2,6 +2,7 @@ namespace App\Classes\Modules\PerfexCRM\Processors; +use App\Classes\Exceptions\MalformedRequestException; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\Jobs\UpdatePerfexCRM; use App\Models\Booking; @@ -11,10 +12,10 @@ class BookingToPerfexCRMProcessor { /** * @param Booking $booking - * @return \Illuminate\Database\Eloquent\Model - * @throws \App\Classes\Exceptions\MalformedRequestException + * @return bool + * @throws MalformedRequestException */ - public function execute(Booking $booking) + public function execute(Booking $booking): bool { $companyReference = $booking->company->reference; $companyName = $booking->company->name; @@ -37,6 +38,7 @@ class BookingToPerfexCRMProcessor [], [] ); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject, null, null); return true; diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessorV2.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessorV2.php new file mode 100644 index 00000000..3a2d2a5b --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessorV2.php @@ -0,0 +1,169 @@ +owner instanceof \App\Models\Booking) { + $bookingInfo = $this->extractBookingInfo($model); + $projectName = 'Exchange | ' . $bookingInfo['serviceTypeName'] . ' | ' . $bookingInfo['bookingMarking']; + $tasks = $this->defineTasks($model, $status); + + if(count($tasks) > 0) { + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $bookingInfo['companyName'], + $bookingInfo['companyReference'], + $bookingInfo['contactName'], + $bookingInfo['contactEmail'], + $bookingInfo['bookingMarking'], + $projectName, + PerfexCRMProjectStatus::IN_PROGRESS, + [], + $tasks + ); + $this->dispatchUpdateJob($model, $status, $updatePerfexCRMObject); + } + } + } catch (\Exception $exception) { + Log::error('TransactionToPerfexCRMProcessor debug:'); + Log::error($exception); + } + return true; + } + + private function extractBookingInfo(Transaction $model): array + { + $bookingInfo = []; + $bookingInfo['companyReference'] = $model->owner->company->reference; + $bookingInfo['companyName'] = $model->owner->company->name; + $bookingInfo['contactEmail'] = $model->owner->company->employees()->first()->email; + $bookingInfo['contactName'] = $model->owner->company->employees()->first()->name; + $bookingInfo['bookingMarking'] = $model->owner->marking; + $bookingInfo['serviceTypeName'] = $model->owner->company->services()->where('id', $model->owner->service_id)->first()->name; + + return $bookingInfo; + } + + private function defineTasks(Transaction $model, int $status): array + { + $tasks = []; + + if($status === ApprovalStatus::PENDING_VERIFICATION && (int) $model->type === TransactionType::PAYMENT) { + $tasks = $this->definePaymentTasks($model); + } elseif($status === ApprovalStatus::PENDING_VERIFICATION && $model->type === TransactionType::PURCHASE_ORDER) { + if($model->owner->service_id === 1 || $model->owner->service_id === 3) { + $tasks = [PerfexCRMTasks::TASK_PURCHASE_ORDER_1]; + } + } elseif($status === ApprovalStatus::APPROVED && $model->type === TransactionType::PAYMENT) { + $task = PerfexCRMTasks::TASK_1_DAY_TRANSFER_2; + $task['status'] = PerfexCRMTaskStatus::COMPLETED; + $tasks = [$task]; + } + + return $tasks; + } + + private function definePaymentTasks(Transaction $model): array + { + $tasks = [ +// PerfexCRMTasks::TASK_1 + ]; + + if ($model->owner->service_id === 1) { + $tasks = array_merge($tasks, $this->oneDayTransferTasks()); + } elseif ($model->owner->service_id === 3) { + $tasks = array_merge($tasks, $this->threeDayTransferTasks()); + } elseif ($model->owner->service_id === 4) { + $tasks = array_merge($tasks, $this->payment1688Tasks()); + } + + if ($model->owner->service_id === 1 || $model->owner->service_id === 3) { + $purchaseOrder = $model->booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->complete()->first(); + if(is_null($purchaseOrder)){ + $tasks = array_merge($tasks, $this->purchaseOrderTasks()); + } + } + + return $tasks; + } + + private function oneDayTransferTasks(): array + { + return [ +// PerfexCRMTasks::TASK_1_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_2, +// PerfexCRMTasks::TASK_1_DAY_TRANSFER_3, +// PerfexCRMTasks::TASK_1_DAY_TRANSFER_3_1, +// PerfexCRMTasks::TASK_1_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_6 + ]; + } + + private function threeDayTransferTasks(): array + { + return [ +// PerfexCRMTasks::TASK_3_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_2, +// PerfexCRMTasks::TASK_3_DAY_TRANSFER_3, +// PerfexCRMTasks::TASK_3_DAY_TRANSFER_3_1, +// PerfexCRMTasks::TASK_3_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_6 + ]; + } + + private function payment1688Tasks(): array + { + return [ +// PerfexCRMTasks::TASK_1688_PAYMENT_1, + PerfexCRMTasks::TASK_1688_PAYMENT_2, +// PerfexCRMTasks::TASK_1688_PAYMENT_3, +// PerfexCRMTasks::TASK_1688_PAYMENT_3_1, +// PerfexCRMTasks::TASK_1688_PAYMENT_4, + PerfexCRMTasks::TASK_1688_PAYMENT_5, +// PerfexCRMTasks::TASK_1688_PAYMENT_6, + PerfexCRMTasks::TASK_1688_PAYMENT_7, + PerfexCRMTasks::TASK_1688_PAYMENT_8, + PerfexCRMTasks::TASK_1688_PAYMENT_9, + PerfexCRMTasks::TASK_1688_PAYMENT_10, + PerfexCRMTasks::TASK_1688_PAYMENT_11, + PerfexCRMTasks::TASK_1688_PAYMENT_12, + PerfexCRMTasks::TASK_1688_PAYMENT_13 + ]; + } + + private function purchaseOrderTasks(): array + { + $potask1 = PerfexCRMTasks::TASK_PURCHASE_ORDER_1; + $potask1['status'] = PerfexCRMTaskStatus::NOT_STARTED; + + return [ + $potask1, +// PerfexCRMTasks::TASK_PURCHASE_ORDER_2 + ]; + } + + private function dispatchUpdateJob(Transaction $model, int $status, UpdatePerfexCRMObject $updatePerfexCRMObject) + { + Log::info(json_encode($updatePerfexCRMObject->getTasks())); + $withInvoice = ($model->type === TransactionType::PAYMENT && $model->owner === Booking::class && $status === ApprovalStatus::APPROVED); + UpdatePerfexCRMPrelude::dispatch($model, $updatePerfexCRMObject, $withInvoice); + } +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php index 752c9644..0bfe2ba5 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -109,7 +109,7 @@ class UpdatePerfexCRMProcessor */ public function execute(UpdatePerfexCRMObject $updatePerfexCRMObject) { $projectId = ""; - + // Customer has to exist first before Project can appear under it // Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer $crmCompany = $updatePerfexCRMObject->getCompanyName(); @@ -205,6 +205,7 @@ class UpdatePerfexCRMProcessor // Get existing or create task $result = $this->fetchesPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, 'project', $projectId); if(isset($result->payload)){ + Log::info(json_encode([$taskStatus != PerfexCRMTaskStatus::NOT_STARTED, $result->payload[0]['status'] == PerfexCRMTaskStatus::NOT_STARTED])); if($taskStatus != PerfexCRMTaskStatus::NOT_STARTED && $result->payload[0]['status'] == PerfexCRMTaskStatus::NOT_STARTED) { $task = $result->payload[0]; diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index 2091c3cf..9d6b9fe4 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -3,23 +3,24 @@ namespace App\Classes\Modules\Transactions\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; +use App\Classes\Modules\PerfexCRM\Processors\TransactionToPerfexCRMProcessorV2; use App\Models\Transaction; use App\Classes\Modules\PerfexCRM\Processors\TransactionToPerfexCRMProcessor; class UpdatesTransactionStatus extends AbstractUpdateRecord { - /** @var TransactionToPerfexCRMProcessor */ + /** @var TransactionToPerfexCRMProcessorV2 */ private $transactionToPerfexCRMProcessor; /** - * UpdatesTransactionStatus constructor. - * @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor + * @param TransactionToPerfexCRMProcessorV2 $transactionToPerfexCRMProcessor */ - public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor) + public function __construct(TransactionToPerfexCRMProcessorV2 $transactionToPerfexCRMProcessor) { $this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor; } + /** * @param Transaction $model * @param int $status diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php b/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php index 9e19ccec..4129f2a8 100644 --- a/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php +++ b/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php @@ -43,9 +43,9 @@ class PerfexCRMTasks ○ Outcomes: The payment will be approved in exchange, allowing the next steps in the process to be initiated.
', 'milestone' => '', 'reference' => 'TASK_1_DAY_TRANSFER_2', - 'on_task_completion' => 'TASK_1_DAY_TRANSFER_3,TASK_1_DAY_TRANSFER_5', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_5', 'department' => 'Accounts', - 'status' => '', + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, 'priority' => PerfexCRMTaskPriority::HIGH, 'duedate' => 0 ]; @@ -160,9 +160,9 @@ class PerfexCRMTasks ○ Link to order page: {link_transfer}
', 'milestone' => '', 'reference' => 'TASK_3_DAY_TRANSFER_2', - 'on_task_completion' => 'TASK_3_DAY_TRANSFER_3,TASK_3_DAY_TRANSFER_5', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_5', 'department' => 'Accounts', - 'status' => '', + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, 'priority' => PerfexCRMTaskPriority::HIGH, 'duedate' => 0 ]; @@ -286,9 +286,9 @@ class PerfexCRMTasks ○ Outcomes: The payment will be approved in exchange, allowing the next steps in the process to be initiated.
', 'milestone' => '', 'reference' => 'TASK_1688_PAYMENT_2', - 'on_task_completion' => 'TASK_1688_PAYMENT_3,TASK_1688_PAYMENT_5', + 'on_task_completion' => 'TASK_1688_PAYMENT_5', 'department' => 'Accounts', - 'status' => '', + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, 'priority' => PerfexCRMTaskPriority::HIGH, 'duedate' => 0 ]; @@ -353,7 +353,7 @@ class PerfexCRMTasks ○ Outcomes: The order is placed with a supplier and the customer\'s order is confirmed.
', 'milestone' => '', 'reference' => 'TASK_1688_PAYMENT_5', - 'on_task_completion' => 'TASK_1688_PAYMENT_6', + 'on_task_completion' => 'TASK_1688_PAYMENT_7', 'department' => 'Operations', 'status' => '', 'priority' => PerfexCRMTaskPriority::HIGH, @@ -454,14 +454,14 @@ class PerfexCRMTasks ○ link: {link_transfer}
', 'milestone' => '', 'reference' => 'TASK_1688_PAYMENT_12', - 'on_task_completion' => 'TASK_1688_PAYMENT_13', + 'on_task_completion' => '', 'department' => 'Operations', 'status' => '', 'priority' => PerfexCRMTaskPriority::LOW, 'duedate' => 1 ]; public const TASK_1688_PAYMENT_13 = [ - 'name' => 'Complete Order bookeeping', + 'name' => 'Complete Order bookkeeping', 'description' => '○ Purpose: To complete the bookkeeping for the booking.
○ Initial Status: Not Started
○ Deadline: Same day
@@ -493,7 +493,7 @@ class PerfexCRMTasks ○ Outcomes: Bank transaction is mapped successfully, allowing the next steps in the process to be initiated.
', 'milestone' => '', 'reference' => 'TASK_PURCHASE_ORDER_1', - 'on_task_completion' => 'TASK_PURCHASE_ORDER_2', + 'on_task_completion' => '', 'department' => 'Operations', 'status' => PerfexCRMTaskStatus::IN_PROGRESS, 'priority' => PerfexCRMTaskPriority::LOW, diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 0df23186..cf2dddb9 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -25,6 +25,11 @@ class Transaction extends AbstractModel implements Documentable, Transactionable use SoftDeletes; use LogData; + protected $casts = [ + 'type' => 'int', + 'status' => 'int', + ]; + protected $table = 'transactions'; public function owner(): morphTo @@ -112,6 +117,14 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $this->HasOne(GroupTransaction::class, 'transaction_id'); } + /** + * @return HasOne + */ + public function voucherRedemption(): HasOne + { + return $this->HasOne(VoucherRedemption::class, 'transaction_id', 'id'); + } + public function convert_original_amount() { if($this->booking()->first()->fix_currency_id !== 1) {