X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContribute%2FBAO%2FContribution.php;h=da03b77f875ad13249a9d24b425e8eedc6893e4a;hb=d4173e73a9eca7c63702046b74277c699acbe3b4;hp=6b4c70b367787227ae57a4c33b53793c192a7213;hpb=648631cd94799e87fe2347487d465b1a7256aa57;p=civicrm-core.git diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 6b4c70b367..da03b77f87 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -825,15 +825,6 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ), ); - $contributionRecurId = array( - 'contribution_recur_id' => array( - 'title' => ts('Recurring Contributions ID'), - 'name' => 'contribution_recur_id', - 'where' => 'civicrm_contribution.contribution_recur_id', - 'data_type' => CRM_Utils_Type::T_INT, - ), - ); - $extraFields = array( 'contribution_batch' => array( 'title' => ts('Batch Name'), @@ -893,7 +884,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ); $fields = array_merge($impFields, $typeField, $contributionStatus, $contributionPage, $optionField, $expFieldProduct, - $expFieldsContrib, $contributionNote, $contributionRecurId, $extraFields, $softCreditFields, $financialAccount, $premiums, $campaignTitle, + $expFieldsContrib, $contributionNote, $extraFields, $softCreditFields, $financialAccount, $premiums, $campaignTitle, CRM_Core_BAO_CustomField::getFieldsForImport('Contribution', FALSE, FALSE, FALSE, $checkPermission) ); @@ -3615,19 +3606,12 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac } } if ($context == 'changePaymentInstrument') { - foreach ($params['line_item'] as $lineitems) { - foreach ($lineitems as $fieldValueId => $fieldValues) { - $prevFinancialItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($fieldValues['id']); - // save to entity_financial_trxn table - $entityFinancialTrxnParams = array( - 'entity_table' => "civicrm_financial_item", - 'entity_id' => $prevFinancialItem->id, - 'financial_trxn_id' => $trxn->id, - 'amount' => $trxn->total_amount, - ); - civicrm_api3('entityFinancialTrxn', 'create', $entityFinancialTrxnParams); - } - } + // store financial item Proportionaly. + $trxnParams = array( + 'total_amount' => $trxn->total_amount, + 'contribution_id' => $params['contribution']->id, + ); + self::assignProportionalLineItems($trxnParams, $trxn->id, $params['prevContribution']->total_amount); } CRM_Core_BAO_FinancialTrxn::createDeferredTrxn(CRM_Utils_Array::value('line_item', $params), $params['contribution'], TRUE, $context); } @@ -3776,6 +3760,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac * @param string $paymentType * 'owed' for purpose of recording partial payments, 'refund' for purpose of recording refund payments. * @param int $participantId + * @param bool $updateStatus * * @return null|object */ @@ -4076,9 +4061,9 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) LEFT JOIN civicrm_entity_financial_trxn eft ON (eft.entity_id = con.id AND eft.entity_table = 'civicrm_contribution') INNER JOIN civicrm_financial_trxn ft ON ft.id = eft.financial_trxn_id AND ft.to_financial_account_id != %2 - INNER JOIN civicrm_entity_financial_trxn ef ON (ef.financial_trxn_id = ft.id AND ef.entity_table = 'civicrm_financial_item') + LEFT JOIN civicrm_entity_financial_trxn ef ON (ef.financial_trxn_id = ft.id AND ef.entity_table = 'civicrm_financial_item') LEFT JOIN civicrm_financial_item fi ON fi.id = ef.entity_id - INNER JOIN civicrm_financial_account fa ON fa.id = fi.financial_account_id + LEFT JOIN civicrm_financial_account fa ON fa.id = fi.financial_account_id WHERE con.id = %1 AND ft.is_payment = 1 GROUP BY ft.id"; @@ -4337,9 +4322,11 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) /** * Compute the stats values * - * @param $stat either 'mode' or 'median' - * @param $sql - * @param $alias of civicrm_contribution + * @param string $stat either 'mode' or 'median' + * @param string $sql + * @param string $alias of civicrm_contribution + * + * @return array|null */ public static function computeStats($stat, $sql, $alias = NULL) { $mode = $median = array(); @@ -4392,7 +4379,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) return $median; default: - return; + return NULL; } } @@ -4429,6 +4416,8 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) * Duplication of param needs review. Only used by AuthorizeNetIPN * @param int $isFirstOrLastRecurringPayment * Deprecated param only used by AuthorizeNetIPN. + * + * @return array */ public static function completeOrder(&$input, &$ids, $objects, $transaction, $recur, $contribution, $isRecurring, $isFirstOrLastRecurringPayment) { $primaryContributionID = isset($contribution->id) ? $contribution->id : $objects['first_contribution']->id; @@ -4478,6 +4467,12 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) )); $contributionParams['payment_processor'] = $input['payment_processor'] = $paymentProcessorId; + // If paymentProcessor is not set then the payment_instrument_id would not be correct. + // not clear when or if this would occur if you encounter this please fix here & add a unit test. + if (empty($contributionParams['payment_instrument_id']) && isset($contribution->_relatedObjects['paymentProcessor']['payment_instrument_id'])) { + $contributionParams['payment_instrument_id'] = $contribution->_relatedObjects['paymentProcessor']['payment_instrument_id']; + } + if ($recurringContributionID) { $contributionParams['contribution_recur_id'] = $recurringContributionID; } @@ -4720,14 +4715,8 @@ LIMIT 1;"; $contribution->loadRelatedObjects($input, $ids, TRUE); // set receipt from e-mail and name in value if (!$returnMessageText) { - $userID = CRM_Core_Session::singleton()->getLoggedInContactID(); - if (!empty($userID)) { - list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID); - $values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $input, $userEmail); - $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $input, $userName); - } + list($values['receipt_from_name'], $values['receipt_from_email']) = self::generateFromEmailAndName($input, $contribution); } - $return = $contribution->composeMessageArray($input, $ids, $values, $recur, $returnMessageText); // Contribution ID should really always be set. But ? if (!$returnMessageText && (!isset($input['receipt_update']) || $input['receipt_update']) && empty($contribution->receipt_date)) { @@ -4736,6 +4725,42 @@ LIMIT 1;"; return $return; } + /** + * Generate From email and from name in an array values + */ + public static function generateFromEmailAndName($input, $contribution) { + // Use input valuse if supplied. + if (!empty($input['receipt_from_email'])) { + return array(CRM_Utils_array::value('receipt_from_name', $input, ''), $input['receipt_from_email']); + } + // if we are still empty see if we can use anything from a contribution page. + $pageValues = array(); + if (!empty($contribution->contribution_page_id)) { + $pageValues = civicrm_api3('ContributionPage', 'getsingle', array('id' => $contribution->contribution_page_id)); + } + // if we are still empty see if we can use anything from a contribution page. + if (!empty($pageValues['receipt_from_email'])) { + return array($pageValues['receipt_from_name'], $pageValues['receipt_from_email']); + } + // If we are still empty fall back to the domain. + $domain = civicrm_api3('domain', 'getsingle', array('id' => CRM_Core_Config::domainID())); + if (!empty($domain['from_email'])) { + return array($domain['from_name'], $domain['from_email']); + } + if (!empty($domain['domain_email'])) { + return array($domain['name'], $domain['domain_email']); + } + $userID = CRM_Core_Session::singleton()->getLoggedInContactID(); + $userName = ''; + $userEmail = ''; + if (!empty($userID)) { + list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID); + } + // If still empty fall back to the logged in user details. + // return empty values no matter what. + return array($userName, $userEmail); + } + /** * Generate credit note id with next avaible number * @@ -4942,38 +4967,23 @@ LIMIT 1;"; $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($trxnParams['contribution_id']); if (!empty($lineItems)) { // get financial item - $sql = "SELECT fi.id, li.price_field_value_id - FROM civicrm_financial_item fi - INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item' - WHERE li.contribution_id = %1"; - $dao = CRM_Core_DAO::executeQuery($sql, array(1 => array($trxnParams['contribution_id'], 'Integer'))); - while ($dao->fetch()) { - $ftIds[$dao->price_field_value_id] = $dao->id; - } - $eftParams = array( - 'entity_table' => 'civicrm_financial_item', - 'financial_trxn_id' => $trxnId, + list($ftIds, $taxItems) = self::getLastFinancialItemIds($trxnParams['contribution_id']); + $entityParams = array( + 'contribution_total_amount' => $contributionTotalAmount, + 'trxn_total_amount' => $trxnParams['total_amount'], + 'trxn_id' => $trxnId, ); - foreach ($lineItems as $key => $value) { - if ($value['qty'] == 0) { - continue; - } - $paid = $value['line_total'] * ($trxnParams['total_amount'] / $contributionTotalAmount); - // Record Entity Financial Trxn - $eftParams['amount'] = round($paid, 2); - $eftParams['entity_id'] = $ftIds[$value['price_field_value_id']]; - - civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); - } + self::createProportionalFinancialEntries($entityParams, $lineItems, $ftIds, $taxItems); } } /** - * Function to check line items + * Function to check line items. * * @param array $params * array of order params. * + * @throws \API_Exception */ public static function checkLineItems(&$params) { $totalAmount = CRM_Utils_Array::value('total_amount', $params); @@ -5376,4 +5386,103 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co return CRM_Utils_Money::format($netAmount, NULL, '%a'); } + /** + * Retrieve Sales Tax Financial Accounts. + * + * + * @return array + * + */ + public static function getSalesTaxFinancialAccounts() { + $query = "SELECT cfa.id FROM civicrm_entity_financial_account ce + INNER JOIN civicrm_financial_account cfa ON ce.financial_account_id = cfa.id + WHERE `entity_table` = 'civicrm_financial_type' AND cfa.is_tax = 1 AND ce.account_relationship = %1 GROUP BY cfa.id"; + $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' ")); + $queryParams = array(1 => array($accountRel, 'Integer')); + $dao = CRM_Core_DAO::executeQuery($query, $queryParams); + $financialAccount = array(); + while ($dao->fetch()) { + $financialAccount[$dao->id] = $dao->id; + } + return $financialAccount; + } + + /** + * Create tax entry in civicrm_entity_financial_trxn table. + * + * @param array $entityParams + * + * @param array $eftParams + * + */ + public static function createProportionalEntry($entityParams, $eftParams) { + $paid = $entityParams['line_item_amount'] * ($entityParams['trxn_total_amount'] / $entityParams['contribution_total_amount']); + // Record Entity Financial Trxn + // CRM-20145 + $eftParams['amount'] = number_format((float)round($paid, 2), 2, '.', ''); + civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); + } + + /** + * Create array of last financial item id's. + * + * @param int $contributionId + * + * @return array + */ + public static function getLastFinancialItemIds($contributionId) { + $sql = "SELECT fi.id, li.price_field_value_id, li.tax_amount, fi.financial_account_id + FROM civicrm_financial_item fi + INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item' + WHERE li.contribution_id = %1"; + $dao = CRM_Core_DAO::executeQuery($sql, array(1 => array($contributionId, 'Integer'))); + $ftIds = $taxItems = array(); + $salesTaxFinancialAccount = self::getSalesTaxFinancialAccounts(); + while ($dao->fetch()) { + /* if sales tax item*/ + if (in_array($dao->financial_account_id, $salesTaxFinancialAccount)) { + $taxItems[$dao->price_field_value_id] = array( + 'financial_item_id' => $dao->id, + 'amount' => $dao->tax_amount, + ); + } + else { + $ftIds[$dao->price_field_value_id] = $dao->id; + } + } + return array($ftIds, $taxItems); + } + + /** + * Create proportional entries in civicrm_entity_financial_trxn. + * + * @param array $entityParams + * + * @param array $lineItems + * + * @param array $ftIds + * + * @param array $taxItems + * + */ + public static function createProportionalFinancialEntries($entityParams, $lineItems, $ftIds, $taxItems) { + $eftParams = array( + 'entity_table' => 'civicrm_financial_item', + 'financial_trxn_id' => $entityParams['trxn_id'], + ); + foreach ($lineItems as $key => $value) { + if ($value['qty'] == 0) { + continue; + } + $eftParams['entity_id'] = $ftIds[$value['price_field_value_id']]; + $entityParams['line_item_amount'] = $value['line_total']; + self::createProportionalEntry($entityParams, $eftParams); + if (array_key_exists($value['price_field_value_id'], $taxItems)) { + $entityParams['line_item_amount'] = $taxItems[$value['price_field_value_id']]['amount']; + $eftParams['entity_id'] = $taxItems[$value['price_field_value_id']]['financial_item_id']; + self::createProportionalEntry($entityParams, $eftParams); + } + } + } + }