diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index a6c6c0b4515a..092e8875e822 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -177,6 +177,9 @@ public static function add(&$params, $ids = array()) { $params['prevContribution'] = self::getValues(array('id' => $contributionID), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } + // CRM-16189 + CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params, $contributionID); + if ($contributionID) { CRM_Utils_Hook::pre('edit', 'Contribution', $contributionID, $params); } diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php index 318b7f229076..7d65913dd792 100644 --- a/CRM/Contribute/Form/Contribution.php +++ b/CRM/Contribute/Form/Contribution.php @@ -1008,6 +1008,14 @@ public static function formRule($fields, $files, $self) { ) { $errors['revenue_recognition_date'] = ts('Month and Year are required field for Revenue Recognition.'); } + // CRM-16189 + try { + CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($fields, $self->_id, $self->_priceSet['fields']); + } + catch (CRM_Core_Exception $e) { + $errors['financial_type_id'] = ' '; + $errors['_qf_default'] = $e->getMessage(); + } $errors = array_merge($errors, $softErrors); return $errors; } diff --git a/CRM/Financial/BAO/FinancialAccount.php b/CRM/Financial/BAO/FinancialAccount.php index f3aecbf4d08c..aea07d410fd5 100644 --- a/CRM/Financial/BAO/FinancialAccount.php +++ b/CRM/Financial/BAO/FinancialAccount.php @@ -358,29 +358,31 @@ public static function validateFinancialAccount($financialAccountId, $financialA /** * Validate Financial Type has Deferred Revenue account relationship - * with Financial Account + * with Financial Account. * * @param array $params + * Holds submitted formvalues and params from api for updating/adding contribution. * * @param int $contributionID + * Contribution ID * - * @param obj $form + * @param array $priceSetFields + * Array of price fields of a price set. * - * @return string + * @return bool * */ - public static function checkFinancialTypeHasDeferred($params, $contributionID = NULL, $form = NULL) { + public static function checkFinancialTypeHasDeferred($params, $contributionID = NULL, $priceSetFields = NULL) { if (!CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled')) { return FALSE; } $recognitionDate = CRM_Utils_Array::value('revenue_recognition_date', $params); if (!(!CRM_Utils_System::isNull($recognitionDate) - || ($contributionID && $params['prevContribution']->revenue_recognition_date)) + || ($contributionID && !CRM_Utils_System::isNull($params['prevContribution']->revenue_recognition_date))) ) { return FALSE; } - $message = ts('Revenue recognition date can only be specified if the financial type selected has a deferred revenue account configured. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts'); $lineItems = CRM_Utils_Array::value('line_item', $params); $financialTypeID = CRM_Utils_Array::value('financial_type_id', $params); if (!$financialTypeID) { @@ -388,7 +390,7 @@ public static function checkFinancialTypeHasDeferred($params, $contributionID = } if (($contributionID || !empty($params['price_set_id'])) && empty($lineItems)) { if (!$contributionID) { - CRM_Price_BAO_PriceSet::processAmount($form->_priceSet['fields'], + CRM_Price_BAO_PriceSet::processAmount($priceSetFields, $params, $items); } else { @@ -399,19 +401,25 @@ public static function checkFinancialTypeHasDeferred($params, $contributionID = } } $deferredFinancialType = self::getDeferredFinancialType(); + $isError = FALSE; if (!empty($lineItems)) { foreach ($lineItems as $lineItem) { foreach ($lineItem as $items) { if (!array_key_exists($items['financial_type_id'], $deferredFinancialType)) { - return $message; + $isError = TRUE; } } } } elseif (!array_key_exists($financialTypeID, $deferredFinancialType)) { - return $message; + $isError = TRUE; } - return FALSE; + + if ($isError) { + $error = ts('Revenue recognition date can only be specified if the financial type selected has a deferred revenue account configured. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts'); + throw new CRM_Core_Exception($error); + } + return $isError; } /** @@ -419,6 +427,13 @@ public static function checkFinancialTypeHasDeferred($params, $contributionID = * with Financial Account. * * @param int $financialTypeId + * Financial Type Id. + * + * @param int $entityID + * Holds id for PriceSet/PriceField/PriceFieldValue. + * + * @param string $entity + * Entity like PriceSet/PriceField/PriceFieldValue. * * @return bool * diff --git a/tests/phpunit/CRM/Financial/BAO/FinancialAccountTest.php b/tests/phpunit/CRM/Financial/BAO/FinancialAccountTest.php index 1a987f1e954a..7e228595462e 100644 --- a/tests/phpunit/CRM/Financial/BAO/FinancialAccountTest.php +++ b/tests/phpunit/CRM/Financial/BAO/FinancialAccountTest.php @@ -249,9 +249,9 @@ public function testcheckFinancialTypeHasDeferred() { $cid = $this->individualCreate(); $params = array( 'contact_id' => $cid, - 'receive_date' => '2010-01-20', + 'receive_date' => '2016-01-20', 'total_amount' => 100, - 'financial_type_id' => 3, + 'financial_type_id' => 4, 'revenue_recognition_date' => date('Ymd', strtotime("+1 month")), 'line_items' => array( array( @@ -264,6 +264,7 @@ public function testcheckFinancialTypeHasDeferred() { 'qty' => 1, 'unit_price' => 100, 'line_total' => 100, + 'financial_type_id' => 4, ), array( 'entity_table' => 'civicrm_contribution', @@ -273,17 +274,32 @@ public function testcheckFinancialTypeHasDeferred() { 'qty' => 1, 'unit_price' => 200, 'line_total' => 200, - 'financial_type_id' => 1, + 'financial_type_id' => 4, ), ), - 'params' => array(), ), ), ); - $contribution = CRM_Contribute_BAO_Contribution::create($params); - $valid = CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params, $contribution->id); - $message = "Revenue recognition date can only be specified if the financial type selected has a deferred revenue account configured. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts"; - $this->assertEquals($valid, $message, "The messages do not match"); + try { + CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params); + } + catch (CRM_Core_Exception $e) { + $this->fail("Missed expected exception"); + } + $params = array( + 'contact_id' => $cid, + 'receive_date' => '2016-01-20', + 'total_amount' => 100, + 'financial_type_id' => 1, + 'revenue_recognition_date' => date('Ymd', strtotime("+1 month")), + ); + try { + CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params); + $this->fail("Missed expected exception"); + } + catch (CRM_Core_Exception $e) { + $this->assertEquals('Revenue recognition date can only be specified if the financial type selected has a deferred revenue account configured. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts', $e->getMessage()); + } } /**