Документы. Вывод нового документа на печать

Добрый день.
Необходимо в личном кабинете покупателя, на странице с деталями сформированного ранее заказа, рядом со ссылкой “распечатать счет” сделать еще одну ссылку “распечатать другой документ”. В моем случае надо выводить “ведомость материалов”. Подскажите, как это сделать.

Что уже сделал.

  1. Создал новый документ в админке в разделе Уведомления->Документы. Выгрузил xml с шаблоном Счет (order.invoice), изменил <code>, загрузил обратно. Создался новый документ Ведомость материалов (order.listofmaterials). Отредактировал содержимое документа, получил нужный вид, теперь надо сделать, чтобы этот документ появился на странице уже созданного заказа.

  2. Создал свой модуль. В файле /app/addons/vr_listofmaterials/init.php прописал:

<?php
if (!defined('BOOTSTRAP')) { die('Access denied'); }
fn_register_hooks(
    'details_tools'
);

В файле /design/themes/responsive/templates/addons/vr_listofmaterials/hooks/orders/details_tools.post.tpl прописал следующее (скопировал то, что было в файле /design/themes/responsive/templates/views/orders/details.tpl после {hook name=“orders:details_tools”})

{$print_order = __("template_document_order_listofmaterials")}
                        {if $status_settings.appearance_type == "C" && $order_info.doc_ids[$status_settings.appearance_type]}
                            {$print_order = __("print_credit_memo")}
                        {elseif $status_settings.appearance_type == "O"}
                            {$print_order = __("print_order_details")}
                        {/if}
                        {include file="buttons/button.tpl" but_role="text" but_text=$print_order but_href="orders.print_invoice?order_id=`$order_info.order_id`" but_meta="cm-new-window ty-btn__text" but_icon="ty-icon-print orders-print__icon"}

На странице с деталями заказа появилась новая ссылка:

По этой ссылке, конечно, пока открывается Счет (order.invoice). И ссылка у него получается такая:
/index.php?dispatch=orders.print_invoice&order_id=105

Меняю в этом же файле:
but_href="orders.print_invoice?order_id=$order_info.order_id"
на
but_href="orders.print_listofmaterials?order_id=$order_info.order_id"

Теперь ссылка получается такая:
/index.php?dispatch=orders.print_listofmaterials&order_id=105

Насколько я понимаю, теперь надо создать контроллер и mode для него? Подскажите, как это сделать? Как сделать, чтобы в итоге открывался новый документ “Ведомость материалов”?

Разобрался.
Создал файл /app/addons/vr_listofmaterials/controllers/frontend/orders.post.php

в него скопировал код из /app/controllers/frontend/orders.php и изменил $mode и название функции:

<?php
//
// Show invoice
//
if ($mode == 'invoice') {
    fn_add_breadcrumb(__('order') . ' #' . $_REQUEST['order_id'], "orders.details?order_id=$_REQUEST[order_id]");
    fn_add_breadcrumb(__('invoice'));

    Tygh::$app['view']->assign('order_info', fn_get_order_info($_REQUEST['order_id']));

} elseif ($mode === 'print_listofmaterials') {
    if (!empty($_REQUEST['order_id'])) {
        $print_params = [];
        if (fn_allowed_for('MULTIVENDOR')) {
            $print_params['use_i18n_company_fields'] = true;
        }
        $print_params = array_merge($_REQUEST, $print_params);
        echo(fn_print_order_listofmaterials($_REQUEST['order_id'], $print_params));
    }

    return [CONTROLLER_STATUS_NO_CONTENT];
}

Затем создал файл /app/addons/vr_listofmaterials/func.php
И в него скопировал функцию fn_print_order_invoices, изменив название функции на fn_print_order_listofmaterials. И изменил template_code - вместо invoice написал listofmaterials. Таким образом, теперь выводится созданный в самом начале документ.

<?php
use Tygh\Enum\ProductOptionsApplyOrder;
use Tygh\Enum\SiteArea;
use Tygh\Registry;
use Tygh\Tools\SecurityHelper;

if (!defined('BOOTSTRAP')) { die('Access denied'); }

