Skip to content

Commit

Permalink
Merge pull request #975 from compucorp/BTHAB-185-display-statuses
Browse files Browse the repository at this point in the history
BTHAB-185: Implement invoicing and payment statuses for quotations
  • Loading branch information
erawat authored Sep 21, 2023
2 parents 072f2c8 + 439822b commit 27073c4
Show file tree
Hide file tree
Showing 25 changed files with 901 additions and 650 deletions.
60 changes: 59 additions & 1 deletion CRM/Civicase/DAO/CaseSalesOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* Generated from uk.co.compucorp.civicase/xml/schema/CRM/Civicase/CaseSalesOrder.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:555941e9f2d2bb4c81224d13c42ac043)
* (GenCodeChecksum:88cd4ea87464d1254915637375e0a5a5)
*/
use CRM_Civicase_ExtensionUtil as E;

Expand Down Expand Up @@ -96,6 +96,24 @@ class CRM_Civicase_DAO_CaseSalesOrder extends CRM_Core_DAO {
*/
public $status_id;

/**
* One of the values of the case_sales_order_invoicing_status option group
*
* @var int|string
* (SQL type: int unsigned)
* Note that values will be retrieved from the database as a string.
*/
public $invoicing_status_id;

/**
* One of the values of the case_sales_order_payment_status option group
*
* @var int|string
* (SQL type: int unsigned)
* Note that values will be retrieved from the database as a string.
*/
public $payment_status_id;

/**
* Sales order deesctiption
*
Expand Down Expand Up @@ -313,6 +331,46 @@ public static function &fields() {
],
'add' => NULL,
],
'invoicing_status_id' => [
'name' => 'invoicing_status_id',
'type' => CRM_Utils_Type::T_INT,
'description' => E::ts('One of the values of the case_sales_order_invoicing_status option group'),
'required' => TRUE,
'where' => 'civicase_sales_order.invoicing_status_id',
'table_name' => 'civicase_sales_order',
'entity' => 'CaseSalesOrder',
'bao' => 'CRM_Civicase_DAO_CaseSalesOrder',
'localizable' => 0,
'html' => [
'type' => 'Select',
'label' => E::ts("Invoicing"),
],
'pseudoconstant' => [
'optionGroupName' => 'case_sales_order_invoicing_status',
'optionEditPath' => 'civicrm/admin/options/case_sales_order_invoicing_status',
],
'add' => NULL,
],
'payment_status_id' => [
'name' => 'payment_status_id',
'type' => CRM_Utils_Type::T_INT,
'description' => E::ts('One of the values of the case_sales_order_payment_status option group'),
'required' => TRUE,
'where' => 'civicase_sales_order.payment_status_id',
'table_name' => 'civicase_sales_order',
'entity' => 'CaseSalesOrder',
'bao' => 'CRM_Civicase_DAO_CaseSalesOrder',
'localizable' => 0,
'html' => [
'type' => 'Select',
'label' => E::ts("Payments"),
],
'pseudoconstant' => [
'optionGroupName' => 'case_sales_order_payment_status',
'optionEditPath' => 'civicrm/admin/options/case_sales_order_payment_status',
],
'add' => NULL,
],
'description' => [
'name' => 'description',
'type' => CRM_Utils_Type::T_TEXT,
Expand Down
86 changes: 86 additions & 0 deletions CRM/Civicase/Hook/Post/CaseSalesOrderPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

use Civi\Api4\CaseSalesOrder;
use Civi\Api4\Contribution;

/**
* Handles CaseSalesOrder payment processing.
*/
class CRM_Civicase_Hook_Post_CaseSalesOrderPayment {

/**
* Updates CaseSaleOrder statuses when creating a payment transcation.
*
* @param string $op
* The operation being performed.
* @param string $objectName
* Object name.
* @param mixed $objectId
* Object ID.
* @param object $objectRef
* Object reference.
*/
public function run($op, $objectName, $objectId, &$objectRef) {
if (!$this->shouldRun($op, $objectName)) {
return;
}

$entityFinancialTrxn = civicrm_api3('EntityFinancialTrxn', 'get', [
'sequential' => 1,
'entity_table' => 'civicrm_contribution',
'financial_trxn_id' => $objectRef->financial_trxn_id,
]);

if (empty($entityFinancialTrxn['values'][0])) {
return;
}

$contributionId = $entityFinancialTrxn['values'][0]['entity_id'];

$salesOrderID = Contribution::get()
->addSelect('Opportunity_Details.Quotation')
->addWhere('id', '=', $contributionId)
->execute()
->first()['Opportunity_Details.Quotation'];

if (empty($salesOrderID)) {
return;
}

$transaction = CRM_Core_Transaction::create();

try {
$caseSaleOrderContributionService = new CRM_Civicase_Service_CaseSaleOrderContribution($salesOrderID);
$paymentStatusID = $caseSaleOrderContributionService->calculatePaymentStatus();
$invoicingStatusID = $caseSaleOrderContributionService->calculateInvoicingStatus();

CaseSalesOrder::update()
->addWhere('id', '=', $salesOrderID)
->addValue('invoicing_status_id', $invoicingStatusID)
->addValue('payment_status_id', $paymentStatusID)
->execute();

$transaction->commit();
}
catch (\Throwable $th) {
$transaction->rollback();
CRM_Core_Error::statusBounce(ts('Error updating sales order statues'));
}
}

/**
* Determines if the hook should run or not.
*
* @param string $op
* The operation being performed.
* @param string $objectName
* Object name.
*
* @return bool
* returns a boolean to determine if hook will run or not.
*/
private function shouldRun($op, $objectName) {
return $objectName == 'EntityFinancialTrxn' && $op == 'create';
}

}
45 changes: 38 additions & 7 deletions CRM/Civicase/Hook/Post/CreateSalesOrderContribution.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?php

use Civi\Api4\CaseSalesOrder;
use Civi\Api4\Contribution;

/**
* Handles sales order contribution post processing.
*/
class CRM_Civicase_Hook_Post_CreateSalesOrderContribution {

/**
* Creates Sales Order Contribtution.
* Updates CaseSaleOrder status when creating a quotation contribution.
*
* @param string $op
* The operation being performed.
Expand All @@ -20,18 +21,39 @@ class CRM_Civicase_Hook_Post_CreateSalesOrderContribution {
* Object reference.
*/
public function run($op, $objectName, $objectId, &$objectRef) {
if (!$this->shouldRun($op, $objectName)) {
return;
}

$salesOrderId = CRM_Utils_Request::retrieve('sales_order', 'Integer');
$salesOrderStatusId = CRM_Utils_Request::retrieve('sales_order_status_id', 'Integer');
if (empty($salesOrderId)) {
$salesOrderId = $this->getQuotationID($objectId)['Opportunity_Details.Quotation'];
}

if (!$this->shouldRun($op, $objectName, $salesOrderId)) {
if (empty($salesOrderId)) {
return;
}

$salesOrderStatusId = CRM_Utils_Request::retrieve('sales_order_status_id', 'Integer');
if (empty($salesOrderStatusId)) {
$salesOrderStatusId = CaseSalesOrder::get()
->addSelect('status_id')
->addWhere('id', '=', $salesOrderId)
->execute()
->first()['status_id'];
}

$transaction = CRM_Core_Transaction::create();
try {
$caseSaleOrderContributionService = new CRM_Civicase_Service_CaseSaleOrderContribution($salesOrderId);
$paymentStatusID = $caseSaleOrderContributionService->calculatePaymentStatus();
$invoicingStatusID = $caseSaleOrderContributionService->calculateInvoicingStatus();

CaseSalesOrder::update()
->addWhere('id', '=', $salesOrderId)
->addValue('status_id', $salesOrderStatusId)
->addValue('invoicing_status_id', $invoicingStatusID)
->addValue('payment_status_id', $paymentStatusID)
->execute();
}
catch (\Throwable $th) {
Expand All @@ -47,14 +69,23 @@ public function run($op, $objectName, $objectId, &$objectRef) {
* The operation being performed.
* @param string $objectName
* Object name.
* @param string $salesOrderId
* The sales order that triggered the contribution (if any).
*
* @return bool
* returns a boolean to determine if hook will run or not.
*/
private function shouldRun($op, $objectName, $salesOrderId) {
return strtolower($objectName) == 'contribution' && !empty($salesOrderId) && $op == 'create';
private function shouldRun($op, $objectName) {
return strtolower($objectName) == 'contribution' && $op == 'create';
}

/**
* Gets quotation ID by contribution ID.
*/
private function getQuotationId($id) {
return Contribution::get()
->addSelect('Opportunity_Details.Quotation')
->addWhere('id', '=', $id)
->execute()
->first();
}

}
Loading

0 comments on commit 27073c4

Please sign in to comment.