Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTHAB-185: Implement invoicing and payment statuses for quotations #975

Merged
merged 14 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading