//add lineitems for recurring payments
if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id && $addLineItems) {
- $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id);
+ $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id, CRM_Core_DAO::$_nullArray);
}
+ //copy initial contribution custom fields for recurring contributions
+ if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id) {
+ $this->copyCustomValues($objects['contributionRecur']->id, $contribution->id);
+ }
+
if (!CRM_Utils_Array::value('skipComponentSync', $input)) {
if (!empty($memberships)) {
+ // if transaction is failed then set "Cancelled" as membership status
+ $cancelStatusId = array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus());
foreach ($memberships as $membership) {
if ($membership) {
- $membership->status_id = 4;
+ $membership->status_id = $cancelStatusId;
$membership->save();
//update related Memberships.
//add lineitems for recurring payments
if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id && $addLineItems) {
- $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id);
+ $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id, CRM_Core_DAO::$_nullArray);
}
+ //copy initial contribution custom fields for recurring contributions
+ if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id) {
+ $this->copyCustomValues($objects['contributionRecur']->id, $contribution->id);
+ }
+
if (!CRM_Utils_Array::value('skipComponentSync', $input)) {
if (!empty($memberships)) {
foreach ($memberships as $membership) {
//add lineitems for recurring payments
if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id && $addLineItems) {
- $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id);
+ $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id, $input);
}
+ //copy initial contribution custom fields for recurring contributions
+ if ($recurContrib && $recurContrib->id) {
+ $this->copyCustomValues($recurContrib->id, $contribution->id);
+ }
+
// next create the transaction record
$paymentProcessor = $paymentProcessorId = '';
if (isset($objects['paymentProcessor'])) {
$lineSets[$pricesetID->price_set_id][] = $value;
}
}
-
- CRM_Price_BAO_LineItem::processPriceSet($contributionId, $lineSets);
+ if (!empty($input)) {
+ $input['line_item'] = $lineSets;
+ }
+ else {
+ CRM_Price_BAO_LineItem::processPriceSet($contributionId, $lineSets);
+ }
}
}
-}
+ // function to copy custom data of the
+ // initial contribution into its recurring contributions
+ function copyCustomValues($recurId, $targetContributionId) {
+ if ($recurId && $targetContributionId) {
+ // get the initial contribution id of recur id
+ $sourceContributionId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $recurId, 'id', 'contribution_recur_id');
+
+ // if the same contribution is being proccessed then return
+ if ($sourceContributionId == $targetContributionId) {
+ return;
+ }
+ // check if proper recurring contribution record is being processed
+ $targetConRecurId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $targetContributionId, 'contribution_recur_id');
+ if ($targetConRecurId != $recurId) {
+ return;
+ }
+
+ // copy custom data
+ $extends = array('Contribution');
+ $groupTree = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, NULL, $extends);
+ if ($groupTree) {
+ foreach ($groupTree as $groupID => $group) {
+ $table[$groupTree[$groupID]['table_name']] = array('entity_id');
+ foreach ($group['fields'] as $fieldID => $field) {
+ $table[$groupTree[$groupID]['table_name']][] = $groupTree[$groupID]['fields'][$fieldID]['column_name'];
+ }
+ }
+
+ foreach ($table as $tableName => $tableColumns) {
+ $insert = 'INSERT INTO ' . $tableName . ' (' . implode(', ', $tableColumns) . ') ';
+ $tableColumns[0] = $targetContributionId;
+ $select = 'SELECT ' . implode(', ', $tableColumns);
+ $from = ' FROM ' . $tableName;
+ $where = " WHERE {$tableName}.entity_id = {$sourceContributionId}";
+ $query = $insert . $select . $from . $where;
+ $dao = CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray);
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------------------------+
*}
<div class="batch-entry form-item">
- <div id="help">
- {ts}Click Validate & Process below when you've entered all items for the batch. You can also Save & Continue Later at any time. Go to Administer > Customize Display & Screens > Profiles > Reserved Profiles > to add, remove or change the order of columns.{/ts}
- </div>
- {if $batchAmountMismatch}
- <div class="status message status-warning">
- <div class="icon alert-icon"></div> {ts}Total for amounts entered below does not match the expected batch total.{/ts}
- </div>
- <div class="crm-button crm-button_qf_Entry_upload_force-save">
- {$form._qf_Entry_upload_force.html}
+ <div id="help">
+ {ts}Click Validate & Process below when you've entered all items for the batch. You can also Save & Continue Later at any time. Go to Administer > Customize Data and Screens > Profiles > Reserved Profiles > to add, remove or change the order of columns.{/ts}
</div>
- <div class="clear"></div>
- {/if}
- <table class="form-layout-compressed batch-totals">
- <tr><td class="label">{ts}Total amount expected{/ts}</td><td class="right"><span class="batch-expected-total">{$batchTotal|crmMoney}</span></td></tr>
- <tr><td class="label">{ts}Total amount entered{/ts}</td><td class="right">{$config->defaultCurrencySymbol} <span class="batch-actual-total"></span></td></tr>
- </table>
-
- <div class="crm-copy-fields crm-grid-table" id="crm-batch-entry-table">
- <div class="crm-grid-header">
+ {if $batchAmountMismatch}
+ <div class="status message status-warning">
+ <div
+ class="icon alert-icon"></div> {ts}Total for amounts entered below does not match the expected batch total.{/ts}
+ </div>
+ <div class="crm-button crm-button_qf_Entry_upload_force-save">
+ {$form._qf_Entry_upload_force.html}
+ </div>
+ <div class="clear"></div>
+ {/if}
+ <table class="form-layout-compressed batch-totals">
+ <tr>
+ <td class="label">{ts}Total amount expected{/ts}</td>
+ <td class="right"><span class="batch-expected-total">{$batchTotal|crmMoney}</span></td>
+ </tr>
+ <tr>
+ <td class="label">{ts}Total amount entered{/ts}</td>
+ <td class="right">{$config->defaultCurrencySymbol} <span class="batch-actual-total"></span></td>
+ </tr>
+ </table>
+
+ <div class="crm-copy-fields crm-grid-table" id="crm-batch-entry-table">
+ <div class="crm-grid-header">
+ <div class="crm-grid-cell"> </div>
+ <div class="crm-grid-cell">{ts}Contact{/ts}</div>
+ {if $batchType eq 2 }
<div class="crm-grid-cell"> </div>
- <div class="crm-grid-cell">{ts}Contact{/ts}</div>
- {if $batchType eq 2 }
- <div class="crm-grid-cell"> </div>
- {/if}
- {foreach from=$fields item=field key=fieldName}
- <div class="crm-grid-cell">{if $field.name neq 'soft_credit'}<img src="{$config->resourceBase}i/copy.png" alt="{ts 1=$field.title}Click to copy %1 from row one to all rows.{/ts}" fname="{$field.name}" class="action-icon" title="{ts}Click here to copy the value in row one to ALL rows.{/ts}" />{/if}{$field.title}</div>
- {/foreach}
- </div>
+ {/if}
+ {foreach from=$fields item=field key=fieldName}
+ <div class="crm-grid-cell">
+ <img src="{$config->resourceBase}i/copy.png"
+ alt="{ts 1=$field.title}Click to copy %1 from row one to all rows.{/ts}"
+ fname="{$field.name}" class="action-icon"
+ title="{ts}Click here to copy the value in row one to ALL rows.{/ts}"/>{$field.title}
+ </div>
+ {/foreach}
+ </div>
++
{section name='i' start=1 loop=$rowCount}
- {assign var='rowNumber' value=$smarty.section.i.index}
- <div class="{cycle values="odd-row,even-row"} selector-rows crm-grid-row" entity_id="{$rowNumber}">
+ {assign var='rowNumber' value=$smarty.section.i.index}
+ <div class="{cycle values="odd-row,even-row"} selector-rows crm-grid-row" entity_id="{$rowNumber}">
<div class="compressed crm-grid-cell"><span class="batch-edit"></span></div>
{* contact select/create option*}
<div class="compressed crm-grid-cell">
</div>
{literal}
<script type="text/javascript">
- cj(function(){
- cj('.selector-rows').change(function(){
- var options = {
- 'url' : {/literal}"{crmURL p='civicrm/ajax/batch' h=0}"{literal}
- };
+ cj(function () {
+ cj('.selector-rows').change(function () {
+ var options = {
+ 'url': {/literal}"{crmURL p='civicrm/ajax/batch' h=0}"{literal}
+ };
+
+ cj("#Entry").ajaxSubmit(options);
+
+ // validate rows
+ checkColumns(cj(this));
+ });
+
++ cj('input[name^="soft_credit_contact["]').change(function(){
++ var rowNum = cj(this).attr('id').replace('soft_credit_contact_','');
++ var totalAmount = cj('#field_'+rowNum+'_total_amount').val();
++ //assign total amount as default soft credit amount
++ cj('#soft_credit_amount_'+ rowNum).val(totalAmount);
++ });
++
+ // validate rows
+ validateRow();
+
+ //calculate the actual total for the batch
+ calculateActualTotal();
+
+ cj('input[id*="_total_amount"]').bind('keyup change', function () {
+ calculateActualTotal();
+ });
+
+ {/literal}{if $batchType eq 1 }{literal}
+ // hide all dates if send receipt is checked
+ hideSendReceipt();
+
+ // hide the receipt date if send receipt is checked
+ cj('input[id*="][send_receipt]"]').change(function () {
+ showHideReceipt(cj(this));
+ });
+
+ {/literal}{else}{literal}
+ cj('select[id^="member_option_"]').each(function () {
+ if (cj(this).val() == 1) {
+ cj(this).attr('disabled', true);
+ }
+ });
- cj("#Entry").ajaxSubmit(options);
+ // set payment info accord to membership type
+ cj('select[id*="_membership_type_0"]').change(function () {
+ setPaymentBlock(cj(this), null);
+ });
- // validate rows
- checkColumns( cj(this) );
- });
-
- cj('input[name^="soft_credit_contact["]').change(function(){
- var rowNum = cj(this).attr('id').replace('soft_credit_contact_','');
- var totalAmount = cj('#field_'+rowNum+'_total_amount').val();
- //assign total amount as default soft credit amount
- cj('#soft_credit_amount_'+ rowNum).val(totalAmount);
- });
+ cj('select[id*="_membership_type_1"]').change(function () {
+ setPaymentBlock(cj(this), cj(this).val());
+ });
- // validate rows
- validateRow( );
+ {/literal}{/if}{literal}
- //calculate the actual total for the batch
- calculateActualTotal();
+ // line breaks between radio buttons and checkboxes
+ cj('input.form-radio').next().after('<br />');
+ cj('input.form-checkbox').next().after('<br />');
- cj('input[id*="_total_amount"]').bind('keyup change', function(){
- calculateActualTotal();
- });
+ //set the focus on first element
+ cj('#primary_contact_1').focus();
- {/literal}{if $batchType eq 1 }{literal}
- // hide all dates if send receipt is checked
- hideSendReceipt();
+ });
- // hide the receipt date if send receipt is checked
- cj( 'input[id*="][send_receipt]"]').change( function() {
- showHideReceipt( cj(this) );
- });
+ function setPaymentBlock(form, memType) {
+ var rowID = form.closest('div.crm-grid-row').attr('entity_id');
+ var dataUrl = {/literal}"{crmURL p='civicrm/ajax/memType' h=0}"{literal};
- {/literal}{else}{literal}
- cj('select[id^="member_option_"]').each( function() {
- if ( cj(this).val() == 1 ) {
- cj(this).attr('disabled', true);
- }
- });
+ if (!memType) {
+ memType = cj('select[id="field_' + rowID + '_membership_type_1"]').val();
+ }
- // set payment info accord to membership type
- cj( 'select[id*="_membership_type_0"]').change( function() {
- setPaymentBlock( cj(this), null );
- });
+ cj.post(dataUrl, {mtype: memType}, function (data) {
+ cj('#field_' + rowID + '_financial_type').val(data.financial_type_id);
+ cj('#field_' + rowID + '_total_amount').val(data.total_amount).change();
+ }, 'json');
+ }
- cj( 'select[id*="_membership_type_1"]').change( function() {
- setPaymentBlock( cj(this), cj(this).val() );
- });
+ function hideSendReceipt() {
+ cj('input[id*="][send_receipt]"]').each(function () {
+ showHideReceipt(cj(this));
+ });
+ }
- {/literal}{/if}{literal}
+ function showHideReceipt(elem) {
+ var rowID = elem.closest('div.crm-grid-row').attr('entity_id');
+ if (elem.prop('checked')) {
+ cj('.crm-batch-receipt_date-' + rowID).hide();
+ }
+ else {
+ cj('.crm-batch-receipt_date-' + rowID).show();
+ }
+ }
- // line breaks between radio buttons and checkboxes
- cj('input.form-radio').next().after('<br />');
- cj('input.form-checkbox').next().after('<br />');
-
- //set the focus on first element
- cj('#primary_contact_1').focus();
-
- });
-
- function setPaymentBlock( form, memType ) {
- var rowID = form.closest('div.crm-grid-row').attr('entity_id');
- var dataUrl = {/literal}"{crmURL p='civicrm/ajax/memType' h=0}"{literal};
-
- if ( !memType ) {
- memType = cj( 'select[id="field_'+ rowID+'_membership_type_1"]').val();
- }
-
- cj.post( dataUrl, {mtype: memType}, function( data ) {
- cj('#field_' + rowID + '_financial_type').val( data.financial_type_id );
- cj('#field_' + rowID + '_total_amount').val( data.total_amount ).change();
- }, 'json');
- }
-
- function hideSendReceipt() {
- cj( 'input[id*="][send_receipt]"]').each( function() {
- showHideReceipt( cj(this) );
- });
- }
-
- function showHideReceipt( elem ) {
- var rowID = elem.closest('div.crm-grid-row').attr('entity_id');
- var element = 'field_' + rowID + '_receipt_date';
- if ( elem.prop('checked') ) {
- cj('.crm-batch-receipt_date-'+ rowID ).hide();
- } else {
- cj('.crm-batch-receipt_date-'+ rowID ).show();
- }
- }
-
- function validateRow( ) {
- cj('.selector-rows').each(function(){
- checkColumns( cj(this) );
- });
- }
-
- function checkColumns( parentRow ) {
- // show valid row icon if all required data is field
- var validRow = 0;
- var inValidRow = 0;
- var errorExists = false;
- parentRow.find('div .required').each(function(){
- if ( !cj(this).val( ) ) {
- inValidRow++;
- } else if ( cj(this).hasClass('error') && !cj(this).hasClass('valid') ) {
- errorExists = true;
- } else {
- validRow++;
- }
- });
-
- // this means use has entered some data
- if ( errorExists ) {
- parentRow.find("div:first span").prop('class', 'batch-invalid');
- } else if ( inValidRow == 0 && validRow > 0 ) {
- parentRow.find("div:first span").prop('class', 'batch-valid');
- } else {
- parentRow.find("div:first span").prop('class', 'batch-edit');
- }
- }
-
- function calculateActualTotal() {
- var total = 0;
- cj('input[id*="_total_amount"]').each(function(){
- if ( cj(this).val() ) {
- total += parseFloat(cj(this).val());
+ function validateRow() {
+ cj('.selector-rows').each(function () {
+ checkColumns(cj(this));
+ });
+ }
+
+ function checkColumns(parentRow) {
+ // show valid row icon if all required data is field
+ var validRow = 0;
+ var inValidRow = 0;
+ var errorExists = false;
+ var rowID = parentRow.closest('div.crm-grid-row').attr('entity_id');
+
+ parentRow.find('div .required').each(function () {
+ //special case to handle contact autocomplete select
+ var fieldId = cj(this).attr('id');
+ if (fieldId.substring(0, 16) == 'primary_contact_') {
+ // if display value is set then make sure we also check if contact id is set
+ if (!cj(this).val()) {
+ inValidRow++;
+ }
+ else {
+ if (cj(this).val() && !cj('input[name="primary_contact_select_id[' + rowID + ']"]').val()) {
+ inValidRow++;
+ errorExists = true;
+ }
+ }
+ }
+ else {
+ if (!cj(this).val()) {
+ inValidRow++;
}
- });
+ else {
+ if (cj(this).hasClass('error') && !cj(this).hasClass('valid')) {
+ errorExists = true;
+ }
+ else {
+ validRow++;
+ }
+ }
+ }
+ });
- cj('.batch-actual-total').html(formatMoney(total));
- }
+ // this means user has entered some data
+ if (errorExists) {
+ parentRow.find("div:first span").prop('class', 'batch-invalid');
+ }
+ else {
+ if (inValidRow == 0 && validRow > 0) {
+ parentRow.find("div:first span").prop('class', 'batch-valid');
+ }
+ else {
+ parentRow.find("div:first span").prop('class', 'batch-edit');
+ }
+ }
+ }
- //money formatting/localization
- function formatMoney ( amount ) {
- var c = 2;
- var t = '{/literal}{$config->monetaryThousandSeparator}{literal}';
- var d = '{/literal}{$config->monetaryDecimalPoint}{literal}';
+ function calculateActualTotal() {
+ var total = 0;
+ cj('input[id*="_total_amount"]').each(function () {
+ if (cj(this).val()) {
+ total += parseFloat(cj(this).val());
+ }
+ });
- var n = amount,
- c = isNaN(c = Math.abs(c)) ? 2 : c,
- d = d == undefined ? "," : d,
- t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
- i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
- j = (j = i.length) > 3 ? j % 3 : 0;
+ cj('.batch-actual-total').html(formatMoney(total));
+ }
- return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
- }
+ //money formatting/localization
+ function formatMoney(amount) {
+ var c = 2;
+ var t = '{/literal}{$config->monetaryThousandSeparator}{literal}';
+ var d = '{/literal}{$config->monetaryDecimalPoint}{literal}';
- function updateContactInfo( blockNo, prefix ) {
- var contactHiddenElement = 'input[name="' + prefix + 'contact_select_id[' + blockNo +']"]';
- var contactId = cj( contactHiddenElement ).val();;
-
- var returnProperties = '';
- var profileFields = new Array();
- {/literal}
- {if $contactFields}
- {foreach from=$contactFields item=val key=fldName}
- var fldName = "{$fldName}";
- {literal}
- if ( returnProperties ) {
- returnProperties = returnProperties + ',';
- }
- var fld = fldName.split('-');
- returnProperties = returnProperties + fld[0];
- profileFields[fld[0]] = fldName;
- {/literal}
- {/foreach}
- {/if}
- {literal}
+ var n = amount,
+ c = isNaN(c = Math.abs(c)) ? 2 : c,
+ d = d == undefined ? "," : d,
+ t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
+ i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
+ j = (j = i.length) > 3 ? j % 3 : 0;
- CRM.api('Contact','get',{
- 'sequential' :'1',
+ return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
+ }
+
+ function updateContactInfo(blockNo, prefix) {
+ var contactHiddenElement = 'input[name="' + prefix + 'contact_select_id[' + blockNo + ']"]';
+ var contactId = cj(contactHiddenElement).val();
+
+ var returnProperties = '';
+ var profileFields = new Array();
+ {/literal}
+ {if $contactFields}
+ {foreach from=$contactFields item=val key=fldName}
+ var fldName = "{$fldName}";
+ {literal}
+ if (returnProperties) {
+ returnProperties = returnProperties + ',';
+ }
+ var fld = fldName.split('-');
+ returnProperties = returnProperties + fld[0];
+ profileFields[fld[0]] = fldName;
+ {/literal}
+ {/foreach}
+ {/if}
+ {literal}
+
+ CRM.api('Contact', 'get', {
+ 'sequential': '1',
'contact_id': contactId,
'return': returnProperties },
- { success: function (data) {
- cj.each ( data.values[0], function( key, value ) {
- // set the values
- var actualFldName = profileFields[key];
- if ( key == 'country' || key == 'state_province' ) {
- idFldName = key + '_id';
- value = data.values[0][idFldName];
- }
- setFieldValue( actualFldName, value, blockNo )
- });
+ { success: function (data) {
+ cj.each(data.values[0], function (key, value) {
+ // set the values
+ var actualFldName = profileFields[key];
+ if (key == 'country' || key == 'state_province') {
+ idFldName = key + '_id';
+ value = data.values[0][idFldName];
+ }
+ setFieldValue(actualFldName, value, blockNo)
+ });
- // for membership batch entry based on contact we need to enable / disable
- // add membership select
- {/literal}{if $batchType eq 2}{literal}
- CRM.api('Membership','get',{
- 'sequential' :'1',
- 'contact_id': contactId,
- },
- { success: function (data) {
- if ( data.count > 0 ) {
- //get the information on membership type
- var membershipTypeId = data.values[0].membership_type_id;
- var membershipJoinDate = data.values[0].join_date;
- CRM.api('MembershipType','get',{
- 'sequential' :'1',
- 'id' : membershipTypeId
- },
- { success: function (data){
- var memTypeContactId = data.values[0].member_of_contact_id;
- cj('select[id="member_option_' + blockNo + '"]').removeAttr('disabled').val(2);
- cj('select[id="field_' + blockNo + '_membership_type_0"]').val( memTypeContactId ).change();
- cj('select[id="field_' + blockNo + '_membership_type_1"]').val( membershipTypeId ).change();
- setDateFieldValue( 'join_date', membershipJoinDate, blockNo )
- }
+ // for membership batch entry based on contact we need to enable / disable
+ // add membership select
+ {/literal}{if $batchType eq 2}{literal}
+ CRM.api('Membership', 'get', {
+ 'sequential': '1',
+ 'contact_id': contactId,
+ },
+ { success: function (data) {
+ if (data.count > 0) {
+ //get the information on membership type
+ var membershipTypeId = data.values[0].membership_type_id;
+ var membershipJoinDate = data.values[0].join_date;
+ CRM.api('MembershipType', 'get', {
+ 'sequential': '1',
+ 'id': membershipTypeId
+ },
+ { success: function (data) {
+ var memTypeContactId = data.values[0].member_of_contact_id;
+ cj('select[id="member_option_' + blockNo + '"]').removeAttr('disabled').val(2);
+ cj('select[id="field_' + blockNo + '_membership_type_0"]').val(memTypeContactId).change();
+ cj('select[id="field_' + blockNo + '_membership_type_1"]').val(membershipTypeId).change();
+ setDateFieldValue('join_date', membershipJoinDate, blockNo)
+ }
});
- }
}
+ }
});
- {/literal}{/if}{literal}
- }
+ {/literal}{/if}{literal}
+ }
});
- }
+ }
/**
* This function is use to setdefault elements via ajax