From 5a199fccb4431cfbf7aa6e4e3ea16c4a465b3540 Mon Sep 17 00:00:00 2001 From: glovetleong Date: Thu, 27 Oct 2022 00:48:18 +0800 Subject: [PATCH 01/18] docker setup --- docker-setup/Dockerfile | 28 ++++++++++++++++++++++++++++ docker-setup/nginx/default.conf | 27 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 docker-setup/Dockerfile create mode 100644 docker-setup/nginx/default.conf diff --git a/docker-setup/Dockerfile b/docker-setup/Dockerfile new file mode 100644 index 00000000..13ce0249 --- /dev/null +++ b/docker-setup/Dockerfile @@ -0,0 +1,28 @@ +FROM php:7.4-fpm + +WORKDIR /var/www/html + +RUN docker-php-ext-install pdo pdo_mysql + +RUN apt-get update && apt-get install -y \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + zip \ + cron \ + supervisor \ + nano \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) gd \ + && docker-php-ext-install zip \ + && docker-php-ext-install bcmath + +COPY --from=composer:1.9.3 /usr/bin/composer /usr/bin/composer + +#NODEJS & NPM +RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - +RUN apt-get -y install nodejs + +RUN chown -R www-data:www-data /var/www +RUN chmod 755 /var/www \ No newline at end of file diff --git a/docker-setup/nginx/default.conf b/docker-setup/nginx/default.conf new file mode 100644 index 00000000..8761015c --- /dev/null +++ b/docker-setup/nginx/default.conf @@ -0,0 +1,27 @@ +server { + listen 80; + index index.php index.html; + server_name localhost; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/html/public; + + server_name localhost; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass php:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_intercept_errors on; + fastcgi_keep_conn on; + fastcgi_param PHP_VALUE "auto_prepend_file= \n allow_url_include=Off"; + } +} \ No newline at end of file From 9a10919f4c8ddab4354385e0e7f3420e00b2b19c Mon Sep 17 00:00:00 2001 From: glovetleong Date: Thu, 27 Oct 2022 00:52:21 +0800 Subject: [PATCH 02/18] docker-compose.yml --- .gitignore | 1 - docker-setup/docker-compose.yml | 51 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 docker-setup/docker-compose.yml diff --git a/.gitignore b/.gitignore index 476bf6a0..095342e0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,6 @@ gox.iml rebuild_docker.sh docker/* db/* -docker-compose.yml package-lock.json public/* /public/* diff --git a/docker-setup/docker-compose.yml b/docker-setup/docker-compose.yml new file mode 100644 index 00000000..3a46a193 --- /dev/null +++ b/docker-setup/docker-compose.yml @@ -0,0 +1,51 @@ +version: '3' + +networks: + exchange-staging: + +services: + ################################################################# + nginx: + image: nginx:stable-alpine + container_name: exchange-ngnix + ports: + - "8081:80" + volumes: + - ../:/var/www/html + - ./nginx/default.conf:/etc/nginx/conf.d/default.conf + depends_on: + - php + - mysql + networks: + - exchange-staging + ################################################################# + mysql: + image: mysql:5.7.29 + container_name: exchange-mysql + restart: unless-stopped + tty: true + ports: + - 3307:3306 + environment: + MYSQL_ROOT_USER: root + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: exchange-db + MYSQL_USER: master + MYSQL_PASSWORD: cDe7gcrRBWetaAP + volumes: + - /var/docker/lib/mysql:/var/lib/mysql + networks: + - exchange-staging + ################################################################# + php: + build: + context: . + dockerfile: Dockerfile + container_name: exchange-php + volumes: + - ../:/var/www/html + ports: + - "9001:9000" + networks: + - exchange-staging + ################################################################# \ No newline at end of file From d21d97d957833cabc1eac4c903aad28b9a354626 Mon Sep 17 00:00:00 2001 From: Dillon Date: Wed, 2 Nov 2022 05:53:59 +0800 Subject: [PATCH 03/18] Update mapping --- docker-setup/docker-compose.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docker-setup/docker-compose.yml b/docker-setup/docker-compose.yml index 3a46a193..deb02207 100644 --- a/docker-setup/docker-compose.yml +++ b/docker-setup/docker-compose.yml @@ -9,7 +9,7 @@ services: image: nginx:stable-alpine container_name: exchange-ngnix ports: - - "8081:80" + - "8082:80" volumes: - ../:/var/www/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf @@ -25,7 +25,7 @@ services: restart: unless-stopped tty: true ports: - - 3307:3306 + - 3302:3306 environment: MYSQL_ROOT_USER: root MYSQL_ROOT_PASSWORD: root @@ -33,7 +33,7 @@ services: MYSQL_USER: master MYSQL_PASSWORD: cDe7gcrRBWetaAP volumes: - - /var/docker/lib/mysql:/var/lib/mysql + - mysql-data:/var/lib/mysql networks: - exchange-staging ################################################################# @@ -45,7 +45,10 @@ services: volumes: - ../:/var/www/html ports: - - "9001:9000" + - "9002:9000" networks: - exchange-staging - ################################################################# \ No newline at end of file + ################################################################# + +volumes: + mysql-data: From 63f06709239416170ad8bd2df2cf0e69a812e62c Mon Sep 17 00:00:00 2001 From: Dillon Date: Tue, 3 Jan 2023 15:41:30 +0800 Subject: [PATCH 04/18] PerfexCRM Integration --- app/Classes/Jobs/InitializePerfexCRM.php | 33 ++++ app/Classes/Jobs/UpdatePerfexCRM.php | 33 ++++ .../ControllersLogic/CreateCustomerLogic.php | 16 +- .../CustomerContactObject.php | 99 +++++++++++ .../InitialPerfexCRMObject.php | 100 +++++++++++ .../InvoicePaymentPerfexCRMObject.php | 86 ++++++++++ .../InvoicePerfexCRMObject.php | 145 ++++++++++++++++ .../InvoiceSingleItemPerfexCRMObject.php | 86 ++++++++++ .../UpdatePerfexCRMObject.php | 100 +++++++++++ .../CreatePerfexCRMInvoiceProcessor.php | 159 ++++++++++++++++++ .../CreatePerfexCRMLeadProcessor.php | 36 ++++ .../InitializePerfexCRMProcessor.php | 155 +++++++++++++++++ .../TransactionToPerfexCRMProcessor.php | 140 +++++++++++++++ .../Processors/UpdatePerfexCRMProcessor.php | 156 +++++++++++++++++ .../ConvertsPerfexCRMLeadToCustomer.php | 34 ++++ .../Services/CreatesPerfexCRMCustomer.php | 37 ++++ .../CreatesPerfexCRMCustomerContact.php | 44 +++++ .../CreatesPerfexCRMCustomerProject.php | 43 +++++ .../Services/CreatesPerfexCRMInvoice.php | 60 +++++++ .../CreatesPerfexCRMInvoicePayment.php | 43 +++++ .../Services/CreatesPerfexCRMLead.php | 41 +++++ .../Services/CreatesPerfexCRMMilestone.php | 46 +++++ .../Services/CreatesPerfexCRMTask.php | 47 ++++++ .../Services/FetchesPerfexCRMMilestone.php | 35 ++++ .../Services/FetchesPerfexCRMProject.php | 35 ++++ .../Services/FetchesPerfexCRMTask.php | 35 ++++ .../Services/UpdatesPerfexCRMTask.php | 48 ++++++ .../CreateInvoiceTransactionProcessor.php | 11 +- .../Services/UpdatesTransactionStatus.php | 15 +- .../Constants/PerfexCRMMilestones.php | 12 ++ .../ValueObjects/Constants/PerfexCRMTasks.php | 57 +++++++ config/perfexcrm.php | 6 + 32 files changed, 1988 insertions(+), 5 deletions(-) create mode 100644 app/Classes/Jobs/InitializePerfexCRM.php create mode 100644 app/Classes/Jobs/UpdatePerfexCRM.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/CustomerContactObject.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePaymentPerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php create mode 100644 app/Classes/ValueObjects/Constants/PerfexCRMMilestones.php create mode 100644 app/Classes/ValueObjects/Constants/PerfexCRMTasks.php create mode 100644 config/perfexcrm.php diff --git a/app/Classes/Jobs/InitializePerfexCRM.php b/app/Classes/Jobs/InitializePerfexCRM.php new file mode 100644 index 00000000..ac77f87e --- /dev/null +++ b/app/Classes/Jobs/InitializePerfexCRM.php @@ -0,0 +1,33 @@ +initialPerfexCRMObject = $initialPerfexCRMObject; + } + + public function handle() + { + (App()->make(InitializePerfexCRMProcessor::class))->execute($this->initialPerfexCRMObject); + } +} diff --git a/app/Classes/Jobs/UpdatePerfexCRM.php b/app/Classes/Jobs/UpdatePerfexCRM.php new file mode 100644 index 00000000..cbc686e3 --- /dev/null +++ b/app/Classes/Jobs/UpdatePerfexCRM.php @@ -0,0 +1,33 @@ +updatePerfexCRMObject = $updatePerfexCRMObject; + } + + public function handle() + { + (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject); + } +} diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index 2c732126..101f9cba 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -12,6 +12,7 @@ use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; use App\Classes\Modules\Companies\Processors\CreateCompanyProcessor; use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject; use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; +use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMLeadProcessor; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\BusinessType; use App\Classes\ValueObjects\Constants\CompanyType; @@ -56,6 +57,9 @@ class CreateCustomerLogic extends AbstractControllerLogic /** @var GenerateEmailVerificationAttemptProcessor */ private $generateEmailVerificationAttemptProcessor; + /** @var CreatePerfexCRMLeadProcessor */ + private $createPerfexCRMLeadProcessor; + /** * CreateCustomerLogic constructor. * @param CreateUserProcessor $createUserProcessor @@ -65,8 +69,10 @@ class CreateCustomerLogic extends AbstractControllerLogic * @param AssignSegmentProcessor $assignSegmentProcessor * @param AuthenticationProcessor $authenticationProcessor * @param GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor + * @param CreatePerfexCRMLeadProcessor $createPerfexCRMLeadProcessor */ - public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateContactProcessor $createContactProcessor, AssignEmployeeProcessor $assignEmployeeProcessor, AssignSegmentProcessor $assignSegmentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor) + public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateContactProcessor $createContactProcessor, AssignEmployeeProcessor $assignEmployeeProcessor, AssignSegmentProcessor $assignSegmentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor, + CreatePerfexCRMLeadProcessor $createPerfexCRMLeadProcessor) { $this->createUserProcessor = $createUserProcessor; $this->createCompanyProcessor = $createCompanyProcessor; @@ -75,6 +81,7 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->assignSegmentProcessor = $assignSegmentProcessor; $this->authenticationProcessor = $authenticationProcessor; $this->generateEmailVerificationAttemptProcessor = $generateEmailVerificationAttemptProcessor; + $this->createPerfexCRMLeadProcessor = $createPerfexCRMLeadProcessor; } /** @@ -101,9 +108,12 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->assignSegmentProcessor->execute($company); - $this->generateEmailVerificationAttemptProcessor->execute($user); + $this->createPerfexCRMLeadProcessor->execute($request); + + //cief TODO: This line is intentionally commented because otherwise frontend cannot load/hit error + //$this->generateEmailVerificationAttemptProcessor->execute($user); return $this->response($this->authenticationProcessor->execute($request)); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CustomerContactObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CustomerContactObject.php new file mode 100644 index 00000000..3530524d --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CustomerContactObject.php @@ -0,0 +1,99 @@ +customerId = $customerId; + $this->firstname = $firstname; + $this->lastname = $lastname; + $this->email = $email; + $this->password = $password; + $this->isPrimary = $isPrimary; + $this->sendSetPasswordEmail = $sendSetPasswordEmail; + } + + /** + * @return int + */ + public function getCustomerId(): int + { + return $this->customerId; + } + + /** + * @return string + */ + public function getFirstName(): string + { + return $this->firstname; + } + + /** + * @return string + */ + public function getLastName(): string + { + return $this->lastname; + } + + /** + * @return string + */ + public function getEmail(): string + { + return $this->email; + } + + /** + * @return string + */ + public function getPassword(): string + { + return $this->password; + } + + /** + * @return string + */ + public function getIsPrimary(): string + { + return $this->isPrimary; + } + + /** + * @return string + */ + public function getSendSetPasswordEmail(): string + { + return $this->sendSetPasswordEmail; + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php new file mode 100644 index 00000000..00a913a0 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php @@ -0,0 +1,100 @@ +companyName = $companyName; + $this->companyReference = $companyReference; + $this->contactEmail = $contactEmail; + $this->bookingMarking = $bookingMarking; + $this->projectName = $projectName; + $this->milestoneNames = $milestoneNames; + $this->taskNames = $taskNames; + } + + /** + * @return string + */ + public function getCompanyName(): string + { + return $this->companyName; + } + + /** + * @return string + */ + public function getCompanyReference(): string + { + return $this->companyReference; + } + + /** + * @return string + */ + public function getContactEmail(): string + { + return $this->contactEmail; + } + + /** + * @return string + */ + public function getBookingMarking(): string + { + return $this->bookingMarking; + } + + /** + * @return string + */ + public function getProjectName(): string + { + return $this->projectName; + } + + /** + * @return array + */ + public function getMilestoneNames(): array + { + return $this->milestoneNames; + } + + /** + * @return array + */ + public function getTaskNames(): array + { + return $this->taskNames; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePaymentPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePaymentPerfexCRMObject.php new file mode 100644 index 00000000..3d34c540 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePaymentPerfexCRMObject.php @@ -0,0 +1,86 @@ +invoiceId = $invoiceId; + $this->amount = $amount; + $this->date = $date; + $this->paymentMode = $paymentMode; + $this->transactionId = $transactionId; + $this->note = $note; + } + + /** + * @return int + */ + public function getInvoiceId(): int + { + return $this->invoiceId; + } + + /** + * @return float + */ + public function getAmount(): float + { + return $this->amount; + } + + /** + * @return string + */ + public function getDate(): string + { + return $this->date; + } + + /** + * @return int + */ + public function getPaymentMode(): int + { + return $this->paymentMode; + } + + /** + * @return string + */ + public function getTransactionId(): string + { + return $this->transactionId; + } + + /** + * @return string + */ + public function getNote(): string + { + return $this->note; + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php new file mode 100644 index 00000000..7e204ff8 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php @@ -0,0 +1,145 @@ +clientId = $clientId; + $this->number = $number; + $this->date = $date; + $this->dueDate = $dueDate; + $this->currency = $currency; + $this->subTotal = $subTotal; + $this->total = $total; + $this->billingStreet = $billingStreet; + $this->projectId = $projectId; + $this->allowedPaymentModes = $allowedPaymentModes; + $this->invoiceItems = $invoiceItems; + } + + /** + * @return int + */ + public function getClientId(): int + { + return $this->clientId; + } + + /** + * @return string + */ + public function getNumber(): string + { + return $this->number; + } + + /** + * @return string + */ + public function getDate(): string + { + return $this->date; + } + + /** + * @return string + */ + public function getDueDate(): string + { + return $this->dueDate; + } + + /** + * @return string + */ + public function getCurrency(): string + { + return $this->currency; + } + + /** + * @return float + */ + public function getSubTotal(): float + { + return $this->subTotal; + } + + /** + * @return float + */ + public function getTotal(): float + { + return $this->total; + } + + /** + * @return string + */ + public function getBillingStreet(): string + { + return $this->billingStreet; + } + + /** + * @return string + */ + public function getProjectId(): string + { + return $this->projectId; + } + + /** + * @return array + */ + public function getAllowedPaymentModes(): array + { + return $this->allowedPaymentModes; + } + + /** + * @return array + */ + public function getInvoiceItems(): array + { + return $this->invoiceItems; + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php new file mode 100644 index 00000000..4f92895d --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php @@ -0,0 +1,86 @@ +description = $description; + $this->longDescription = $longDescription; + $this->qty = $qty; + $this->rate = $rate; + $this->order = $order; + $this->unit = $unit; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return string + */ + public function getLongDescription(): string + { + return $this->longDescription; + } + + /** + * @return int + */ + public function getQty(): int + { + return $this->qty; + } + + /** + * @return float + */ + public function getRate(): float + { + return $this->rate; + } + + /** + * @return int + */ + public function getOrder(): int + { + return $this->order; + } + + /** + * @return string + */ + public function getUnit(): string + { + return $this->unit; + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php new file mode 100644 index 00000000..be9328ac --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php @@ -0,0 +1,100 @@ +companyName = $companyName; + $this->companyReference = $companyReference; + $this->contactEmail = $contactEmail; + $this->bookingMarking = $bookingMarking; + $this->projectName = $projectName; + $this->milestoneName = $milestoneName; + $this->taskName = $taskName; + } + + /** + * @return string + */ + public function getCompanyName(): string + { + return $this->companyName; + } + + /** + * @return string + */ + public function getCompanyReference(): string + { + return $this->companyReference; + } + + /** + * @return string + */ + public function getContactEmail(): string + { + return $this->contactEmail; + } + + /** + * @return string + */ + public function getBookingMarking(): string + { + return $this->bookingMarking; + } + + /** + * @return string + */ + public function getProjectName(): string + { + return $this->projectName; + } + + /** + * @return string + */ + public function getMilestoneName(): string + { + return $this->milestoneName; + } + + /** + * @return string + */ + public function getTaskName(): string + { + return $this->taskName; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php new file mode 100644 index 00000000..5cc3d1b4 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -0,0 +1,159 @@ +createsPerfexCRMInvoice = $createsPerfexCRMInvoice; + $this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment; + $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; + } + + /** + * @param $transaction + * @param $purchaseOrder + * @param $supplier + * @return null|object + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute($transaction, $purchaseOrder, $supplier) { + $clientId = ""; + $number = $transaction->bill_no; + $prefix = "INV-"; + if (substr($number, 0, strlen($prefix)) == $prefix) { + $number = substr($number, strlen($prefix)); + } + + $date = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); + $dueDate = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); + $currency = 1; //cief TODO: To look into Malaysia and Chinese currency + $subTotal = 0.00; + $total = 0.00; + + $billingStreet = ""; + $addresses = $supplier->addresses()->where('billing', '=', true)->first(); + + $billingStreet = $billingStreet.$addresses->street_one; + $billingStreet = $billingStreet.$addresses->street_two.','; + $billingStreet = $billingStreet.$addresses->district()->first()->name.','; + $billingStreet = $billingStreet.$addresses->postcode; + $billingStreet = $billingStreet.$addresses->state()->first()->name.','; + $billingStreet = $billingStreet.$addresses->country()->first()->name; + + $projectId = ""; + $allowedPaymentModes = []; + $invoiceItems = []; + + $email = $supplier->employees()->first()->email; + $email = 'dillon36@yahoo.com'; //cief TODO: To be updated to user actual email address + $result = $this->convertsPerfexCRMLeadToCustomer->execute($email); + if(isset($result->payload)){ + $clientId = $result->payload['client_id']; + } + + //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 += (1/$transaction->currency_rate) * $transaction_detail->price * $transaction_detail->quantity; + } + else + { + //$totalAmount = (float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity; + $subTotal += $transaction_detail->price * $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); + } + + if($transaction->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; + } + + //cief TODO: To be updated, temporarily hardcoded allow payment modes + array_push($allowedPaymentModes, 1, 2); + + $invoicePerfexCRMObject = new InvoicePerfexCRMObject( + $clientId, + $number, + $date, + $dueDate, + $currency, + $subTotal, + $total, + $billingStreet, + $projectId, + $allowedPaymentModes, + $invoiceItems + ); + + $result = $this->createsPerfexCRMInvoice->execute($invoicePerfexCRMObject); + + //If there is a checking whether an payment to an invoice need to be generated, do it here + if(true && $result->payload['id']){ + $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject( + $result->payload['id'], + $total, + $date, + 1, + "", + "" + ); + $this->createsPerfexCRMInvoicePayment->execute($invoicePaymentPerfexCRMObject); + } + + return true; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php new file mode 100644 index 00000000..b7b96773 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php @@ -0,0 +1,36 @@ +createsPerfexCRMLead = $createsPerfexCRMLead; + } + + /** + * @param Request $request + * @return null|object + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(Request $request) { + return $this->createsPerfexCRMLead->execute($request->input('name'), $request->input('email')); + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php new file mode 100644 index 00000000..12b4a6d4 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php @@ -0,0 +1,155 @@ +convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; + $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; + $this->createsPerfexCRMMilestone = $createsPerfexCRMMilestone; + $this->createsPerfexCRMTask = $createsPerfexCRMTask; + $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; + $this->fetchesPerfexCRMMilestone = $fetchesPerfexCRMMilestone; + $this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask; + $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; + $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; + } + + /** + * @param InitialPerfexCRMObject $initialPerfexCRMObject + * @return null|object + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(InitialPerfexCRMObject $initialPerfexCRMObject) { + + // 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 + $result = $this->convertsPerfexCRMLeadToCustomer->execute($initialPerfexCRMObject->getContactEmail()); + if(isset($result->payload)){ + $crmClientId = $result->payload['client_id']; + } + else{ + //if reach this point, this means this user is not a official customer nor is a lead in crm + //Create Customer has 2 parts: Create Company (client), Create Contact + $result = $this->createsPerfexCRMCustomer->execute($initialPerfexCRMObject->getCompanyName()); + $crmClientId = $result->payload['clientId']; + + $customerContactObject = new CustomerContactObject( + $crmClientId, + $initialPerfexCRMObject->getCompanyName(), + $initialPerfexCRMObject->getCompanyName(), + $initialPerfexCRMObject->getContactEmail(), + "123456abcabc", + "on", + "on" + ); + $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); + } + + // Get existing or create project, project has to exist first before milestone can appear under it + $result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId); + if(isset($result->payload)){ //Here means project creation successful + $projectId = $result->payload['project_id']; + } + else{ + $projectId = $this->fetchesPerfexCRMProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId)->id; + } + + if(!is_null($result)){ + $tasks = $initialPerfexCRMObject->getTaskNames(); + + //Create tasks with milestone + for($count=0; $count < count($tasks); $count++) { + $milestoneId = 0; //By default milestoneId is 0, having this set at individual task is optional + if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined + { + // Get existing or create milestone, milestone has to exist first before task can appear under it + $result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count); + if(isset($result->payload)){ + $milestoneId = $result->payload['milestone_id']; + } + else{ + $milestone = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId); + $array = json_decode(json_encode($milestone), true); + $milestoneId = $array[0]['id']; + } + } + + // Get existing or create task + $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, $projectId, $tasks[$count]['reference']); + } + } + return true; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php new file mode 100644 index 00000000..6c55c529 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -0,0 +1,140 @@ +updatePerfexCRMProcessor = $updatePerfexCRMProcessor; + $this->initializePerfexCRMProcessor = $initializePerfexCRMProcessor; + $this->fetchesCompany = $fetchesCompany; + } + + + /** + * @param Transaction $model + * @param int $status + * @return \Illuminate\Database\Eloquent\Model + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(Transaction $model, int $status) + { + $companyName = "dillon36"; //cief TODO: To be updated by removing this line to user actual company name + if(!is_null($model->owner->company)){ + //For owner_type > App\Models\Booking + $companyReference = $model->owner->company->reference; + } + else{ + //For owner_type > App\Models\Wallet + $companyReference = $model->owner->owner->reference; + $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); + $email = $company->employees()->first()->email; + } + $contactEmail = "dillon36@yahoo.com"; //cief TODO: To be updated to user actual email address + $bookingMarking = $model->owner->marking; + if($model->owner instanceof \App\Models\Booking && $model->payment_reference != null && $status == ApprovalStatus::APPROVED){ + + $initialPerfexCRMObject = new InitialPerfexCRMObject( + $companyName, + $companyReference, + $contactEmail, + $bookingMarking, + $companyReference.'-'.$bookingMarking, + [], + [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_2, + PerfexCRMTasks::TASK_3, + PerfexCRMTasks::TASK_4, + PerfexCRMTasks::TASK_5, + PerfexCRMTasks::TASK_6, + PerfexCRMTasks::TASK_7, + PerfexCRMTasks::TASK_8, + PerfexCRMTasks::TASK_9, + PerfexCRMTasks::TASK_10, + ] + ); + + //$this->initializePerfexCRMProcessor->execute($initialPerfexCRMObject); + InitializePerfexCRM::dispatch($initialPerfexCRMObject); + + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactEmail, + $bookingMarking, + $companyReference.'-'.$bookingMarking, + PerfexCRMTasks::TASK_1['milestone'], + PerfexCRMTasks::TASK_1['name'] + ); + + //Mark task in Perfex CRM as done (5 means completed task) + // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } + else if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ + + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactEmail, + $bookingMarking, + $companyReference.'-'.$bookingMarking, + PerfexCRMTasks::TASK_3['milestone'], + PerfexCRMTasks::TASK_3['name'] + ); + + //Mark task in Perfex CRM as done (5 means completed task) + // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } + else if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::PENDING_VERIFICATION){ + + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactEmail, + $bookingMarking, + $companyReference.'-'.$bookingMarking, + PerfexCRMTasks::TASK_2['milestone'], + PerfexCRMTasks::TASK_2['name'] + ); + + //Mark task in Perfex CRM as done (5 means completed task) + //$this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } + return true; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php new file mode 100644 index 00000000..031fdb4f --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -0,0 +1,156 @@ +convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; + $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; + $this->createsPerfexCRMMilestone = $createsPerfexCRMMilestone; + $this->createsPerfexCRMTask = $createsPerfexCRMTask; + $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; + $this->fetchesPerfexCRMMilestone = $fetchesPerfexCRMMilestone; + $this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask; + $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; + $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; + $this->updatesPerfexCRMTask = $updatesPerfexCRMTask; + } + + /** + * @param PerfexCRMObject $perfexCRMObject + * @return null|object + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(UpdatePerfexCRMObject $updatePerfexCRMObject) { + + // 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 + $result = $this->convertsPerfexCRMLeadToCustomer->execute($updatePerfexCRMObject->getContactEmail()); + if(isset($result->payload)){ + $crmClientId = $result->payload['client_id']; + } + else{ + //if reach this point, this means this user is not a official customer nor is a lead in crm + //Create Customer has 2 parts: Create Company (client), Create Contact + $result = $this->createsPerfexCRMCustomer->execute($updatePerfexCRMObject->getCompanyName()); + $crmClientId = $result->payload['clientId']; + + $customerContactObject = new CustomerContactObject( + $crmClientId, + $updatePerfexCRMObject->getCompanyName(), + $updatePerfexCRMObject->getCompanyName(), + $updatePerfexCRMObject->getContactEmail(), + "123456abcabc", + "on", + "on" + ); + $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); + } + + // Get existing or create project, project has to exist first before milestone can appear under it + $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); + if(isset($result->payload)){ + $projectId = $result->payload['project_id']; + } + else{ + $projectId = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId)->id; + } + + // Get existing or create milestone, milestone has to exist first before task can appear under it + $result = $this->createsPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId); + if(isset($result->payload)){ + $milestoneId = $result->payload['milestone_id']; + } + else{ + $milestone = $this->fetchesPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId); + $array = json_decode(json_encode($milestone), true); + $milestoneId = $array[0]['id']; + } + + // Get existing or create task + $result = $this->createsPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId); + if(isset($result->payload)){ + $taskId = $result->payload['task_id']; + } + else{ + $taskId = $this->fetchesPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId)->id; + } + + //cief TODO: To update task status dynamically, now is hardcoded 5 (5 means completed task) + $this->updatesPerfexCRMTask->execute($taskId, $updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId, 5); + + return null; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php new file mode 100644 index 00000000..e6e7323e --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php @@ -0,0 +1,34 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/leads/convertocustomer/'.$email); + + 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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php new file mode 100644 index 00000000..e5a19ce3 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php @@ -0,0 +1,37 @@ + $companyName + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/customers',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php new file mode 100644 index 00000000..600b928e --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php @@ -0,0 +1,44 @@ + $customerContactObject->getCustomerId(), + 'firstname' => $customerContactObject->getFirstName(), + 'lastname' => $customerContactObject->getLastName(), + 'email' => $customerContactObject->getEmail(), //$email + 'password' => $customerContactObject->getPassword(), + 'is_primary' => $customerContactObject->getIsPrimary(), + 'send_set_password_email' => $customerContactObject->getSendSetPasswordEmail(), + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/contacts',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php new file mode 100644 index 00000000..e719ccef --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php @@ -0,0 +1,43 @@ + $projectName, + 'rel_type' => 'customer', + 'billing_type' => 1, + 'clientid' => $clientId, + 'start_date' => date('Y-m-d'), + 'status' => 1 + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/projects',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php new file mode 100644 index 00000000..196e3130 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php @@ -0,0 +1,60 @@ + $invoicePerfexCRMObject->getClientId(), + 'number' => $invoicePerfexCRMObject->getNumber(), + 'date' => $invoicePerfexCRMObject->getDate(), + 'duedate' => $invoicePerfexCRMObject->getDueDate(), + 'currency' => $invoicePerfexCRMObject->getCurrency(), + 'subtotal' => $invoicePerfexCRMObject->getSubTotal(), + 'total' => $invoicePerfexCRMObject->getTotal(), + 'billing_street' => $invoicePerfexCRMObject->getBillingStreet(), + 'project_id' => $invoicePerfexCRMObject->getProjectId(), + 'allowed_payment_modes[0]' => 1, + 'allowed_payment_modes[1]' => 2, + ]; + + for($count=0; $count < count($invoicePerfexCRMObject->getInvoiceItems()); $count++) { + $oneItem = [ + "newitems[".$count."][description]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->description, + "newitems[".$count."][long_description]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->longDescription, + "newitems[".$count."][qty]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->qty, + "newitems[".$count."][rate]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->rate, + "newitems[".$count."][order]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->order, + "newitems[".$count."][unit]" => $invoicePerfexCRMObject->getInvoiceItems()[$count]->unit, + ]; + $data = array_merge($data, $oneItem); + } + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/invoices',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php new file mode 100644 index 00000000..035cc1b8 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php @@ -0,0 +1,43 @@ + $invoicePaymentPerfexCRMObject->getInvoiceId(), + 'amount' => $invoicePaymentPerfexCRMObject->getAmount(), + 'date' => $invoicePaymentPerfexCRMObject->getDate(), + 'paymentmode' => $invoicePaymentPerfexCRMObject->getPaymentMode(), + 'transactionid' => $invoicePaymentPerfexCRMObject->getTransactionId(), + 'note' => $invoicePaymentPerfexCRMObject->getNote(), + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/invoices/recordpayment',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php new file mode 100644 index 00000000..07db48a8 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -0,0 +1,41 @@ + $name, + 'email' => $email, + 'source' => 3, + 'status' => 2 + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/leads/byemail',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php new file mode 100644 index 00000000..80cb49bf --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php @@ -0,0 +1,46 @@ + $milestoneName, + 'project_id' => $projectId, + 'due_date' => date('Y-m-d'), + 'start_date' => date('Y-m-d') + ]; + + if($milestoneOrder != ""){ + $data['milestone_order'] = $milestoneOrder; + } + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/milestones',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php new file mode 100644 index 00000000..7e340c26 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php @@ -0,0 +1,47 @@ + $taskName, + 'milestone' => $milestoneId, + 'startdate' => date('Y-m-d'), + 'rel_type' => 'project', + 'rel_id' => $projectId, + 'status' => $status, + 'is_system_created' => 1, + 'reference' => $reference + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/tasks',$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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php new file mode 100644 index 00000000..8a5ba559 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php @@ -0,0 +1,35 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/milestones/bynameandprojectid/'.rawurlencode($milestoneName).'/'.$projectId); + + 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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php new file mode 100644 index 00000000..41115be8 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php @@ -0,0 +1,35 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/projects/bynameandclientid/'.$projectName.'/'.$clientId); + + 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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php new file mode 100644 index 00000000..97707acb --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php @@ -0,0 +1,35 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/tasks/bynameandmilestoneid/'.rawurlencode($taskName).'/'.$milestoneId); + + 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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php new file mode 100644 index 00000000..928f9c5a --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php @@ -0,0 +1,48 @@ + $taskName, + 'milestone' => $milestoneId, + 'startdate' => date('Y-m-d'), + 'duedate' => date('Y-m-d'), + 'rel_type' => 'project', + 'rel_id' => $projectId, + 'status' => $status, + 'repeat_every' => '', + ]; + + $response = Http::asJson()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->put(config('perfexcrm.base_url').'/api/tasks/'.$taskId, $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()); + } + } +} diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index 6da2f352..0129ab32 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -13,6 +13,7 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\SegmentConstants; use App\Classes\ValueObjects\Constants\TransactionType; @@ -55,6 +56,9 @@ class CreateInvoiceTransactionProcessor /** @var CreateInvoiceDocumentProcessor */ private $invoiceDocumentProcessor; + /** @var CreatePerfexCRMInvoiceProcessor */ + private $createPerfexCRMInvoiceProcessor; + /** * CreateInvoiceTransactionProcessor constructor. * @param ListsTransactions $listsTransactions @@ -68,8 +72,9 @@ class CreateInvoiceTransactionProcessor * @param FetchesCompany $fetchesCompany * @param UpdatesBookingStatus $updatesBookingStatus * @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor + * @param CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor */ - public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor) + public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor) { $this->listsTransactions = $listsTransactions; $this->createsTransaction = $createsTransaction; @@ -82,6 +87,7 @@ class CreateInvoiceTransactionProcessor $this->fetchesCompany = $fetchesCompany; $this->updatesBookingStatus = $updatesBookingStatus; $this->invoiceDocumentProcessor = $invoiceDocumentProcessor; + $this->createPerfexCRMInvoiceProcessor = $createPerfexCRMInvoiceProcessor; } @@ -198,6 +204,9 @@ class CreateInvoiceTransactionProcessor // supply deliver order $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER); + // update perfex crm + $this->createPerfexCRMInvoiceProcessor->execute($invoice_transaction, $purchaseOrder, $supplier); + $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); } } diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index ec0bb673..82329cf4 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -4,9 +4,21 @@ namespace App\Classes\Modules\Transactions\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; use App\Models\Transaction; +use App\Classes\Modules\PerfexCRM\Processors\TransactionToPerfexCRMProcessor; class UpdatesTransactionStatus extends AbstractUpdateRecord { + /** @var TransactionToPerfexCRMProcessor */ + private $transactionToPerfexCRMProcessor; + + /** + * UpdatesTransactionStatus constructor. + * @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor + */ + public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor) + { + $this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor; + } /** * @param Transaction $model @@ -16,8 +28,9 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord */ public function execute(Transaction $model, int $status) { + $this->transactionToPerfexCRMProcessor->execute($model, $status); $model->status = $status; return $this->handler($model); } -} \ No newline at end of file +} diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMMilestones.php b/app/Classes/ValueObjects/Constants/PerfexCRMMilestones.php new file mode 100644 index 00000000..70b5fee3 --- /dev/null +++ b/app/Classes/ValueObjects/Constants/PerfexCRMMilestones.php @@ -0,0 +1,12 @@ + 'TASK A', + 'milestone' => 'MILESTONE 1 - Customer Paid', + 'reference' => '' + ]; + public const TASK_2 = [ + 'name' => 'TASK B', + 'milestone' => 'MILESTONE 2 - Order Placed', + 'reference' => '' + ]; + public const TASK_3 = [ + 'name' => 'TASK C', + 'milestone' => 'MILESTONE 3 - Purchase Order Approved', + 'reference' => '' + ]; + public const TASK_4 = [ + 'name' => 'TASK D', + 'milestone' => 'MILESTONE 4', + 'reference' => '' + ]; + public const TASK_5 = [ + 'name' => 'TASK E', + 'milestone' => 'MILESTONE 5', + 'reference' => '' + ]; + public const TASK_6 = [ + 'name' => 'TASK F', + 'milestone' => '', + 'reference' => 'THIS_IS_TASK_NUMBER_6' + ]; + public const TASK_7 = [ + 'name' => 'TASK G', + 'milestone' => '', + 'reference' => 'THIS_IS_TASK_NUMBER_7' + ]; + public const TASK_8 = [ + 'name' => 'TASK H', + 'milestone' => '', + 'reference' => 'THIS_IS_TASK_NUMBER_8' + ]; + public const TASK_9 = [ + 'name' => 'TASK I', + 'milestone' => '', + 'reference' => 'THIS_IS_TASK_NUMBER_9' + ]; + public const TASK_10 = [ + 'name' => 'TASK J', + 'milestone' => '', + 'reference' => 'THIS_IS_TASK_NUMBER_10' + ]; +} diff --git a/config/perfexcrm.php b/config/perfexcrm.php new file mode 100644 index 00000000..aa3f00de --- /dev/null +++ b/config/perfexcrm.php @@ -0,0 +1,6 @@ + env('PERFEXCRM_BASE_URL', 'http://192.168.1.102:8084'), //cief todo: Update crm api domain here + 'api_key' => env('PERFEXCRM_API_KEY', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGlsbG9uIiwibmFtZSI6ImRldmVsb3BtZW50IiwiQVBJX1RJTUUiOjE2NzAwNjM0OTB9.ClR07m_QvvOHe4-hsTFAyXLvLCkXcym3cQpq0V8PHLo'), +]; From d0e6caed9fe37b15e5becdf34ab371c293fb9869 Mon Sep 17 00:00:00 2001 From: Dillon Date: Sun, 8 Jan 2023 22:03:51 +0800 Subject: [PATCH 05/18] Another round of testing with different email adderss --- .../PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php | 2 +- .../PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 5cc3d1b4..7a893bde 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -72,7 +72,7 @@ class CreatePerfexCRMInvoiceProcessor $invoiceItems = []; $email = $supplier->employees()->first()->email; - $email = 'dillon36@yahoo.com'; //cief TODO: To be updated to user actual email address + $email = 'dillon37@yahoo.com'; //cief TODO: To be updated to user actual email address $result = $this->convertsPerfexCRMLeadToCustomer->execute($email); if(isset($result->payload)){ $clientId = $result->payload['client_id']; diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index 6c55c529..c24f6417 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -49,7 +49,7 @@ class TransactionToPerfexCRMProcessor */ public function execute(Transaction $model, int $status) { - $companyName = "dillon36"; //cief TODO: To be updated by removing this line to user actual company name + $companyName = "dillon37"; //cief TODO: To be updated by removing this line to user actual company name if(!is_null($model->owner->company)){ //For owner_type > App\Models\Booking $companyReference = $model->owner->company->reference; @@ -60,7 +60,7 @@ class TransactionToPerfexCRMProcessor $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); $email = $company->employees()->first()->email; } - $contactEmail = "dillon36@yahoo.com"; //cief TODO: To be updated to user actual email address + $contactEmail = "dillon37@yahoo.com"; //cief TODO: To be updated to user actual email address $bookingMarking = $model->owner->marking; if($model->owner instanceof \App\Models\Booking && $model->payment_reference != null && $status == ApprovalStatus::APPROVED){ From 4d7b41b0a44dd07661efeda75e12a9d0e2d56145 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 17 Feb 2023 06:28:59 +0800 Subject: [PATCH 06/18] CRM integration MVP Phase 1 --- app/Classes/Jobs/CreatePerfexCRMCustomer.php | 33 +++++++++++ .../ControllersLogic/CreateCustomerLogic.php | 17 ++++-- .../CreateLeadPerfexCRMObject.php | 40 +++++++++++++ .../InitialPerfexCRMObject.php | 14 ++++- .../CreatePerfexCRMLeadProcessor.php | 8 +-- .../InitializePerfexCRMProcessor.php | 51 +++++++++++++--- .../TransactionToPerfexCRMProcessor.php | 58 ++++++++++--------- .../Processors/UpdatePerfexCRMProcessor.php | 21 +------ .../CreatesPerfexCRMCustomerContact.php | 2 +- .../Services/CreatesPerfexCRMLead.php | 4 +- .../Services/UpdatesPerfexCRMCustomer.php | 46 +++++++++++++++ .../CreateInvoiceTransactionProcessor.php | 5 +- .../Services/UpdatesTransactionStatus.php | 4 +- .../Constants/PerfexCRMStatus.php | 17 ++++++ .../ValueObjects/Constants/PerfexCRMTasks.php | 2 +- config/perfexcrm.php | 5 +- 16 files changed, 257 insertions(+), 70 deletions(-) create mode 100644 app/Classes/Jobs/CreatePerfexCRMCustomer.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php create mode 100644 app/Classes/ValueObjects/Constants/PerfexCRMStatus.php diff --git a/app/Classes/Jobs/CreatePerfexCRMCustomer.php b/app/Classes/Jobs/CreatePerfexCRMCustomer.php new file mode 100644 index 00000000..b313dca6 --- /dev/null +++ b/app/Classes/Jobs/CreatePerfexCRMCustomer.php @@ -0,0 +1,33 @@ +createLeadPerfexCRMObject = $createLeadPerfexCRMObject; + } + + public function handle() + { + (App()->make(CreatePerfexCRMLeadProcessor::class))->execute($this->createLeadPerfexCRMObject); + } +} diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index 101f9cba..b8aeec12 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -10,19 +10,22 @@ use App\Classes\Modules\Accounts\Processors\GenerateEmailVerificationAttemptProc use App\Classes\Modules\Companies\Processors\AssignEmployeeProcessor; use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; use App\Classes\Modules\Companies\Processors\CreateCompanyProcessor; -use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject; use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMLeadProcessor; +use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject; +use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateLeadPerfexCRMObject; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\BusinessType; use App\Classes\ValueObjects\Constants\CompanyType; use App\Classes\ValueObjects\Constants\RoleTypes; +use App\Classes\Jobs\CreatePerfexCRMCustomer; use App\Models\Company; use App\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; + class CreateCustomerLogic extends AbstractControllerLogic { @@ -108,10 +111,16 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->assignSegmentProcessor->execute($company); - $this->createPerfexCRMLeadProcessor->execute($request); + if(config('perfexcrm.is_enabled') == 'true'){ + //$this->createPerfexCRMLeadProcessor->execute($request); + $createLeadPerfexCRMObject = new CreateLeadPerfexCRMObject( + $request->input('name'), + $request->input('email') + ); + CreatePerfexCRMCustomer::dispatch($createLeadPerfexCRMObject); + } - //cief TODO: This line is intentionally commented because otherwise frontend cannot load/hit error - //$this->generateEmailVerificationAttemptProcessor->execute($user); + $this->generateEmailVerificationAttemptProcessor->execute($user); return $this->response($this->authenticationProcessor->execute($request)); diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php new file mode 100644 index 00000000..fead15ec --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php @@ -0,0 +1,40 @@ +name = $name; + $this->email = $email; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getEmail(): string + { + return $this->email; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php index 00a913a0..1c4a9db5 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php @@ -13,6 +13,9 @@ class InitialPerfexCRMObject implements DataTransferObject /** @var string */ private $companyReference; + /** @var string */ + private $contactName; + /** @var string */ private $contactEmail; @@ -29,11 +32,12 @@ class InitialPerfexCRMObject implements DataTransferObject private $taskNames; - public function __construct(string $companyName, string $companyReference, string $contactEmail, string $bookingMarking, string $projectName, array $milestoneNames, array $taskNames) + public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, array $milestoneNames, array $taskNames) { $this->companyName = $companyName; $this->companyReference = $companyReference; + $this->contactName = $contactName; $this->contactEmail = $contactEmail; $this->bookingMarking = $bookingMarking; $this->projectName = $projectName; @@ -57,6 +61,14 @@ class InitialPerfexCRMObject implements DataTransferObject return $this->companyReference; } + /** + * @return string + */ + public function getContactName(): string + { + return $this->contactName; + } + /** * @return string */ diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php index b7b96773..81c90335 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php @@ -7,7 +7,7 @@ use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMLead; use App\Classes\Exceptions\MalformedRequestException; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; -use Illuminate\Http\Request; +use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateLeadPerfexCRMObject; class CreatePerfexCRMLeadProcessor { @@ -25,12 +25,12 @@ class CreatePerfexCRMLeadProcessor } /** - * @param Request $request + * @param CreateLeadPerfexCRMObject $createLeadPerfexCRMObject * @return null|object * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(Request $request) { - return $this->createsPerfexCRMLead->execute($request->input('name'), $request->input('email')); + public function execute(CreateLeadPerfexCRMObject $createLeadPerfexCRMObject) { + return $this->createsPerfexCRMLead->execute($createLeadPerfexCRMObject->getName(), $createLeadPerfexCRMObject->getEmail()); } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php index 12b4a6d4..0aac3bf9 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php @@ -11,12 +11,14 @@ use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMMilestone; use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMTask; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerContact; +use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\DataTransferObjects\CustomerContactObject; use App\Classes\Exceptions\MalformedRequestException; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\ValueObjects\Constants\PerfexCRMMilestones; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; +use App\Classes\ValueObjects\Constants\PerfexCRMStatus; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; @@ -53,6 +55,9 @@ class InitializePerfexCRMProcessor /** @var UpdatesPerfexCRM */ private $updatePerfexCRM; + /** @var UpdatesPerfexCRMCustomer */ + private $updatesPerfexCRMCustomer; + /** * @param ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer * @param CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject @@ -63,6 +68,7 @@ class InitializePerfexCRMProcessor * @param FetchesPerfexCRMTask $fetchesPerfexCRMTask * @param CreatesPerfexCRMCustomer $createsPerfexCRMCustomer * @param CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact + * @param UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer */ public function __construct(ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer, CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject, @@ -72,7 +78,8 @@ class InitializePerfexCRMProcessor FetchesPerfexCRMMilestone $fetchesPerfexCRMMilestone, FetchesPerfexCRMTask $fetchesPerfexCRMTask, CreatesPerfexCRMCustomer $createsPerfexCRMCustomer, - CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact) + CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact, + UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer) { $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; @@ -83,6 +90,7 @@ class InitializePerfexCRMProcessor $this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask; $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; + $this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer; } /** @@ -94,28 +102,52 @@ class InitializePerfexCRMProcessor // 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 = $initialPerfexCRMObject->getCompanyName(); $result = $this->convertsPerfexCRMLeadToCustomer->execute($initialPerfexCRMObject->getContactEmail()); + if(isset($result->payload)){ - $crmClientId = $result->payload['client_id']; + $crmClientId = $result->payload['client_id']; + if (isset($result->payload['company'])) { + $crmCompany = $result->payload['company']; + } } else{ //if reach this point, this means this user is not a official customer nor is a lead in crm //Create Customer has 2 parts: Create Company (client), Create Contact - $result = $this->createsPerfexCRMCustomer->execute($initialPerfexCRMObject->getCompanyName()); + $result = $this->createsPerfexCRMCustomer->execute($crmCompany); + if(is_null($result)){ + $crmCompany = $crmCompany." 2"; + $result = $this->createsPerfexCRMCustomer->execute($crmCompany); + } $crmClientId = $result->payload['clientId']; $customerContactObject = new CustomerContactObject( $crmClientId, - $initialPerfexCRMObject->getCompanyName(), - $initialPerfexCRMObject->getCompanyName(), + $initialPerfexCRMObject->getContactName(), + $initialPerfexCRMObject->getContactName(), $initialPerfexCRMObject->getContactEmail(), - "123456abcabc", + "pU^T@sC#9Q", "on", "on" ); $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); } + //Update custom fields to identify company reference from exchange or shipping portal + $value_exists = false; + if (isset($result->payload['customfields'])) { + foreach ($result->payload['customfields'] as $element) { + if ($element['value'] === $initialPerfexCRMObject->getCompanyReference()) { + $value_exists = true; + break; + } + } + } + if(!$value_exists); + { + $result = $this->updatesPerfexCRMCustomer->execute($crmClientId, $crmCompany, $initialPerfexCRMObject->getCompanyReference()); + } + // Get existing or create project, project has to exist first before milestone can appear under it $result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId); if(isset($result->payload)){ //Here means project creation successful @@ -145,8 +177,13 @@ class InitializePerfexCRMProcessor } } + $taskStatus = PerfexCRMStatus::NOT_STARTED; + if($tasks[$count]['name'] == PerfexCRMTasks::TASK_1['name']){ + $taskStatus = PerfexCRMStatus::COMPLETED; + } + // Get existing or create task - $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, $projectId, $tasks[$count]['reference']); + $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, $projectId, $tasks[$count]['reference'], $taskStatus); } } return true; diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index c24f6417..07610849 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -49,59 +49,62 @@ class TransactionToPerfexCRMProcessor */ public function execute(Transaction $model, int $status) { - $companyName = "dillon37"; //cief TODO: To be updated by removing this line to user actual company name - if(!is_null($model->owner->company)){ + $proceed = false; + if($model->owner instanceof \App\Models\Booking){ //For owner_type > App\Models\Booking $companyReference = $model->owner->company->reference; + $companyName = $model->owner->company->name; + $employee = $model->owner->company->employees()->first(); + $contactEmail = $employee->email; + $contactName = $employee->name; + $proceed = true; } - else{ + else if($model->owner instanceof \App\Models\Wallet){ //For owner_type > App\Models\Wallet $companyReference = $model->owner->owner->reference; + $companyName = $model->owner->company->name; $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); - $email = $company->employees()->first()->email; + $employee = $company->employees()->first(); + $contactEmail = $employee->email; + $contactName = $employee->name; + $proceed = true; } - $contactEmail = "dillon37@yahoo.com"; //cief TODO: To be updated to user actual email address + $bookingMarking = $model->owner->marking; - if($model->owner instanceof \App\Models\Booking && $model->payment_reference != null && $status == ApprovalStatus::APPROVED){ + if($proceed && $model->owner instanceof \App\Models\Booking && $model->payment_reference != null && $status == ApprovalStatus::APPROVED){ $initialPerfexCRMObject = new InitialPerfexCRMObject( $companyName, $companyReference, + $contactName, $contactEmail, $bookingMarking, $companyReference.'-'.$bookingMarking, [], [ PerfexCRMTasks::TASK_1, - PerfexCRMTasks::TASK_2, - PerfexCRMTasks::TASK_3, - PerfexCRMTasks::TASK_4, - PerfexCRMTasks::TASK_5, - PerfexCRMTasks::TASK_6, - PerfexCRMTasks::TASK_7, - PerfexCRMTasks::TASK_8, - PerfexCRMTasks::TASK_9, - PerfexCRMTasks::TASK_10, ] ); //$this->initializePerfexCRMProcessor->execute($initialPerfexCRMObject); InitializePerfexCRM::dispatch($initialPerfexCRMObject); - $updatePerfexCRMObject = new UpdatePerfexCRMObject( - $companyName, - $companyReference, - $contactEmail, - $bookingMarking, - $companyReference.'-'.$bookingMarking, - PerfexCRMTasks::TASK_1['milestone'], - PerfexCRMTasks::TASK_1['name'] - ); + // $updatePerfexCRMObject = new UpdatePerfexCRMObject( + // $companyName, + // $companyReference, + // $contactEmail, + // $bookingMarking, + // $companyReference.'-'.$bookingMarking, + // PerfexCRMTasks::TASK_1['milestone'], + // PerfexCRMTasks::TASK_1['name'] + // ); - //Mark task in Perfex CRM as done (5 means completed task) - // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + // //Mark task in Perfex CRM as done (5 means completed task) + // // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); + // UpdatePerfexCRM::dispatch($updatePerfexCRMObject); } + + /* else if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ $updatePerfexCRMObject = new UpdatePerfexCRMObject( @@ -134,6 +137,7 @@ class TransactionToPerfexCRMProcessor //$this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); UpdatePerfexCRM::dispatch($updatePerfexCRMObject); } + */ return true; } diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php index 031fdb4f..0b452d02 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -15,6 +15,7 @@ use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMTask; use App\Classes\Modules\PerfexCRM\DataTransferObjects\CustomerContactObject; use App\Classes\Exceptions\MalformedRequestException; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; +use App\Classes\ValueObjects\Constants\PerfexCRMStatus; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; @@ -100,23 +101,6 @@ class UpdatePerfexCRMProcessor if(isset($result->payload)){ $crmClientId = $result->payload['client_id']; } - else{ - //if reach this point, this means this user is not a official customer nor is a lead in crm - //Create Customer has 2 parts: Create Company (client), Create Contact - $result = $this->createsPerfexCRMCustomer->execute($updatePerfexCRMObject->getCompanyName()); - $crmClientId = $result->payload['clientId']; - - $customerContactObject = new CustomerContactObject( - $crmClientId, - $updatePerfexCRMObject->getCompanyName(), - $updatePerfexCRMObject->getCompanyName(), - $updatePerfexCRMObject->getContactEmail(), - "123456abcabc", - "on", - "on" - ); - $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); - } // Get existing or create project, project has to exist first before milestone can appear under it $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); @@ -147,8 +131,7 @@ class UpdatePerfexCRMProcessor $taskId = $this->fetchesPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId)->id; } - //cief TODO: To update task status dynamically, now is hardcoded 5 (5 means completed task) - $this->updatesPerfexCRMTask->execute($taskId, $updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId, 5); + $this->updatesPerfexCRMTask->execute($taskId, $updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId, PerfexCRMStatus::COMPLETED); return null; } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php index 600b928e..519c1495 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php @@ -23,7 +23,7 @@ class CreatesPerfexCRMCustomerContact 'email' => $customerContactObject->getEmail(), //$email 'password' => $customerContactObject->getPassword(), 'is_primary' => $customerContactObject->getIsPrimary(), - 'send_set_password_email' => $customerContactObject->getSendSetPasswordEmail(), + //'send_set_password_email' => $customerContactObject->getSendSetPasswordEmail(), ]; $response = Http::asForm()->withHeaders([ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php index 07db48a8..97a659a6 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -19,8 +19,8 @@ class CreatesPerfexCRMLead $data = [ 'name' => $name, 'email' => $email, - 'source' => 3, - 'status' => 2 + 'source' => 1, //1: Exchange, 2: Shipping Portal + 'status' => 2 //2: Lead, 1: Customer ]; $response = Http::asForm()->withHeaders([ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php new file mode 100644 index 00000000..561795f8 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php @@ -0,0 +1,46 @@ + [ + 1 => $companyReference + ] + ]; + + $data = [ + 'company' => $companyName, + 'custom_fields' => $custom_fields + ]; + + $response = Http::asJson()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->put(config('perfexcrm.base_url').'/api/customers/'.$customerId, $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()); + } + } +} diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index 0129ab32..4ebcface 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -205,7 +205,10 @@ class CreateInvoiceTransactionProcessor $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER); // update perfex crm - $this->createPerfexCRMInvoiceProcessor->execute($invoice_transaction, $purchaseOrder, $supplier); + // if(config('perfexcrm.is_enabled') == 'true'){ + // { + // $this->createPerfexCRMInvoiceProcessor->execute($invoice_transaction, $purchaseOrder, $supplier); + // } $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); } diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index 82329cf4..db56631c 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -28,7 +28,9 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord */ public function execute(Transaction $model, int $status) { - $this->transactionToPerfexCRMProcessor->execute($model, $status); + if(config('perfexcrm.is_enabled') == 'true'){ + $this->transactionToPerfexCRMProcessor->execute($model, $status); + } $model->status = $status; return $this->handler($model); } diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMStatus.php b/app/Classes/ValueObjects/Constants/PerfexCRMStatus.php new file mode 100644 index 00000000..b274b001 --- /dev/null +++ b/app/Classes/ValueObjects/Constants/PerfexCRMStatus.php @@ -0,0 +1,17 @@ + 'TASK A', + 'name' => 'Customer Paid', 'milestone' => 'MILESTONE 1 - Customer Paid', 'reference' => '' ]; diff --git a/config/perfexcrm.php b/config/perfexcrm.php index aa3f00de..f67040f5 100644 --- a/config/perfexcrm.php +++ b/config/perfexcrm.php @@ -1,6 +1,7 @@ env('PERFEXCRM_BASE_URL', 'http://192.168.1.102:8084'), //cief todo: Update crm api domain here - 'api_key' => env('PERFEXCRM_API_KEY', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGlsbG9uIiwibmFtZSI6ImRldmVsb3BtZW50IiwiQVBJX1RJTUUiOjE2NzAwNjM0OTB9.ClR07m_QvvOHe4-hsTFAyXLvLCkXcym3cQpq0V8PHLo'), + 'base_url' => env('PERFEXCRM_BASE_URL', 'http://192.168.1.100:8084'), //cief todo: Update crm api domain here + 'api_key' => env('PERFEXCRM_API_KEY', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZXhjaGFuZ2Utc2hpcHBpbmciLCJuYW1lIjoiRXhjaGFuZ2UgYW5kIFNoaXBwaW5nIFBvcnRhbCIsIkFQSV9USU1FIjoxNjc1MDg2Mzc4fQ.SGAHWl5stcxQwp55TBGeMRVTdlLeWQIbsvJh5glyVvs'), + 'is_enabled' => env('PERFEXCRM_IS_ENABLED', 'true'), ]; From b14b1c8bc6ad441bb5acdc950b562552f2dd105c Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 17 Feb 2023 08:51:05 +0800 Subject: [PATCH 07/18] CRM integration MVP Phase 1 - minor cleanup --- .../TransactionToPerfexCRMProcessor.php | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index 07610849..73b1ab89 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -49,30 +49,25 @@ class TransactionToPerfexCRMProcessor */ public function execute(Transaction $model, int $status) { - $proceed = false; - if($model->owner instanceof \App\Models\Booking){ - //For owner_type > App\Models\Booking + // else if($model->owner instanceof \App\Models\Wallet){ + // //For owner_type > App\Models\Wallet + // $companyReference = $model->owner->owner->reference; + // $companyName = $model->owner->company->name; + // $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); + // $employee = $company->employees()->first(); + // $contactEmail = $employee->email; + // $contactName = $employee->name; + // $proceed = true; + // } + + if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ $companyReference = $model->owner->company->reference; $companyName = $model->owner->company->name; $employee = $model->owner->company->employees()->first(); $contactEmail = $employee->email; $contactName = $employee->name; - $proceed = true; - } - else if($model->owner instanceof \App\Models\Wallet){ - //For owner_type > App\Models\Wallet - $companyReference = $model->owner->owner->reference; - $companyName = $model->owner->company->name; - $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); - $employee = $company->employees()->first(); - $contactEmail = $employee->email; - $contactName = $employee->name; - $proceed = true; - } - - $bookingMarking = $model->owner->marking; - if($proceed && $model->owner instanceof \App\Models\Booking && $model->payment_reference != null && $status == ApprovalStatus::APPROVED){ + $bookingMarking = $model->owner->marking; $initialPerfexCRMObject = new InitialPerfexCRMObject( $companyName, $companyReference, From 6c7123e585c039af6294fcb20372e6612fda0002 Mon Sep 17 00:00:00 2001 From: Dillon Date: Wed, 22 Feb 2023 10:41:34 +0800 Subject: [PATCH 08/18] Include company name and phone number into lead during regirstration --- .../ControllersLogic/CreateCustomerLogic.php | 4 ++- .../CreateLeadPerfexCRMObject.php | 27 +++++++++++++++++-- .../CreatePerfexCRMLeadProcessor.php | 2 +- .../Services/CreatesPerfexCRMLead.php | 12 +++++---- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index b8aeec12..2fa5f9e0 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -115,7 +115,9 @@ class CreateCustomerLogic extends AbstractControllerLogic //$this->createPerfexCRMLeadProcessor->execute($request); $createLeadPerfexCRMObject = new CreateLeadPerfexCRMObject( $request->input('name'), - $request->input('email') + $request->input('email'), + $request->input('phone'), + $request->input('type') === CompanyType::COMPANY_BUSINESS ? $request->input('company_name') : $request->input('name') ); CreatePerfexCRMCustomer::dispatch($createLeadPerfexCRMObject); } diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php index fead15ec..fc4c17cd 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php @@ -13,12 +13,19 @@ class CreateLeadPerfexCRMObject implements DataTransferObject /** @var string */ private $email; + /** @var string */ + private $phone; - public function __construct(string $name, string $email) + /** @var string */ + private $companyName; + + + public function __construct(string $name, string $email, string $phone, string $companyName) { - $this->name = $name; $this->email = $email; + $this->phone = $phone; + $this->companyName = $companyName; } /** @@ -37,4 +44,20 @@ class CreateLeadPerfexCRMObject implements DataTransferObject return $this->email; } + /** + * @return string + */ + public function getPhone(): string + { + return $this->phone; + } + + /** + * @return string + */ + public function getCompanyName(): string + { + return $this->companyName; + } + } diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php index 81c90335..5a0bc6dc 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMLeadProcessor.php @@ -30,7 +30,7 @@ class CreatePerfexCRMLeadProcessor * @throws \App\Classes\Exceptions\MalformedRequestException */ public function execute(CreateLeadPerfexCRMObject $createLeadPerfexCRMObject) { - return $this->createsPerfexCRMLead->execute($createLeadPerfexCRMObject->getName(), $createLeadPerfexCRMObject->getEmail()); + return $this->createsPerfexCRMLead->execute($createLeadPerfexCRMObject); } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php index 97a659a6..b1706c03 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -5,20 +5,22 @@ namespace App\Classes\Modules\PerfexCRM\Services; use Illuminate\Support\Facades\Http; use App\Classes\Exceptions\MalformedRequestException; use Illuminate\Support\Facades\Log; +use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateLeadPerfexCRMObject; class CreatesPerfexCRMLead { /** - * @param string $name - * @param string $email + * @param CreateLeadPerfexCRMObject $createLeadPerfexCRMObject * @return null|object * @throws MalformedRequestException */ - public function execute(string $name, string $email) { + public function execute(CreateLeadPerfexCRMObject $createLeadPerfexCRMObject) { try{ $data = [ - 'name' => $name, - 'email' => $email, + 'name' => $createLeadPerfexCRMObject->getName(), + 'email' => $createLeadPerfexCRMObject->getEmail(), + 'phonenumber' => $createLeadPerfexCRMObject->getPhone(), + 'company' => $createLeadPerfexCRMObject->getCompanyName(), 'source' => 1, //1: Exchange, 2: Shipping Portal 'status' => 2 //2: Lead, 1: Customer ]; From 3dd24b46657043dabe538f7dd9da3e820329e62f Mon Sep 17 00:00:00 2001 From: Dillon Date: Wed, 22 Feb 2023 18:07:39 +0800 Subject: [PATCH 09/18] User feedback fix and enhancements on crm integration --- .../Processors/TransactionToPerfexCRMProcessor.php | 7 +++++-- .../PerfexCRM/Services/FetchesPerfexCRMProject.php | 11 ++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index 73b1ab89..809463bb 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -66,15 +66,18 @@ class TransactionToPerfexCRMProcessor $employee = $model->owner->company->employees()->first(); $contactEmail = $employee->email; $contactName = $employee->name; - $bookingMarking = $model->owner->marking; + + $serviceTypeName = $model->owner->company->services()->where('id', $model->owner->service_id)->first()->name; + $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; + $initialPerfexCRMObject = new InitialPerfexCRMObject( $companyName, $companyReference, $contactName, $contactEmail, $bookingMarking, - $companyReference.'-'.$bookingMarking, + $projectName, [], [ PerfexCRMTasks::TASK_1, diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php index 41115be8..c55f2c01 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php @@ -16,9 +16,14 @@ class FetchesPerfexCRMProject */ public function execute(string $projectName, string $clientId) { try{ - $response = Http::withHeaders([ - 'authtoken' => config('perfexcrm.api_key'),]) - ->get(config('perfexcrm.base_url').'/api/projects/bynameandclientid/'.$projectName.'/'.$clientId); + $data = [ + 'name' => $projectName, + 'clientid' => $clientId, + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/projects/bynameandclientid', $data); if($response->successful()){ $data = $response->json(); From 607a6f111bc51ea6d03a179fcfb5365ff47734da Mon Sep 17 00:00:00 2001 From: Dillon Date: Wed, 1 Mar 2023 12:27:26 +0800 Subject: [PATCH 10/18] Add new tasks post payment into CRM + Add task append to lead --- .../Jobs/CreatePerfexCRMSingleTask.php | 42 ++ .../CreateTaskPerfexCRMObject.php | 127 ++++++ .../CreatePerfexCRMTaskProcessor.php | 41 ++ .../InitializePerfexCRMProcessor.php | 8 +- .../NewLeadTaskToPerfexCRMProcessor.php | 34 ++ .../TransactionToPerfexCRMProcessor.php | 113 ++--- .../Services/CreatesPerfexCRMTask.php | 25 +- .../Services/FetchesPerfexCRMLead.php | 34 ++ .../Services/UpdatesTransactionStatus.php | 9 +- .../ValueObjects/Constants/PerfexCRMTasks.php | 420 ++++++++++++++++-- 10 files changed, 741 insertions(+), 112 deletions(-) create mode 100644 app/Classes/Jobs/CreatePerfexCRMSingleTask.php create mode 100644 app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php diff --git a/app/Classes/Jobs/CreatePerfexCRMSingleTask.php b/app/Classes/Jobs/CreatePerfexCRMSingleTask.php new file mode 100644 index 00000000..586efe0f --- /dev/null +++ b/app/Classes/Jobs/CreatePerfexCRMSingleTask.php @@ -0,0 +1,42 @@ +createTaskPerfexCRMObject = $createTaskPerfexCRMObject; + } + + public function handle() + { + $lead = (App()->make(FetchesPerfexCRMLead::class))->execute($this->createTaskPerfexCRMObject->getEmail()); + if(!is_null($lead)) + { + $this->createTaskPerfexCRMObject->setLeadId($lead->id); + (App()->make(CreatePerfexCRMTaskProcessor::class))->execute($this->createTaskPerfexCRMObject); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php new file mode 100644 index 00000000..70bae013 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php @@ -0,0 +1,127 @@ +email = $email; + $this->name = $name; + $this->description = $description; + $this->leadId = $leadId; + $this->projectId = $projectId; + $this->milestoneId = $milestoneId; + $this->reference = $reference; + $this->onTaskCompletion = $onTaskCompletion; + $this->status = $status; + } + + /** + * @return string + */ + public function getEmail(): string + { + return $this->email; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return string + */ + public function getLeadId(): string + { + return $this->leadId; + } + + public function setLeadId(string $leadId) + { + $this->leadId = $leadId; + } + + /** + * @return string + */ + public function getProjectId(): string + { + return $this->projectId; + } + + /** + * @return string + */ + public function getMilestoneId(): string + { + return $this->milestoneId; + } + + /** + * @return string + */ + public function getReference(): string + { + return $this->reference; + } + + /** + * @return string + */ + public function getOnTaskCompletion(): string + { + return $this->onTaskCompletion; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php new file mode 100644 index 00000000..965f6f34 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php @@ -0,0 +1,41 @@ +createsPerfexCRMTask = $createsPerfexCRMTask; + } + + /** + * @param CreateTaskPerfexCRMObject $createTaskPerfexCRMObject + * @return true + * @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->getStatus(), + ); + return true; + } + +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php index 0aac3bf9..9fa2bee4 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php @@ -178,14 +178,14 @@ class InitializePerfexCRMProcessor } $taskStatus = PerfexCRMStatus::NOT_STARTED; - if($tasks[$count]['name'] == PerfexCRMTasks::TASK_1['name']){ - $taskStatus = PerfexCRMStatus::COMPLETED; + if($tasks[$count]['status'] != ''){ + $taskStatus = $tasks[$count]['status']; } // Get existing or create task - $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, $projectId, $tasks[$count]['reference'], $taskStatus); + $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $taskStatus); } - } + } return true; } diff --git a/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php new file mode 100644 index 00000000..9602696d --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php @@ -0,0 +1,34 @@ +owner instanceof \App\Models\Wallet){ - // //For owner_type > App\Models\Wallet - // $companyReference = $model->owner->owner->reference; - // $companyName = $model->owner->company->name; - // $company = $this->fetchesCompany->execute(['id' => $model->owner->owner->id]); - // $employee = $company->employees()->first(); - // $contactEmail = $employee->email; - // $contactName = $employee->name; - // $proceed = true; - // } - if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ $companyReference = $model->owner->company->reference; $companyName = $model->owner->company->name; @@ -70,7 +54,50 @@ class TransactionToPerfexCRMProcessor $serviceTypeName = $model->owner->company->services()->where('id', $model->owner->service_id)->first()->name; $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; + $tasks = [ + PerfexCRMTasks::TASK_1 + ]; + if($model->owner->service_id == 1){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_2, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_3, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_6, + ]; + } + else if($model->owner->service_id == 2){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_2, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_3, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_6, + ]; + } + else if($model->owner->service_id == 4){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_1688_PAYMENT_1, + PerfexCRMTasks::TASK_1688_PAYMENT_2, + PerfexCRMTasks::TASK_1688_PAYMENT_3, + 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, + ]; + } $initialPerfexCRMObject = new InitialPerfexCRMObject( $companyName, $companyReference, @@ -79,64 +106,12 @@ class TransactionToPerfexCRMProcessor $bookingMarking, $projectName, [], - [ - PerfexCRMTasks::TASK_1, - ] + $tasks ); //$this->initializePerfexCRMProcessor->execute($initialPerfexCRMObject); InitializePerfexCRM::dispatch($initialPerfexCRMObject); - - // $updatePerfexCRMObject = new UpdatePerfexCRMObject( - // $companyName, - // $companyReference, - // $contactEmail, - // $bookingMarking, - // $companyReference.'-'.$bookingMarking, - // PerfexCRMTasks::TASK_1['milestone'], - // PerfexCRMTasks::TASK_1['name'] - // ); - - // //Mark task in Perfex CRM as done (5 means completed task) - // // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); - // UpdatePerfexCRM::dispatch($updatePerfexCRMObject); } - - /* - else if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ - - $updatePerfexCRMObject = new UpdatePerfexCRMObject( - $companyName, - $companyReference, - $contactEmail, - $bookingMarking, - $companyReference.'-'.$bookingMarking, - PerfexCRMTasks::TASK_3['milestone'], - PerfexCRMTasks::TASK_3['name'] - ); - - //Mark task in Perfex CRM as done (5 means completed task) - // $this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); - } - else if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::PENDING_VERIFICATION){ - - $updatePerfexCRMObject = new UpdatePerfexCRMObject( - $companyName, - $companyReference, - $contactEmail, - $bookingMarking, - $companyReference.'-'.$bookingMarking, - PerfexCRMTasks::TASK_2['milestone'], - PerfexCRMTasks::TASK_2['name'] - ); - - //Mark task in Perfex CRM as done (5 means completed task) - //$this->updatePerfexCRMProcessor->execute($updatePerfexCRMObject); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); - } - */ return true; } - } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php index 7e340c26..1674c999 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php @@ -10,25 +10,46 @@ class CreatesPerfexCRMTask { /** * @param string $taskName + * @param string $taskDescription + * @param string $leadId * @param string $milestoneId * @param string $projectId + * @param string $reference, default: '' + * @param string $on_task_completion, default: '' * @param string $status, default: 1 * @return null|object * @throws MalformedRequestException */ - public function execute(string $taskName, string $milestoneId, string $projectId, string $reference = '', string $status = "1") { + public function execute(string $taskName, string $taskDescription, string $leadId, string $milestoneId, string $projectId, string $reference = '', string $on_task_completion = '', string $status = "1") { try{ $data = [ 'name' => $taskName, + 'description' => $taskDescription, 'milestone' => $milestoneId, 'startdate' => date('Y-m-d'), 'rel_type' => 'project', 'rel_id' => $projectId, 'status' => $status, 'is_system_created' => 1, - 'reference' => $reference + 'reference' => $reference, + 'on_task_completion' => $on_task_completion ]; + 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 + ]; + } + $response = Http::asForm()->withHeaders([ 'authtoken' => config('perfexcrm.api_key')]) ->post(config('perfexcrm.base_url').'/api/tasks',$data); diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php new file mode 100644 index 00000000..df9c754d --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php @@ -0,0 +1,34 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/leads/byemail/'.$email); + + 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()); + } + } +} diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index db56631c..2843e0c2 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -5,19 +5,25 @@ 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) + public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor) { $this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor; + $this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor; } /** @@ -30,6 +36,7 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord { if(config('perfexcrm.is_enabled') == 'true'){ $this->transactionToPerfexCRMProcessor->execute($model, $status); + // $this->newLeadTaskToPerfexCRMProcessor->execute(); } $model->status = $status; return $this->handler($model); diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php b/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php index b1abecec..b21e379f 100644 --- a/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php +++ b/app/Classes/ValueObjects/Constants/PerfexCRMTasks.php @@ -6,52 +6,400 @@ class PerfexCRMTasks { public const TASK_1 = [ 'name' => 'Customer Paid', + 'description' => '', 'milestone' => 'MILESTONE 1 - Customer Paid', - 'reference' => '' + 'reference' => '', + 'on_task_completion' => '', + 'status' => PerfexCRMStatus::COMPLETED ]; - public const TASK_2 = [ - 'name' => 'TASK B', - 'milestone' => 'MILESTONE 2 - Order Placed', - 'reference' => '' - ]; - public const TASK_3 = [ - 'name' => 'TASK C', - 'milestone' => 'MILESTONE 3 - Purchase Order Approved', - 'reference' => '' - ]; - public const TASK_4 = [ - 'name' => 'TASK D', - 'milestone' => 'MILESTONE 4', - 'reference' => '' - ]; - public const TASK_5 = [ - 'name' => 'TASK E', - 'milestone' => 'MILESTONE 5', - 'reference' => '' - ]; - public const TASK_6 = [ - 'name' => 'TASK F', + + public const TASK_1_DAY_TRANSFER_1 = [ + 'name' => 'Map Bank Transaction Record', + 'description' => '○ Purpose: To map a transaction to bank transaction in the bank statement
+ ○ Initial Status: In Progress
+ ○ Deadline: If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Approve payment status to "In Progress" upon successful completion of the operation.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: None
+ ○ Outcomes: Bank transaction is mapped successfully, allowing the next steps in the process to be initiated.
', 'milestone' => '', - 'reference' => 'THIS_IS_TASK_NUMBER_6' + 'reference' => 'TASK_1_DAY_TRANSFER_1', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_2', + 'status' => PerfexCRMStatus::IN_PROGRESS ]; - public const TASK_7 = [ - 'name' => 'TASK G', + public const TASK_1_DAY_TRANSFER_2 = [ + 'name' => 'Approve Payment', + 'description' => '○ Purpose: To verify and approve the customer\'s payment on exchange
+ ○ Initial Status: Not Started
+ ○ Deadline:If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step:
+ i. Change the status of the Issue Exchange Autocount Invoice operation to "In Progress"
+ ii. Change the status of the Order Placed in White Form operation to "In Progress" upon successful completion.
+ ○ Additional details: When the payment method is FPX or Wallet this task is performed automatically by the system.
+ ○ Dependencies: Map Transaction operation must be completed before this operation can begin.
+ ○ Outcomes: The payment will be approved in exchange, allowing the next steps in the process to be initiated.
', 'milestone' => '', - 'reference' => 'THIS_IS_TASK_NUMBER_7' + 'reference' => 'TASK_1_DAY_TRANSFER_2', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_3', + 'status' => '' ]; - public const TASK_8 = [ - 'name' => 'TASK H', + public const TASK_1_DAY_TRANSFER_3 = [ + 'name' => 'Issue Exchange Autocount Invoince', + 'description' => '○ Purpose: To issue an invoice for the customer\'s payment in accounting software.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Knockoff Invoice operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ Outcomes: An invoice will be issued in accounting software for the customer\'s payment.
', 'milestone' => '', - 'reference' => 'THIS_IS_TASK_NUMBER_8' + 'reference' => 'TASK_1_DAY_TRANSFER_3', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_4', + 'status' => '' ]; - public const TASK_9 = [ - 'name' => 'TASK I', + public const TASK_1_DAY_TRANSFER_4 = [ + 'name' => 'Knockoff Invoice', + 'description' => '○ Purpose: The purpose of this operation is to issue the official receipt and knockoff with invoice for the customer\'s payment.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day.
+ ○ Responsible Department: Accounts
+ ○ Next Step: None
+ ○ Additional Details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Issue Exchange Autocount Invoice operation must be completed before this operation can begin.
+ ○ Outcomes: The customer\'s payment is applied to the accounting software invoice and invoice is marked as paid.
', 'milestone' => '', - 'reference' => 'THIS_IS_TASK_NUMBER_9' + 'reference' => 'TASK_1_DAY_TRANSFER_4', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_5', + 'status' => '' ]; - public const TASK_10 = [ - 'name' => 'TASK J', + public const TASK_1_DAY_TRANSFER_5 = [ + 'name' => 'Order Placed in White Form', + 'description' => '○ Purpose: To confirm that the order has been placed with the supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Upload China Bank Slip operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ Outcomes: The order is placed with a supplier and the customer\'s order is confirmed.
', 'milestone' => '', - 'reference' => 'THIS_IS_TASK_NUMBER_10' + 'reference' => 'TASK_1_DAY_TRANSFER_5', + 'on_task_completion' => 'TASK_1_DAY_TRANSFER_6', + 'status' => '' ]; + public const TASK_1_DAY_TRANSFER_6 = [ + 'name' => 'Upload China Bank Slip', + 'description' => '○ Purpose: To confirm that the customer order has been transferred to the customer\'s supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day
+ ○ Responsible department: Operations
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Order Placed in White Form operation must be completed before this operation can begin.
+ ○ Outcomes: The customer can download the payment transfer proof to send to their supplier.
', + 'milestone' => '', + 'reference' => 'TASK_1_DAY_TRANSFER_6', + 'on_task_completion' => '', + 'status' => '' + ]; + + public const TASK_3_DAY_TRANSFER_1 = [ + 'name' => 'Map Bank Transaction Record', + 'description' => '○ Purpose: To map a transaction to bank transaction in the bank statement
+ ○ Initial Status: In Progress
+ ○ Deadline: If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Approve payment status to "In Progress" upon successful completion of the operation.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: None
+ ○ Outcomes: Bank transaction is mapped successfully, allowing the next steps in the process to be initiated.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_1', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_2', + 'status' => PerfexCRMStatus::IN_PROGRESS + ]; + public const TASK_3_DAY_TRANSFER_2 = [ + 'name' => 'Approve Payment', + 'description' => '○ Purpose: To verify and approve the customer\'s payment on exchange
+ ○ Initial Status: Not Started
+ ○ Deadline:If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step:
+ i. Change the status of the Issue Exchange Autocount Invoice operation to "In Progress"
+ ii. Change the status of the Order Placed in White Form operation to "In Progress" upon successful completion.
+ ○ Additional details: When the payment method is FPX or Wallet this task is performed automatically by the system.
+ ○ Dependencies: Map Transaction operation must be completed before this operation can begin.
+ ○ Outcomes: The payment will be approved in exchange, allowing the next steps in the process to be initiated.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_2', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_3', + 'status' => '' + ]; + public const TASK_3_DAY_TRANSFER_3 = [ + 'name' => 'Issue Exchange Autocount Invoince', + 'description' => '○ Purpose: To issue an invoice for the customer\'s payment in accounting software.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Knockoff Invoice operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ Outcomes: An invoice will be issued in accounting software for the customer\'s payment.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_3', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_4', + 'status' => '' + ]; + public const TASK_3_DAY_TRANSFER_4 = [ + 'name' => 'Knockoff Invoice', + 'description' => '○ Purpose: The purpose of this operation is to issue the official receipt and knockoff with invoice for the customer\'s payment.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day.
+ ○ Responsible Department: Accounts
+ ○ Next Step: None
+ ○ Additional Details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Issue Exchange Autocount Invoice operation must be completed before this operation can begin.
+ ○ Outcomes: The customer\'s payment is applied to the accounting software invoice and invoice is marked as paid.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_4', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_5', + 'status' => '' + ]; + public const TASK_3_DAY_TRANSFER_5 = [ + 'name' => 'Order Placed in White Form', + 'description' => '○ Purpose: To confirm that the order has been placed with the supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: After 2 days
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Upload China Bank Slip operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ Outcomes: The order is placed with a supplier and the customer\'s order is confirmed.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_5', + 'on_task_completion' => 'TASK_3_DAY_TRANSFER_6', + 'status' => '' + ]; + public const TASK_3_DAY_TRANSFER_6 = [ + 'name' => 'Upload China Bank Slip', + 'description' => '○ Purpose: To confirm that the customer order has been transferred to the customer\'s supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: After 3 days
+ ○ Responsible department: Operations
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Order Placed in White Form operation must be completed before this operation can begin.
+ ○ Outcomes: The customer can download the payment transfer proof to send to their supplier.
', + 'milestone' => '', + 'reference' => 'TASK_3_DAY_TRANSFER_6', + 'on_task_completion' => '', + 'status' => '' + ]; + + + public const TASK_1688_PAYMENT_1 = [ + 'name' => 'Map Bank Transaction Record', + 'description' => '○ Purpose: To map a transaction to bank transaction in the bank statement
+ ○ Initial Status: In Progress
+ ○ Deadline: If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Approve payment status to "In Progress" upon successful completion of the operation.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: None
+ ○ Outcomes: Bank transaction is mapped successfully, allowing the next
+ steps in the process to be initiated.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_1', + 'on_task_completion' => 'TASK_1688_PAYMENT_2', + 'status' => PerfexCRMStatus::IN_PROGRESS + ]; + public const TASK_1688_PAYMENT_2 = [ + 'name' => 'Approve Payment', + 'description' => '○ Purpose: To verify and approve the customer\'s payment on exchange
+ ○ Initial Status: Not Started
+ ○ Deadline:If payment is created before 4:30 pm, it must be made on the same day. If payment is created after 4:30 pm, it must be made the next day
+ ○ Responsible department: Accounts
+ ○ Next step:
+ i. Change the status of the Issue Exchange Autocount Invoice operation to "In Progress"
+ ii. Change the status of the Order Placed in White Form operation to "In Progress" upon successful completion.
+ ○ Additional details: When the payment method is FPX or Wallet this task is performed automatically by the system.
+ ○ Dependencies: Map Transaction operation must be completed before this operation can begin.
+ ○ 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', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_3 = [ + 'name' => 'Issue Exchange Autocount Invoice', + 'description' => '○ Purpose: To issue an invoice for the customer\'s payment in accounting software.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day
+ ○ Responsible department: Accounts
+ ○ Next step: Change the status of the Knockoff Invoice operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ Outcomes: An invoice will be issued in accounting software for the customer\'s payment.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_3', + 'on_task_completion' => 'TASK_1688_PAYMENT_4', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_4 = [ + 'name' => 'Knockoff Invoice', + 'description' => '○ Purpose: The purpose of this operation is to issue the official receipt and knockoff with invoice for the customer\'s payment.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day.
+ ○ Responsible Department: Accounts
+ ○ Next Step: None
+ ○ Additional Details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Issue Exchange Autocount Invoice operation must be completed before this operation can begin.
+ ○ Outcomes: The customer\'s payment is applied to the accounting software invoice and invoice is marked as paid.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_4', + 'on_task_completion' => 'TASK_1688_PAYMENT_5', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_5 = [ + 'name' => 'Order Placed in White Form', + 'description' => '○ Purpose: To confirm that the order has been placed with the supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same Day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Send White Form to Operation
+ Department operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Payment operation must be completed before this operation can begin.
+ ○ 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', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_6 = [ + 'name' => 'Send White Form to Operation Department', + 'description' => '○ Purpose: To give confirmation to the operation department to process the order.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Upload China Bank Slip operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Order Placed in White Form operation must be completed before this operation can begin.
+ ○ Outcomes: The customer\'s order is confirmed and placed in a white form.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_6', + 'on_task_completion' => 'TASK_1688_PAYMENT_7', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_7 = [ + 'name' => 'Authorize Customer\'s 1688 Account', + 'description' => '○ Purpose: To authorize the alipay account to make payment to the customer\'s 1688 account.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Make Payment for Customer 1688
+ Order operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Send White Form to Operation Department operation
+ must be completed before this operation can begin.
+ ○ Outcomes: The customer\'s 1688 account is authorized to use the alipay account for making payments.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_7', + 'on_task_completion' => 'TASK_1688_PAYMENT_8', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_8 = [ + 'name' => 'Make Payment for Customer 1688 Order', + 'description' => '○ Purpose: To confirm that the order has been placed with the supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Upload China Bank Slip operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Authorize Customer’s 1688 Account operation must be completed before this operation can begin.
+ ○ Outcomes: The customer’s 1688 order is paid.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_8', + 'on_task_completion' => 'TASK_1688_PAYMENT_9', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_9 = [ + 'name' => 'Upload China Bank Slip', + 'description' => '○ Purpose: To confirm that the customer order has been transferred to the customer\'s supplier.
+ ○ Initial Status: Not Started
+ ○ Deadline: After 3 days
+ ○ Responsible department: Operations
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Make Payment for Customer 1688 Order operation must be completed before this operation can begin.
+ ○ Outcomes: The customer can download the payment transfer proof to send to their supplier.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_9', + 'on_task_completion' => 'TASK_1688_PAYMENT_10', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_10 = [ + 'name' => 'Upload 1688 Purchase Order PDF', + 'description' => '○ Purpose: To store a copy of the original purchase order document for bookkeeping.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Upload China Bank Slip operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Make Payment for Customer 1688 Order operation must be completed before this operation can begin.
+ ○ Outcomes: The 1688 purchase order’s pdf is attached to the booking.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_10', + 'on_task_completion' => 'TASK_1688_PAYMENT_11', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_11 = [ + 'name' => 'Fill Up Purchase Order', + 'description' => '○ Purpose: To store the purchase order details to generate the invoice.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Approve Purchase Order operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Upload 1688 Purchase Order PDF operation must be completed before this operation can begin.
+ ○ Outcomes: The purchase order’s details are added to the booking.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_11', + 'on_task_completion' => 'TASK_1688_PAYMENT_12', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_12 = [ + 'name' => 'Approve Purchase Order', + 'description' => '○ Purpose: To check that the customer submitted a purchase order that complies with our company’s guidelines.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: Change the status of Complete Order bookkeeping operation to "In Progress" upon successful completion.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Fill Up Purchase Order operation must be completed before this operation can begin.
+ ○ Outcomes: The purchase order submitted is approved.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_12', + 'on_task_completion' => 'TASK_1688_PAYMENT_13', + 'status' => '' + ]; + public const TASK_1688_PAYMENT_13 = [ + 'name' => 'Complete Order bookeeping', + 'description' => '○ Purpose: To complete the bookkeeping for the booking.
+ ○ Initial Status: Not Started
+ ○ Deadline: Same day
+ ○ Responsible department: Operations
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Purchase Order and Upload China Bank Slip operation must be completed before this operation can begin.
+ ○ Outcomes: The order is placed with a supplier and the customer’s order is confirmed.
', + 'milestone' => '', + 'reference' => 'TASK_1688_PAYMENT_13', + 'on_task_completion' => '', + 'status' => '' + ]; + } From 914b961d66ad77386b43392330741d89b8b85aff Mon Sep 17 00:00:00 2001 From: Dillon Date: Sun, 5 Mar 2023 20:26:20 +0800 Subject: [PATCH 11/18] CRM create invoice --- app/Classes/Jobs/CreatePerfexCRMInvoice.php | 42 +++++++++++++++++++ .../InvoicePerfexCRMObject.php | 6 +-- .../InvoiceSingleItemPerfexCRMObject.php | 8 ++-- .../CreatePerfexCRMInvoiceProcessor.php | 40 +++++++++++------- .../Services/CreatesPerfexCRMInvoice.php | 4 +- .../CreatesPerfexCRMInvoicePayment.php | 2 +- .../Services/FetchesPerfexCRMCustomer.php | 34 +++++++++++++++ .../Services/FetchesPerfexCRMInvoice.php | 36 ++++++++++++++++ .../CreateInvoiceTransactionProcessor.php | 8 ++-- .../Constants/PerfexCRMInvoiceStatus.php | 14 +++++++ 10 files changed, 165 insertions(+), 29 deletions(-) create mode 100644 app/Classes/Jobs/CreatePerfexCRMInvoice.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php create mode 100644 app/Classes/ValueObjects/Constants/PerfexCRMInvoiceStatus.php diff --git a/app/Classes/Jobs/CreatePerfexCRMInvoice.php b/app/Classes/Jobs/CreatePerfexCRMInvoice.php new file mode 100644 index 00000000..a6905be4 --- /dev/null +++ b/app/Classes/Jobs/CreatePerfexCRMInvoice.php @@ -0,0 +1,42 @@ +transaction = $transaction; + $this->purchaseOrder = $purchaseOrder; + $this->supplier = $supplier; + } + + public function handle() + { + (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($this->transaction, $this->purchaseOrder, $this->supplier); + } +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php index 7e204ff8..f1f21f11 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoicePerfexCRMObject.php @@ -7,7 +7,7 @@ use App\Classes\General\Interfaces\DataTransferObject; class InvoicePerfexCRMObject implements DataTransferObject { - /** @var int */ + /** @var string */ private $clientId; /** @var string */ @@ -56,9 +56,9 @@ class InvoicePerfexCRMObject implements DataTransferObject } /** - * @return int + * @return string */ - public function getClientId(): int + public function getClientId(): string { return $this->clientId; } diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php index 4f92895d..7b9428db 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InvoiceSingleItemPerfexCRMObject.php @@ -14,7 +14,7 @@ class InvoiceSingleItemPerfexCRMObject implements DataTransferObject /** @var string */ public $longDescription; - /** @var int */ + /** @var float */ public $qty; /** @var float */ @@ -26,7 +26,7 @@ class InvoiceSingleItemPerfexCRMObject implements DataTransferObject /** @var string */ public $unit; - public function __construct(string $description, string $longDescription, int $qty, float $rate, int $order, string $unit) + public function __construct(string $description, string $longDescription, float $qty, float $rate, int $order, string $unit) { $this->description = $description; $this->longDescription = $longDescription; @@ -53,9 +53,9 @@ class InvoiceSingleItemPerfexCRMObject implements DataTransferObject } /** - * @return int + * @return float */ - public function getQty(): int + public function getQty(): float { return $this->qty; } diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 7a893bde..ccdfcdb8 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -44,12 +44,16 @@ class CreatePerfexCRMInvoiceProcessor * @throws \App\Classes\Exceptions\MalformedRequestException */ public function execute($transaction, $purchaseOrder, $supplier) { + $clientId = ""; $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; $date = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); $dueDate = Carbon::parse($transaction->booking->created_at)->format('Y-m-d'); @@ -72,7 +76,7 @@ class CreatePerfexCRMInvoiceProcessor $invoiceItems = []; $email = $supplier->employees()->first()->email; - $email = 'dillon37@yahoo.com'; //cief TODO: To be updated to user actual email address + $result = $this->convertsPerfexCRMLeadToCustomer->execute($email); if(isset($result->payload)){ $clientId = $result->payload['client_id']; @@ -94,12 +98,12 @@ class CreatePerfexCRMInvoiceProcessor if($transaction->booking()->first()->fix_currency_id !== 1){ //$totalAmount = (float)number_format( (1/$transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity; - $subTotal += (1/$transaction->currency_rate) * $transaction_detail->price * $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 += $transaction_detail->price * $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 @@ -121,7 +125,8 @@ class CreatePerfexCRMInvoiceProcessor $total = $transaction->amount + $transaction->service_charge + $transaction->tax; } - //cief TODO: To be updated, temporarily hardcoded allow payment modes + //This setting is similar to Setup > Leads > Sources, Setup > Leads > Statuses + //Can be found at Finance > Payment Modes array_push($allowedPaymentModes, 1, 2); $invoicePerfexCRMObject = new InvoicePerfexCRMObject( @@ -140,18 +145,23 @@ class CreatePerfexCRMInvoiceProcessor $result = $this->createsPerfexCRMInvoice->execute($invoicePerfexCRMObject); - //If there is a checking whether an payment to an invoice need to be generated, do it here - if(true && $result->payload['id']){ - $invoicePaymentPerfexCRMObject = new InvoicePaymentPerfexCRMObject( - $result->payload['id'], - $total, - $date, - 1, - "", - "" - ); - $this->createsPerfexCRMInvoicePayment->execute($invoicePaymentPerfexCRMObject); + 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; } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php index 196e3130..b595a86f 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php @@ -22,8 +22,8 @@ class CreatesPerfexCRMInvoice 'date' => $invoicePerfexCRMObject->getDate(), 'duedate' => $invoicePerfexCRMObject->getDueDate(), 'currency' => $invoicePerfexCRMObject->getCurrency(), - 'subtotal' => $invoicePerfexCRMObject->getSubTotal(), - 'total' => $invoicePerfexCRMObject->getTotal(), + 'subtotal' => number_format($invoicePerfexCRMObject->getSubTotal(), 2, '.', ''), + 'total' => number_format($invoicePerfexCRMObject->getTotal(), 2, '.', ''), 'billing_street' => $invoicePerfexCRMObject->getBillingStreet(), 'project_id' => $invoicePerfexCRMObject->getProjectId(), 'allowed_payment_modes[0]' => 1, diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php index 035cc1b8..f3e92529 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php @@ -18,7 +18,7 @@ class CreatesPerfexCRMInvoicePayment try{ $data = [ 'invoiceid' => $invoicePaymentPerfexCRMObject->getInvoiceId(), - 'amount' => $invoicePaymentPerfexCRMObject->getAmount(), + 'amount' => number_format($invoicePaymentPerfexCRMObject->getAmount(), 2, '.', ''), 'date' => $invoicePaymentPerfexCRMObject->getDate(), 'paymentmode' => $invoicePaymentPerfexCRMObject->getPaymentMode(), 'transactionid' => $invoicePaymentPerfexCRMObject->getTransactionId(), diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php new file mode 100644 index 00000000..9f3928f6 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php @@ -0,0 +1,34 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/customers/byemail/'.$email); + + 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()); + } + } +} diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php new file mode 100644 index 00000000..cd7aff30 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php @@ -0,0 +1,36 @@ + config('perfexcrm.api_key'),]) + ->get(config('perfexcrm.base_url').'/api/invoices/customsearch/'.$clientId.'/'.$invoicePrefix.'/'.$invoiceNumber); + + 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()); + } + } +} diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index a983a332..06a87cb5 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -19,6 +19,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\SegmentConstants; use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\ValueObjects\Constants\DocumentType; +use App\Classes\Jobs\CreatePerfexCRMInvoice; use App\Models\Booking; use App\Models\SegmentConstant; @@ -199,10 +200,9 @@ class CreateInvoiceTransactionProcessor $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER); // update perfex crm - // if(config('perfexcrm.is_enabled') == 'true'){ - // { - // $this->createPerfexCRMInvoiceProcessor->execute($invoice_transaction, $purchaseOrder, $supplier); - // } + if(config('perfexcrm.is_enabled') == 'true'){ + CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); + } $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); } diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMInvoiceStatus.php b/app/Classes/ValueObjects/Constants/PerfexCRMInvoiceStatus.php new file mode 100644 index 00000000..2e692129 --- /dev/null +++ b/app/Classes/ValueObjects/Constants/PerfexCRMInvoiceStatus.php @@ -0,0 +1,14 @@ + Date: Mon, 6 Mar 2023 00:26:08 +0800 Subject: [PATCH 12/18] Tie invoice to project --- .../CreatePerfexCRMInvoiceProcessor.php | 20 +++++++++++++++++-- .../CreateInvoiceTransactionProcessor.php | 7 +------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index ccdfcdb8..2086276d 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -6,6 +6,7 @@ namespace App\Classes\Modules\PerfexCRM\Processors; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoice; 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\DataTransferObjects\InvoicePerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject; @@ -23,17 +24,22 @@ class CreatePerfexCRMInvoiceProcessor /** @var ConvertsPerfexCRMLeadToCustomer */ private $convertsPerfexCRMLeadToCustomer; + /** @var FetchesPerfexCRMProject */ + private $fetchesPerfexCRMProject; + /** * CreatePerfexCRMInvoiceProcessor constructor. * @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice */ public function __construct(CreatesPerfexCRMInvoice $createsPerfexCRMInvoice, CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment, - ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer) + ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer, + FetchesPerfexCRMProject $fetchesPerfexCRMProject) { $this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice; $this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment; $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; + $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; } /** @@ -71,7 +77,7 @@ class CreatePerfexCRMInvoiceProcessor $billingStreet = $billingStreet.$addresses->state()->first()->name.','; $billingStreet = $billingStreet.$addresses->country()->first()->name; - $projectId = ""; + $allowedPaymentModes = []; $invoiceItems = []; @@ -82,6 +88,16 @@ class CreatePerfexCRMInvoiceProcessor $clientId = $result->payload['client_id']; } + //get project + $projectId = ""; + $bookingMarking = $transaction->owner->marking; + $serviceTypeName = $transaction->owner->company->services()->where('id', $transaction->owner->service_id)->first()->name; + $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; + $project = $this->fetchesPerfexCRMProject->execute($projectName, $clientId); + if(!is_null($project)){ + $projectId = $project->id; + } + //newitems foreach ($purchaseOrder->transactionDetails as $key => $transaction_detail){ $order = $key + 1; diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index 06a87cb5..d48d4d5b 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -14,7 +14,6 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; -use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMInvoiceProcessor; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\SegmentConstants; use App\Classes\ValueObjects\Constants\TransactionType; @@ -53,8 +52,6 @@ class CreateInvoiceTransactionProcessor /** @var CreateInvoiceDocumentProcessor */ private $invoiceDocumentProcessor; - /** @var CreatePerfexCRMInvoiceProcessor */ - private $createPerfexCRMInvoiceProcessor; /** * CreateInvoiceTransactionProcessor constructor. @@ -69,9 +66,8 @@ class CreateInvoiceTransactionProcessor * @param FetchesCompany $fetchesCompany * @param UpdatesBookingStatus $updatesBookingStatus * @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor - * @param CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor */ - public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CreatePerfexCRMInvoiceProcessor $createPerfexCRMInvoiceProcessor) + public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor) { $this->createsTransaction = $createsTransaction; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; @@ -82,7 +78,6 @@ class CreateInvoiceTransactionProcessor $this->fetchesCompany = $fetchesCompany; $this->updatesBookingStatus = $updatesBookingStatus; $this->invoiceDocumentProcessor = $invoiceDocumentProcessor; - $this->createPerfexCRMInvoiceProcessor = $createPerfexCRMInvoiceProcessor; } From a29255c432c4b05cacb8f70bc8f245c1e2b88c46 Mon Sep 17 00:00:00 2001 From: Dillon Date: Mon, 6 Mar 2023 01:02:42 +0800 Subject: [PATCH 13/18] Fix a mistake in Update service type id for 3 days transfer --- .../PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index bd8561ea..c512e6b5 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -68,7 +68,7 @@ class TransactionToPerfexCRMProcessor PerfexCRMTasks::TASK_1_DAY_TRANSFER_6, ]; } - else if($model->owner->service_id == 2){ + else if($model->owner->service_id == 3){ $tasks = [ PerfexCRMTasks::TASK_1, PerfexCRMTasks::TASK_3_DAY_TRANSFER_1, From edcc6acfab0565176ab2981caea4c3dab9e806d7 Mon Sep 17 00:00:00 2001 From: Dillon Date: Mon, 6 Mar 2023 15:19:07 +0800 Subject: [PATCH 14/18] CRM new service --- .../Services/UpdatesPerfexCRMInvoice.php | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php new file mode 100644 index 00000000..5240d931 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -0,0 +1,68 @@ +The Invoice number field is required.<\/p> + //

