| Current Path : /var/www/homesaver/www/bitrix/classes/general/ |
| Current File : /var/www/homesaver/www/bitrix/classes/general/CMainOfdFerma.php |
<?php
CModule::IncludeModule(CMainOfdFerma::$MODULE_ID);
class CMainOfdFerma
{
public static $MODULE_ID = 'ofdferma';
/**
* @param \CAdminSaleList|\CAdminList $list
*/
public static function onAdminListDisplay($list)
{
/** @var \CMain $APPLICATION */
global $APPLICATION;
if ($APPLICATION->GetCurPage() === '/bitrix/admin/sale_order.php') {
$APPLICATION->AddHeadScript('/bitrix/js/ofdferma/ofdferma_receipts.js');
foreach ($list->aRows as $row) {
$actions = $row->aActions;
$newActions = [
[
'ICON' => 'edit',
'TEXT' => 'Сформировать чек прихода',
'ACTION' => 'window.ofdferma.openOrderReceiptPanel("' . $row->id . '");',
], [
'ICON' => 'edit',
'TEXT' => 'Сформировать чек возврата',
'ACTION' => 'window.ofdferma.openOrderRefundPanel("' . $row->id . '");',
],
];
array_splice($actions, -2, 0, $newActions);
$row->AddActions($actions);
}
}
}
public static function onAdminContextMenuShow(&$items)
{
/** @var \CMain $APPLICATION */
global $APPLICATION;
if ($APPLICATION->GetCurPage() === '/bitrix/admin/sale_order_view.php') {
$APPLICATION->AddHeadScript('/bitrix/js/ofdferma/ofdferma_receipts.js');
$orderId = (int)$_GET['ID'];
$newItems = [
[
'TEXT' => 'Сформировать чек',
'TITLE' => 'Сформировать чек прихода',
'MENU' => [
[
'TEXT' => 'Чек прихода',
'TITLE' => 'Сформировать чек прихода',
'ACTION' => 'window.ofdferma.openOrderReceiptPanel("' . $orderId . '");',
], [
'TEXT' => 'Чек возврата',
'TITLE' => 'Сформировать чек возврата',
'ACTION' => 'window.ofdferma.openOrderRefundPanel("' . $orderId . '");',
],
],
],
];
array_splice($items, -2, 0, $newItems);
}
}
public static function onSalePayOrder($orderId, $state)
{
$enabled = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_agent_auto_create', 'Y');
if ($enabled !== 'Y') {
return null;
}
if (empty($orderId)) {
CMainOfdFerma::log(
'Отправка фискального чека', null,
'Фискальный чек не отправлен, поскольку не указан номер заказа.', 'WARNING'
);
return null;
}
if ($state !== 'Y') {
return null;
}
$order = CSaleOrder::GetByID($orderId);
if (!$order) {
CMainOfdFerma::log(
'Отправка фискального чека', 'Заказ №' . $orderId,
'Фискальный чек не отправлен, поскольку заказ не найден в базе.', 'WARNING'
);
return null;
}
$user = CUser::GetByID($order['USER_ID'])->NavNext();
$items = [];
$itemsResult = CSaleBasket::GetList([], [
'ORDER_ID' => $orderId,
]);
while ($item = $itemsResult->NavNext()) {
$items[] = $item;
}
try {
$fermaApiClient = CMainOfdFerma::getApiClient();
} catch (\RuntimeException $e) {
CMainOfdFerma::log(
'Отправка фискального чека', 'Заказ №' . $orderId,
'Фискальный чек не отправлен, поскольку не указаны параметры подключения к ферме.', 'WARNING'
);
return null;
}
$receiptData = $fermaApiClient->prepareElectronReceipt('Income', $order, $items);
CAgent::AddAgent(
'CMainOfdFerma::sendReceiptAgent(' . json_encode($orderId) . ', "' . addslashes(json_encode($receiptData)) . '");',
CMainOfdFerma::$MODULE_ID,
'Y', 30
);
return true;
}
public static function onSalePayCancelOrder($orderId, $state)
{
$enabled = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_agent_auto_create', 'Y');
if ($enabled !== 'Y') {
return null;
}
if (empty($orderId)) {
CMainOfdFerma::log(
'Отправка фискального чека возврата', null,
'Фискальный чек возврата не отправлен, поскольку не указан номер заказа.', 'WARNING'
);
return null;
}
if ($state !== 'N') {
return null;
}
$order = CSaleOrder::GetByID($orderId);
if (!$order) {
CMainOfdFerma::log(
'Отправка фискального чека возврата', 'Заказ №' . $orderId,
'Фискальный чек возврата не отправлен, поскольку заказ не найден в базе.', 'WARNING'
);
return null;
}
$user = CUser::GetByID($order['USER_ID'])->NavNext();
$items = [];
$itemsResult = CSaleBasket::GetList([], [
'ORDER_ID' => $orderId,
]);
while ($item = $itemsResult->NavNext()) {
$items[] = $item;
}
try {
$fermaApiClient = CMainOfdFerma::getApiClient();
} catch (\RuntimeException $e) {
CMainOfdFerma::log(
'Отправка фискального чека возврата', 'Заказ №' . $orderId,
'Фискальный чек возврата не отправлен, поскольку не указаны параметры подключения к ферме.', 'WARNING'
);
return null;
}
$receiptData = $fermaApiClient->prepareElectronReceipt('IncomeReturn', $order, $items);
CAgent::AddAgent(
'CMainOfdFerma::sendReceiptAgent(' . json_encode($orderId) . ', "' . addslashes(json_encode($receiptData)) . '");',
CMainOfdFerma::$MODULE_ID,
'Y', 30
);
return true;
}
public static function sendReceiptAgent($orderId, $receiptData)
{
$receiptData = json_decode($receiptData, true);
try {
CMainOfdFerma::sendReceiptData($orderId, $receiptData);
} catch (\RuntimeException $e) {
CMainOfdFerma::log(
'Отправка фискального чека', 'Заказ №' . $orderId,
$e->getMessage(), 'WARNING'
);
// чек уже есть в базе
if ($e->getCode() === 1019) {
return false;
}
return 'CMainOfdFerma::sendReceiptAgent(' . json_encode($orderId) . ', "' . addslashes(json_encode($receiptData)) . '");';
}
CMainOfdFerma::log(
'Отправка фискального чека', 'Заказ №' . $orderId,
'Фискальный чек успешно отправлен в ферму.', 'INFO'
);
return false;
}
public static function checkReceiptStatusAgent($receiptId)
{
$receipt = COfdFermaReceipt::GetByID($receiptId);
if (empty($receipt)) {
CMainOfdFerma::log(
'Проверка фискального чека', 'Чек №' . $receiptId,
'Проверка фискального чека не удалась, поскольку чек не найден.', 'WARNING'
);
return false;
}
try {
$fermaApiClient = CMainOfdFerma::getApiClient();
} catch (\RuntimeException $e) {
CMainOfdFerma::log(
'Проверка фискального чека', 'Чек №' . $receiptId,
'Проверка фискального чека не удалась, поскольку не указаны параметры подключения к ферме.', 'WARNING'
);
return false;
}
try {
$response = $fermaApiClient->getElectronReceiptStatus($receipt['RECEIPT_ID']);
} catch (CFermaApiException $e) {
return 'CMainOfdFerma::checkReceiptStatusAgent(' . json_encode($receipt['ID']) . ');';
}
if ($response['Status'] === 'Failed') {
if (isset($response['Error']['Message'])) {
CMainOfdFerma::log(
'Проверка фискального чека', 'Чек №' . $receiptId,
sprintf('Проверка фискального чека не удалась: %s.', $response['Error']['Message']), 'WARNING'
);
} else {
CMainOfdFerma::log(
'Проверка фискального чека', 'Чек №' . $receiptId,
sprintf('Проверка фискального чека не удалась по неизвестной причине.'), 'WARNING'
);
}
return false;
}
$data = $response['Data'];
COfdFermaReceipt::Update($receipt['ID'], [
'STATUS_ID' => $data['StatusCode'],
'STATUS_NAME' => $data['StatusName'],
'STATUS_MESSAGE' => $data['StatusMessage'],
'DEVICE_ID' => $data['Device']['DeviceId'],
'RNM' => $data['Device']['RNM'],
'ZN' => $data['Device']['ZN'],
'FN' => $data['Device']['FN'],
'FDN' => $data['Device']['FDN'],
'FPD' => $data['Device']['FPD'],
]);
CMainOfdFerma::log(
'Проверка фискального чека', 'Чек №' . $receiptId,
'Статус фискального чека успешно проверен.', 'INFO'
);
if ($data['StatusCode'] < 2) {
return 'CMainOfdFerma::checkReceiptStatusAgent(' . json_encode($receipt['ID']) . ');';
}
// возвращаем false при успешной операции для того, чтобы агент не перезапускался
return false;
}
public static function sendReceiptData($orderId, $receiptData)
{
global $DB;
try {
$fermaApiClient = CMainOfdFerma::getApiClient();
} catch (\RuntimeException $e) {
throw new \RuntimeException('Фискальный чек не отправлен, поскольку не указаны параметры подключения к ферме.');
}
try {
$response = $fermaApiClient->sendElectronReceipt($receiptData);
} catch (CFermaApiException $e) {
throw new \RuntimeException(sprintf('Фискальный чек не отправлен: %s.', $e->getMessage()));
}
if (empty($response)) {
throw new \RuntimeException('Фискальный чек не отправлен, поскольку ферма вернула пустой результат.');
}
if ($response['Status'] === 'Failed') {
if (!isset($response['Error']['Message'])) {
throw new \RuntimeException('Фискальный чек не отправлен по неизвестной причине.');
}
throw new \RuntimeException(sprintf('Фискальный чек не отправлен: %s.', $response['Error']['Message']), $response['Error']['Code']);
}
$total = 0;
foreach ($receiptData['CustomerReceipt']['Items'] as $item) {
$total += $item['Amount'];
}
$id = COfdFermaReceipt::Add([
'SITE_ID' => SITE_ID,
'RECEIPT_ID' => $response['Data']['ReceiptId'],
'ORDER_ID' => $orderId,
'CONTENT' => json_encode($receiptData),
'TYPE' => $receiptData['Type'],
'TOTAL_PRICE' => $total,
'=DATE_CREATE' => $DB->GetNowFunction(),
'=DATE_UPDATE' => $DB->GetNowFunction(),
]);
CAgent::AddAgent(
'CMainOfdFerma::checkReceiptStatusAgent(' . json_encode($id) . ');',
CMainOfdFerma::$MODULE_ID,
'Y', 10
);
return true;
}
/**
* @var \CFermaApiService
*/
private static $client;
public static function getApiClient()
{
if (null === CMainOfdFerma::$client) {
$fermaApiHost = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_api_host', 'https://ferma.ofd.ru');
$fermaApiLogin = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_api_login');
$fermaApiPassword = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_api_password');
$agentInn = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_agent_inn');
$agentTaxation = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_agent_taxation_system');
$errorsEmail = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, CMainOfdFerma::$MODULE_ID . '_errors_email');
if (empty($fermaApiHost) || empty($fermaApiLogin) || empty($fermaApiPassword)
|| empty($agentInn) || empty($agentTaxation)) {
throw new \RuntimeException('Не указаны параметры подключения к ферме.');
}
CMainOfdFerma::$client = CFermaApiService::instance(
$fermaApiHost, $fermaApiLogin, $fermaApiPassword,
$agentInn, $agentTaxation, $errorsEmail
);
}
return CMainOfdFerma::$client;
}
public static function log($operation, $entity, $message, $level)
{
if (class_exists('CEventLog')) {
CEventLog::Add([
'SEVERITY' => $level,
'AUDIT_TYPE_ID' => $operation,
'MODULE_ID' => CMainOfdFerma::$MODULE_ID,
'ITEM_ID' => $entity,
'DESCRIPTION' => $message,
]);
}
}
}