From 9c5b99a93946c204cbbfc96b7a51f68b65127b2c Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 15 Jun 2022 17:33:42 +1200 Subject: [PATCH] Add paid_amount, balance_amount, tax_exclusive_amount to apiv4 --- CRM/Core/BAO/FinancialTrxn.php | 2 + .../Provider/ContributionGetSpecProvider.php | 113 ++++++++++++++++++ Civi/Schema/Traits/DataTypeSpecTrait.php | 4 +- .../Contribute/ActionMapping/ByTypeTest.php | 4 + .../CRM/Core/BAO/FinancialTrxnTest.php | 10 +- 5 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 Civi/Api4/Service/Spec/Provider/ContributionGetSpecProvider.php diff --git a/CRM/Core/BAO/FinancialTrxn.php b/CRM/Core/BAO/FinancialTrxn.php index 33d2083254..a788e7fa6c 100644 --- a/CRM/Core/BAO/FinancialTrxn.php +++ b/CRM/Core/BAO/FinancialTrxn.php @@ -401,6 +401,8 @@ WHERE ceft.entity_id = %1"; * @param int $contributionID * @param bool $includeRefund * + * @deprecated use Apiv4. + * * @return float */ public static function getTotalPayments($contributionID, $includeRefund = FALSE): float { diff --git a/Civi/Api4/Service/Spec/Provider/ContributionGetSpecProvider.php b/Civi/Api4/Service/Spec/Provider/ContributionGetSpecProvider.php new file mode 100644 index 0000000000..056dbb1e76 --- /dev/null +++ b/Civi/Api4/Service/Spec/Provider/ContributionGetSpecProvider.php @@ -0,0 +1,113 @@ +getValue('paid_amount')) { + $field = new FieldSpec('paid_amount', 'Contribution', 'Float'); + $field->setLabel(ts('Amount Paid')) + ->setTitle(ts('Amount Paid')) + ->setDescription(ts('Amount paid')) + ->setType('Extra') + ->setDataType('Money') + ->setReadonly(TRUE) + ->setSqlRenderer([__CLASS__, 'calculateAmountPaid']); + $spec->addFieldSpec($field); + } + if (!$spec->getValue('balance_amount')) { + $field = new FieldSpec('balance_amount', 'Contribution', 'Float'); + $field->setLabel(ts('Balance')) + ->setTitle(ts('Balance')) + ->setDescription(ts('Balance')) + ->setType('Extra') + ->setDataType('Money') + ->setReadonly(TRUE) + ->setSqlRenderer([__CLASS__, 'calculateBalance']); + $spec->addFieldSpec($field); + } + if (!$spec->getValue('tax_exclusive_amount')) { + $field = new FieldSpec('tax_exclusive_amount', 'Contribution', 'Float'); + $field->setLabel(ts('Tax Exclusive Amount')) + ->setTitle(ts('Tax Exclusive Amount')) + ->setDescription(ts('Tax Exclusive Amount')) + ->setType('Extra') + ->setDataType('Money') + ->setReadonly(TRUE) + ->setSqlRenderer([__CLASS__, 'calculateTaxExclusiveAmount']); + $spec->addFieldSpec($field); + } + } + + /** + * @param string $entity + * @param string $action + * + * @return bool + */ + public function applies($entity, $action): bool { + return $entity === 'Contribution' && $action === 'get'; + } + + /** + * Generate SQL for amount_paid field + * + * @return string + */ + public static function calculateTaxExclusiveAmount(): string { + return 'COALESCE(a.total_amount, 0) - COALESCE(a.tax_amount, 0)'; + } + + /** + * Generate SQL for amount_paid field + * + * @return string + */ + public static function calculateAmountPaid(): string { + $statusIDs = [ + \CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'), + \CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'), + ]; + + return "COALESCE((SELECT SUM(ft.total_amount) FROM civicrm_financial_trxn ft + INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution') + WHERE eft.entity_id = a.id AND ft.is_payment = 1 AND ft.status_id IN (" . implode(',', $statusIDs) . ')), 0)'; + } + + /** + * Generate SQL for age field + * + * @return string + */ + public static function calculateBalance(): string { + $statusIDs = [ + \CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'), + \CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'), + ]; + + return "a.total_amount - COALESCE((SELECT SUM(ft.total_amount) FROM civicrm_financial_trxn ft + INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution') + WHERE eft.entity_id = a.id AND ft.is_payment = 1 AND ft.status_id IN (" . implode(',', $statusIDs) . ')), 0)'; + } + +} diff --git a/Civi/Schema/Traits/DataTypeSpecTrait.php b/Civi/Schema/Traits/DataTypeSpecTrait.php index 6b0a00af9a..0afbef7e26 100644 --- a/Civi/Schema/Traits/DataTypeSpecTrait.php +++ b/Civi/Schema/Traits/DataTypeSpecTrait.php @@ -63,7 +63,7 @@ trait DataTypeSpecTrait { * @param $dataType * * @return $this - * @throws \Exception + * @throws \CRM_Core_Exception */ public function setDataType($dataType) { if (array_key_exists($dataType, self::$typeAliases)) { @@ -71,7 +71,7 @@ trait DataTypeSpecTrait { } if (!in_array($dataType, $this->getValidDataTypes())) { - throw new \Exception(sprintf('Invalid data type "%s', $dataType)); + throw new \CRM_Core_Exception(sprintf('Invalid data type "%s', $dataType)); } $this->dataType = $dataType; diff --git a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php index 9ce73d2f0d..24fffc1d48 100644 --- a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php +++ b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php @@ -315,6 +315,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr total_amount = {contribution.total_amount} net_amount = {contribution.net_amount} fee_amount = {contribution.fee_amount} + paid_amount = {contribution.paid_amount} + balance_amount = {contribution.balance_amount} campaign_id = {contribution.campaign_id} campaign name = {contribution.campaign_id:name} campaign label = {contribution.campaign_id:label}'; @@ -341,6 +343,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr 'total_amount = €100.00', 'net_amount = €95.00', 'fee_amount = €5.00', + 'paid_amount = €100.00', + 'balance_amount = €0.00', 'campaign_id = 1', 'campaign name = big_campaign', 'campaign label = Campaign', diff --git a/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php b/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php index 8120f82773..959d063748 100644 --- a/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php +++ b/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php @@ -9,6 +9,8 @@ +--------------------------------------------------------------------+ */ +use Civi\Api4\Contribution; + /** * Class CRM_Core_BAO_FinancialTrxnTest * @group headless @@ -53,7 +55,7 @@ class CRM_Core_BAO_FinancialTrxnTest extends CiviUnitTestCase { * * @throws \CRM_Core_Exception */ - public function testGetTotalPayments() { + public function testGetTotalPayments(): void { $contactId = $this->individualCreate(); $params = [ @@ -81,13 +83,19 @@ class CRM_Core_BAO_FinancialTrxnTest extends CiviUnitTestCase { $totalPaymentAmount = CRM_Core_BAO_FinancialTrxn::getTotalPayments($contribution['id']); $this->assertEquals(0, $totalPaymentAmount, 'Amount not matching.'); + $this->assertEquals(0, Contribution::get()->addWhere('id', '=', $contribution['id']) + ->addSelect('paid_amount')->execute()->first()['paid_amount']); $params['id'] = $contribution['id']; $params['contribution_status_id'] = 1; $contribution = $this->callAPISuccess('Contribution', 'create', $params); $totalPaymentAmount = CRM_Core_BAO_FinancialTrxn::getTotalPayments($contribution['id']); + $this->assertEquals('200.00', Contribution::get()->addWhere('id', '=', $contribution['id']) + ->addSelect('paid_amount')->execute()->first()['paid_amount']); + $this->assertEquals('200.00', $totalPaymentAmount, 'Amount not matching.'); + } /** -- 2.25.1