Skip to content

Commit

Permalink
BTHAB-271: Fix invoice and payment status bugs for quotations
Browse files Browse the repository at this point in the history
The payment and invoice statuses were being calculated in accordance to just invoiced amount without considering the quoted amount and the calculations previously also took into account the deleted invoices which were resulting in incorrect statuses calculations
  • Loading branch information
shahrukh-compuco committed Oct 23, 2023
1 parent 9c1de62 commit c51eef2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 18 deletions.
10 changes: 8 additions & 2 deletions CRM/Civicase/Hook/Pre/DeleteSalesOrderContribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public function run($op, $objectName, $objectId, &$params) {
return;
}

$caseSaleOrderContributionService = new CRM_Civicase_Service_CaseSalesOrderContributionCalculator($salesOrderId);
$caseSaleOrderContributionService = new CRM_Civicase_Service_CaseSalesOrderContributionCalculator(
$salesOrderId,
(int) $objectId
);
$invoicingStatusId = $caseSaleOrderContributionService->calculateInvoicingStatus();
$paymentStatusId = $caseSaleOrderContributionService->calculatePaymentStatus();

Expand All @@ -46,7 +49,10 @@ public function run($op, $objectName, $objectId, &$params) {
->execute()
->first();

$caseSaleOrderContributionService = new \CRM_Civicase_Service_CaseSalesOrderOpportunityCalculator($caseSalesOrder['case_id']);
$caseSaleOrderContributionService = new \CRM_Civicase_Service_CaseSalesOrderOpportunityCalculator(
$caseSalesOrder['case_id'],
(int) $objectId
);
$caseSaleOrderContributionService->updateOpportunityFinancialDetails();
}