function fn_print_order_listofmaterials($order_ids, $params = [])
{
    // Backward compatibility
    if (is_bool($params)) {
        // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
        $args = func_get_args();
        $params = [];

        /**
         * Executes when normalizing parameters for invoice printing, allows you to populate additional parameters.
         *
         * @param array<int, string|bool>    $args   Function arguments
         * @param array<string, string|bool> $params Normalized parameters
         */
        
        if (isset($args[2])) {
            $params['area'] = $args[2];
        }
        if (isset($args[3])) {
            $params['lang_code'] = $args[3];
        }
    }

    // Default params
    $params = array_merge(
        [
            'area'               => AREA,
            'lang_code'          => CART_LANGUAGE,
            'secondary_currency' => CART_SECONDARY_CURRENCY,
            'html_wrap'          => true,
            'add_page_break'     => true,
        ],
        $params
    );

    $order_ids = (array) $order_ids;

    /**
     * Executes before printing order invoices, allows you to modify parameters passed to the function.
     *
     * @param array<int>                 $order_ids Order IDs to print invoices for
     * @param array<string, string|bool> $params    Print parameters
     */
   

    $html = [];
    $data = [];

    $data['order_status_descr'] = fn_get_simple_statuses(STATUSES_ORDER, true, true, $params['lang_code']);
    $data['profile_fields'] = fn_get_profile_fields('I', [], $params['lang_code']);

    foreach ($order_ids as $order_id) {
        if (Registry::get('settings.Appearance.email_templates') === 'old') {
            $order_info = fn_get_order_info($order_id, false, true, false, false, $params['lang_code']);

            if (empty($order_info)) {
                continue;
            }

            if (!empty($order_info['notes'])) {
                $order_info['notes'] = SecurityHelper::sanitizeHtml($order_info['notes']);
            }
            if (!empty($order_info['details'])) {
                $order_info['details'] = SecurityHelper::sanitizeHtml($order_info['details']);
            }

            if (fn_allowed_for('MULTIVENDOR')) {
                $data['take_surcharge_from_vendor'] = fn_take_payment_surcharge_from_vendor($order_info['products']);
            }

            list($shipments) = fn_get_shipments_info(['order_id' => $order_info['order_id'], 'advanced_info' => true]);
            $use_shipments = !fn_one_full_shipped($shipments);

            $data['order_info'] = $order_info;
            $data['shipments'] = $shipments;
            $data['use_shipments'] = $use_shipments;
            $data['payment_method'] = fn_get_payment_data(
                !empty($order_info['payment_method']['payment_id']) ? $order_info['payment_method']['payment_id'] : 0,
                $order_info['order_id'],
                $params['lang_code']
            );
            $data['order_status'] = fn_get_status_data(
                $order_info['status'],
                STATUSES_ORDER,
                $order_info['order_id'],
                $params['lang_code'],
                $order_info['company_id']
            );
            $data['status_settings'] = fn_get_status_params($order_info['status']);

            if (fn_allowed_for('MULTIVENDOR') && SiteArea::isStorefront($params['area'])) {
                $data['company_data'] = fn_filter_company_data_by_profile_fields(
                    fn_get_company_placement_info($order_info['company_id'], $params['lang_code']),
                    [
                        'field_prefix' => 'company_',
                    ]
                );
            } else {
                $data['company_data'] = fn_get_company_placement_info($order_info['company_id'], $params['lang_code']);
            }

            /** @var \Tygh\SmartyEngine\Core $view */
            $view = Tygh::$app['view'];
            foreach ($data as $key => $value) {
                $view->assign($key, $value);
            }

            $template = $params['html_wrap'] ? 'orders/print_invoice.tpl' : 'orders/invoice.tpl';
            $html[] = $view->displayMail(
                $template,
                false,
                $params['area'],
                $order_info['company_id'],
                $params['lang_code']
            );
        } else {
            /** @var \Tygh\Template\Document\Order\Type $document_type */
            $document_type = Tygh::$app['template.document.order.type'];
            $template_code = isset($params['template_code']) ? $params['template_code'] : 'listofmaterials';

            $order_params = [];
            if (fn_allowed_for('MULTIVENDOR') && !empty($params['use_i18n_company_fields'])) {
                $order_params = [
                    'use_i18n_company_fields' => true
                ];
            }

            $template = $document_type->renderById(
                $order_id,
                $template_code,
                $params['lang_code'],
                $params['secondary_currency'],
                $params['area'],
                $order_params
            );

            if ($params['html_wrap']) {
                /** @var \Tygh\SmartyEngine\Core $view */
                $view = Tygh::$app['view'];
                $view->assign('content', $template);
                $template = $view->displayMail('common/wrap_document.tpl', false, 'A');
            }

            $html[] = $template;
        }

        if (
            !$params['add_page_break']
            || $order_id === end($order_ids)
        ) {
            continue;
        }

        $html[] = "<div style='page-break-before: always;'>&nbsp;</div>";
    }

    $output = implode(PHP_EOL, $html);

    /**
     * Executes after order invoices are generated, allows you to execute additional invoice data modifications.
     *
     * @param array<int>                 $order_ids Order IDs to print invoices for
     * @param array<string, string|bool> $params    Print parameters
     * @param array<string>              $html      Invoice HTML
     * @param string                     $output    Generated invoices
     */
   

    return $output;
}

Решил не удалять пост.
Может, кому-нибудь пригодится.

5 лайков