/**
* Output the service XML
*
* Method will construct the XML string using the information stored in $this->xmlNode and return the XML string
*
* @access protected
* @param bool $isQuery TRUE if this service is a query, FALSE if not (add, mod, etc). Default is FALSE
* @return string The constructed XML string
*/
protected function buildOutput($isQuery = false)
{
/**
* Add the replacement for the client's qbXML version
*/
$clientVersion = $this->quickbooks->getAccountingSessionKey('QBXML_VERSION');
$clientCountry = $this->quickbooks->getAccountingSessionKey('CLIENT_COUNTRY');
/**
* If this version 2-3 and where are UK/CA then we need to prepend the country code in the version
*/
if ((isc_strtolower($clientCountry) == "uk" || isc_strtolower($clientCountry) == "ca") && version_compare($clientVersion, "3.0") !== 1) {
$version = isc_strtoupper($clientCountry) . (string) $clientVersion;
} else {
$version = (string) $clientVersion;
}
$GLOBALS['VersionNo'] = $version;
$GLOBALS['EntityType'] = $this->data->service;
$GLOBALS['EntityXML'] = $this->xmlNode->outputMemory(true);
$xml = $this->quickbooks->ParseTemplate('module.quickbooks.qbxml', true);
/**
* If this is a query then remove the <$this->data->service> tags. Why can't everything be the same
*/
if ($isQuery) {
$xml = str_replace('<' . $this->data->service . '>', '', $xml);
$xml = str_replace('</' . $this->data->service . '>', '', $xml);
}
return $xml;
}
/**
* Include the form field code file
*
* Method will include (once) the form field code file
*
* @access private
* @param string $fieldType The field type to include
* @return string The class name of the field class if the code source file was found and
* included successfully, FALSE if not
*/
private function includeFormFieldCode($fieldType)
{
$typeToLower = isc_strtolower($fieldType);
if ($typeToLower == '' || $typeToLower == 'base' || preg_match('/[^a-z]+/', $typeToLower)) {
return false;
}
$filepath = $this->fieldPath . '/formfield.' . $typeToLower . '.php';
if (!file_exists($filepath) || !is_file($filepath)) {
return false;
}
$className = "ISC_FORMFIELD_" . isc_strtoupper($fieldType);
if (!class_exists($className)) {
include_once $filepath;
}
return $className;
}
/**
* Validates the posted form data
*
* @param int $templateid The template used when checking for existing template name
*/
private function ValidateInput($templateid = 0)
{
// check for template name
if (!isset($_POST["templateName"]) || !trim($_POST["templateName"])) {
throw new Exception(GetLang("NoTemplateName"));
} else {
$templatename = trim($_POST["templateName"]);
// check for existing template
$query = "SELECT * FROM [|PREFIX|]import_templates WHERE UCASE(importtemplatename) = '" . $GLOBALS['ISC_CLASS_DB']->Quote(isc_strtoupper($templatename)) . "'";
if ($templateid) {
$query .= " AND importtemplateid != '" . $GLOBALS['ISC_CLASS_DB']->Quote($templateid) . "'";
}
$vendorid = $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId();
$query .= " AND vendorid = '" . $GLOBALS['ISC_CLASS_DB']->Quote($vendorid) . "'";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
if ($GLOBALS['ISC_CLASS_DB']->CountResult($result)) {
throw new Exception(sprintf(GetLang("TemplateAlreadyExists"), $templatename));
}
}
}
public function convert_accounting_spool()
{
$query = "ALTER TABLE [|PREFIX|]accountingref MODIFY `accountingreftype` enum('customer','customergroup','product','order','salestaxcode','account','inventorylevel','orderlineitem') NOT NULL";
if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
return false;
}
if (!$this->TableExists('accountingspool')) {
$query = "\n\t\t\t\tCREATE TABLE `[|PREFIX|]accountingspool` (\n\t\t\t\t `accountingspoolid` int(10) unsigned NOT NULL auto_increment,\n\t\t\t\t `accountingspoolparentid` int(10) unsigned NOT NULL default '0',\n\t\t\t\t `accountingspoolmoduleid` varchar(100) NOT NULL default '',\n\t\t\t\t `accountingspoolnodeid` int(10) unsigned NOT NULL default '0',\n\t\t\t\t `accountingspoolserial` text,\n\t\t\t\t `accountingspooltype` enum('customer','customergroup','product','order','salestaxcode','account','inventorylevel') NOT NULL,\n\t\t\t\t `accountingspoolservice` enum('add','edit','query') NOT NULL,\n\t\t\t\t `accountingspoollock` char(36) NOT NULL default '',\n\t\t\t\t `accountingspoolstatus` tinyint(1) default '0',\n\t\t\t\t `accountingspooldisabled` tinyint(1) NOT NULL default '0',\n\t\t\t\t `accountingspoolerrmsg` tinytext,\n\t\t\t\t `accountingspoolerrno` int(10) unsigned NOT NULL default '0',\n\t\t\t\t `accountingspoolreturn` text,\n\t\t\t\t PRIMARY KEY (`accountingspoolid`),\n\t\t\t\t KEY `i_accountingspool_accountingspoolparentid` (`accountingspoolparentid`),\n\t\t\t\t KEY `i_accountingspool_accountingspoolmoduleid` (`accountingspoolmoduleid`),\n\t\t\t\t KEY `i_accountingspool_accountingspoolnodeid` (`accountingspoolnodeid`),\n\t\t\t\t KEY `i_accountingspool_accountingspooltype` (`accountingspooltype`)\n\t\t\t\t) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
return false;
}
/**
* If this table already exists and it has records in it then DO NOT import the spool files as order will double up and could potentially duplciate
* products and customers
*/
} else {
$result = $GLOBALS['ISC_CLASS_DB']->Query("SELECT * FROM [|PREFIX|]accountingspool");
if ($result && $GLOBALS['ISC_CLASS_DB']->CountResult($result) > 0) {
return true;
}
}
/**
* Now convert the existsing spool files into database accountingspool records. Force out the mandatory account spools just in case
*/
$accounting = GetClass('ISC_ACCOUNTING');
$initdata = array(array('type' => 'account', 'service' => 'add', 'data' => array('Name' => GetLang('QuickBooksIncomeAccountName'), 'AccountType' => 'Income')), array('type' => 'account', 'service' => 'add', 'data' => array('Name' => GetLang('QuickBooksCOGSAccountName'), 'AccountType' => 'CostOfGoodsSold')), array('type' => 'account', 'service' => 'add', 'data' => array('Name' => GetLang('QuickBooksAssetAccountName'), 'AccountType' => 'FixedAsset')));
foreach ($initdata as $data) {
$accounting->createServiceRequest($data['type'], $data['service'], $data['data']);
}
/**
* Now for the rest. These will be in the spool cache file so you'll need to read the files from there
*/
$files = scandir(ISC_BASE_PATH . '/cache/spool');
foreach ($files as $file) {
$realfile = ISC_BASE_PATH . '/cache/spool/' . $file;
if (!is_file($realfile) || !is_readable($realfile) || substr($file, 0, 6) !== 'spool.') {
continue;
}
$spooldata = null;
@(include_once $realfile);
if (!is_array($spooldata)) {
continue;
}
/**
* Find out if this entity exists. If not then do not import it
*/
if (isId($spooldata['nodeid'])) {
$className = "ISC_ENTITY_" . isc_strtoupper($spooldata['type']);
$entity = new $className();
if (!$entity->exists($spooldata['nodeid'])) {
continue;
}
/**
* Save it using the data array instead of the nodeid as they might delete that entity before they import
*/
$savedata = $entity->get($spooldata['nodeid']);
if (!$savedata) {
continue;
}
} else {
continue;
}
switch (isc_strtolower($spooldata['type'])) {
case 'order':
/**
* We need to check if the customer and all of the products for this order still exist
*/
$query = "SELECT IF(EXISTS(SELECT * FROM [|PREFIX|]customers c WHERE o.ordcustid=c.customerid), 1, 0) AS CustomerExists,\n\t\t\t\t\t\t\t\t\t(SELECT COUNT(*) FROM [|PREFIX|]order_products op1 WHERE op1.orderorderid=o.orderid) AS TotalProducts,\n\t\t\t\t\t\t\t\t\t(SELECT COUNT(*) FROM [|PREFIX|]order_products op2 JOIN [|PREFIX|]products p ON op2.ordprodid=p.productid WHERE op2.orderorderid=o.orderid) AS ValidProducts\n\t\t\t\t\t\t\t\tFROM [|PREFIX|]orders o\n\t\t\t\t\t\t\t\tWHERE o.orderid=" . (int) $spooldata['nodeid'];
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
if (!$result) {
break;
}
$row = $GLOBALS['ISC_CLASS_DB']->Fetch($result);
if (!$row) {
break;
}
if (!$row['CustomerExists'] || $row['TotalProducts'] !== $row['ValidProducts']) {
break;
}
$accounting->createServiceRequest('order', 'add', $savedata, 'order_create');
break;
case 'product':
case 'customer':
case 'customergroup':
/**
* Find out if this is an add or mod. If query then skip
*/
if (substr(isc_strtolower($spooldata['service']), -3) == 'add') {
$permission = 'create';
$service = 'add';
} else {
if (substr(isc_strtolower($spooldata['service']), -3) == 'mod') {
$permission = 'edit';
$service = 'edit';
} else {
break;
}
}
//.........这里部分代码省略.........
/**
* Validates the posted form data
*
* @param int $templateid The template used when checking for existing template name
*/
private function ValidateInput($templateid = 0)
{
// check for template name
if (!isset($_POST["templateName"]) || !trim($_POST["templateName"])) {
throw new Exception(GetLang("NoTemplateName"));
} else {
$templatename = trim($_POST["templateName"]);
// check for existing template
$query = "SELECT * FROM [|PREFIX|]export_templates WHERE builtin = 0 AND UCASE(exporttemplatename) = '" . $GLOBALS['ISC_CLASS_DB']->Quote(isc_strtoupper($templatename)) . "'";
if ($templateid) {
$query .= " AND exporttemplateid != '" . $GLOBALS['ISC_CLASS_DB']->Quote($templateid) . "'";
}
$vendorid = $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId();
$query .= " AND vendorid = '" . $GLOBALS['ISC_CLASS_DB']->Quote($vendorid) . "'";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
if ($GLOBALS['ISC_CLASS_DB']->CountResult($result)) {
throw new Exception(sprintf(GetLang("TemplateAlreadyExists"), $templatename));
}
}
// ensure at least one file is selected
if (!isset($_POST["includeType"])) {
throw new Exception(GetLang("NoFilesSelected"));
}
// check for valid date format
if (!array_key_exists($_POST['dateFormat'], $this->GetDateFormats())) {
throw new Exception(GetLang("NoDateFormat"));
}
// check for valid price format
if (!array_key_exists($_POST['priceFormat'], $this->GetPriceFormats())) {
throw new Exception(GetLang("NoPriceFormat"));
}
// check for valid bool format
if (!array_key_exists($_POST['boolFormat'], $this->GetBoolFormats())) {
throw new Exception(GetLang("NoBoolFormat"));
}
// validate each type
foreach ($_POST['includeType'] as $type => $blah) {
// check that at least one field is checked for the type
if (!isset($_POST[$type . "Field"])) {
throw new Exception(sprintf(GetLang("NoFields"), $type));
}
// check that ticked fields have a header
$filetype = ISC_ADMIN_EXPORTFILETYPE_FACTORY::GetExportFileType($type);
$fields = $filetype->FlattenFields($filetype->LoadFields());
foreach ($_POST[$type . "Field"] as $field => $val) {
if (!isset($_POST[$type . "Header"][$field]) || !trim($_POST[$type . "Header"][$field])) {
throw new Exception(GetLang("FieldNoHeader") . '"' . $fields[$field]['label'] . '"');
}
}
}
}
/**
* Get the file path and the class name of a class file
*
* Method will return an array where "file" will be the file path and "name" will be the class name
*
* @access public
* @param string $type The class type ("classes", "handlers", "services" or "entities")
* @param string $class The class name (Not the full name)
* @param bool $includeParentBase TRUE to also find and include the base parent. Default is TRUE
* @return array An array with the class file path and full class name on success, NULL if no result, FALSE on error
*/
public function findModuleClass($type, $class, $includeParentBase=true)
{
if (trim($type) == '' || trim($class) == '') {
return false;
}
$filePathPrefix = dirname(__FILE__) . "/includes";
$classNamePrefix = "ACCOUNTING_QUICKBOOKS_";
switch (isc_strtolower($type)) {
case "classes":
$filePathPrefix .= "/classes/class.";
$classNamePrefix .= "CLASS_";
break;
case "handlers":
$filePathPrefix .= "/handlers/handler.";
$classNamePrefix .= "HANDLER_";
break;
case "services":
$filePathPrefix .= "/services/service.";
$classNamePrefix .= "SERVICE_";
break;
case "entities":
$filePathPrefix .= "/entities/entity.";
$classNamePrefix .= "ENTITY_";
break;
default:
return null;
}
$filePath = realpath($filePathPrefix . isc_strtolower($class) . ".php");
$className = $classNamePrefix . isc_strtoupper($class);
if ($filePath == '' || !file_exists($filePath)) {
$xargs = func_get_args();
$this->logError("Cannot find module class file", $xargs);
return null;
}
if ($includeParentBase) {
$basePath = realpath(realpath($filePathPrefix . "base.php"));
if ($basePath == '' || !file_exists($basePath)) {
$xargs = func_get_args();
$this->logError("Cannot find module base class file", $xargs);
return null;
} else {
@include_once($basePath);
}
}
return array("file" => $filePath, "class" => $className);
}
请发表评论