Files
crm.clientright.ru/modules/SPCMLConnector/SalesOrderController.php

351 lines
13 KiB
PHP
Raw Normal View History

<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: SalesPlatform Ltd
* The Initial Developer of the Original Code is SalesPlatform Ltd.
* All Rights Reserved.
* If you have any questions or comments, please email: devel@salesplatform.ru
************************************************************************************/
require_once "modules/SPCMLConnector/OperationController.php";
require_once "modules/SPCMLConnector/ProductsController.php";
require_once "modules/SPCMLConnector/ServicesController.php";
require_once "modules/SPCMLConnector/AccountsController.php";
/**
* Describes create/update and xml upload operations by CmlSalesOrder inventory.
*/
class SalesOrderController extends OperationController {
private $productsController;
private $servicesController;
protected $accountController; //need acces in childs - to redefine account in order
/**
* CmlSalesorder object which need to be saved.
* @var CmlSalesOrder
*/
protected $cmlSalesOrder;
public function __construct($assignedUserName) {
parent::__construct($assignedUserName);
$this->productsController = new ProductsController($assignedUserName);
$this->servicesController = new ServicesController($assignedUserName);
$this->accountController = new AccountsController($assignedUserName);
}
/**
* Return reference of products module.
* @return int
*/
private function getProductsPrefix() {
$result = $this->describe("Products");
return $result['idPrefix'];
}
/**
* Generate REST description of inventories by $cmlSalesOrder
* @return array
*/
private function generateInventoriesRest() {
$inventoriesRest = array();
foreach($this->cmlSalesOrder->getProducts() as $cmlProduct) {
$productRest = $this->productsController->getSalesOrderInventoryRest($cmlProduct);
$inventoriesRest['LineItems'][] = $productRest;
}
foreach($this->cmlSalesOrder->getServices() as $cmlService) {
$serviceRest = $this->servicesController->getSalesOrderInventoryRest($cmlService);
$inventoriesRest['LineItems'][] = $serviceRest;
}
$inventoriesRest['productid'] = $this->getProductsPrefix(); //vtiger 6 need it param
return $inventoriesRest;
}
/**
* Generates REST description of account in order.
* @return array
*/
private function generateAccountRest() {
$cmlAccount = $this->cmlSalesOrder->getAccount();
return $this->accountController->getSalesOrderAccountRest($cmlAccount);
}
/**
* Return REST description of currency and tax type (individual)
* @return array
*/
private function generateTaxRest() {
$currencyCode = $this->cmlSalesOrder->getCurrency();
$currencyReference = $this->getCurrencyReference($currencyCode);
$restData = array();
$restData['currency_id'] = $currencyReference;
$restData['hdnTaxType'] = 'individual';
return $restData;
}
/**
* Add inventories REST to order
* @param array $order
* @param array $inventories
* @return array
*/
private function joinInventoriesToOrder($order, $inventories) {
return array_merge($order, $inventories);
}
/**
* Updates exists record from 1C information.
* @param cmlSalesOrder $cmlSalesOrder
* @param String $reference
*/
private function updateOrder($reference) {
$restData = $this->buildSalesOrderRest();
$this->update($restData, $reference);
}
/**
* Return reference on order specified to 1C.
* @param cmlSalesorder $cmlSalesOrder
*/
protected function getReference() {
$number = $this->cmlSalesOrder->getNumber();
$result = $this->query("select id from SalesOrder where salesorder_no = '$number';");
return $this->getFirstReference($result);
}
/**
* Return basic SalesOrder REST array, specified for controller type (here it 1C)
* @return array
*/
protected function getBasicRest() {
$restData['one_s_id'] = $this->cmlSalesOrder->getOneEsId();
return $restData;
}
/**
* Return REST description of sostatus and invoicestatus
* @return array
*/
protected function generateStatuses() {
$restData = array();
if($this->cmlSalesOrder->getPropValue("Номер оплаты по 1С") != null) {
$restData['invoicestatus'] = 'Paid';
} else {
$restData['invoicestatus'] = 'AutoCreated';
}
/* One Es generate values as strings true or false */
if($this->cmlSalesOrder->getPropValue("Проведен") === 'true') {
$restData['sostatus'] = 'Delivered';
} elseif($this->cmlSalesOrder->getPropValue("ПометкаУдаления") === 'true') {
$restData['sostatus'] = 'Cancelled';
} else {
$restData['sostatus'] = 'Created';
}
return $restData;
}
/**
* Return REST to save salesOrder by information from one es.
* @param cmlSalesorder $cmlSalesOrder
*/
protected function buildSalesOrderRest() {
$orderBasic = $this->getBasicRest();
$statuses = $this->generateStatuses();
$account = $this->generateAccountRest();
$taxes = $this->generateTaxRest();
$orederRest = array_merge($statuses, $account, $taxes, $orderBasic);
/* Add to order REST inventories to save, and return REST description */
$inventories = $this->generateInventoriesRest();
return $this->joinInventoriesToOrder($orederRest, $inventories);
}
/**
* Filter SalesOrders which will be uploaded.
* @param String $beginTime
* @return array
*/
protected function getSalesOrdersToUpload($beginTime) {
$salesOrdersResult = $this->query("select id from SalesOrder where modifiedtime > '$beginTime';");
$salesOrders = array();
foreach($salesOrdersResult as $resultLine) {
$salesOrders[] = $this->retrieve($resultLine['id']);
}
return $salesOrders;
}
/**
* Save SalesOrder by 1C information.
* @param CmlSalesOrder $cmlSalesOrder
*/
public function saveOrder($cmlSalesOrder) {
$this->cmlSalesOrder = $cmlSalesOrder;
$reference = $this->getReference();
/* Only update exists SalesOrder from 1C - never create new */
if($reference != null) {
$this->updateOrder($reference);
}
}
/**
* Return xml description of all orders, which modified after $beginTime.
* @param String $beginTime - date after which SalesOrder search. Need Mysql DateTime format.
*/
public function getXmlOrders($beginTime) {
if($beginTime == null) {
$beginTime = date("Y-m-d H:i:s", 0); //if no time - upload all salesOrders
}
$salesOrders = $this->getSalesOrdersToUpload($beginTime);
$commerceData = $this->getCommerceHeader();
foreach($salesOrders as $order) {
$this->addSalesOrder($commerceData, $order);
}
return $commerceData->asXML();
}
/**
* Add currency code to document by refernece.
* @param SimpleXmlElement $document
* @param array $salesOrderRest
* @return String
*/
private function addXmlCurrencyCode($document, $salesOrderRest) {
$currencyReference = $salesOrderRest['currency_id'];
$currencyCode = $this->getCurrencyCode($currencyReference);
$document->addChild("Валюта", $currencyCode);
}
/**
* Add to order account information. Billing and shipping addresses add from
* salesOrder REST data - because in account can be empty fileds.
* @param SimpleXmlElement $document
* @param array $salesOrderRest
*/
protected function addXmlAccount($document, $salesOrderRest) {
$accountReference = $salesOrderRest['account_id'];
$account = $this->accountController->getXmlBaseAccount($accountReference);
$accounts = $document->addChild("Контрагенты");
$this->appendXmlElement($accounts, $account);
}
/**
*
* @param SimpleXmlElement $document
* @param array $salesOrderRest
*/
private function addXmlOrderInventories($document, $salesOrderRest) {
$inventoriesContainer = $document->addChild("Товары");
foreach($salesOrderRest['LineItems'] as $inventory) {
$this->addXmlInventory($inventoriesContainer, $inventory);
}
}
/**
* Add inventory to inventories tag container.
* @param SimpleXmlElement $inventoriesContainer
* @param array $inventory
*/
private function addXmlInventory($inventoriesContainer, $inventory) {
$inventoryId = $this->trimReference($inventory['productid']);
$inventoryXml = $this->productsController->getCatalogXmlInventoryById($inventoryId);
if($inventoryXml == null) {
$inventoryXml = $this->servicesController->getCatalogXmlInventoryById($inventoryId);
}
/* In CRM may be deleted inventories from CRM, but not deleted from order. */
if($inventoryXml == null) {
return;
}
/* Common fields of products and services on SalesOrder */
$inventoryXml->addChild("ЦенаЗаЕдиницу", $inventory['listprice']);
$inventoryXml->addChild("Количество", $inventory['quantity']);
$inventoryXml->addChild("Сумма", $inventory['quantity'] * $inventory['listprice']);
$this->appendXmlElement($inventoriesContainer, $inventoryXml);
}
/**
* Add order identificator to order.
* @param SimpleXmlElement $order
* @param array $salesOrderRest
*/
protected function addXmlOrderIdentificator($order, $salesOrderRest) {
if($salesOrderRest['one_s_id']!=null){
$order->addChild("Ид", $salesOrderRest['one_s_id']);
} else {
$order->addChild("Ид", $salesOrderRest['salesorder_no']);
}
}
/**
* Add props to document by information from REST description.
* @param SimpleXmlElement $document
* @param array $salesOrderRest
*/
protected function addOrderProps($document, $salesOrderRest) {
$documentProps = $document->addChild("ЗначенияРеквизитов");
$documentProp = $documentProps->addChild("ЗначениеРеквизита");
$documentProp->addChild("Наименование", "НомерНаСайте");
$documentProp->addChild("Значение", $salesOrderRest['salesorder_no']);
$documentProp = $documentProps->addChild("ЗначениеРеквизита");
$documentProp->addChild("Наименование", "ДатаНаСайте");
$documentProp->addChild("Значение", strstr($salesOrderRest['createdtime'], " ", true));
$documentProp = $documentProps->addChild("ЗначениеРеквизита");
$documentProp->addChild("Наименование", "Статус заказа");
$documentProp->addChild("Значение", $salesOrderRest['sostatus']);
}
/**
* Add to documrnt it number, specified for order - from one es or from website.
* @param SimpleXmlElement $document
* @param array $salesOrderRest
*/
protected function addXmlOrderNumber($document, $salesOrderRest) {
$document->addChild("Номер",$salesOrderRest['salesorder_no']);
}
/**
* Add to xml order description base order information.
* @param SimpleXmlElement $document
* @param array $salesOrderRest
*/
private function addXmlOrderHeader($document, $salesOrderRest) {
$this->addXmlOrderNumber($document, $salesOrderRest);
$document->addChild("Дата", strstr($salesOrderRest['createdtime'], " ", true));
$document->addChild("ХозОперация", "Заказ товара");
$document->addChild("Роль", "Продавец");
$document->addChild("Время", substr($salesOrderRest['createdtime'],
strpos($salesOrderRest['createdtime'], " ") + 1) );
}
/**
* Add to commerceData salesOrder.
* @param SimpleXmlElement $commerceData
* @param array $salesOrderRest
*/
private function addSalesOrder($commerceData, $salesOrderRest) {
$document = $commerceData->addChild("Документ");
$this->addXmlOrderHeader($document, $salesOrderRest);
$this->addXmlOrderIdentificator($document, $salesOrderRest);
$this->addXmlCurrencyCode($document, $salesOrderRest);
$this->addXmlAccount($document, $salesOrderRest);
$this->addXmlOrderInventories($document, $salesOrderRest);
$this->addOrderProps($document, $salesOrderRest);
}
}