Занялся Интернет-магазином на базе Woocommerce. Заказчик попросил добавить метод оплаты по счету для клиентов без привязки к какой-либо платежной системе. Поискав в сети обнаружил, что готового плагина для этих целей нет. Cоздавать свой плагин для этой цели нет ни возможности, ни бюджета. В данной статье мы воспользуемся 2 плагинами: WooCommerce PDF Invoices & Packing Slips для создания счёта на оплату и WooCommerce Invoice Gateway для добавления метода оплаты по счёту.
Итак, установим первый плагин и создадим форму счета. В нашем случае сумма будет без НДС, доставка не нужна, а реквизиты получателя мы впишем напрямую в форму. Для этого создаем каталог /woocommerce/pdf/MyInvoice в вашей (дочерней) теме. В эту папку копируем все файлы из папки /wp-content/plugins/woocommerce-pdf-invoices-packing-slips/templates/Simple. После этого в настройках плагина появится ваш шаблон.
Теперь счет формируется и формате PDF. Осталось добавить метод оплаты и при использовании метода выдавать ссылку на счет. Для этого устанавливаем второй плагин WooCommerce Invoice Gateway и настраиваем по моему подобию:
Название метода "Оплата по счету" мы в дальнейшем будем использовать как условие для отображение ссылки на счет.
Далее идем в functions.php вашей темы и добавляем такой код:
Итак, установим первый плагин и создадим форму счета. В нашем случае сумма будет без НДС, доставка не нужна, а реквизиты получателя мы впишем напрямую в форму. Для этого создаем каталог /woocommerce/pdf/MyInvoice в вашей (дочерней) теме. В эту папку копируем все файлы из папки /wp-content/plugins/woocommerce-pdf-invoices-packing-slips/templates/Simple. После этого в настройках плагина появится ваш шаблон.
Теперь переходим к файлу /wp-content/themes/ваша-тема/woocommerce/pdf/MyInvoice/invoice.php
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
<?php do_action( 'wpo_wcpdf_before_document', $this->type, $this->order ); ?>
<style>
body { margin-left: auto; margin-right: auto; border: 1px #efefef solid; font-size: 9pt;}
table.invoice_bank_rekv { border-collapse: collapse; border: 1px solid; }
table.invoice_bank_rekv > tbody > tr > td, table.invoice_bank_rekv > tr > td { border: 1px solid; }
table.invoice_items { border: 2px solid; border-collapse: collapse; margin-bottom: 8px; }
table.invoice_items td, table.invoice_items th { border: 1px solid; text-align: center;}
.woocommerce-Price-currencySymbol { display: none; }
.price { width: 10%;} .sum { width: 12%;}
.number { width: 5%;} .quantity, .value { width: 8%;}
</style>
<table>
<tr>
<td class="header">
</td>
<td class="shop-info">
<div class="shop-name"><h3><?php /* $this->shop_name(); */?></h3></div>
<div class="shop-address"><?php /* $this->shop_address(); */?></div>
</td>
</tr>
</table>
<h1 class="document-type-label">
<?php if( $this->has_header_logo() ) echo $this->get_title(); ?>
</h1>
<?php do_action( 'wpo_wcpdf_after_document_label', $this->type, $this->order ); ?>
<table width="100%" cellpadding="2" cellspacing="2" class="invoice_bank_rekv">
<tr>
<td colspan="2" rowspan="2" style="min-height:13mm;">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="height: 13mm;">
<tr>
<td valign="top">
<div>Тут название банка получателя</div>
</td>
</tr>
<tr>
<td valign="bottom" style="height: 3mm;">
<div>Банк получателя </div>
</td>
</tr>
</table>
</td>
<td style="min-height:7mm;height:auto; ">
<div>БИK</div>
</td>
<td rowspan="2" style="vertical-align: top; ">
<div style=" height: 7mm; line-height: 7mm; vertical-align: top;">045004774</div>
<div>тут номер счёта</div>
</td>
</tr>
<tr>
<td style="width: 25mm;">
<div>Сч. №</div>
</td>
</tr>
<tr>
<td style="min-height:6mm; height:auto; ">
<div>ИНН тут инн</div>
</td>БзкуЮ
<td style="min-height:6mm; height:auto;">
<div>КПП</div>
</td>
<td rowspan="2" style="min-height:19mm; height:auto; vertical-align: top;">
<div>Сч. №</div>
</td>
<td rowspan="2" style="min-height:19mm; height:auto; vertical-align: top;;">
<div>тут счет</div>
</td>
</tr>
<tr>
<td colspan="2" style="min-height:13mm; height:auto;">
<table border="0" cellpadding="0" cellspacing="0" style="height: 13mm;">
<tr>
<td valign="top">
<div>Тут наименование получателя</div>
</td>
</tr>
<tr>
<td valign="bottom" style="height: 3mm;">
<div style="font-size: 10pt;">Получатель</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<br/>
<div style="font-weight: bold; font-size: 16pt; padding: 5px 0 0 5px;">
Счет №<?php $this->invoice_number(); ?> от <?php $this->invoice_date(); ?></div>
<br/>
<div style="background-color:#000000; width:100%; font-size:1px; height:2px;"> </div>
<table width="100%">
<tr>
<td style="width: 30mm; padding-top: 5px;">
<div style=" padding-left:2px; padding-bottom: 5px; padding-top: 5px;">Поставщик (Исполнитель): </div>
</td>
<td>
<div style="font-weight:bold; padding-left:2px; padding-top: 5px;">
Тут наименование поставщика, ИНН 000000000000, ОГРНИП 111111111111111</div>
</td>
</tr>
<tr>
<td style="width: 30mm;">
<div style=" padding-left:2px; padding-top: 5px;">Покупатель: </div>
</td>
<td>
<div style="font-weight:bold; padding-left:2px; padding-bottom: 5px; padding-top: 5px;">
<?php $this->custom_field('last_name'); echo " "; $this->custom_field('first_name'); echo " "; $this->custom_field('billing_patronymic_name'); ?></div>
</td>
</tr>
<tr>
<td style="width: 30mm;">
<div style=" padding-left:2px; padding-top: 5px;">Основание: </div>
</td>
<td>
<div style="font-weight:bold; padding-left:2px; padding-top: 5px; padding-bottom: 10px; ">
Заказ №<?php $this->order_number(); ?> от <?php $this->order_date(); ?></div>
</td>
</tr>
</table>
<?php do_action( 'wpo_wcpdf_before_order_details', $this->type, $this->order ); ?>
<table width="100%" class="invoice_items" cellpadding="2" cellspacing="2">
<thead>
<tr>
<th class="number">№</th>
<th class="product">Товары (работы, услуги)</th>
<th class="quantity">Кол-во</th>
<th class="value">Ед.</th>
<th class="price">Цена</th>
<th class="sum">Сумма</th>
</tr>
</thead>
<tbody>
<?php $i=0 /* для нумерации строк и подсчета количества позиций */ ?>
<!-- В цикле выводим список позиций -->
<?php $items = $this->get_order_items(); if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
<tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
<td><?php $i++; echo $i; ?></td><!-- номер строки -->
<td style="text-align: left;" class="product">
<?php $description_label = __( 'Description', 'woocommerce-pdf-invoices-packing-slips' ); // registering alternate label translation ?>
<span class="item-name"><?php echo $item['name']; ?></span>
<?php do_action( 'wpo_wcpdf_before_item_meta', $this->type, $item, $this->order ); ?>
<span class="item-meta"><?php echo $item['meta']; ?></span>
<?php do_action( 'wpo_wcpdf_after_item_meta', $this->type, $item, $this->order ); ?>
</td><!-- наименование продукта -->
<td style="text-align: right;" class="quantity"><?php echo $item['quantity']; ?></td><!-- количество -->
<td style="text-align: right;" class="value">шт.
</td><!-- единица измерения -->
<td style="text-align: right;" class="price"><?php echo $item['single_line_total']; ?></td><!-- цена за штуку -->
<td style="text-align: right;" class="sum"><?php echo $item['order_price']; ?></td><!-- сумма -->
</tr>
<?php endforeach; endif; ?>
</tbody>
</table>
<!-- Выводим таблицу Итого -->
<table border="0" width="100%" cellpadding="1" cellspacing="1">
<tr>
<td></td>
<td style="width:27mm; font-weight:bold; text-align:right;">Итого:</td>
<td style="width:27mm; font-weight:bold; text-align:right;"><?php echo $order->get_total();?></td>
</tr>
<tr>
<td></td>
<td style="width:40mm; font-weight:bold; text-align:right;">Без налога (НДС):</td>
<td style="width:27mm; font-weight:bold; text-align:right;">-</td>
</tr>
<tr>
<td></td>
<td style="width:27mm; font-weight:bold; text-align:right;">Всего к оплате:</td>
<td style="width:27mm; font-weight:bold; text-align:right;"><?php echo $order->get_total(); ?></td>
</tr>
</table>
Всего наименований: <?php echo $i; ?> на сумму <?php echo $order->get_total(); ?> рублей.<br>
<?php
/* Указываем переменной orderp чистое значение суммы заказа */
$orderp = $order->get_total();
/* Конвертируем его из строки в тип double */
$orderp = (double)$orderp;
/* Оборачиваем в функцию для возвращения суммы прописью (функция описана в functions.php моей темы) */
$slova = num2str($orderp);
/* Выводим сумму словами, первую букву делаем заглавную и добавляем точку в конце*/
echo "<b>".mb_strtoupper(mb_substr($slova, 0, 1)) . mb_substr($slova, 1, mb_strlen($slova)).".</b>"; ?>
<div style ="margin-top: 50px;">
Внимание!<br>
Оплата данного счета означает согласие с условиями поставки товара.<br>
Уведомление об оплате обязательно, в противном случае не гарантируется наличие товара на складе.<br>
Товар отпускается по факту прихода денег на р/с Поставщика, самовывозом, при наличии доверенности и паспорта.</div>
<?php if ( $this->get_footer() ): ?>
<div id="footer">
<?php $this->footer(); ?>
</div><!-- #letter-footer -->
<?php endif; ?>
<?php do_action( 'wpo_wcpdf_after_document', $this->type, $this->order ); ?>
Вам нужно будет указать свои реквизиты в нужных местах. Единицы измерения у меня всегда шт., поэтому эти данные указал напрямую. Я также добавил отдельное поля для отчества пользователя, которое он вводит при регистрации: billing_patronymic_name. В коде мы использовали функцию для вывода суммы прописью из данной статьи на хабре. Для того, чтобы она заработала, я добавил саму функцию в файл functions.php своей темы между тегами <?php ?> :/* Эти функции (num2str и morph) нужна для переводы суммы счета в буквенный формат
Мы используем её в файле /wp-content/themes/mytheme/woocommerce/pdf/MyInvoice/invoice.php */
/**
* Возвращает сумму прописью
* @author runcore
* @uses morph(...)
*/
if (!function_exists('num2str')) {
function num2str($num) {
$nul='ноль';
$ten=array(
array('','один','два','три','четыре','пять','шесть','семь', 'восемь','девять'),
array('','одна','две','три','четыре','пять','шесть','семь', 'восемь','девять'),
);
$a20=array('десять','одиннадцать','двенадцать','тринадцать','четырнадцать' ,'пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать');
$tens=array(2=>'двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят' ,'восемьдесят','девяносто');
$hundred=array('','сто','двести','триста','четыреста','пятьсот','шестьсот', 'семьсот','восемьсот','девятьсот');
$unit=array( // Units
array('копейка' ,'копейки' ,'копеек', 1),
array('рубль' ,'рубля' ,'рублей' ,0),
array('тысяча' ,'тысячи' ,'тысяч' ,1),
array('миллион' ,'миллиона','миллионов' ,0),
array('миллиард','милиарда','миллиардов',0),
);
//
list($rub,$kop) = explode('.',sprintf("%015.2f", floatval($num)));
$out = array();
if (intval($rub)>0) {
foreach(str_split($rub,3) as $uk=>$v) { // by 3 symbols
if (!intval($v)) continue;
$uk = sizeof($unit)-$uk-1; // unit key
$gender = $unit[$uk][3];
list($i1,$i2,$i3) = array_map('intval',str_split($v,1));
// mega-logic
$out[] = $hundred[$i1]; # 1xx-9xx
if ($i2>1) $out[]= $tens[$i2].' '.$ten[$gender][$i3]; # 20-99
else $out[]= $i2>0 ? $a20[$i3] : $ten[$gender][$i3]; # 10-19 | 1-9
// units without rub & kop
if ($uk>1) $out[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
} //foreach
}
else $out[] = $nul;
$out[] = morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
$out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
}
}
/**
* Склоняем словоформу
* @ author runcore
*/
if (!function_exists('morph')) {
function morph($n, $f1, $f2, $f5) {
$n = abs(intval($n)) % 100;
if ($n>10 && $n<20) return $f5;
$n = $n % 10;
if ($n>1 && $n<5) return $f2;
if ($n==1) return $f1;
return $f5;
}
}
Теперь счет формируется и формате PDF. Осталось добавить метод оплаты и при использовании метода выдавать ссылку на счет. Для этого устанавливаем второй плагин WooCommerce Invoice Gateway и настраиваем по моему подобию:
Название метода "Оплата по счету" мы в дальнейшем будем использовать как условие для отображение ссылки на счет.
Далее идем в functions.php вашей темы и добавляем такой код:
/* Добавляем ссылку на счет после выбора оплаты по счету */
add_filter('woocommerce_thankyou_order_received_text', 'wpo_wcpdf_thank_you_link', 10, 2);
function wpo_wcpdf_thank_you_link( $text, $order ) {
if ( is_user_logged_in() ) {
/* Выводим ссылку на счет, только если в качестве оплаты выбран способ Оплата по счету */
if(wp_kses_post( $order->get_payment_method_title() ) == 'Оплата по счету') {
$order_id = method_exists($order, 'get_id') ? $order->get_id() : $order->id;
$pdf_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=generate_wpo_wcpdf&template_type=invoice&order_ids=' . $order_id . '&my-account'), 'generate_wpo_wcpdf' );
$text .= '<p><a style="color: red;" href="'.esc_attr($pdf_url).'" target="_blank">Скачать счет на оплату (формат PDF)</a></p>';
}
}
return $text;
}
Теперь заказы, для которых был выбран метод оплаты по счету меняют статус на "На удержании", а покупатель получает ссылку на счет и может оплатить по реквизитам в любом банке.
А как сделать что бы после того как человек нажмет на оплату его сразу переносило на PDF страницу
ОтветитьУдалитьДумаю, можно попробовать используя JS с таймаутом, например, в 1 секунду вместо ссылки на файл
УдалитьsetTimeout(function() {window.location.href = "esc_attr($pdf_url)";}, 1000);
не забыв взять это в тег script.
Спасибо, отличный метод! Было бы здорово добавить ссылку на ПДФ в имейл уведомление, или прикрепить счет к письму в ПДФ формате.
ОтветитьУдалитьЯ попытался прописать строку со ссылкой в шаблон письам но ничего не вышло. Ссылка ведет на неверную страницу
Подскажите как не очень понятно для чего плагин WooCommerce Invoice Gateway если счет выставляется и по средствам WooCoommerce такой же.
ОтветитьУдалитьИ знаете ли как можно реализовать выставление от двух разных компаний? В зависимости от выбора покупателей
Как можно реализовать выставление с двух разных компаний? Зависит от выбора с НДС или без.
ОтветитьУдалитьИ для чего плагин WooCommerce Invoice Gateway? Со штатным средством WooCommerce это тоже работает
Добрый день, к сожалению статью писал давно и уже не вспомню подробностей. Плагин WooCommerce Invoice Gateway использовал т.к. на том момент штатными средствами у меня не получилось. По поводы выбора компании в зависимости от НДС, я бы попробовал подправить код из functions.php в конце статьи добавив туда условие при выборе НДС и без и создав шаблон или метод под каждый счет (нужно смотреть как будет удобнее).
Удалить