Expand Down
2 changes: 1 addition & 1 deletion CRM/Civicase/Service/AbstractBaseSalesOrderCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ abstract class CRM_Civicase_Service_AbstractBaseSalesOrderCalculator {
INVOICING_STATUS_FULLY_INVOICED = 'fully_invoiced',
PAYMENT_STATUS_NO_PAYMENTS = 'no_payments',
PAYMENT_STATUS_PARTIALLY_PAID = 'partially_paid',
PAYMENT_STATUS_OVERPAID = 'overpaid',
PAYMENT_STATUS_OVERPAID = 'over_paid',
PAYMENT_STATUS_FULLY_PAID = 'fully_paid';

/**
Expand Down
29 changes: 22 additions & 7 deletions CRM/Civicase/Service/CaseSalesOrderContributionCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,30 @@ class CRM_Civicase_Service_CaseSalesOrderContributionCalculator extends CRM_Civi
* @var float
*/
private float $totalPaymentsAmount;
/**
* ID of contribution that is being deleted.
*
* @var null|int
*/
private ?int $deletingContributionId = null;

/**
* Class constructor.
*
* @param string $salesOrderId
* Sales Order ID.
*
* @param string $deletingContributionId
* ID of contribution that is being deleted.
*
* @throws API_Exception
* @throws CiviCRM_API3_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
public function __construct($salesOrderId) {
public function __construct($salesOrderId, ?int $deletingContributionId = null) {
parent::__construct();
$this->salesOrder = $this->getSalesOrder($salesOrderId);
$this->deletingContributionId = $deletingContributionId;
$this->contributions = $this->getContributions();
$this->totalInvoicedAmount = $this->getTotalInvoicedAmount();
$this->totalPaymentsAmount = $this->getTotalPaymentsAmount();
Expand Down Expand Up @@ -115,11 +125,12 @@ public function calculatePaymentStatus() {
return $this->getValueFromOptionValues(parent::PAYMENT_STATUS_NO_PAYMENTS, $this->paymentStatusOptionValues);
}

if ($this->totalPaymentsAmount < $this->totalInvoicedAmount) {
$quotationTotalAmount = $this->salesOrder['total_after_tax'];
if ($this->totalPaymentsAmount < $quotationTotalAmount) {
return $this->getValueFromOptionValues(parent::PAYMENT_STATUS_PARTIALLY_PAID, $this->paymentStatusOptionValues);
}

if ($this->totalPaymentsAmount > $this->totalInvoicedAmount) {
if ($this->totalPaymentsAmount > $quotationTotalAmount) {
return $this->getValueFromOptionValues(parent::PAYMENT_STATUS_OVERPAID, $this->paymentStatusOptionValues);
}

Expand All @@ -140,10 +151,14 @@ private function getContributions() {
return [];
}

return Contribution::get(FALSE)
->addWhere('Opportunity_Details.Quotation', '=', $this->salesOrder['id'])
->execute()
->getArrayCopy();
$contributions = Contribution::get(FALSE)
->addWhere('Opportunity_Details.Quotation', '=', $this->salesOrder['id']);

if ($this->deletingContributionId !== null) {
$contributions->addWhere('id', '!=', $this->deletingContributionId);
}

return $contributions->execute()->getArrayCopy();
}

/**
Expand Down
30 changes: 22 additions & 8 deletions CRM/Civicase/Service/CaseSalesOrderOpportunityCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,26 @@ class CRM_Civicase_Service_CaseSalesOrderOpportunityCalculator extends CRM_Civic
* @var string
*/
private string $caseId;
/**
* ID of contribution that is being deleted.
*
* @var null|int
*/
private ?int $deletingContributionId = null;

/**
* Constructor for CaseSalesOrderOpportunityCalculator class.
*
* @param string $caseId
* Case Id.
*
* @param string $deletingContributionId
* ID of contribution that is being deleted.
*/
public function __construct($caseId) {
public function __construct($caseId, ?int $deletingContributionId = null) {
parent::__construct();
$this->caseId = $caseId;
$this->deletingContributionId = $deletingContributionId;
$contributions = $this->getContributions($caseId);
$this->calculateOpportunityFinancialAmount($contributions);
}
Expand Down Expand Up @@ -104,11 +114,11 @@ public function calculatePaymentStatus() {
return $this->getLabelFromOptionValues(parent::PAYMENT_STATUS_NO_PAYMENTS, $this->paymentStatusOptionValues);
}

if ($this->totalPaidAmount < $this->totalInvoicedAmount) {
if ($this->totalPaidAmount < $this->totalQuotedAmount) {
return $this->getLabelFromOptionValues(parent::PAYMENT_STATUS_PARTIALLY_PAID, $this->paymentStatusOptionValues);
}

if ($this->totalPaidAmount > $this->totalInvoicedAmount) {
if ($this->totalPaidAmount > $this->totalQuotedAmount) {
return $this->getLabelFromOptionValues(parent::PAYMENT_STATUS_OVERPAID, $this->paymentStatusOptionValues);

}
Expand All @@ -122,7 +132,7 @@ public function calculatePaymentStatus() {
public function updateOpportunityFinancialDetails(): void {
CiviCase::update()
->addValue('Case_Opportunity_Details.Total_Amount_Quoted', $this->calculateTotalQuotedAmount())
->addValue('Case_Opportunity_Details.Total_Amount_Invoiced', $this->calculateTotalQuotedAmount())
->addValue('Case_Opportunity_Details.Total_Amount_Invoiced', $this->calculateTotalInvoicedAmount())
->addValue('Case_Opportunity_Details.Invoicing_Status', $this->calculateInvoicingStatus())
->addValue('Case_Opportunity_Details.Total_Amounts_Paid', $this->calculateTotalPaidAmount())
->addValue('Case_Opportunity_Details.Payments_Status', $this->calculatePaymentStatus())
Expand Down Expand Up @@ -161,11 +171,15 @@ private function calculateOpportunityFinancialAmount($contributions) {
* List of contributions that link to the opportunity.
*/
private function getContributions($caseId) {
return Contribution::get(FALSE)
$contributions = Contribution::get(FALSE)
->addSelect('*', 'Opportunity_Details.Quotation')
->addWhere('Opportunity_Details.Case_Opportunity', '=', $caseId)
->execute()
->getArrayCopy();
->addWhere('Opportunity_Details.Case_Opportunity', '=', $caseId);

if ($this->deletingContributionId !== null) {
$contributions->addWhere('id', '!=', $this->deletingContributionId);
}

return $contributions->execute()->getArrayCopy();
}

}

0 comments on commit c51eef2

Please sign in to comment.