Commit 6a9ff830 authored by Monish Deb's avatar Monish Deb

Add support for Intacct AP entries

parent 63be91d7
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 5 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2018 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2018
*/
/**
* @link http://wiki.civicrm.org/confluence/display/CRM/CiviAccounts+Specifications+-++Batches#CiviAccountsSpecifications-Batches-%C2%A0Overviewofimplementation
*/
class CRM_Financial_BAO_ExportFormat_SyncIntacctAP extends CRM_Financial_BAO_ExportFormat {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* @param array $exportParams
*/
public function export($exportParams) {
parent::export($exportParams);
}
/**
* @param int $batchId
*
* @return Object
*/
public function generateExportQuery($batchID) {
civicrm_api3('Batch', 'create', [
'id' => $batchID,
'data' => 'Not Synchronized',
]);
return $batchID;
}
/**
* Generate CSV array for export.
*
* @param array $export
*/
public function makeExport($export) {
$batchEntries = [];
foreach ($export as $batchID) {
$this->_batchIds = $batchID;
CRM_Core_DAO::executeQuery("INSERT IGNORE INTO civicrm_intacct_batches(`batch_id`, `mode`) VALUES ($batchID, 'AP')");
$batchEntries[$batchID] = CRM_Syncintacct_Util::fetchTransactionrecords($batchID, 'civicrm_contribution');
}
// Save the file in the public directory.
$fileName = self::putFile($batchEntries);
$this->output($fileName);
}
/**
* Exports sbatches in $this->_batchIds, and saves to file.
*
* @param string $fileName - use this file name (if applicable)
*/
public function output($fileName = NULL) {
// Default behaviour, override if needed:
self::createActivityExport($this->_batchIds, $fileName);
}
/**
* @param $batchIds
* @param string $fileName
*
* @throws CRM_Core_Exception
*/
public static function createActivityExport($batchIds, $fileName) {
$loggedInContactId = CRM_Core_Session::getLoggedInContactID();
$values = array();
$params = array('id' => $batchIds);
CRM_Batch_BAO_Batch::retrieve($params, $values);
$createdBy = CRM_Contact_BAO_Contact::displayName($values['created_id']);
$modifiedBy = CRM_Contact_BAO_Contact::displayName($values['modified_id']);
$values['payment_instrument_id'] = '';
if (isset($values['payment_instrument_id'])) {
$paymentInstrument = array_flip(CRM_Contribute_PseudoConstant::paymentInstrument('label'));
$values['payment_instrument_id'] = array_search($values['payment_instrument_id'], $paymentInstrument);
}
$details = '<p>' . ts('Record:') . ' ' . $values['title'] . '</p><p>' . ts('Description:') . '</p><p>' . ts('Created By:') . " $createdBy" . '</p><p>' . ts('Created Date:') . ' ' . $values['created_date'] . '</p><p>' . ts('Last Modified By:') . ' ' . $modifiedBy . '</p><p>' . ts('Payment Method:') . ' ' . $values['payment_instrument_id'] . '</p>';
if (!empty($values['total'])) {
$details .= ts('Total') . '[' . CRM_Utils_Money::format($values['total']) . '],';
}
if (!empty($values['item_count'])) {
$details .= ' ' . ts('Count') . '[' . $values['item_count'] . '],';
}
// create activity.
$details .= ' ' . ts('Batch') . '[' . $values['title'] . ']';
$activityParams = array(
'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Export Accounting Batch'),
'subject' => 'Grant payments exported to Intacct',
'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'status_id', 'Scheduled'),
'activity_date_time' => date('YmdHis'),
'source_contact_id' => $loggedInContactId,
'source_record_id' => $values['id'],
'target_contact_id' => $loggedInContactId,
'details' => $details,
'attachFile_1' => array(
'uri' => $fileName,
'type' => 'text/plain',
'location' => $fileName,
'upload_date' => date('YmdHis'),
),
);
CRM_Activity_BAO_Activity::create($activityParams);
}
/**
* @param $export
*
* @return string
*/
public function putFile($export) {
$fileName = CRM_Core_Config::singleton()->uploadDir . 'Financial_Transactions_APEntries_' . date('YmdHis') . '.' . $this->getFileExtension();
$out = fopen($fileName, 'w');
foreach ($export as $batchID => $entries) {
$content = sprintf('Batch ID - %d: %s', $batchID, var_export($entries, TRUE));
file_put_contents($fileName, $content, FILE_APPEND);
}
fclose($out);
return $fileName;
}
/**
* @return void
*/
public function getFileExtension() {
return 'txt';
}
}
......@@ -10,6 +10,8 @@ use Intacct\Functions\Common\Query\QueryString;
use Intacct\Functions\Traits\CustomFieldsTrait;
use Intacct\Functions\GeneralLedger\JournalEntryCreate;
use Intacct\Functions\GeneralLedger\JournalEntryLineCreate;
use Intacct\Functions\AccountsPayable\BillCreate;
use Intacct\Functions\AccountsPayable\BillLineCreate;
use Intacct\Functions\GeneralLedger\CustomAllocationSplit;
use Intacct\Functions\GeneralLedger\AccountCreate;
use Intacct\Exception\ResponseException;
......@@ -107,6 +109,31 @@ class CRM_Syncintacct_API {
return $this->sendRequest($journalEntry);
}
public function createAPBatch($APBatch) {
$billEntry = new BillCreate();
$billEntry->setVendorId($APBatch['VENDORID']);
$billEntry->setTransactionDate($APBatch['TRXN_DATE']);
$billEntry->setDescription($APBatch['DESCRIPTION']);
$billEntry->setLines($APBatch['ENTRIES']);
$billEntry->setDueDate($APBatch['DUE_DATE']);
$billEntry->setTransactionCurrency($APBatch['CURRENCY']);
$billEntry->getBaseCurrency('USD');
return $this->sendRequest($billEntry);
}
public function createAPEntry($entry) {
$billLineEntry = new BillLineCreate();
$billLineEntry->setGlAccountNumber($entry['ACCOUNTNO']);
$billLineEntry->setTransactionAmount($entry['AMOUNT']);
// @TODO this is a dummy active location id passed
$billLineEntry->setLocationId('Elim');
// TODO: BillLineCreate does not support adding custom fields yet
// $customFields = new CustomAllocationSplit($entry['customfields']);
// $billLineEntry->setCustomAllocationSplits($customFields);
return $billLineEntry;
}
/**
* Function to fetch vendors
*/
......
......@@ -21,7 +21,8 @@ class CRM_Syncintacct_Util {
return $dao->N;
}
public static function fetchTransactionrecords($batchID, $entityType) {
public static function createEntries($batchID, $entityType) {
$entityTable = ($entityType == 'GL') ? 'civicrm_contribution' : 'civicrm_grant';
$sql = "SELECT
ft.id as financial_trxn_id,
ft.trxn_date,
......@@ -51,14 +52,15 @@ class CRM_Syncintacct_Util {
fac.accounting_code AS from_credit_account,
fac.name AS from_credit_account_name,
fi.description AS item_description,
fi.id AS financial_item_id
fi.id AS financial_item_id,
eftc.entity_id AS entity_id
FROM civicrm_entity_batch eb
LEFT JOIN civicrm_financial_trxn ft ON (eb.entity_id = ft.id AND eb.entity_table = 'civicrm_financial_trxn')
LEFT JOIN civicrm_financial_account fa_to ON fa_to.id = ft.to_financial_account_id
LEFT JOIN civicrm_financial_account fa_from ON fa_from.id = ft.from_financial_account_id
LEFT JOIN civicrm_option_group cog ON cog.name = 'payment_instrument'
LEFT JOIN civicrm_option_value cov ON (cov.value = ft.payment_instrument_id AND cov.option_group_id = cog.id)
LEFT JOIN civicrm_entity_financial_trxn eftc ON (eftc.financial_trxn_id = ft.id AND eftc.entity_table = '{$entityType}')
LEFT JOIN civicrm_entity_financial_trxn eftc ON (eftc.financial_trxn_id = ft.id AND eftc.entity_table = '{$entityTable}')
LEFT JOIN civicrm_contribution c ON c.id = eftc.entity_id
LEFT JOIN civicrm_contact cc ON cc.id = c.contact_id
LEFT JOIN civicrm_option_group cog_status ON cog_status.name = 'contribution_status'
......@@ -73,6 +75,15 @@ class CRM_Syncintacct_Util {
$params = array(1 => array($batchID, 'Integer'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
if ($entityType == 'AP') {
return self::createAPEntries(self::formatAPBatchParams($dao, $batchID));
}
else {
return self::createGLEntries(self::formatGLBatchParams($dao, $batchID));
}
}
public static function formatGLBatchParams($dao, $batchID) {
$batch = civicrm_api3('Batch', 'getsingle', ['id' => $batchID]);
$GLBatch = [
'JOURNAL' => 'CIVIBATCH' . $batchID,
......@@ -91,6 +102,7 @@ class CRM_Syncintacct_Util {
'batch_id' => $batchID,
'financial_trxn_id' => $dao->financial_trxn_id,
'financial_item_id' => $dao->financial_item_id,
'url' => CRM_Utils_System::url('civicrm/contact/view/contribution', "reset=1&id={$dao->entity_id}&cid={$dao->contact_id}&action=view"),
]
];
$GLBatch['ENTRIES'][] = [
......@@ -103,16 +115,85 @@ class CRM_Syncintacct_Util {
'batch_id' => $batchID,
'financial_trxn_id' => $dao->financial_trxn_id,
'financial_item_id' => $dao->financial_item_id,
]
'url' => CRM_Utils_System::url('civicrm/contact/view/contribution', "reset=1&id={$dao->entity_id}&cid={$dao->contact_id}&action=view"),
],
];
}
return $GLBatch;
}
public static function formatAPBatchParams($dao, $batchID) {
$APBatch = [];
while ($dao->fetch()) {
$APBatch[$dao->entity_id] = [
'CURRENCY' => $dao->currency,
'VENDORID' => $dao->display_name,
'DESCRIPTION' => $dao->item_description,
'TRXN_DATE' => new DateTime($dao->trxn_date),
'DUE_DATE' => new DateTime(date('Ymd')),
'ENTRIES' => [],
];
$APBatch[$dao->entity_id]['ENTRIES'][] = [
'ACCOUNTNO' => $dao->credit_account ?: $dao->from_credit_account,
'AMOUNT' => -$dao->debit_total_amount,
'customfields' => [
'batch_id' => $batchID,
'financial_trxn_id' => $dao->financial_trxn_id,
'financial_item_id' => $dao->financial_item_id,
'url' => CRM_Utils_System::url('civicrm/contact/view/grant', "reset=1&id={$dao->entity_id}&cid={$dao->contact_id}&action=view"),
]
];
$APBatch[$dao->entity_id]['ENTRIES'][] = [
'ACCOUNTNO' => $dao->to_account_code,
'AMOUNT' => $dao->debit_total_amount,
'DESCRIPTION' => $dao->item_description,
'customfields' => [
'batch_id' => $batchID,
'financial_trxn_id' => $dao->financial_trxn_id,
'financial_item_id' => $dao->financial_item_id,
'url' => CRM_Utils_System::url('civicrm/contact/view/grant', "reset=1&id={$dao->entity_id}&cid={$dao->contact_id}&action=view"),
],
];
}
return $APBatch;
}
public static function createAPEntries($batchEntries) {
$syncIntacctConfig = CRM_Syncintacct_API::singleton();
$fetchVendors = $syncIntacctConfig->getVendors(array_unique(CRM_Utils_Array::collect('VENDORID', $batchEntries)));
$displayNames = [];
$result = '';
foreach ($fetchVendors as $vendor) {
$key = (string) $vendor->NAME;
$displayNames[$key] = (string) $vendor->VENDORID;
}
foreach ($batchEntries as $trxnID => &$entry) {
$vendorID = CRM_Utils_Array::value($entry['VENDORID'], $displayNames);
if (strstr($vendorID, 'VEN-')) {
$entry['VENDORID'] = $vendorID;
}
else {
$result = $syncIntacctConfig->createVendors($entry['VENDORID']);
if (!empty($result[0])) {
$entry['VENDORID'] = (string) $result[0]->VENDORID;
}
}
foreach ($entry['ENTRIES'] as $key => $trxn) {
$entry['ENTRIES'][$key] = $syncIntacctConfig->createAPEntry($trxn);
}
$response['Trxn ID -' . $trxnID] = $syncIntacctConfig->createAPBatch($entry);
}
CRM_Core_Error::debug_var('a', $response);
return $response;
}
public static function createGLEntries($batchEntries) {
$fetchVendors = CRM_Syncintacct_API::singleton()
->getVendors(array_unique(CRM_Utils_Array::collect('VENDORID', $batchEntries['ENTRIES'])));
$syncIntacctConfig = CRM_Syncintacct_API::singleton();
$fetchVendors = $syncIntacctConfig->getVendors(array_unique(CRM_Utils_Array::collect('VENDORID', $batchEntries['ENTRIES'])));
$displayNames = [];
$result = '';
......@@ -127,15 +208,15 @@ class CRM_Syncintacct_Util {
$entry['VENDORID'] = $vendorID;
}
else {
$result = CRM_Syncintacct_API::singleton()->createVendors($entry['VENDORID']);
$result = $syncIntacctConfig->createVendors($entry['VENDORID']);
if (!empty($result[0])) {
$batchEntries['ENTRIES'][$key]['VENDORID'] = (string) $result[0]->VENDORID;
}
}
$batchEntries['ENTRIES'][$key] = CRM_Syncintacct_API::singleton()->createGLEntry($entry);
$batchEntries['ENTRIES'][$key] = $syncIntacctConfig->createGLEntry($entry);
}
return CRM_Syncintacct_API::singleton()->createGLBatch($batchEntries);
return $syncIntacctConfig->createGLBatch($batchEntries);
}
public static function processSyncIntacctResponse($batchID, $response) {
......
......@@ -39,10 +39,7 @@ function civicrm_api3_intacct_SyncFinancialAccount($params) {
function civicrm_api3_intacct_processBatchSyncToIntacct($params) {
$dao = CRM_Core_DAO::executeQuery('SELECT * FROM civicrm_intacct_batches ORDER BY id ASC');
while($dao->fetch()) {
$entityTable = ($dao->mode == 'GL') ? 'civicrm_contribution' : 'civicrm_grant';
$batchEntries = CRM_Syncintacct_Util::fetchTransactionrecords($dao->batch_id, $entityTable);
$response = CRM_Syncintacct_Util::createGLEntries($batchEntries);
CRM_Core_Error::Debug_var('res', $response);
$response = CRM_Syncintacct_Util::createEntries($dao->batch_id, $dao->mode);
CRM_Syncintacct_Util::processSyncIntacctResponse($dao->batch_id, $response);
}
......
<?php
/**
* Job.ProcessBatchSyncToIntacct API
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_job_ProcessBatchSyncToIntacct($params) {
$dao = CRM_Core_DAO::executeQuery('SELECT * FROM civicrm_intacct_batches ORDER BY id ASC');
while($dao->fetch()) {
$entityTable = ($dao->mode == 'GL') ? 'civicrm_contribution' : 'civicrm_grant';
$batchEntries = CRM_Syncintacct_Util::fetchTransactionrecords($dao->batch_id, $entityTable);
CRM_Syncintacct_Util::createGLEntries($batchEntries);
}
}
......@@ -83,10 +83,12 @@ function syncintacct_civicrm_buildForm($formName, &$form) {
'SyncIntacctGL' => ts('Sync to Sage Intacct G/L'),
);
$form->addRadio('export_format', NULL, $optionTypes, NULL, '<br/>', TRUE);
if (!empty($_GET['export_format'])) {
$exportOption = CRM_Utils_Array::value('export_format', $_GET, $form->getVar('export-format'));
if ($exportOption) {
$form->setVar('export-format', $exportOption);
CRM_Core_Resources::singleton()->addScript(
"CRM.$(function($) {
$('input[name=\"export_format\"]').filter('[value=" . $_GET['export_format'] . "]').prop('checked', true);
$('input[name=\"export_format\"]').filter('[value={$exportOption}]').prop('checked', true);
});"
);
}
......@@ -101,6 +103,7 @@ function syncintacct_civicrm_validateForm($formName, &$fields, &$files, &$form,
];
if (in_array($fields['export_format'], array_keys($exporters))) {
$batchIds = (array) $form->getVar('_batchIds');
$form->setVar('export-format', $fields['export_format']);
$grantBatches = CRM_Syncintacct_Util::batchesByEntityTable($batchIds, 'civicrm_grant');
$contributionBatches = CRM_Syncintacct_Util::batchesByEntityTable($batchIds, 'civicrm_contribution');
if ($grantBatches == 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment