Your IP : 216.73.216.86


Current Path : /var/www/homesaver/www/bitrix/classes/general/ferma-api/
Upload File :
Current File : /var/www/homesaver/www/bitrix/classes/general/ferma-api/CFermaApiService.php

<?php

class CFermaApiService
{
    /**
     * @var string
     */
    private $apiLogin;
    /**
     * @var string
     */
    private $apiPassword;
    /**
     * @var string
     */
    private $agentInn;
    /**
     * @var string
     */
    private $agentTaxation;
    /**
     * @var string
     */
    private $accessToken;
    /**
     * @var \CFermaApiClient
     */
    private $client;

    private static $instances = [];

    public function __construct(
        $apiHost,
        $apiLogin,
        $apiPassword,
        $agentInn,
        $agentTaxation,
        $errorsEmail,
        $timeout = 15
    ) {
        $this->apiLogin = $apiLogin;
        $this->apiPassword = $apiPassword;
        $this->agentInn = $agentInn;
        $this->agentTaxation = $agentTaxation;

        $this->client = CFermaApiClient::instance($apiHost, $errorsEmail, $timeout);
    }

    /**
     * @param string $apiHost
     * @param string $apiLogin
     * @param string $apiPassword
     * @param string $agentInn
     * @param string $agentTaxation
     * @param string $errorsEmail
     * @return CFermaApiClient
     */
    public static function instance($apiHost, $apiLogin, $apiPassword, $agentInn, $agentTaxation, $errorsEmail)
    {
        $hash = sha1($apiHost . '/' . $apiLogin . '/' . $apiPassword);

        if (!isset(static::$instances[$hash])) {
            static::$instances[$hash] = new static($apiHost, $apiLogin, $apiPassword, $agentInn, $agentTaxation, $errorsEmail);
        }

        return static::$instances[$hash];
    }

    public function getAccessToken()
    {
        if (null === $this->accessToken) {
            $this->renewAccessToken();
        }

        return $this->accessToken;
    }

    /**
     * @param string $receiptId
     * @return array
     * @throws \CFermaApiException
     */
    public function getElectronReceiptStatus($receiptId)
    {
        return $this->client->post('/api/kkt/cloud/status', ['Request' => ['ReceiptId' => $receiptId]], $this->getAccessToken());
    }

    /**
     * @param array $electronReceiptData
     * @return array
     * @throws \CFermaApiException
     */
    public function sendElectronReceipt($electronReceiptData)
    {
        return $this->client->post('/api/kkt/cloud/receipt', ['Request' => $electronReceiptData], $this->getAccessToken());
    }

    public function prepareElectronReceipt($type, $order, $basketItems)
    {
        list($email, $phone) = Ferma_getCustomerContacts($order['ID']);

        $deliveryInfo = Ferma_getDeliveryInfo($order);

        return $this->createElectronReceipt($type, $email, $phone, 0, $order['ID'], $order['DATE_PAYED'], $this->formatOrderItems($basketItems, $deliveryInfo));
    }

    public function createElectronReceipt(
        $type,
        $email,
        $phone,
        $paymentType,
        $orderId,
        $orderDate,
        $items
    ) {
        $invoiceId = $orderId . '/' . $type;

        $date = new \DateTime;

        if ($type === 'Income') {
            $date = new \DateTime(empty($orderDate) ? 'now' : $orderDate);
        }

        // unique invoice id
        /** @noinspection NonSecureUniqidUsageInspection */
        $invoiceId .= '/' . uniqid();

        return [
            'Inn' => $this->agentInn,
            'Type' => $type,
            'InvoiceId' => $invoiceId,
            'LocalDate' => $date->format('Y-m-d\TH:i:s'),
            'CustomerReceipt' => [
                'Email' => $email,
                'Phone' => $phone,
                'TaxationSystem' => $this->agentTaxation,
                'PaymentType' => $paymentType ? $paymentType : null,
                'Items' => array_values($items),
                'PaymentItems' => array_map(function ($item) {
                    return [
                        'PaymentType' => 1,
                        'Sum' => $item['Amount'],
                    ];
                }, $items),
            ],
        ];
    }

    private function formatOrderItems($basketItems, $deliveryInfo = null)
    {
        $result = [];

        $productsId = [];

        foreach ($basketItems as $item) {
            $productsId[$item['PRODUCT_ID']] = true;
        }

        if (empty($productsId)) {
            return $result;
        }

        $products = Ferma_getProducts(array_keys($productsId));
        $vats = Ferma_getVats();

        $defaultPaymentMethod = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, 'ofdferma_payment_default_method', '4');
        $defaultVat = COption::GetOptionString(CMainOfdFerma::$MODULE_ID, 'ofdferma_payment_default_vat', 'VatNo');

        foreach ($basketItems as $item) {
            $price = (float)$item['PRICE'];

            $vatId = $products[$item['PRODUCT_ID']]['VAT_ID'];

            $result[] = [
                'Label' => $item['NAME'],
                'Price' => $price,
                'Quantity' => $item['QUANTITY'],
                'Amount' => $price * $item['QUANTITY'],
                'Vat' => null === $vatId ? $defaultVat : CVatCollection::determinateVat($vats[$vatId]),
                'PaymentMethod' => $defaultPaymentMethod,
            ];
        }

        $deliveryReceipt = COption::GetOptionString('ofdferma', 'ofdferma_payment_delivery', 'Include');

        if ($deliveryReceipt === 'Include' && !empty($deliveryInfo) && !empty($deliveryInfo['PRICE'])) {
            $result[] = [
                // можно установить реальное имя доставки
                // 'Label' => $deliveryInfo['NAME'],
                'Label' => 'Доставка',
                'Price' => $deliveryInfo['PRICE'],
                'Quantity' => 1,
                'Amount' => $deliveryInfo['PRICE'],
                'Vat' => $defaultVat,
                'PaymentMethod' => $defaultPaymentMethod,
            ];
        }

        return $result;
    }

    private function renewAccessToken()
    {
        $response = $this->client->post('/api/Authorization/CreateAuthToken', [
            'Login' => $this->apiLogin,
            'Password' => $this->apiPassword,
        ]);

        if ($response['Status'] === 'Success') {
            $this->accessToken = $response['Data']['AuthToken'];
        } elseif ($response['Status'] === 'Failed' && isset($response['Error']['Message'])) {
            throw new CFermaApiException(sprintf('Api return failed response: %s.', $response['Error']['Message']));
        } else {
            throw new CFermaApiException('Api return invalid response.');
        }
    }
}

function Ferma_getProducts($productsId)
{
    $result = [];

    $products = CCatalogProduct::GetList([], ['ID' => $productsId]);

    while ($product = $products->NavNext()) {
        $result[$product['ID']] = $product;
    }

    return $result;
}

function Ferma_getVats()
{
    $result = [];

    $vats = CCatalogVat::GetList();

    while ($product = $vats->NavNext()) {
        $result[$product['ID']] = $product;
    }

    return $result;
}

function Ferma_getCustomerContacts($orderId)
{
    $email = null;
    $phone = null;

    $props = (new CSaleOrderPropsValue())->GetList([], [
        'ORDER_ID' => $orderId,
        'CODE' => ['EMAIL', 'PHONE'],
    ]);

    while ($item = $props->Fetch()) {
        if ($item['CODE'] === 'EMAIL') {
            $email = $item['VALUE'];
        }

        if ($item['CODE'] === 'PHONE') {
            $phone = $item['VALUE'];
        }
    }

    return [$email, $phone];
}

function Ferma_getDeliveryInfo($order)
{
    if (!empty($order['DELIVERY_ID']) && !empty($order['PRICE_DELIVERY']) && $order['PRICE_DELIVERY'] !== 0) {
        $delivery = CSaleDelivery::GetByID($order['DELIVERY_ID']);

        if ($delivery) {
            return [
                'NAME' => $delivery['NAME'],
                'PRICE' => $order['PRICE_DELIVERY'],
            ];
        }
    }

    return null;
}