From 8cf6bd8333164208608eb1d9ef3479aee0128d56 Mon Sep 17 00:00:00 2001 From: Pradeep Nayak Date: Fri, 15 Jul 2016 23:09:53 +0530 Subject: [PATCH] =?utf8?q?[ready-for-core-team-review]CRM-16189,=20added?= =?utf8?q?=20code=20to=20create=20entries=20in=20accounting=20tables=20for?= =?utf8?q?=20defe=E2=80=A6=20(#8576)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * CRM-16189, added code to create entries in accounting tables for deferred revenue ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, added code to set recognition date for membership ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, added code to create entries for revenue recognition ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * --CRM-16189, removed function calling * CRM-16189, updated function to ignore deferred trxns entries ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, added code to create entries for deferred revenue for event registration ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, store financial item DAO values in variable and return variable ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, added code to create financial trxn entries ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, removed white space ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, fixed notice error ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * CRM-16189, changed class name ---------------------------------------- * CRM-16189: Improve support for Accrual Method bookkeeping https://issues.civicrm.org/jira/browse/CRM-16189 * --CRM-16189, fixed code for updating of line item --- CRM/Contribute/BAO/Contribution.php | 38 ++++++++++++++----- CRM/Contribute/Form/CloseAccPeriod.php | 2 +- CRM/Core/BAO/FinancialTrxn.php | 14 +++++-- CRM/Event/Form/Participant.php | 6 +++ CRM/Event/Form/Registration/Confirm.php | 12 ++++++ CRM/Financial/BAO/FinancialItem.php | 10 +++-- CRM/Price/BAO/LineItem.php | 10 +++-- .../CRM/Core/BAO/FinancialTrxnTest.php | 2 +- 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index a04b72a3bc..02f2f66210 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -152,6 +152,15 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { $params['contribution_status_id'] = civicrm_api3('Contribution', 'getvalue', array('id' => $contributionID, 'return' => 'contribution_status_id')); } + if (!$contributionID + && CRM_Utils_Array::value('membership_id', $params) + && self::checkContributeSettings('deferred_revenue_enabled') + ) { + $memberStartDate = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $params['membership_id'], 'start_date'); + if ($memberStartDate) { + $params['revenue_recognition_date'] = date('Ymd', strtotime($memberStartDate)); + } + } self::calculateMissingAmountParams($params, $contributionID); if (!empty($params['payment_instrument_id'])) { @@ -3211,9 +3220,13 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac if (!empty($params['financial_type_id']) && $params['contribution']->financial_type_id != $params['prevContribution']->financial_type_id ) { - $incomeTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Income Account is' ")); - $oldFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $incomeTypeId); - $newFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $incomeTypeId); + $accountRelationship = 'Income Account is'; + if (!empty($params['revenue_recognition_date']) || $params['prevContribution']->revenue_recognition_date) { + $accountRelationship = 'Deferred Revenue Account is'; + } + $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE '$accountRelationship' ")); + $oldFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $relationTypeId); + $newFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); if ($oldFinancialAccount != $newFinancialAccount) { $params['total_amount'] = 0; if (in_array($params['contribution']->contribution_status_id, $pendingStatus)) { @@ -3229,10 +3242,11 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac self::updateFinancialAccounts($params, 'changeFinancialType'); /* $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; */ $params['financial_account_id'] = $newFinancialAccount; - $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; + $params['total_amount'] = $params['trxnParams']['total_amount'] = $params['trxnParams']['net_amount'] = $trxnParams['total_amount']; self::updateFinancialAccounts($params); $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; $updated = TRUE; + $params['deferred_financial_account_id'] = $newFinancialAccount; } } @@ -3441,7 +3455,12 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac } elseif ($context == 'changePaymentInstrument') { if ($params['trxnParams']['total_amount'] < 0) { - $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['prevContribution']->id, 'DESC'); + $deferredFinancialAccount = CRM_Utils_Array::value('deferred_financial_account_id', $params); + if (empty($deferredFinancialAccount)) { + $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Deferred Revenue Account is' ")); + $deferredFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $relationTypeId); + } + $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['prevContribution']->id, 'DESC', FALSE, NULL, $deferredFinancialAccount); if (!empty($lastFinancialTrxnId['financialTrxnId'])) { $params['trxnParams']['to_financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $lastFinancialTrxnId['financialTrxnId'], 'to_financial_account_id'); $params['trxnParams']['payment_instrument_id'] = $params['prevContribution']->payment_instrument_id; @@ -3503,9 +3522,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $trxnIds['id'] = $params['entity_id']; foreach ($params['line_item'] as $fieldId => $fields) { foreach ($fields as $fieldValueId => $fieldValues) { - $prevParams['entity_id'] = $fieldValues['id']; - $prevFinancialItem = CRM_Financial_BAO_FinancialItem::retrieve($prevParams, CRM_Core_DAO::$_nullArray); - + $prevFinancialItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($fieldValues['id']); $receiveDate = CRM_Utils_Date::isoToMysql($params['prevContribution']->receive_date); if ($params['contribution']->receive_date) { $receiveDate = CRM_Utils_Date::isoToMysql($params['contribution']->receive_date); @@ -3542,7 +3559,9 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac 'entity_table' => 'civicrm_line_item', 'entity_id' => $fieldValues['id'], ); - CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds); + $financialItem = CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds); + $params['line_item'][$fieldId][$fieldValueId]['deferred_line_total'] = $amount; + $params['line_item'][$fieldId][$fieldValueId]['financial_item_id'] = $financialItem->id; if ($fieldValues['tax_amount']) { $invoiceSettings = Civi::settings()->get('contribution_invoice_settings'); @@ -3565,6 +3584,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac } } } + CRM_Core_BAO_FinancialTrxn::createDeferredTrxn(CRM_Utils_Array::value('line_item', $params), $params['contribution'], TRUE, $context); } /** diff --git a/CRM/Contribute/Form/CloseAccPeriod.php b/CRM/Contribute/Form/CloseAccPeriod.php index 6a19ea4b7c..9a0670a191 100644 --- a/CRM/Contribute/Form/CloseAccPeriod.php +++ b/CRM/Contribute/Form/CloseAccPeriod.php @@ -38,7 +38,7 @@ class CRM_Contribute_Form_CloseAccPeriod extends CRM_Core_Form { $defaults = $period = array(); $period = Civi::settings()->get('closing_date'); if (empty($period)) { - $prior = CRM_Contribute_PseudoConstant::checkContributeSettings('prior_financial_period'); + $prior = CRM_Contribute_BAO_Contribution::checkContributeSettings('prior_financial_period'); } else { $defaults['closing_date'] = $period; diff --git a/CRM/Core/BAO/FinancialTrxn.php b/CRM/Core/BAO/FinancialTrxn.php index cfc66df199..c2f2c5f118 100644 --- a/CRM/Core/BAO/FinancialTrxn.php +++ b/CRM/Core/BAO/FinancialTrxn.php @@ -154,14 +154,19 @@ class CRM_Core_BAO_FinancialTrxn extends CRM_Financial_DAO_FinancialTrxn { * array of category id's the contact belongs to. * */ - public static function getFinancialTrxnId($entity_id, $orderBy = 'ASC', $newTrxn = FALSE, $whereClause = '') { + public static function getFinancialTrxnId($entity_id, $orderBy = 'ASC', $newTrxn = FALSE, $whereClause = '', $fromAccountID = NULL) { $ids = array('entityFinancialTrxnId' => NULL, 'financialTrxnId' => NULL); + $params = array(1 => array($entity_id, 'Integer')); $condition = ""; if (!$newTrxn) { $condition = " AND ((ceft1.entity_table IS NOT NULL) OR (cft.payment_instrument_id IS NOT NULL AND ceft1.entity_table IS NULL)) "; } + if ($fromAccountID) { + $condition .= " AND (cft.from_financial_account_id <> %2 OR cft.from_financial_account_id IS NULL)"; + $params[2] = array($fromAccountID, 'Integer'); + } if ($orderBy) { $orderBy = CRM_Utils_Type::escape($orderBy, 'String'); } @@ -178,7 +183,6 @@ WHERE ceft.entity_id = %1 AND (cfi.entity_table <> 'civicrm_financial_trxn' or c ORDER BY cft.id {$orderBy} LIMIT 1;"; - $params = array(1 => array($entity_id, 'Integer')); $dao = CRM_Core_DAO::executeQuery($query, $params); if ($dao->fetch()) { $ids['entityFinancialTrxnId'] = $dao->id; @@ -641,7 +645,8 @@ WHERE pp.participant_id = {$entityId} AND ft.to_financial_account_id != {$toFina continue; } foreach ($lineItem as $key => $item) { - if ($item['line_total'] <= 0 && !$update) { + $lineTotal = !empty($item['deferred_line_total']) ? $item['deferred_line_total'] : $item['line_total']; + if ($lineTotal <= 0 && !$update) { continue; } $deferredRevenues[$key] = $item; @@ -652,12 +657,13 @@ WHERE pp.participant_id = {$entityId} AND ft.to_financial_account_id != {$toFina array('civicrm_participant', 'civicrm_contribution')) ) { $deferredRevenues[$key]['revenue'][] = array( - 'amount' => $item['line_total'], + 'amount' => $lineTotal, 'revenue_date' => $revenueRecognitionDate, ); } else { // for membership + $item['line_total'] = $lineTotal; $deferredRevenues[$key]['revenue'] = self::getMembershipRevenueAmount($item); } } diff --git a/CRM/Event/Form/Participant.php b/CRM/Event/Form/Participant.php index 8a46f09e44..06b04f8d65 100644 --- a/CRM/Event/Form/Participant.php +++ b/CRM/Event/Form/Participant.php @@ -942,6 +942,12 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment $contributionParams = array(); $lineItem = array(); $additionalParticipantDetails = array(); + if (CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled')) { + $eventStartDate = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $this->_eventId, 'start_date'); + if ($eventStartDate) { + $contributionParams['revenue_recognition_date'] = date('Ymd', strtotime($eventStartDate)); + } + } if (($this->_id && $this->_action & CRM_Core_Action::UPDATE) && $this->_paymentId) { $participantBAO = new CRM_Event_BAO_Participant(); $participantBAO->id = $this->_id; diff --git a/CRM/Event/Form/Registration/Confirm.php b/CRM/Event/Form/Registration/Confirm.php index 38b6afd690..28cfda5d45 100644 --- a/CRM/Event/Form/Registration/Confirm.php +++ b/CRM/Event/Form/Registration/Confirm.php @@ -1011,6 +1011,18 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { $contribParams['id'] = $contribID; } + if (CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled')) { + $eventStartDate = CRM_Utils_Array::value( + 'start_date', + CRM_Utils_Array::value( + 'event', + $form->_values + ) + ); + if ($eventStartDate) { + $contribParams['revenue_recognition_date'] = date('Ymd', strtotime($eventStartDate)); + } + } //create an contribution address // The concept of contributeMode is deprecated. Elsewhere we use the function processBillingAddress() - although // currently that is only inherited by back-office forms. diff --git a/CRM/Financial/BAO/FinancialItem.php b/CRM/Financial/BAO/FinancialItem.php index 244e5e9c53..28e51b70d3 100644 --- a/CRM/Financial/BAO/FinancialItem.php +++ b/CRM/Financial/BAO/FinancialItem.php @@ -108,7 +108,11 @@ class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem { $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' ")); } else { - $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Income Account is' ")); + $accountRelName = 'Income Account is'; + if (property_exists($contribution, 'revenue_recognition_date') && !CRM_Utils_System::isNull($contribution->revenue_recognition_date)) { + $accountRelName = 'Deferred Revenue Account is'; + } + $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE '{$accountRelName}' ")); } if ($lineItem->financial_type_id) { $searchParams = array( @@ -125,8 +129,8 @@ class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem { $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE); $trxnId['id'] = $trxn['financialTrxnId']; } - - return self::create($params, NULL, $trxnId); + $financialItem = self::create($params, NULL, $trxnId); + return $financialItem; } /** diff --git a/CRM/Price/BAO/LineItem.php b/CRM/Price/BAO/LineItem.php index c1d5b09be2..70e42140df 100644 --- a/CRM/Price/BAO/LineItem.php +++ b/CRM/Price/BAO/LineItem.php @@ -426,12 +426,12 @@ AND li.entity_id = {$entityId} return; } - foreach ($lineItem as $priceSetId => $values) { + foreach ($lineItem as $priceSetId => &$values) { if (!$priceSetId) { continue; } - foreach ($values as $line) { + foreach ($values as &$line) { $line['entity_table'] = $entityTable; if (empty($line['entity_id'])) { $line['entity_id'] = $entityId; @@ -453,13 +453,17 @@ AND li.entity_id = {$entityId} } $lineItems = CRM_Price_BAO_LineItem::create($line); if (!$update && $contributionDetails) { - CRM_Financial_BAO_FinancialItem::add($lineItems, $contributionDetails); + $financialItem = CRM_Financial_BAO_FinancialItem::add($lineItems, $contributionDetails); + $line['financial_item_id'] = $financialItem->id; if (!empty($line['tax_amount'])) { CRM_Financial_BAO_FinancialItem::add($lineItems, $contributionDetails, TRUE); } } } } + if (!$update && $contributionDetails) { + CRM_Core_BAO_FinancialTrxn::createDeferredTrxn($lineItem, $contributionDetails); + } } /** diff --git a/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php b/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php index adfaa78a0c..854f08a172 100644 --- a/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php +++ b/tests/phpunit/CRM/Core/BAO/FinancialTrxnTest.php @@ -140,7 +140,6 @@ class CRM_Core_BAO_FinancialTrxnTest extends CiviUnitTestCase { 'receive_date' => '2016-01-20', 'total_amount' => 622, 'financial_type_id' => 4, - 'revenue_recognition_date' => date('Ymd', strtotime("+1 month")), 'line_items' => array( array( 'line_item' => array( @@ -166,6 +165,7 @@ class CRM_Core_BAO_FinancialTrxnTest extends CiviUnitTestCase { // Get financial trxns for contribution $trxn = $this->callAPISuccess("FinancialTrxn", "get", array('total_amount' => 622)); $this->assertEquals(date('Ymd', strtotime($trxn['values'][$trxn['id']]['trxn_date'])), date('Ymd', strtotime('2016-01-20'))); + $contribution->revenue_recognition_date = date('Ymd', strtotime("+1 month")); CRM_Core_BAO_FinancialTrxn::createDeferredTrxn($lineItems, $contribution); $trxn = $this->callAPISuccess("FinancialTrxn", "get", array('total_amount' => 622, 'id' => array("NOT IN" => array($trxn['id'])))); $this->assertEquals(date('Ymd', strtotime($trxn['values'][$trxn['id']]['trxn_date'])), date('Ymd', strtotime("+1 month"))); -- 2.25.1