/**
* Get a 'complex' invoice.
*
* Only call this via the api... I made it public static because of the move away from 'real' BAO
* classes in preparation for doctrine but the api is the way to go.
*
* @param array $params
*
* @return array
*/
public static function getDerived($params)
{
try {
// ok this chaining is a bit heavy but it would be good to work towards API returning this more efficiently
// ie. not keen on the fact you can't easily get line items for contributions related to participants
// & TBH the communication with Xero takes 90% of the script time ...
// @todo - set return properties on contribution.get
// @todo at the moment we use getsingle because we are only dealing with 1 but should alter to 'get'
// as in theory any params could be passed in - resulting in many - there are some api
// issues around getfields to resolve though - see notes on api
$contribution = civicrm_api3('contribution', 'getsingle', array_merge(array('api.participant_payment.get' => array('return' => 'api.participant., participant_id', 'api.participant.get' => array('api.line_item.get' => 1, 'return' => 'participant_source, event_id, financial_type_id'))), $params));
// There is a chaining bug on line item because chaining passes contribution_id along as entity_id.
// CRM-16522.
$contribution['api.line_item.get'] = civicrm_api3('line_item', 'get', array('contribution_id' => $contribution['id']));
if ($contribution['api.line_item.get']['count']) {
$contribution['line_items'] = $contribution['api.line_item.get']['values'];
} else {
//we'll keep the participant record for anyone trying to do hooks
$contribution['participant'] = $contribution['api.participant_payment.get']['values'][0]['api.participant.get']['values'][0];
$contribution['line_items'] = $contribution['participant']['api.line_item.get']['values'];
//if multiple participants one line item each
self::_getAdditionalParticipanLineItems($contribution);
}
foreach ($contribution['line_items'] as &$lineItem) {
$lineItem['accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($lineItem['financial_type_id']);
$lineItem['accounts_contact_id'] = self::getAccountsContact($lineItem['financial_type_id']);
$contributionAccountsContactIDs[$lineItem['accounts_contact_id']] = TRUE;
if (!isset($lineItem['contact_id'])) {
//this would have been set for a secondary participant above so we are ensuring primary ones have it
// for conformity & ease downstream
$lineItem['contact_id'] = $contribution['contact_id'];
}
if (!isset($lineItem['display_name'])) {
//this would have been set for a secondary participant above so we are ensuring primary ones have it
// for conformity & ease downstream
$lineItem['display_name'] = $contribution['display_name'];
}
}
//@todo move the getAccountingCode to a fn that caches it
$contribution['accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($contribution['financial_type_id']);
$contribution['accounts_contact_id'] = array_keys($contributionAccountsContactIDs);
} catch (Exception $e) {
// probably shouldn't catch & let calling class catch
}
// In 4.6 this might be more reliable as Monish did some tidy up on BAO_Search stuff.
// Relying on it being unique makes me nervous...
if (empty($contribution['payment_instrument_id'])) {
$paymentInstruments = civicrm_api3('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
$contribution['payment_instrument_id'] = array_search($contribution['payment_instrument'], $paymentInstruments['values']);
}
$instrumentFinancialAccounts = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount();
$contribution['payment_instrument_financial_account_id'] = $instrumentFinancialAccounts[$contribution['payment_instrument_id']];
try {
$contribution['payment_instrument_accounting_code'] = civicrm_api3('financial_account', 'getvalue', array('id' => $contribution['payment_instrument_financial_account_id'], 'return' => 'accounting_code'));
} catch (Exception $e) {
}
return array($contribution['id'] => $contribution);
}
/**
* Global validation rules for the form.
*
* @param array $values
* posted values of the form
* @param $files
* @param $self
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($values, $files, $self)
{
$errorMsg = array();
$financialAccountTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Liability' "));
if (isset($values['is_tax'])) {
if ($values['financial_account_type_id'] != $financialAccountTypeId) {
$errorMsg['financial_account_type_id'] = ts('Taxable accounts should have Financial Account Type set to Liability.');
}
if (CRM_Utils_Array::value('tax_rate', $values) == NULL) {
$errorMsg['tax_rate'] = ts('Please enter value for tax rate');
}
}
if (CRM_Utils_Array::value('tax_rate', $values) != NULL) {
if ($values['tax_rate'] < 0 || $values['tax_rate'] >= 100) {
$errorMsg['tax_rate'] = ts('Tax Rate Should be between 0 - 100');
}
}
if ($self->_action & CRM_Core_Action::UPDATE) {
if (!isset($values['is_tax'])) {
$relationshipId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
$params = array('financial_account_id' => $self->_id, 'account_relationship' => $relationshipId);
$result = CRM_Financial_BAO_FinancialTypeAccount::retrieve($params, $defaults);
if ($result) {
$errorMsg['is_tax'] = ts('Is Tax? must be set for this financial account');
}
}
}
return CRM_Utils_Array::crmIsEmptyArray($errorMsg) ? TRUE : $errorMsg;
}
/**
* Function to process the form
*
* @access public
* @return void
*/
public function postProcess()
{
if ($this->_action & CRM_Core_Action::DELETE) {
CRM_Financial_BAO_FinancialTypeAccount::del($this->_id, $this->_aid);
CRM_Core_Session::setStatus(ts('Selected financial type account has been deleted.'));
} else {
$params = $ids = array();
// store the submitted values in an array
$params = $this->exportValues();
if ($this->_action & CRM_Core_Action::UPDATE) {
$ids['entityFinancialAccount'] = $this->_id;
}
if ($this->_action & CRM_Core_Action::ADD || $this->_action & CRM_Core_Action::UPDATE) {
$params['financial_account_id'] = $this->_submitValues['financial_account_id'];
}
$params['entity_table'] = 'civicrm_financial_type';
if ($this->_action & CRM_Core_Action::ADD) {
$params['entity_id'] = $this->_aid;
}
$financialTypeAccount = CRM_Financial_BAO_FinancialTypeAccount::add($params, $ids);
CRM_Core_Session::setStatus(ts('The financial type Account has been saved.'));
}
$buttonName = $this->controller->getButtonName();
$session = CRM_Core_Session::singleton();
if ($buttonName == $this->getButtonName('next', 'new')) {
CRM_Core_Session::setStatus(ts(' You can add another Financial Account Type.'));
$session->replaceUserContext(CRM_Utils_System::url('civicrm/admin/financial/financialType/accounts', "reset=1&action=add&aid={$this->_aid}"));
} else {
$session->replaceUserContext(CRM_Utils_System::url('civicrm/admin/financial/financialType/accounts', "reset=1&action=browse&aid={$this->_aid}"));
}
}
/**
* Add the financial types.
*
* @param array $params
* Reference array contains the values submitted by the form.
* @param array $ids
* Reference array contains the id.
*
* @return object
*/
public static function add(&$params, &$ids = array())
{
if (empty($params['id'])) {
$params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE);
$params['is_deductible'] = CRM_Utils_Array::value('is_deductible', $params, FALSE);
$params['is_reserved'] = CRM_Utils_Array::value('is_reserved', $params, FALSE);
}
// action is taken depending upon the mode
$financialType = new CRM_Financial_DAO_FinancialType();
$financialType->copyValues($params);
if (!empty($ids['financialType'])) {
$financialType->id = CRM_Utils_Array::value('financialType', $ids);
if (self::isACLFinancialTypeStatus()) {
$prevName = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $financialType->id, 'name');
if ($prevName != $params['name']) {
CRM_Core_Session::setStatus(ts("Changing the name of a Financial Type will result in losing the current permissions associated with that Financial Type.\n Before making this change you should likely note the existing permissions at Administer > Users and Permissions > Permissions (Access Control),\n then clicking the Access Control link for your Content Management System, then noting down the permissions for 'CiviCRM: {financial type name} view', etc.\n Then after making the change of name, reset the permissions to the way they were."), ts('Warning'), 'warning');
}
}
}
$financialType->save();
// CRM-12470
if (empty($ids['financialType']) && empty($params['id'])) {
$titles = CRM_Financial_BAO_FinancialTypeAccount::createDefaultFinancialAccounts($financialType);
$financialType->titles = $titles;
}
return $financialType;
}
请发表评论