The Invoice date field is required.<\/p> + //

The Currency field is required.<\/p> + //

The Items field is required.<\/p> + //

The Allow Payment Mode field is required.<\/p> + //

The Billing Street field is required.<\/p> + //

The Sub Total field is required.<\/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){ + dd(json_encode($exception)); + throw new MalformedRequestException('Unable to get correct response from Perfex CRM server: ' . $exception->getMessage()); + } + } +} From 40e4aae185c1144e6f3272bd670861b576409787 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 10 Mar 2023 02:42:00 +0800 Subject: [PATCH 15/18] CRM create all remaining tasks according to documentation --- .../ControllersLogic/CreateBookingLogic.php | 15 +- .../CreateIdentificationDocumentLogic.php | 13 +- .../InitialPerfexCRMObject.php | 14 +- .../UpdatePerfexCRMObject.php | 50 +++-- .../BookingToPerfexCRMProcessor.php | 44 +++++ .../CreatePerfexCRMInvoiceProcessor.php | 15 +- .../InitializePerfexCRMProcessor.php | 15 +- .../NewLeadTaskToPerfexCRMProcessor.php | 18 +- .../TransactionToPerfexCRMProcessor.php | 180 +++++++++--------- .../Processors/UpdatePerfexCRMProcessor.php | 137 +++++++++---- .../CreatesPerfexCRMCustomerProject.php | 4 +- .../Services/UpdatesPerfexCRMProject.php | 43 +++++ .../Constants/PerfexCRMProjectStatus.php | 16 ++ ...xCRMStatus.php => PerfexCRMTaskStatus.php} | 4 +- .../ValueObjects/Constants/PerfexCRMTasks.php | 58 +++++- 15 files changed, 468 insertions(+), 158 deletions(-) create mode 100644 app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php create mode 100644 app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php create mode 100644 app/Classes/ValueObjects/Constants/PerfexCRMProjectStatus.php rename app/Classes/ValueObjects/Constants/{PerfexCRMStatus.php => PerfexCRMTaskStatus.php} (86%) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php index e4fa3666..0fbf2519 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php @@ -13,6 +13,8 @@ use App\Classes\Modules\Bookings\Services\CreatesBooking; use App\Classes\Modules\Bookings\Services\GeneratesBookingMarking; use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; +use App\Classes\Modules\PerfexCRM\Processors\BookingToPerfexCRMProcessor; + use App\Http\Resources\BookingResource; use ErrorException; @@ -44,19 +46,24 @@ class CreateBookingLogic extends AbstractControllerLogic /** @var FetchesCompany */ private $fetchesCompany; + /** @var BookingToPerfexCRMProcessor */ + private $bookingToPerfexCRMProcessor; + /** * CreateBookingLogic constructor. * @param CanCreateBooking $canCreateBooking * @param CreatesBooking $createsBooking * @param GeneratesBookingMarking $generatesBookingMarking * @param FetchesCompany $fetchesCompany + * @param BookingToPerfexCRMProcessor $bookingToPerfexCRMProcessor */ - public function __construct(CanCreateBooking $canCreateBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany) + public function __construct(CanCreateBooking $canCreateBooking, CreatesBooking $createsBooking, GeneratesBookingMarking $generatesBookingMarking, FetchesCompany $fetchesCompany, BookingToPerfexCRMProcessor $bookingToPerfexCRMProcessor) { $this->canCreateBooking = $canCreateBooking; $this->createsBooking = $createsBooking; $this->generatesBookingMarking = $generatesBookingMarking; $this->fetchesCompany = $fetchesCompany; + $this->bookingToPerfexCRMProcessor = $bookingToPerfexCRMProcessor; } @@ -77,7 +84,11 @@ class CreateBookingLogic extends AbstractControllerLogic $booking = $this->createsBooking->execute($company, $object); + if(config('perfexcrm.is_enabled') == 'true'){ + $this->bookingToPerfexCRMProcessor->execute($booking); + } + return $this->resourceResponse(new BookingResource($booking)); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php index bbf91ea7..c08dc4ef 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php @@ -9,6 +9,7 @@ use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; use App\Classes\Modules\Documents\Services\CreatesDocument; use App\Classes\Modules\Documents\Services\CreatesFiles; +use App\Classes\Modules\PerfexCRM\Processors\NewLeadTaskToPerfexCRMProcessor; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\CompanyType; use App\Classes\ValueObjects\Constants\DocumentType; @@ -42,6 +43,8 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic /** @var UpdatesCompanyStatus */ private $updatesCompanyStatus; + /** @var NewLeadTaskToPerfexCRMProcessor */ + private $newLeadTaskToPerfexCRMProcessor; /** * CreateIdentificationDocumentLogic constructor. @@ -49,13 +52,15 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic * @param CreatesDocument $createsDocument * @param CreatesFiles $createsFile * @param UpdatesCompanyStatus $updatesCompanyStatus + * @param NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor */ - public function __construct(FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesCompanyStatus $updatesCompanyStatus) + public function __construct(FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesCompanyStatus $updatesCompanyStatus, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor) { $this->fetchesCompany = $fetchesCompany; $this->createsDocument = $createsDocument; $this->createsFile = $createsFile; $this->updatesCompanyStatus = $updatesCompanyStatus; + $this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor; } /** @@ -78,7 +83,11 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic $this->updatesCompanyStatus->execute($company, ApprovalStatus::PENDING_VERIFICATION); + if(config('perfexcrm.is_enabled') == 'true'){ + $this->newLeadTaskToPerfexCRMProcessor->execute($company); + } + return $this->response([]); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php index 1c4a9db5..66c2c86c 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/InitialPerfexCRMObject.php @@ -25,6 +25,9 @@ class InitialPerfexCRMObject implements DataTransferObject /** @var string */ private $projectName; + /** @var int */ + private $projectStatus; + /** @var array */ private $milestoneNames; @@ -32,7 +35,7 @@ class InitialPerfexCRMObject implements DataTransferObject private $taskNames; - public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, array $milestoneNames, array $taskNames) + public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $taskNames) { $this->companyName = $companyName; @@ -41,6 +44,7 @@ class InitialPerfexCRMObject implements DataTransferObject $this->contactEmail = $contactEmail; $this->bookingMarking = $bookingMarking; $this->projectName = $projectName; + $this->projectStatus = $projectStatus; $this->milestoneNames = $milestoneNames; $this->taskNames = $taskNames; } @@ -93,6 +97,14 @@ class InitialPerfexCRMObject implements DataTransferObject return $this->projectName; } + /** + * @return string + */ + public function getProjectStatus(): int + { + return $this->projectStatus; + } + /** * @return array */ diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php index be9328ac..a246d25a 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php @@ -13,6 +13,9 @@ class UpdatePerfexCRMObject implements DataTransferObject /** @var string */ private $companyReference; + /** @var string */ + private $contactName; + /** @var string */ private $contactEmail; @@ -22,23 +25,28 @@ class UpdatePerfexCRMObject implements DataTransferObject /** @var string */ private $projectName; - /** @var string */ - private $milestoneName; + /** @var int */ + private $projectStatus; - /** @var string */ - private $taskName; + /** @var array */ + private $milestoneNames; + + /** @var array */ + private $taskNames; - public function __construct(string $companyName, string $companyReference, string $contactEmail, string $bookingMarking, string $projectName, string $milestoneName, string $taskName) + public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $taskNames) { $this->companyName = $companyName; $this->companyReference = $companyReference; + $this->contactName = $contactName; $this->contactEmail = $contactEmail; $this->bookingMarking = $bookingMarking; $this->projectName = $projectName; - $this->milestoneName = $milestoneName; - $this->taskName = $taskName; + $this->projectStatus = $projectStatus; + $this->milestoneNames = $milestoneNames; + $this->taskNames = $taskNames; } /** @@ -57,6 +65,14 @@ class UpdatePerfexCRMObject implements DataTransferObject return $this->companyReference; } + /** + * @return string + */ + public function getContactName(): string + { + return $this->contactName; + } + /** * @return string */ @@ -82,19 +98,27 @@ class UpdatePerfexCRMObject implements DataTransferObject } /** - * @return string + * @return int */ - public function getMilestoneName(): string + public function getProjectStatus(): int { - return $this->milestoneName; + return $this->projectStatus; } /** - * @return string + * @return array */ - public function getTaskName(): string + public function getMilestoneNames(): array { - return $this->taskName; + return $this->milestoneNames; + } + + /** + * @return array + */ + public function getTaskNames(): array + { + return $this->taskNames; } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php new file mode 100644 index 00000000..5929ea1d --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Processors/BookingToPerfexCRMProcessor.php @@ -0,0 +1,44 @@ +company->reference; + $companyName = $booking->company->name; + $employee = $booking->company->employees()->first(); + $contactEmail = $employee->email; + $contactName = $employee->name; + $bookingMarking = $booking->marking; + + $serviceTypeName = $booking->company->services()->where('id', $booking->service_id)->first()->name; + $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; + + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactName, + $contactEmail, + $bookingMarking, + $projectName, + PerfexCRMProjectStatus::NOT_STARTED, + [], + [] + ); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + + return true; + } +} diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 2086276d..767bd894 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -7,9 +7,11 @@ use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMInvoice; 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\PerfexCRM\DataTransferObjects\InvoicePerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoicePaymentPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\InvoiceSingleItemPerfexCRMObject; +use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; use Carbon\Carbon; class CreatePerfexCRMInvoiceProcessor @@ -27,6 +29,9 @@ class CreatePerfexCRMInvoiceProcessor /** @var FetchesPerfexCRMProject */ private $fetchesPerfexCRMProject; + /** @var CreatesPerfexCRMCustomerProject */ + private $createsPerfexCRMCustomerProject; + /** * CreatePerfexCRMInvoiceProcessor constructor. * @param CreatesPerfexCRMInvoice $createsPerfexCRMInvoice @@ -34,12 +39,14 @@ class CreatePerfexCRMInvoiceProcessor public function __construct(CreatesPerfexCRMInvoice $createsPerfexCRMInvoice, CreatesPerfexCRMInvoicePayment $createsPerfexCRMInvoicePayment, ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer, - FetchesPerfexCRMProject $fetchesPerfexCRMProject) + FetchesPerfexCRMProject $fetchesPerfexCRMProject, + CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject) { $this->createsPerfexCRMInvoice = $createsPerfexCRMInvoice; $this->createsPerfexCRMInvoicePayment = $createsPerfexCRMInvoicePayment; $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; + $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; } /** @@ -97,6 +104,12 @@ class CreatePerfexCRMInvoiceProcessor if(!is_null($project)){ $projectId = $project->id; } + else{ + $result = $this->createsPerfexCRMCustomerProject->execute($projectName, PerfexCRMProjectStatus::NOT_STARTED, $clientId); + if(isset($result->payload)){ //Here means project creation successful + $projectId = $result->payload['project_id']; + } + } //newitems foreach ($purchaseOrder->transactionDetails as $key => $transaction_detail){ diff --git a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php index 9fa2bee4..875dd35f 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php @@ -18,7 +18,7 @@ use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\ValueObjects\Constants\PerfexCRMMilestones; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; -use App\Classes\ValueObjects\Constants\PerfexCRMStatus; +use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; @@ -149,7 +149,7 @@ class InitializePerfexCRMProcessor } // Get existing or create project, project has to exist first before milestone can appear under it - $result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId); + $result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $initialPerfexCRMObject->getProjectStatus(), $crmClientId); if(isset($result->payload)){ //Here means project creation successful $projectId = $result->payload['project_id']; } @@ -157,8 +157,9 @@ class InitializePerfexCRMProcessor $projectId = $this->fetchesPerfexCRMProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId)->id; } - if(!is_null($result)){ - $tasks = $initialPerfexCRMObject->getTaskNames(); + + $tasks = $initialPerfexCRMObject->getTaskNames(); + if(count($tasks) > 0){ //Create tasks with milestone for($count=0; $count < count($tasks); $count++) { @@ -177,16 +178,18 @@ class InitializePerfexCRMProcessor } } - $taskStatus = PerfexCRMStatus::NOT_STARTED; + $taskStatus = PerfexCRMTaskStatus::NOT_STARTED; if($tasks[$count]['status'] != ''){ $taskStatus = $tasks[$count]['status']; } // Get existing or create task $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $taskStatus); + if(is_null($result)){ + break; //Breaking the rest of the tasks in array assuming that they are all created as a batch previously + } } } return true; } - } diff --git a/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php index 9602696d..bce779f1 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php @@ -3,28 +3,32 @@ namespace App\Classes\Modules\PerfexCRM\Processors; use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateTaskPerfexCRMObject; -use App\Classes\ValueObjects\Constants\PerfexCRMStatus; use App\Classes\Jobs\CreatePerfexCRMSingleTask; +use App\Classes\ValueObjects\Constants\PerfexCRMTasks; +use App\Models\Company; class NewLeadTaskToPerfexCRMProcessor { /** - * @param None + * @param Company $company * @return true * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute() + public function execute(Company $company) { + $employee = $company->employees()->first(); + $contactEmail = $employee->email; + $createTaskPerfexCRMObject = new CreateTaskPerfexCRMObject( - "dillontest1@gmail.com", - "test is the name of the task", - "this is the description of the task", + $contactEmail, + PerfexCRMTasks::TASK_IDENTIFICATION_1['name'], + PerfexCRMTasks::TASK_IDENTIFICATION_1['description'], "", "", "", "", "", - PerfexCRMStatus::NOT_STARTED + PerfexCRMTasks::TASK_IDENTIFICATION_1['status'] ); CreatePerfexCRMSingleTask::dispatch($createTaskPerfexCRMObject); diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index c512e6b5..cd7ba6b0 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -2,40 +2,17 @@ namespace App\Classes\Modules\PerfexCRM\Processors; -use App\Classes\Modules\PerfexCRM\Processors\UpdatePerfexCRMProcessor; -use App\Classes\Modules\PerfexCRM\Processors\InitializePerfexCRMProcessor; -use App\Classes\Modules\Companies\Services\FetchesCompany; -use App\Classes\Modules\PerfexCRM\DataTransferObjects\InitialPerfexCRMObject; +use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; -use App\Models\Transaction; use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Classes\Jobs\InitializePerfexCRM; +use App\Classes\ValueObjects\Constants\TransactionType; +use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; +use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus; +use App\Classes\Jobs\UpdatePerfexCRM; +use App\Models\Transaction; class TransactionToPerfexCRMProcessor { - /** @var FetchesCompany */ - private $fetchesCompany; - - /** @var UpdatePerfexCRMProcessor */ - private $updatePerfexCRMProcessor; - - /** @var InitializePerfexCRMProcessor */ - private $initializePerfexCRMProcessor; - - /** - * TransactionToPerfexCRMProcessor constructor. - * @param UpdatePerfexCRMProcessor $updatePerfexCRMProcessor - * @param InitializePerfexCRMProcessor $initializePerfexCRMProcessor - * @param FetchesCompany $fetchesCompany - */ - public function __construct(UpdatePerfexCRMProcessor $updatePerfexCRMProcessor, InitializePerfexCRMProcessor $initializePerfexCRMProcessor, FetchesCompany $fetchesCompany) - { - $this->updatePerfexCRMProcessor = $updatePerfexCRMProcessor; - $this->initializePerfexCRMProcessor = $initializePerfexCRMProcessor; - $this->fetchesCompany = $fetchesCompany; - } - - /** * @param Transaction $model * @param int $status @@ -44,7 +21,8 @@ class TransactionToPerfexCRMProcessor */ public function execute(Transaction $model, int $status) { - if($model->owner instanceof \App\Models\Booking && $status == ApprovalStatus::APPROVED){ + // dd(json_encode($status)); + if($model->owner instanceof \App\Models\Booking) { $companyReference = $model->owner->company->reference; $companyName = $model->owner->company->name; $employee = $model->owner->company->employees()->first(); @@ -54,64 +32,96 @@ class TransactionToPerfexCRMProcessor $serviceTypeName = $model->owner->company->services()->where('id', $model->owner->service_id)->first()->name; $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; - $tasks = [ - PerfexCRMTasks::TASK_1 - ]; - if($model->owner->service_id == 1){ - $tasks = [ - PerfexCRMTasks::TASK_1, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_1, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_2, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_3, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_4, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_5, - PerfexCRMTasks::TASK_1_DAY_TRANSFER_6, - ]; - } - else if($model->owner->service_id == 3){ - $tasks = [ - PerfexCRMTasks::TASK_1, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_1, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_2, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_3, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_4, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_5, - PerfexCRMTasks::TASK_3_DAY_TRANSFER_6, - ]; - } - else if($model->owner->service_id == 4){ - $tasks = [ - PerfexCRMTasks::TASK_1, - PerfexCRMTasks::TASK_1688_PAYMENT_1, - PerfexCRMTasks::TASK_1688_PAYMENT_2, - PerfexCRMTasks::TASK_1688_PAYMENT_3, - 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, - ]; - } - $initialPerfexCRMObject = new InitialPerfexCRMObject( - $companyName, - $companyReference, - $contactName, - $contactEmail, - $bookingMarking, - $projectName, - [], - $tasks - ); + if($status == ApprovalStatus::APPROVED) + { + if($model->type == TransactionType::PAYMENT){ + $tasks = [ + PerfexCRMTasks::TASK_1 + ]; + if($model->owner->service_id == 1){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_2, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_3, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_1_DAY_TRANSFER_6, + ]; + } + else if($model->owner->service_id == 3){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_1, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_2, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_3, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_4, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_5, + PerfexCRMTasks::TASK_3_DAY_TRANSFER_6, + ]; + } + else if($model->owner->service_id == 4){ + $tasks = [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_1688_PAYMENT_1, + PerfexCRMTasks::TASK_1688_PAYMENT_2, + PerfexCRMTasks::TASK_1688_PAYMENT_3, + 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, - //$this->initializePerfexCRMProcessor->execute($initialPerfexCRMObject); - InitializePerfexCRM::dispatch($initialPerfexCRMObject); + ]; + } + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactName, + $contactEmail, + $bookingMarking, + $projectName, + PerfexCRMProjectStatus::IN_PROGRESS, + [], + $tasks + ); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } + } + else if($status == ApprovalStatus::PENDING_VERIFICATION){ + if($model->type == TransactionType::PURCHASE_ORDER){ + $tasks = []; + if($model->owner->service_id == 1 || $model->owner->service_id == 3){ + $tasks = [ + PerfexCRMTasks::TASK_PURCHASE_ORDER_1, + PerfexCRMTasks::TASK_PURCHASE_ORDER_2, + ]; + } + + if(count($tasks) > 0){ + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactName, + $contactEmail, + $bookingMarking, + $projectName, + PerfexCRMProjectStatus::IN_PROGRESS, + [], + $tasks + ); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } + } + } } + return true; } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php index 0b452d02..24d45506 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -12,10 +12,13 @@ use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMTask; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerContact; 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\ValueObjects\Constants\PerfexCRMStatus; +use App\Classes\ValueObjects\Constants\PerfexCRMTaskStatus; +use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; @@ -52,6 +55,11 @@ class UpdatePerfexCRMProcessor /** @var UpdatesPerfexCRMTask */ private $updatesPerfexCRMTask; + /** @var UpdatesPerfexCRMCustomer */ + private $updatesPerfexCRMCustomer; + + /** @var UpdatesPerfexCRMProject */ + private $updatesPerfexCRMProject; /** * @param ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer @@ -64,6 +72,8 @@ class UpdatePerfexCRMProcessor * @param CreatesPerfexCRMCustomer $createsPerfexCRMCustomer * @param CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact * @param UpdatesPerfexCRMTask $updatesPerfexCRMTask + * @param UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer + * @param UpdatesPerfexCRMProject $updatesPerfexCRMProject */ public function __construct(ConvertsPerfexCRMLeadToCustomer $convertsPerfexCRMLeadToCustomer, CreatesPerfexCRMCustomerProject $createsPerfexCRMCustomerProject, @@ -74,7 +84,9 @@ class UpdatePerfexCRMProcessor FetchesPerfexCRMTask $fetchesPerfexCRMTask, CreatesPerfexCRMCustomer $createsPerfexCRMCustomer, CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact, - UpdatesPerfexCRMTask $updatesPerfexCRMTask) + UpdatesPerfexCRMTask $updatesPerfexCRMTask, + UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer, + UpdatesPerfexCRMProject $updatesPerfexCRMProject) { $this->convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; @@ -86,10 +98,12 @@ class UpdatePerfexCRMProcessor $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; $this->updatesPerfexCRMTask = $updatesPerfexCRMTask; + $this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer; + $this->updatesPerfexCRMProject = $updatesPerfexCRMProject; } /** - * @param PerfexCRMObject $perfexCRMObject + * @param UpdatePerfexCRMObject $updatePerfexCRMObject * @return null|object * @throws \App\Classes\Exceptions\MalformedRequestException */ @@ -97,43 +111,100 @@ class UpdatePerfexCRMProcessor // 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(); $result = $this->convertsPerfexCRMLeadToCustomer->execute($updatePerfexCRMObject->getContactEmail()); + if(isset($result->payload)){ - $crmClientId = $result->payload['client_id']; + $crmClientId = $result->payload['client_id']; + if (isset($result->payload['company'])) { + $crmCompany = $result->payload['company']; + } + } + else{ + //if reach this point, this means this user is not a official customer nor is a lead in crm + //Create Customer has 2 parts: Create Company (client), Create Contact + $result = $this->createsPerfexCRMCustomer->execute($crmCompany); + if(is_null($result)){ + $crmCompany = $crmCompany." 2"; + $result = $this->createsPerfexCRMCustomer->execute($crmCompany); + } + $crmClientId = $result->payload['clientId']; + + $customerContactObject = new CustomerContactObject( + $crmClientId, + $updatePerfexCRMObject->getContactName(), + $updatePerfexCRMObject->getContactName(), + $updatePerfexCRMObject->getContactEmail(), + "pU^T@sC#9Q", + "on", + "on" + ); + $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); } - // Get existing or create project, project has to exist first before milestone can appear under it - $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); - if(isset($result->payload)){ - $projectId = $result->payload['project_id']; - } - else{ - $projectId = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId)->id; - } + //Update custom fields to identify company reference from exchange or shipping portal + $value_exists = false; + if (isset($result->payload['customfields'])) { + foreach ($result->payload['customfields'] as $element) { + if ($element['value'] === $updatePerfexCRMObject->getCompanyReference()) { + $value_exists = true; + break; + } + } + } + if(!$value_exists); + { + $result = $this->updatesPerfexCRMCustomer->execute($crmClientId, $crmCompany, $updatePerfexCRMObject->getCompanyReference()); + } - // Get existing or create milestone, milestone has to exist first before task can appear under it - $result = $this->createsPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId); - if(isset($result->payload)){ - $milestoneId = $result->payload['milestone_id']; - } - else{ - $milestone = $this->fetchesPerfexCRMMilestone->execute($updatePerfexCRMObject->getMilestoneName(), $projectId); - $array = json_decode(json_encode($milestone), true); - $milestoneId = $array[0]['id']; - } + // Get existing or create project, project has to exist first before milestone can appear under it + $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $updatePerfexCRMObject->getProjectStatus(), $crmClientId); + if(isset($result->payload)){ //Here means project creation successful + $projectId = $result->payload['project_id']; + } + else{ + $project = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); + $projectId = $project->id; + //if the project status is anything but PerfexCRMProjectStatus::NOT_STARTED, update the project + if($updatePerfexCRMObject->getProjectStatus() != PerfexCRMProjectStatus::NOT_STARTED) + { + $this->updatesPerfexCRMProject->execute($project, $updatePerfexCRMObject->getProjectStatus()); + } + } - // Get existing or create task - $result = $this->createsPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId); - if(isset($result->payload)){ - $taskId = $result->payload['task_id']; - } - else{ - $taskId = $this->fetchesPerfexCRMTask->execute($updatePerfexCRMObject->getTaskName(), $milestoneId)->id; - } - $this->updatesPerfexCRMTask->execute($taskId, $updatePerfexCRMObject->getTaskName(), $milestoneId, $projectId, PerfexCRMStatus::COMPLETED); + $tasks = $updatePerfexCRMObject->getTaskNames(); + if(count($tasks) > 0){ - return null; + //Create tasks with milestone + for($count=0; $count < count($tasks); $count++) { + $milestoneId = 0; //By default milestoneId is 0, having this set at individual task is optional + if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined + { + // Get existing or create milestone, milestone has to exist first before task can appear under it + $result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count); + if(isset($result->payload)){ + $milestoneId = $result->payload['milestone_id']; + } + else{ + $milestone = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId); + $array = json_decode(json_encode($milestone), true); + $milestoneId = $array[0]['id']; + } + } + + $taskStatus = PerfexCRMTaskStatus::NOT_STARTED; + if($tasks[$count]['status'] != ''){ + $taskStatus = $tasks[$count]['status']; + } + + // Get existing or create task + $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $taskStatus); + if(is_null($result)){ + break; //Breaking the rest of the tasks in array assuming that they are all created as a batch previously + } + } + } + return true; } - } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php index e719ccef..f5d4de3e 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php @@ -14,7 +14,7 @@ class CreatesPerfexCRMCustomerProject * @return null|object * @throws MalformedRequestException */ - public function execute(string $projectName, string $clientId) { + public function execute(string $projectName, int $status, string $clientId) { try{ $data = [ 'name' => $projectName, @@ -22,7 +22,7 @@ class CreatesPerfexCRMCustomerProject 'billing_type' => 1, 'clientid' => $clientId, 'start_date' => date('Y-m-d'), - 'status' => 1 + 'status' => $status ]; $response = Http::asForm()->withHeaders([ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php new file mode 100644 index 00000000..6c016ff0 --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php @@ -0,0 +1,43 @@ + $project->name, + 'clientid' => $project->clientid, + // 'rel_type' => 'customer', + 'billing_type' => 1, + 'start_date' => $project->start_date, + 'status' => $status + ]; + + $response = Http::asJson()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->put(config('perfexcrm.base_url').'/api/projects/'.$project->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()); + } + } +} diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMProjectStatus.php b/app/Classes/ValueObjects/Constants/PerfexCRMProjectStatus.php new file mode 100644 index 00000000..5228699f --- /dev/null +++ b/app/Classes/ValueObjects/Constants/PerfexCRMProjectStatus.php @@ -0,0 +1,16 @@ + 'MILESTONE 1 - Customer Paid', 'reference' => '', 'on_task_completion' => '', - 'status' => PerfexCRMStatus::COMPLETED + 'status' => PerfexCRMTaskStatus::COMPLETED ]; public const TASK_1_DAY_TRANSFER_1 = [ @@ -26,7 +26,7 @@ class PerfexCRMTasks 'milestone' => '', 'reference' => 'TASK_1_DAY_TRANSFER_1', 'on_task_completion' => 'TASK_1_DAY_TRANSFER_2', - 'status' => PerfexCRMStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS ]; public const TASK_1_DAY_TRANSFER_2 = [ 'name' => 'Approve Payment', @@ -119,7 +119,7 @@ class PerfexCRMTasks 'milestone' => '', 'reference' => 'TASK_3_DAY_TRANSFER_1', 'on_task_completion' => 'TASK_3_DAY_TRANSFER_2', - 'status' => PerfexCRMStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS ]; public const TASK_3_DAY_TRANSFER_2 = [ 'name' => 'Approve Payment', @@ -214,7 +214,7 @@ class PerfexCRMTasks 'milestone' => '', 'reference' => 'TASK_1688_PAYMENT_1', 'on_task_completion' => 'TASK_1688_PAYMENT_2', - 'status' => PerfexCRMStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS ]; public const TASK_1688_PAYMENT_2 = [ 'name' => 'Approve Payment', @@ -402,4 +402,54 @@ class PerfexCRMTasks 'status' => '' ]; + + + public const TASK_PURCHASE_ORDER_1 = [ + 'name' => 'Approve Purchase Order', + 'description' => '○ Purpose: To check that the customer submitted a purchase order that complies with our company’s guidelines.
+ ○ Initial Status: In Progress
+ ○ Deadline: Next day
+ ○ Responsible department: Operation
+ ○ Next step: Change the status of the Approve payment status to "In Progress" upon successful completion of the operation.
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: None
+ ○ 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', + 'status' => PerfexCRMTaskStatus::IN_PROGRESS + ]; + + public const TASK_PURCHASE_ORDER_2 = [ + 'name' => 'Complete Order bookkeeping', + 'description' => '○ Purpose: To complete the bookkeeping for the booking.
+ ○ Initial Status: Not Started
+ ○ Deadline: Next day
+ ○ Responsible department: Account
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: Approve Purchase Order and Upload China Bank Slip operation must be completed before this operation can begin.
+ ○ Outcomes: A copy of the documents related to the booking should now all be in the google drive relevant folder.
', + 'milestone' => '', + 'reference' => 'TASK_PURCHASE_ORDER_2', + 'on_task_completion' => '', + 'status' => '' + ]; + + + public const TASK_IDENTIFICATION_1 = [ + 'name' => 'Approve Identification Verification', + 'description' => '○ Purpose: To ensure the customer submit information matches the information in their identification document.
+ ○ Initial Status: In Progress
+ ○ Deadline: Same Day
+ ○ Responsible department: Operation
+ ○ Next step: None
+ ○ Additional details: ** Any specific requirements or notes for the operation.**
+ ○ Dependencies: None
+ ○ Outcomes: Customer account identification is verified
', + 'milestone' => '', + 'reference' => 'TASK_IDENTIFICATION_1', + 'on_task_completion' => '', + 'status' => PerfexCRMTaskStatus::IN_PROGRESS + ]; } From 136a433e6019533d364a0d370424484851dc7ae9 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 10 Mar 2023 17:58:50 +0800 Subject: [PATCH 16/18] Feedback from user on crm leads registration --- app/Classes/Jobs/CreatePerfexCRMCustomer.php | 10 +++- .../ControllersLogic/CreateCustomerLogic.php | 3 +- .../CreateLeadPerfexCRMObject.php | 13 ++++- .../Services/CreatesPerfexCRMLead.php | 9 +++- .../Services/UpdatesPerfexCRMLead.php | 50 +++++++++++++++++++ 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php diff --git a/app/Classes/Jobs/CreatePerfexCRMCustomer.php b/app/Classes/Jobs/CreatePerfexCRMCustomer.php index b313dca6..4d7acddd 100644 --- a/app/Classes/Jobs/CreatePerfexCRMCustomer.php +++ b/app/Classes/Jobs/CreatePerfexCRMCustomer.php @@ -3,6 +3,8 @@ namespace App\Classes\Jobs; use App\Classes\Modules\PerfexCRM\Processors\CreatePerfexCRMLeadProcessor; +use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMLead; +use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMLead; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -28,6 +30,12 @@ class CreatePerfexCRMCustomer implements ShouldQueue public function handle() { - (App()->make(CreatePerfexCRMLeadProcessor::class))->execute($this->createLeadPerfexCRMObject); + $lead = (App()->make(FetchesPerfexCRMLead::class))->execute($this->createLeadPerfexCRMObject->getEmail()); + if(!is_null($lead)){ + (App()->make(UpdatesPerfexCRMLead::class))->execute($lead, $this->createLeadPerfexCRMObject->getCompanyReference()); + } + else{ + (App()->make(CreatePerfexCRMLeadProcessor::class))->execute($this->createLeadPerfexCRMObject); + } } } diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index 2fa5f9e0..0e920fe9 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -117,7 +117,8 @@ class CreateCustomerLogic extends AbstractControllerLogic $request->input('name'), $request->input('email'), $request->input('phone'), - $request->input('type') === CompanyType::COMPANY_BUSINESS ? $request->input('company_name') : $request->input('name') + $request->input('type') === CompanyType::COMPANY_BUSINESS ? $request->input('company_name') : $request->input('name'), + $company->reference ); CreatePerfexCRMCustomer::dispatch($createLeadPerfexCRMObject); } diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php index fc4c17cd..bea178f5 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateLeadPerfexCRMObject.php @@ -19,13 +19,17 @@ class CreateLeadPerfexCRMObject implements DataTransferObject /** @var string */ private $companyName; + /** @var string */ + private $companyReference; - public function __construct(string $name, string $email, string $phone, string $companyName) + + public function __construct(string $name, string $email, string $phone, string $companyName, string $companyReference) { $this->name = $name; $this->email = $email; $this->phone = $phone; $this->companyName = $companyName; + $this->companyReference = $companyReference; } /** @@ -60,4 +64,11 @@ class CreateLeadPerfexCRMObject implements DataTransferObject return $this->companyName; } + /** + * @return string + */ + public function getCompanyReference(): string + { + return $this->companyReference; + } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php index b1706c03..373f4171 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -16,13 +16,20 @@ class CreatesPerfexCRMLead */ public function execute(CreateLeadPerfexCRMObject $createLeadPerfexCRMObject) { try{ + $custom_fields = [ + "leads" => [ + 3 => $createLeadPerfexCRMObject->getCompanyReference() + ] + ]; + $data = [ 'name' => $createLeadPerfexCRMObject->getName(), 'email' => $createLeadPerfexCRMObject->getEmail(), 'phonenumber' => $createLeadPerfexCRMObject->getPhone(), 'company' => $createLeadPerfexCRMObject->getCompanyName(), 'source' => 1, //1: Exchange, 2: Shipping Portal - 'status' => 2 //2: Lead, 1: Customer + 'status' => 2, //2: Lead, 1: Customer, + 'custom_fields' => $custom_fields ]; $response = Http::asForm()->withHeaders([ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php new file mode 100644 index 00000000..b9090c2e --- /dev/null +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php @@ -0,0 +1,50 @@ + [ + 3 => $companyReference + ] + ]; + + $data = [ + 'name' => $lead->name, + 'email' => $lead->email, + 'phonenumber' => $lead->phonenumber, + 'company' => $lead->company, + 'custom_fields' => $custom_fields, + 'source' => $lead->source, + 'status' => $lead->status, + ]; + + $response = Http::asJson()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->put(config('perfexcrm.base_url').'/api/leads/'.$lead->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()); + } + } +} From 6275304ff8c6ecd7fa4e6c1f7a50213c69c28d7b Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 10 Mar 2023 19:18:40 +0800 Subject: [PATCH 17/18] fix list admin in settings --- routes/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/account.php b/routes/account.php index 84a7c85b..22671aa2 100644 --- a/routes/account.php +++ b/routes/account.php @@ -34,7 +34,7 @@ Route::group(['prefix' => 'account', 'namespace' => 'Accounts', 'as' => 'account }); Route::group(['prefix' => 'user', 'as' => 'user.', 'middleware' => 'valid.token'], function () { - Route::get('/{email}', 'FetchUserByEmailController@fetch')->name('company'); + Route::get('email/{email}', 'FetchUserByEmailController@fetch')->name('company'); Route::post('/show', 'FetchUserController@fetch')->name('show'); Route::get('/list', 'ListUsersController@list')->name('list'); Route::put('/update/{id}', 'UpdateUserController@update')->name('update'); From c99076ece171044fcb0baa693cc1695d3c1c8465 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sat, 11 Mar 2023 18:48:15 +0800 Subject: [PATCH 18/18] fix bug after fpx top up, redirect to not found page --- .../ControllersLogic/CallbackBillplzLogic.php | 4 ++-- .../UpdateWalletTransactionProcessor.php | 3 +++ .../views/pages/payments_redirect.blade.php | 24 ++++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index f32ea123..a6c0b7fd 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -107,9 +107,9 @@ class CallbackBillplzLogic $token = Auth::fromUser(User::find(1)); $request->headers->set('Authorization', 'Bearer '.$token); - $marking = $transaction->owner instanceof Booking ? $transaction->booking->marking : $transaction->owner->owner->bookings()->orderBy('id', 'DESC')->first()->marking; + $marking = $transaction->owner instanceof Booking ? $transaction->booking->marking : (count($transaction->owner->owner->bookings()->get())? $transaction->owner->owner->bookings()->orderBy('id', 'DESC')->first()->marking: null); - return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking, 'transaction' => $transaction, 'status' => $status]); + return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking ?? null, 'transaction' => $transaction, 'status' => $status]); } } \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/Processors/UpdateWalletTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/UpdateWalletTransactionProcessor.php index 7c7277f8..c1d36edb 100644 --- a/app/Classes/Modules/Transactions/Processors/UpdateWalletTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/UpdateWalletTransactionProcessor.php @@ -27,6 +27,9 @@ class UpdateWalletTransactionProcessor /** @var UpdatesTransactionStatus */ private $updatesTransactionStatus; + /** @var UpdatesWallet */ + private $updatesWallet; + public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWallet $updatesWallet, FetchesTransaction $fetchesTransaction) { $this->fetchesTransaction = $fetchesTransaction; diff --git a/resources/views/pages/payments_redirect.blade.php b/resources/views/pages/payments_redirect.blade.php index 1f3b04cb..e7f98d9c 100644 --- a/resources/views/pages/payments_redirect.blade.php +++ b/resources/views/pages/payments_redirect.blade.php @@ -43,9 +43,11 @@

Transaction History
@endif - -
{{$transaction->owner instanceof \App\Models\Booking ? 'Back to': 'Last'}} Booking
-
+ @if($marking) + +
{{$transaction->owner instanceof \App\Models\Booking ? 'Back to': 'Last'}} Booking
+
+ @endif @@ -64,9 +66,11 @@
Dashboard
- -
{{$transaction->owner instanceof \App\Models\Booking ? 'Back to': 'Last'}} Booking
-
+ @if($marking) + +
{{$transaction->owner instanceof \App\Models\Booking ? 'Back to': 'Last'}} Booking
+
+ @endif @@ -82,9 +86,11 @@