Новые изменения в модуле - отображение статуса фискализации. Весь базовый функционал должен работать. Важные изменения в README + LICENSE

master
Anthony Axenov 2019-09-09 23:17:39 +08:00
parent c5b7af88c1
commit 6f5fdb19c0
14 changed files with 553 additions and 588 deletions

View File

@ -1,7 +1,9 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004 Version 2, December 2004
Copyright (C) 2018 Anthony Axenov (Антон Аксенов) <anthonyaxenov@gmail.com> Copyright (C) 2018 Anthony Axenov (Антон Аксенов) <anthonyaxenov@gmail.com>,
Alexey Kopylov (Алексей Копылов) <kopylov_aleksei@mail.ru>,
LLC Alt-team (ООО "Альт-тим") <manager@alt-team.com>
Everyone is permitted to copy and distribute verbatim or modified Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long copies of this license document, and changing it is allowed as long

View File

@ -2,41 +2,31 @@
## Содержимое репозитория ## Содержимое репозитория
- `./dreamkas-opencart3.ocmod/` - директория с исходным кодом модифицированного мной модуля - `./src/` - директория с исходным кодом модифицированного мной модуля
- `./dreamkas-opencart3.ocmod.zip` - модифицированный модуль, готовый к установке - `./dreamkas-opencart-3.ocmod.zip` - модифицированный модуль, готовый к установке
- `./dreamkas-f opencart.ocmod.zip` - исходный модуль для OpenCart 2.3, на котором основана данная модификация - `./dreamkas-f opencart.ocmod.zip` - исходный модуль для OpenCart 2.3, на котором основана данная модификация
## Описание ## Описание
Модификация тестировалась на **OpenCart 3.0.2.0**. Модификация тестировалась на **OpenCart 3.0.2.0**.
Модуль устанавливается, удаляется, настройки сохраняются, читаются. Модуль устанавливается, удаляется, настройки сохраняются, читаются.
Судя по отзывам ([первый](http://blog.anthonyaxenov.ru/2018/05/09/%d0%bc%d0%be%d0%b4%d1%83%d0%bb%d1%8c-%d0%b8%d0%bd%d1%82%d0%b5%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d0%b8-dreamkas-%d0%b4%d0%bb%d1%8f-opencart-3-0-2-0/#comment-103), [второй](https://help.dreamkas.ru/hc/ru/articles/115005504689-%D0%9F%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C-%D0%BA%D0%B0%D1%81%D1%81%D1%83-%D0%BA-OpenCart)), полученный модуль в целом работает, за исключением одного момента: не отображаются статусы фискализации.
У меня лично нет возможности полноценно проверить насколько качественно работает этот модуль: для этого нужны реальные заказы и покупки. Статусы фискализации не сразу отображаются на главной странице заказов пока не зайдешь в сам заказ.
Проект, в рамках которого я работал над этим модулем, я больше не поддерживаю.
Вся основная логика модуля прописана здесь: Вся основная логика модуля прописана здесь: `upload/catalog/controller/extension/module/dreamkas.php`
`upload/catalog/controller/extension/module/dreamkas.php`
Этот файл я не трогал.
Я лишь восстановил возможность установить, удалить и настроить модуль.
## Краткая информация об изменениях ## Краткая информация об изменениях
Основано на модуле _[dreamkas-f opencart.ocmod.zip](https://help.dreamkas.ru/hc/ru/article_attachments/115010763145/dreamkas-f_opencart.ocmod.zip)_. Основано на модуле _[dreamkas-f opencart.ocmod.zip](https://help.dreamkas.ru/hc/ru/article_attachments/115010763145/dreamkas-f_opencart.ocmod.zip)_ от команды alt-team.ru.
Этот архив предоставляется самими сотрудниками Dreamkas. Этот архив предоставляется самими сотрудниками Dreamkas. Он включен в репозиторий для истории.
Он включен в репозиторий для истории.
Ниже вкратце описаны мои правки, но чтобы узнать детальные изменения, то можете заморочиться с diff-ами. ## Важное замечание относительно НДС
1. Шаблон (`upload/admin/view/template/extension/module/dreamkas.twig`): В этом устаревшем модуле до сих пор существует НДС 18/180.
1. переписан с языка php на язык шаблонизатора Twig
2. изменено расширение с .tpl на .twig **Важно знать, что с 1 января 2019 эти ставки были заменены на НДС 20/120!**
2. Страница настроек:
1. удалены большие куски закомментированного и нерабочего (?) кода
2. исправлено получение списка установленных платёжных систем в настройках
3. форматирование кода (`upload/admin/controller/extension/module/dreamkas.php`)
## Полезные ссылки ## Полезные ссылки
@ -54,9 +44,10 @@
ЛЮБЫЕ МАНИПУЛЯЦИИ С МОДУЛЕМ — НА ВАШ СТРАХ И РИСК. ЛЮБЫЕ МАНИПУЛЯЦИИ С МОДУЛЕМ — НА ВАШ СТРАХ И РИСК.
Я вижу, что люди используют мою модификацию. Но у меня нет никакого интереса и необходимости в этом. Многие вещи об OpenCart, продуктах Dreamkas и этом модуле уже забыты. Поэтому, и поскольку проект изначально не мой, лично я развивать его точно не буду. У меня нет возможности полноценно проверить насколько качественно работает этот модуль: для этого нужны реальные заказы и покупки.
Проект, в рамках которого я работал над этим модулем, я больше не поддерживаю.
Этот репозиторий появился только потому, что на фоне наплевательского отношения со стороны Dreamkas мне случайно удалось сделать из совсем нерабочей вещи почти рабочую. У меня нет никакого интереса и необходимости в этом. Многие вещи об OpenCart, продуктах Dreamkas и этом модуле уже забыты. Поэтому, и поскольку проект изначально не мой, лично я развивать его точно не буду.
Берите и используйте. Не работает — штош. Если у вас есть какие-то доработки — pull-requests are welcome. Но лучше сделайте форк этого репозитория и развивайте проект дальше самостоятельно. Берите и используйте. Не работает — штош. Если у вас есть какие-то доработки — pull-requests are welcome. Но лучше сделайте форк этого репозитория и развивайте проект дальше самостоятельно.
@ -65,14 +56,19 @@
[<img src="http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-1.png" alt="WTFPL" />](LICENSE) [<img src="http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-1.png" alt="WTFPL" />](LICENSE)
Аргументирую: Аргументирую:
1. Компания Dreamkas распространяет свои модули без какой-либо лицензии. 1. Компания Dreamkas распространяет свои модули без какой-либо лицензии.
2. [Код этих модулей не был написан компанией Dreamkas](https://help.dreamkas.ru/hc/ru/articles/115005504689/comments/360000156078), а в этом случае исключительные авторские права Dreamkas на этот код должны быть оговорены только в рамках правовых отношений с подрядчиком. 2. [Код модуля был написан командой alt-team, а не компанией Dreamkas](https://help.dreamkas.ru/hc/ru/articles/115005504689/comments/360000156078). В этом случае исключительные авторские права Dreamkas на этот код должны быть оговорены только в рамках правовых отношений с командой alt-team.
3. Этот модуль находится в открытом доступе в разделе поддержки Dreamkas. Ни [лицензионное соглашение](https://dreamkas.ru/content/kluch-oferta.pdf), ни [договор-оферта](https://dreamkas.ru/content/dogovor-oferta-clients.pdf), публично представленные на сайте Dreamkas: 3. Этот модуль находится в открытом доступе в разделе поддержки Dreamkas. Ни [лицензионное соглашение](https://dreamkas.ru/content/kluch-oferta.pdf), ни [договор-оферта](https://dreamkas.ru/content/dogovor-oferta-clients.pdf), публично представленные на сайте Dreamkas:
* не содержат условий использования, изменения и распространения пользователями этого модуля; - не содержат условий использования, изменения и распространения пользователями этого модуля;
* неприменимы для этого случая (см. п. 2) - неприменимы для этого случая (см. п. 2)
4. [Политика обновлений компании alt-team](https://www.alt-team.ru/upgrade-policy.html) не распространяется на модуль интеграции Dreamkas и Opencart, т.к. этот модуль не продаётся на их сайте;
5. В исходном коде модуля нигде прямо не указан копирайт в соответствии со статьёй 1271 ГК РФ.
Исходя из этого, делаю выводы: Исходя из этого, делаю выводы:
1. Компания Dreamkas никоим образом не заявляет о своих правах на код модуля, об условиях его использования, распространения и изменения. Поэтому я вправе сделать это самостоятельно, так как код был изменён мной.
2. **[Лицензия WTFPL v2](LICENSE)** как никакая другая лучше подходит для этого случая.
Я готов обсудить вопросы лицензии и изменить условия, если вам есть что сказать по существу. 1. Компания Dreamkas и команда alt-team никоим образом не заявляют о своих правах на код модуля, об условиях его использования, распространения и изменения. Поэтому я вправе сделать это самостоятельно.
2. **[Лицензия WTFPL v2](LICENSE)** как никакая другая лучше подходит для этого случая.
3. Компания Альт-тим должна быть упомянута в тексте лицензии среди прочих авторов исходного кода, т.к. в файле `dreamkas-f opencart.ocmod.zip/install.xml` встречается её упоминание.
Я готов обсудить и изменить эти условия, если вам есть что сказать по существу.

Binary file not shown.

Binary file not shown.

View File

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<modification>
<name>Dreamkas 2.3.x</name>
<code>Dreamkas 2.3.x</code>
<version>1.00</version>
<author>Alt-team</author>
<link>https://www.alt-team.ru/</link>
<!--file path="catalog/controller/checkout/success.php">
<operation>
<search><![CDATA[public function index() {]]></search>
<add position="after">
<![CDATA[
if (isset($this->session->data['order_id'])) {
$this->load->controller('extension/module/dreamkas/fiscalize',$this->session->data['order_id']);
}
]]>
</add>
</operation>
</file-->
<file path="admin/view/template/catalog/product_form.tpl">
<operation>
<search><![CDATA[
<label class="col-sm-2 control-label" for="input-price"><?php echo $entry_price; ?></label>
]]></search>
<add position="after" offset="4"><![CDATA[
<div class="form-group">
<label class="col-sm-2 control-label" for="input-width">НДС товара при фискализации</label>
<div class="col-sm-10">
<select name="dk_tax_type" id="input-dk_tax_type" class="form-control">
<option value="0" <?php if (empty($dk_tax_type)) echo "selected=\"selected\"";?>>Выберите НДС</option>
<option value="NDS_NO_TAX" <?php if ($dk_tax_type=='NDS_NO_TAX') echo "selected=\"selected\"";?>>Без НДС</option>
<option value="NDS_0" <?php if ($dk_tax_type=='NDS_0') echo "selected=\"selected\"";?>>НДС 0</option>
<option value="NDS_10" <?php if ($dk_tax_type=='NDS_10') echo "selected=\"selected\"";?>>НДС 10</option>
<option value="NDS_18" <?php if ($dk_tax_type=='NDS_18') echo "selected=\"selected\"";?>>НДС 18</option>
<option value="NDS_10_CALCULATED" <?php if ($dk_tax_type=='NDS_10_CALCULATED') echo "selected=\"selected\"";?>>НДС 10/110</option>
<option value="NDS_18_CALCULATED" <?php if ($dk_tax_type=='NDS_18_CALCULATED') echo "selected=\"selected\"";?>>НДС 18/118</option>
</select>
</div>
</div>
]]></add>
</operation>
</file>
<file path="admin/model/catalog/product.php">
<operation>
<search><![CDATA[
$this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
]]></search>
<add position="before"><![CDATA[
if (isset($data['dk_tax_type'])) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET dk_tax_type = '" . $this->db->escape($data['dk_tax_type']) . "' WHERE product_id = '" . (int)$product_id . "'");
}
]]></add>
</operation>
</file>
<file path="admin/controller/catalog/product.php">
<operation>
<search><![CDATA[
$this->load->model('catalog/recurring');
]]></search>
<add position="before"><![CDATA[
if (isset($this->request->post['dk_tax_type'])) {
$data['dk_tax_type'] = $this->request->post['dk_tax_type'];
} elseif (!empty($product_info['dk_tax_type'])) {
$data['dk_tax_type'] = $product_info['dk_tax_type'];
} else {
$data['dk_tax_type'] = '';
}
]]></add>
</operation>
</file>
<file path="admin/view/template/sale/order_list.tpl">
<operation>
<search><![CDATA[
<td class="text-right"><?php echo $column_action; ?></td>
]]></search>
<add position="before"><![CDATA[
<td class="text-left">Статус фискализации</td>
]]></add>
</operation>
<operation>
<search><![CDATA[
<td class="text-left"><?php echo $order['date_modified']; ?></td>
]]></search>
<add position="after"><![CDATA[
<td class="text-left"><?php echo $order['dk_status']; ?></td>
]]></add>
</operation>
</file>
<file path="admin/view/template/sale/order_info.tpl">
<operation>
<search><![CDATA[
<td><?php echo $text_affiliate; ?>
]]></search>
<add position="before"><![CDATA[
<td><?php echo $entry_dk_status; ?></td>
<td class="text-right"><?php if ($dk_status) { ?><?php echo $dk_status; ?><?php } ?></td>
<td class="text-center"></td>
</tr>
<tr>
]]></add>
</operation>
</file>
<file path="admin/controller/sale/order.php">
<operation>
<search><![CDATA[
$results = $this->model_sale_order->getOrders($filter_data);
]]></search>
<add position="after" offset="2"><![CDATA[
$dkquery = $this->db->query("SELECT dk_status FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$result['order_id']. "'");
]]></add>
</operation>
<operation>
<search><![CDATA['shipping_code' => $result['shipping_code'],]]></search>
<add position="before"><![CDATA[
'dk_status' => !empty($dkquery->row['dk_status'])?$dkquery->row['dk_status']:'',
]]></add>
</operation>
<operation>
<search><![CDATA[$data['tab_additional'] = $this->language->get('tab_additional');]]></search>
<add position="before"><![CDATA[
$query = $this->db->query("SELECT order_status_id FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int)$order_id . "'");
$status = $query->row['order_status_id'];
$query = $this->db->query("SELECT payment_code FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int)$order_id . "'");
$payment_code = $query->row['payment_code'];
if ($status == $this->config->get('dreamkas_paid_order') && in_array($payment_code, $this->config->get('dreamkas_payments_ids'))) {
$query = $this->db->query("SELECT dk_id FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$order_id. "'");
if(!empty($query->row['dk_id'])) {
$dk_id = $query->row['dk_id'];
$ch = curl_init();
$access_token = $this->config->get('dreamkas_access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer $access_token"
));
curl_setopt($ch, CURLOPT_URL, "https://kabinet.dreamkas.ru/api/operations/".$dk_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response, true);
if((substr($response['status'], 0, 1)==4)) {
$this->log->write('Dreamkas debug: ' . json_encode($response));
} elseif(!empty($response['data']['error'])) {
$this->log->write('Dreamkas debug: ' . json_encode($response['data']['error']));
} else {
$dk_date = empty($response['createdAt'])?$response['completedAt']:$response['createdAt'];
$this->db->query("UPDATE `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int)$order_id . "', `dk_id` = '".$response['id']."', `dk_date` ='".$dk_date."', `dk_status` = '" .$response['status']. "' WHERE order_id = '" . (int)$order_id. "'");
}
}
}
$query = $this->db->query("SELECT dk_status FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$order_id. "'");
if(!empty($query->row['dk_status'])) {
$data['dk_status'] = $query->row['dk_status'];
} else {
$data['dk_status']='';
}
$this->load->language('extension/module/dreamkas');
$data['entry_dk_status'] = $this->language->get('entry_dk_status');
]]></add>
</operation>
</file>
</modification>

View File

@ -1,127 +0,0 @@
<?php echo $header; ?><?php echo $column_left; ?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-special" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
<?php if ($error_warning) { ?>
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-pencil"></i> <?php echo $text_edit; ?></h3>
</div>
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-special" class="form-horizontal">
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-name"><?php echo $entry_access_token; ?></label>
<div class="col-sm-10">
<input type="text" name="dreamkas_access_token" value="<?php echo $access_token; ?>" placeholder="<?php echo $entry_access_token; ?>" id="input-name" class="form-control" />
<?php if ($error_access_token) { ?>
<div class="text-danger"><?php echo $error_access_token; ?></div>
<?php } ?>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-limit"><?php echo $entry_device_id; ?></label>
<div class="col-sm-10">
<input type="text" name="dreamkas_device_id" value="<?php echo $device_id; ?>" placeholder="<?php echo $entry_device_id; ?>" id="input-device_id" class="form-control" />
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width"><?php echo $entry_tax_mode; ?></label>
<div class="col-sm-10">
<select name="dreamkas_tax_mode" id="input-tax_mode" class="form-control">
<option value="DEFAULT" <?php if ($tax_mode=='DEFAULT') echo "selected=\"selected\"";?>><?php echo $text_tax_default; ?></option>
<option value="SIMPLE" <?php if ($tax_mode=='SIMPLE') echo "selected=\"selected\"";?>><?php echo $text_tax_simple; ?></option>
<option value="SIMPLE_WO" <?php if ($tax_mode=='SIMPLE_WO') echo "selected=\"selected\"";?>><?php echo $text_tax_simple_wo; ?></option>
<option value="ENVD" <?php if ($tax_mode=='ENVD') echo "selected=\"selected\"";?>><?php echo $text_tax_envd; ?></option>
<option value="AGRICULT" <?php if ($tax_mode=='AGRICULT') echo "selected=\"selected\"";?>><?php echo $text_tax_agricult; ?></option>
<option value="PATENT" <?php if ($tax_mode=='PATENT') echo "selected=\"selected\"";?>><?php echo $text_tax_patent; ?></option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width"><?php echo $entry_tax_type; ?></label>
<div class="col-sm-10">
<select name="dreamkas_tax_type" id="input-tax_type" class="form-control">
<option value="NDS_NO_TAX" <?php if ($tax_type=='NDS_NO_TAX') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_no_tax; ?></option>
<option value="NDS_0" <?php if ($tax_type=='NDS_0') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_0; ?></option>
<option value="NDS_10" <?php if ($tax_type=='NDS_10') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_10; ?></option>
<option value="NDS_18" <?php if ($tax_type=='NDS_18') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_18; ?></option>
<option value="NDS_10_CALCULATED" <?php if ($tax_type=='NDS_10_CALCULATED') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_10_calculated; ?></option>
<option value="NDS_18_CALCULATED" <?php if ($tax_type=='NDS_18_CALCULATED') echo "selected=\"selected\"";?>><?php echo $text_tax_nds_18_calculated; ?></option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-paid_order"><?php echo $entry_paid_order; ?></label>
<div class="col-sm-10">
<select name="dreamkas_paid_order" id="input-paid_order" class="form-control">
<?php $arr = get_defined_vars();
foreach ($arr["order_statuses"] as $value)
{ ?>
<option value=<?php echo $value['order_status_id']; ?>
<?php if ($paid_order==$value['order_status_id'])
echo "selected=\"selected\"";?>
><?php echo $value['name']; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="input-process-status"><?php echo $entry_payments_ids;?></label>
<div class="col-sm-8">
<div class="well well-sm" style="height: 150px; overflow: auto;">
<?php foreach ($extensions as $paymenttype) { ?>
<div class="checkbox">
<label>
<?php if (in_array($paymenttype['code'], $payments_ids)) { ?>
<input type="checkbox" name="dreamkas_payments_ids[]" value="<?php echo $paymenttype['code']; ?>" checked="checked" />
<?php echo $paymenttype['name']; ?>
<?php } else { ?>
<input type="checkbox" name="dreamkas_payments_ids[]" value="<?php echo $paymenttype['code']; ?>" />
<?php echo $paymenttype['name']; ?>
<?php } ?>
</label>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-status"><?php echo $entry_status; ?></label>
<div class="col-sm-10">
<select name="dreamkas_status" id="input-status" class="form-control">
<?php if ($status) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<?php echo $footer; ?>

View File

@ -1,120 +0,0 @@
{{ header }}
{{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-special" data-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="{{ cancel }}" data-toggle="tooltip" title="{{ button_cancel }}" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1>{{ heading_title }}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
{% if error_warning %}
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> {{ error_warning }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-pencil"></i> {{ text_edit }}</h3>
</div>
<div class="panel-body">
<form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-special" class="form-horizontal">
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-name">{{ entry_access_token }}</label>
<div class="col-sm-10">
<input type="text" name="dreamkas_access_token" value="{{ access_token }}" placeholder="{{ entry_access_token }}" id="input-name" class="form-control" />
{% if error_access_token %}
<div class="text-danger">{{ error_access_token }}</div>
{% endif %}
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-limit">{{ entry_device_id }}</label>
<div class="col-sm-10">
<input type="text" name="dreamkas_device_id" value="{{ device_id }}" placeholder="{{ entry_device_id }}" id="input-device_id" class="form-control" />
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width">{{ entry_tax_mode }}</label>
<div class="col-sm-10">
<select name="dreamkas_tax_mode" id="input-tax_mode" class="form-control">
<option value="DEFAULT" {% if tax_mode == 'DEFAULT' %} selected='selected' {% endif %}>{{ text_tax_default }}</option>
<option value="SIMPLE" {% if tax_mode == 'SIMPLE' %} selected='selected' {% endif %}>{{ text_tax_simple }}</option>
<option value="SIMPLE_WO" {% if tax_mode == 'SIMPLE_WO' %} selected='selected' {% endif %}>{{ text_tax_simple_wo }}</option>
<option value="ENVD" {% if tax_mode == 'ENVD' %} selected='selected' {% endif %}>{{ text_tax_envd }}</option>
<option value="AGRICULT" {% if tax_mode == 'AGRICULT' %} selected='selected' {% endif %}>{{ text_tax_agricult }}</option>
<option value="PATENT" {% if tax_mode == 'PATENT' %} selected='selected' {% endif %}>{{ text_tax_patent }}</option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width">{{ entry_tax_type }}</label>
<div class="col-sm-10">
<select name="dreamkas_tax_type" id="input-tax_type" class="form-control">
<option value="NDS_NO_TAX" {% if tax_type == 'NDS_NO_TAX' %} selected='selected' {% endif %}>{{ text_tax_nds_no_tax }}</option>
<option value="NDS_0" {% if tax_type == 'NDS_0' %} selected='selected' {% endif %}>{{ text_tax_nds_0 }}</option>
<option value="NDS_10" {% if tax_type == 'NDS_10' %} selected='selected' {% endif %}>{{ text_tax_nds_10 }}</option>
<option value="NDS_18" {% if tax_type == 'NDS_18' %} selected='selected' {% endif %}>{{ text_tax_nds_18 }}</option>
<option value="NDS_10_CALCULATED" {% if tax_type == 'NDS_10_CALCULATED' %} selected='selected' {% endif %}>{{ text_tax_nds_10_calculated }}</option>
<option value="NDS_18_CALCULATED" {% if tax_type == 'NDS_18_CALCULATED' %} selected='selected' {% endif %}>{{ text_tax_nds_18_calculated }}</option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-paid_order">{{ entry_paid_order }}</label>
<div class="col-sm-10">
<select name="dreamkas_paid_order" id="input-paid_order" class="form-control">
{% for status in order_statuses %}
<option value='{{ status.order_status_id }}' {% if paid_order == status.order_status_id %} selected='selected' {% endif %}>{{ status.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="input-process-status">{{ entry_payments_ids }}</label>
<div class="col-sm-8">
<div class="well well-sm" style="height: 150px; overflow: auto;">
{% for type in paymenttypes %}
<div class="checkbox">
<label>
<input type="checkbox" name="dreamkas_payments_ids[]" value="{{ type.code }}" {% if type.code in payments_ids %} checked="checked" {% endif %}/>{{ type.name }} ({{ type.code }})
</label>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-status">{{ entry_status }}</label>
<div class="col-sm-10">
<select name="dreamkas_status" id="input-status" class="form-control">
{% if status %}
<option value="1" selected="selected">{{ text_enabled }}</option>
<option value="0">{{ text_disabled }}</option>
{% else %}
<option value="1">{{ text_enabled }}</option>
<option value="0" selected="selected">{{ text_disabled }}</option>
{% endif %}
</select>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{{ footer }}

View File

@ -1,120 +0,0 @@
<?php
class ControllerExtensionModuleDreamkas extends Controller {
public function check($data) {}
public function index($route, $data) {
if (isset($data[0]) && !empty($data[0])) {
$this->load->language('extension/module/dreamkas');
$order_id = $data[0];
$query = $this->db->query("SELECT order_status_id FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int) $order_id . "'");
$status = $query->row['order_status_id'];
$query = $this->db->query("SELECT payment_code FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int) $order_id . "'");
$payment_code = $query->row['payment_code'];
if ($status == $this->config->get('dreamkas_paid_order') &&
in_array($payment_code, $this->config->get('dreamkas_payments_ids')))
{
$this->load->model('checkout/order');
$order_info = $this->model_checkout_order->getOrder($order_id);
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int) $order_id . "'");
$products = $query->rows;
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'shipping' ORDER BY sort_order");
$shipping = $query->rows;
$tax_type = $this->config->get('dreamkas_tax_type');
$tax_sum = 0;
$items = array();
foreach ($products as $product) {
$query = $this->db->query("SELECT dk_tax_type FROM " . DB_PREFIX . "product WHERE product_id = '" . (int) $product['product_id'] . "'");
$dk_tax_type = $query->row;
$product_tax_type = empty($dk_tax_type['dk_tax_type']) ? $tax_type : $dk_tax_type['dk_tax_type'];
$items[] = array(
"name" => $product['name'],
"type" => "COUNTABLE",
"quantity" => $product['quantity'],
"price" => ($product['price'] + $product['tax']) * 100,
"priceSum" => ($product['total'] + $product['tax'] * $product['quantity']) * 100,
"tax" => "$product_tax_type",
"taxSum" => 0, //$product['tax']*100*$product['quantity']
);
$tax_sum += $product['tax'] * $product['quantity'];
}
if (!empty($shipping)) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'tax' ORDER BY sort_order");
$tax_total = reset($query->rows);
if (!empty($tax_total['value'])) {
$shipping_tax = $tax_total['value'] - $tax_sum;
} else {
$shipping_tax = 0;
}
foreach ($shipping as $_shipping) {
if ($_shipping['value'] > 0) {
$items[] = array(
"name" => 'Доставка',
"type" => "COUNTABLE",
"quantity" => 1,
"price" => ($_shipping['value'] + $shipping_tax) * 100,
"priceSum" => ($_shipping['value'] + $shipping_tax) * 100,
"tax" => "$tax_type",
"taxSum" => 0, //$shipping_tax*100
);
}
}
}
$request = array(
"deviceId" => $this->config->get('dreamkas_device_id'),
"type" => "SALE",
"timeout" => 180,
"taxMode" => $this->config->get('dreamkas_tax_mode'),
"positions" => $items,
"payments" => array(
array(
"sum" => $order_info['total'] * 100,
"type" => "CASHLESS",
),
),
"attributes" => array(
"email" => $order_info['email'],
"phone" => $order_info['telephone'], //"+71239994499"
),
"total" => array(
"priceSum" => $order_info['total'] * 100,
),
);
$ch = curl_init();
$access_token = $this->config->get('dreamkas_access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer $access_token",
));
curl_setopt($ch, CURLOPT_URL, "https://kabinet.dreamkas.ru/api/receipts");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
$response = curl_exec($ch);
curl_close($ch);
if (!empty($response)) {
$response = json_decode($response, true);
if ((substr($response['status'], 0, 1) == 4)) {
$this->log->write('Dreamkas debug: ' . json_encode($response));
} else {
$dk_date = empty($response['createdAt']) ? $response['completedAt'] : $response['createdAt'];
$query = $this->db->query("SELECT order_id FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int) $order_id . "'");
$exist_order_id = $query->rows;
if (empty($exist_order_id)) {
$this->db->query("INSERT INTO `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int) $order_id . "', `dk_id` = '" . $response['id'] . "', `dk_date` ='" . $dk_date . "', `dk_status` = '" . $response['status'] . "'");
} else {
$this->db->query("UPDATE `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int) $order_id . "', `dk_id` = '" . $response['id'] . "', `dk_date` ='" . $dk_date . "', `dk_status` = '" . $response['status'] . "' WHERE order_id = '" . (int) $order_id . "'");
}
}
}
}
}
}
}

164
src/install.xml 100644
View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8" ?>
<modification>
<name>Dreamkas 3.x</name>
<code>Dreamkas 3.x</code>
<version>1.02</version>
<author>Anthony Axenov, Alexey Kopylov (based on code by alt-team.ru)</author>
<link>https://github.com/anthonyaxenov/dreamkas-opencart-3</link>
<!--
<file path="catalog/controller/checkout/success.php">
<operation>
<search><![CDATA[public function index() {]]></search>
<add position="after">
<![CDATA[if (isset($this->session->data['order_id'])) {
$this->load->controller('extension/module/dreamkas/fiscalize',$this->session->data['order_id']);
}
]]></add>
</operation>
</file>
-->
<file path="admin/view/template/catalog/product_form.twig">
<operation>
<search><![CDATA[<label class="col-sm-2 control-label" for="input-price">{{ entry_price }}</label>]]></search>
<add position="after" offset="4"><![CDATA[
<div class="form-group">
<label class="col-sm-2 control-label" for="input-width">НДС товара при фискализации</label>
<div class="col-sm-10">
<select name="dk_tax_type" id="input-dk_tax_type" class="form-control">
<option value="0" {% if dk_tax_type is empty %} selected="selected" {% endif %}>Выберите НДС</option>
<option value="NDS_NO_TAX" {% if dk_tax_type=='NDS_NO_TAX' %} selected="selected" {% endif %}>Без НДС</option>
<option value="NDS_0" {% if dk_tax_type=='NDS_0' %} selected="selected" {% endif %}>НДС 0</option>
<option value="NDS_10" {% if dk_tax_type=='NDS_10' %} selected="selected" {% endif %}>НДС 10</option>
<option value="NDS_18" {% if dk_tax_type=='NDS_18' %} selected="selected" {% endif %}>НДС 18</option>
<option value="NDS_10_CALCULATED" {% if dk_tax_type=='NDS_10_CALCULATED' %} selected="selected" {% endif %}>НДС 10/110</option>
<option value="NDS_18_CALCULATED" {% if dk_tax_type=='NDS_18_CALCULATED' %} selected="selected" {% endif %}>НДС 18/118</option>
</select>
</div>
</div>
]]>
</add>
</operation>
</file>
<file path="admin/model/catalog/product.php">
<operation>
<search><![CDATA[$this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");]]></search>
<add position="before"><![CDATA[
if (isset($data['dk_tax_type'])) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET dk_tax_type = '" . $this->db->escape($data['dk_tax_type']) . "' WHERE product_id = '" . (int)$product_id . "'");
}
]]>
</add>
</operation>
</file>
<file path="admin/controller/catalog/product.php">
<operation>
<search><![CDATA[$this->load->model('catalog/recurring');]]></search>
<add position="before"><![CDATA[
if (isset($this->request->post['dk_tax_type'])) {
$data['dk_tax_type'] = $this->request->post['dk_tax_type'];
} elseif (!empty($product_info['dk_tax_type'])) {
$data['dk_tax_type'] = $product_info['dk_tax_type'];
} else {
$data['dk_tax_type'] = '';
}
]]>
</add>
</operation>
</file>
<file path="admin/view/template/sale/order_list.twig">
<operation>
<search><![CDATA[<td class="text-right">{{ column_action }}</td>]]></search>
<add position="before"><![CDATA[<td class="text-left">Статус фискализации</td>]]></add>
</operation>
<operation>
<search><![CDATA[<td class="text-left">{{ order.date_modified }}</td>]]></search>
<add position="after"><![CDATA[<td class="text-left">{{order.dk_status}}</td>]]></add>
</operation>
</file>
<file path="admin/view/template/sale/order_info.twig">
<operation>
<search><![CDATA[
<td>{{ text_affiliate }}
]]>
</search>
<add position="before"><![CDATA[
<td>{{ entry_dk_status }}</td>
<td class="text-right">{% if dk_status %} {{dk_status }} {%endif%} </td>
<td class="text-center"></td>
</tr>
<tr>
]]>
</add>
</operation>
</file>
<file path="admin/controller/sale/order.php">
<operation>
<search><![CDATA[
$results = $this->model_sale_order->getOrders($filter_data);
]]>
</search>
<add position="after" offset="2"><![CDATA[
$dkquery = $this->db->query("SELECT dk_status FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$result['order_id']. "'");
]]>
</add>
</operation>
<operation>
<search><![CDATA['shipping_code' => $result['shipping_code'],]]></search>
<add position="before"><![CDATA[
'dk_status' => !empty($dkquery->row['dk_status'])?$dkquery->row['dk_status']:'',
]]> </add>
</operation>
<operation>
<search><![CDATA[$data['date_added'] = date($this->language->get('date_format_short'), strtotime($order_info['date_added']));]]></search>
<add position="before"><![CDATA[
$query = $this->db->query("SELECT order_status_id FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int)$order_id . "'");
$status = $query->row['order_status_id'];
$query = $this->db->query("SELECT payment_code FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int)$order_id . "'");
$payment_code = $query->row['payment_code'];
if ($status == $this->config->get('dreamkas_paid_order') && in_array($payment_code, $this->config->get('dreamkas_payments_ids'))) {
$query = $this->db->query("SELECT dk_id FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$order_id. "'");
if(!empty($query->row['dk_id'])) {
$dk_id = $query->row['dk_id'];
$ch = curl_init();
$access_token = $this->config->get('dreamkas_access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer $access_token"
));
curl_setopt($ch, CURLOPT_URL, "https://kabinet.dreamkas.ru/api/operations/".$dk_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response, true);
if((substr($response['status'], 0, 1)==4)) {
$this->log->write('Dreamkas debug: ' . json_encode($response));
} elseif(!empty($response['data']['error'])) {
$this->log->write('Dreamkas debug: ' . json_encode($response['data']['error']));
} else {
$dk_date = empty($response['createdAt'])?$response['completedAt']:$response['createdAt'];
$this->db->query("UPDATE `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int)$order_id . "', `dk_id` = '".$response['id']."', `dk_date` ='".$dk_date."', `dk_status` = '" .$response['status']. "' WHERE order_id = '" . (int)$order_id. "'");
}
}
}
$query = $this->db->query("SELECT dk_status FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int)$order_id. "'");
if(!empty($query->row['dk_status'])) {
$data['dk_status'] = $query->row['dk_status'];
} else {
$data['dk_status'] = '';
}
$this->load->language('extension/module/dreamkas');
$data['entry_dk_status'] = $this->language->get('entry_dk_status');
]]>
</add>
</operation>
</file>
</modification>

View File

@ -1,8 +1,10 @@
<?php <?php
class ControllerExtensionModuleDreamkas extends Controller { class ControllerExtensionModuleDreamkas extends Controller
{
private $error = array(); private $error = array();
public function index() { public function index()
{
$this->load->language('extension/module/dreamkas'); $this->load->language('extension/module/dreamkas');
$this->document->setTitle($this->language->get('heading_title')); $this->document->setTitle($this->language->get('heading_title'));
$this->load->model('setting/setting'); $this->load->model('setting/setting');
@ -10,10 +12,21 @@ class ControllerExtensionModuleDreamkas extends Controller {
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
$this->model_setting_setting->editSetting('dreamkas', $this->request->post); $this->model_setting_setting->editSetting('dreamkas', $this->request->post);
$this->session->data['success'] = $this->language->get('text_success'); $this->session->data['success'] = $this->language->get('text_success');
//$this->response->redirect($this->url->link('extension/extension', 'user_token=' . $this->session->data['user_token'], 'SSL')); //$this->response->redirect($this->url->link('extension/extension', 'token=' . $this->session->data['token'], 'SSL'));
$this->response->redirect($this->url->link('extension/module/dreamkas', 'user_token=' . $this->session->data['user_token'], 'SSL')); $this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true));
} }
/*
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
if (!isset($this->request->get['module_id'])) {
$this->model_extension_module->addModule('dreamkas', $this->request->post);
} else {
$this->model_extension_module->editModule($this->request->get['module_id'], $this->request->post);
}
//$this->cache->delete('product');
$this->session->data['success'] = $this->language->get('text_success');
$this->response->redirect($this->url->link('extension/extension', 'token=' . $this->session->data['token'] . '&type=module', true));
}
*/
$data['heading_title'] = $this->language->get('heading_title'); $data['heading_title'] = $this->language->get('heading_title');
$data['text_edit'] = $this->language->get('text_edit'); $data['text_edit'] = $this->language->get('text_edit');
$data['text_enabled'] = $this->language->get('text_enabled'); $data['text_enabled'] = $this->language->get('text_enabled');
@ -37,7 +50,15 @@ class ControllerExtensionModuleDreamkas extends Controller {
$data['text_tax_nds_18'] = $this->language->get('text_tax_nds_18'); $data['text_tax_nds_18'] = $this->language->get('text_tax_nds_18');
$data['text_tax_nds_10_calculated'] = $this->language->get('text_tax_nds_10_calculated'); $data['text_tax_nds_10_calculated'] = $this->language->get('text_tax_nds_10_calculated');
$data['text_tax_nds_18_calculated'] = $this->language->get('text_tax_nds_18_calculated'); $data['text_tax_nds_18_calculated'] = $this->language->get('text_tax_nds_18_calculated');
/*
fnr($this);
$data['entry_name'] = $this->language->get('entry_name');
$data['entry_limit'] = $this->language->get('entry_limit');
$data['entry_image'] = $this->language->get('entry_image');
$data['entry_width'] = $this->language->get('entry_width');
$data['entry_height'] = $this->language->get('entry_height');
$data['entry_status'] = $this->language->get('entry_status');
*/
$data['button_save'] = $this->language->get('button_save'); $data['button_save'] = $this->language->get('button_save');
$data['button_cancel'] = $this->language->get('button_cancel'); $data['button_cancel'] = $this->language->get('button_cancel');
@ -66,14 +87,14 @@ class ControllerExtensionModuleDreamkas extends Controller {
); );
$data['breadcrumbs'][] = array( $data['breadcrumbs'][] = array(
'text' => $this->language->get('text_extension'), 'text' => $this->language->get('text_extension'),
'href' => $this->url->link('extension/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true) 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true)
); );
$data['breadcrumbs'][] = array( $data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title'), 'text' => $this->language->get('heading_title'),
'href' => $this->url->link('extension/module/dreamkas', 'user_token=' . $this->session->data['user_token'], true) 'href' => $this->url->link('extension/module/dreamkas', 'user_token=' . $this->session->data['user_token'], true)
); );
$data['action'] = $this->url->link('extension/module/dreamkas', 'user_token=' . $this->session->data['user_token'], true); $data['action'] = $this->url->link('extension/module/dreamkas', 'user_token=' . $this->session->data['user_token'], true);
$data['cancel'] = $this->url->link('extension/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true); $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true);
if (isset($this->request->get['module_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) { if (isset($this->request->get['module_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
$module_info = $this->model_extension_module->getModule($this->request->get['module_id']); $module_info = $this->model_extension_module->getModule($this->request->get['module_id']);
@ -124,14 +145,40 @@ class ControllerExtensionModuleDreamkas extends Controller {
//Get payments //Get payments
$this->load->model('setting/extension'); $this->load->model('setting/extension');
$paymenttypes = $this->model_setting_extension->getInstalled('payment'); $extensions = $this->model_setting_extension->getInstalled('payment');
foreach ($extensions as $key => $value) {
if (!is_file(DIR_APPLICATION . 'controller/extension/payment/' . $value . '.php') && !is_file(DIR_APPLICATION . 'controller/payment/' . $value . '.php')) {
$this->model_extension_extension->uninstall('payment', $value);
unset($extensions[$key]);
}
}
foreach ($paymenttypes as $type) { $data['extensions'] = array();
$this->load->language('extension/payment/' . $type, 'extension');
$data['paymenttypes'][] = array( // Compatibility code for old extension folders
'code' => $type, $files = glob(DIR_APPLICATION . 'controller/{extension/payment,payment}/*.php', GLOB_BRACE);
'name' => $this->language->get('extension')->get('heading_title'), if ($files) {
); foreach ($files as $file) {
$extension = basename($file, '.php');
$this->load->language('extension/payment/' . $extension);
$text_link = $this->language->get('text_' . $extension);
if ($text_link != 'text_' . $extension) {
$link = $this->language->get('text_' . $extension);
} else {
$link = '';
}
$data['extensions'][] = array(
'name' => $this->language->get('heading_title'),
'code' => $extension,
'link' => $link,
'status' => $this->config->get($extension . '_status') ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
'sort_order' => $this->config->get($extension . '_sort_order'),
'install' => $this->url->link('extension/extension/payment/install', 'user_token=' . $this->session->data['user_token'] . '&extension=' . $extension, true),
'uninstall' => $this->url->link('extension/extension/payment/uninstall', 'user_token=' . $this->session->data['user_token'] . '&extension=' . $extension, true),
'installed' => in_array($extension, $extensions),
'edit' => $this->url->link('extension/payment/' . $extension, 'user_token=' . $this->session->data['user_token'], true)
);
}
} }
if (isset($this->request->post['dreamkas_status'])) { if (isset($this->request->post['dreamkas_status'])) {
@ -145,7 +192,8 @@ class ControllerExtensionModuleDreamkas extends Controller {
$this->response->setOutput($this->load->view('extension/module/dreamkas', $data)); $this->response->setOutput($this->load->view('extension/module/dreamkas', $data));
} }
protected function validate() { protected function validate()
{
if (!$this->user->hasPermission('modify', 'extension/module/dreamkas')) { if (!$this->user->hasPermission('modify', 'extension/module/dreamkas')) {
$this->error['warning'] = $this->language->get('error_permission'); $this->error['warning'] = $this->language->get('error_permission');
} }
@ -161,7 +209,8 @@ class ControllerExtensionModuleDreamkas extends Controller {
return !$this->error; return !$this->error;
} }
public function install() { public function install()
{
$this->load->model('setting/event'); $this->load->model('setting/event');
$this->model_setting_event->addEvent('dreamkas', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/dreamkas'); $this->model_setting_event->addEvent('dreamkas', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/dreamkas');
$this->db->query(" $this->db->query("
@ -173,12 +222,14 @@ class ControllerExtensionModuleDreamkas extends Controller {
PRIMARY KEY (`order_id`) PRIMARY KEY (`order_id`)
) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci
"); ");
$this->db->query("ALTER TABLE `" . DB_PREFIX . "product` ADD `dk_tax_type` VARCHAR(50) NOT NULL DEFAULT ''"); $this->db->query("
ALTER TABLE `" . DB_PREFIX . "product` ADD `dk_tax_type` VARCHAR(50) NOT NULL DEFAULT ''
");
} }
public function uninstall() { public function uninstall()
{
$this->load->model('setting/event'); $this->load->model('setting/event');
$this->db->query("ALTER TABLE `" . DB_PREFIX . "product` DROP `dk_tax_type`;");
$this->model_setting_event->deleteEvent('dreamkas'); $this->model_setting_event->deleteEvent('dreamkas');
} }
} }

View File

@ -0,0 +1,39 @@
<?php
// Heading
$_['heading_title'] = 'Дримкас';
// Text
$_['text_extension'] = 'Расширения';
$_['text_module'] = 'Модули';
$_['text_success'] = 'Настройки успешно изменены!';
$_['text_edit'] = 'Настройки модуля';
// Entry
$_['entry_dk_status'] = 'Дримкас статус';
$_['entry_status'] = 'Статус';
$_['entry_access_token'] = 'Токен доступа';
$_['entry_device_id'] = 'Идентификатор устройства, которое будет использовано для фискализации';
$_['entry_tax_mode'] = 'Система налогообложения (если устройство зарегистрировано для работы с несколькими СНО)';
$_['entry_tax_type'] = 'Тип НДС (если не указан, то будет взят из настроек устройства)';
$_['entry_payments_ids'] = 'Список способов оплаты, обработка платежей которых, будет передаваться для фискализации';
$_['entry_paid_order'] = 'Статус оплаченного ордера';
$_['text_tax_default'] = 'Общая';
$_['text_tax_simple'] = 'Упрощенная доход';
$_['text_tax_simple_wo'] = 'Упрощенная доход минус расход';
$_['text_tax_envd'] = 'Единый налог на вмененный доход';
$_['text_tax_agricult'] = 'Единый сельскохозяйственный налог';
$_['text_tax_patent'] = 'Патентная система налогообложения';
$_['text_tax_nds_no_tax'] = 'Без НДС';
$_['text_tax_nds_0'] = 'НДС 0';
$_['text_tax_nds_10'] = 'НДС 10';
$_['text_tax_nds_18'] = 'НДС 18';
$_['text_tax_nds_10_calculated'] = 'НДС 10/110';
$_['text_tax_nds_18_calculated'] = 'НДС 18/118';
// Error
$_['error_device_id'] = 'Введите ID кассы.';
$_['error_access_token'] = 'Необходим токен доступа.';
$_['error_permission'] = 'У Вас нет прав для управления данным модулем!';
$_['error_code'] = 'Необходим код';

View File

@ -0,0 +1,127 @@
{{ header }}
{{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-special" data-toggle="tooltip" title="{{button_save}}" class="btn btn-primary">
<i class="fa fa-save"></i>
</button>
<a href="{{cancel}}" data-toggle="tooltip" title="{{button_cancel}}" class="btn btn-default"><i class="fa fa-reply"></i></a>
</div>
<h1>{{heading_title}}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
{% if error_warning %}
<div class="alert alert-danger">
<i class="fa fa-exclamation-circle"></i>{{ error_warning }}
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-pencil"></i>{{text_edit}}
</h3>
</div>
<div class="panel-body">
<form action="{{action}}" method="post" enctype="multipart/form-data" id="form-special" class="form-horizontal">
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-name">{{entry_access_token}}</label>
<div class="col-sm-10">
<input type="text" name="dreamkas_access_token" value="{{access_token}}" placeholder="{{entry_access_token}}" id="input-name" class="form-control" />
{% if error_access_token %}
<div class="text-danger">{{error_access_token}}</div>
{% endif %}
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-limit">{{entry_device_id}}</label>
<div class="col-sm-10">
<input type="text" name="dreamkas_device_id" value="{{device_id}}" placeholder="{{entry_device_id}}" id="input-device_id" class="form-control" />
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width">{{entry_tax_mode}}</label>
<div class="col-sm-10">
<select name="dreamkas_tax_mode" id="input-tax_mode" class="form-control">
<option value="DEFAULT" {% if tax_mode == 'DEFAULT' %} selected="selected"{% endif %}>{{text_tax_default}}</option>
<option value="SIMPLE" {% if tax_mode == 'SIMPLE' %} selected="selected" {% endif %}>{{text_tax_simple}}</option>
<option value="SIMPLE_WO" {% if tax_mode == 'SIMPLE_WO' %} selected="selected" {% endif %}>{{text_tax_simple_wo}}</option>
<option value="ENVD" {% if tax_mode == 'ENVD' %} selected="selected" {% endif %}>{{text_tax_envd}}</option>
<option value="AGRICULT" {% if tax_mode == 'AGRICULT' %} selected="selected" {% endif %}>{{text_tax_agricult}}</option>
<option value="PATENT" {% if tax_mode == 'PATENT' %} selected="selected" {% endif %}>{{text_tax_patent}}</option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-width">{{entry_tax_type}}</label>
<div class="col-sm-10">
<select name="dreamkas_tax_type" id="input-tax_type" class="form-control">
<option value="NDS_NO_TAX" {% if tax_type == 'NDS_NO_TAX' %} selected="selected" {% endif %}>{{text_tax_nds_no_tax}}</option>
<option value="NDS_0" {% if tax_type == 'NDS_0' %} selected="selected" {% endif %}>{{text_tax_nds_0}}</option>
<option value="NDS_10" {% if tax_type == 'NDS_10' %} selected="selected" {% endif %}>{{text_tax_nds_10}}</option>
<option value="NDS_18" {% if tax_type == 'NDS_18' %} selected="selected" {% endif %}>{{text_tax_nds_18}}</option>
<option value="NDS_10_CALCULATED" {% if tax_type == 'NDS_10_CALCULATED' %} selected="selected" {% endif %}>{{text_tax_nds_10_calculated}}</option>
<option value="NDS_18_CALCULATED" {% if tax_type=='NDS_18_CALCULATED' %} selected="selected" {% endif %}>{{text_tax_nds_18_calculated}}</option>
</select>
</div>
</div>
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-paid_order">{{entry_paid_order}}</label>
<div class="col-sm-10">
<select name="dreamkas_paid_order" id="input-paid_order" class="form-control">
{% for value in order_statuses %}
<option value="{{value.order_status_id}}" {% if paid_order == value.order_status_id %} selected="selected" {% endif %}>{{ value.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="input-process-status">{{entry_payments_ids}}</label>
<div class="col-sm-8">
<div class="well well-sm" style="height: 150px; overflow: auto;">
{% for type in extensions %}
<div class="checkbox">
<label>
<input type="checkbox" name="dreamkas_payments_ids[]" value="{{ type.code }}" {% if type.code in payments_ids %} checked="checked" {% endif %}/>{{ type.name }} ({{ type.code }})
</label>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-status">{{entry_status}}</label>
<div class="col-sm-10">
<select name="dreamkas_status" id="input-status" class="form-control">
{% if status %}
<option value="1" selected="selected">{{text_enabled}}</option>
<option value="0">{{text_disabled}}</option>
{% else %}
<option value="1">{{text_enabled}}</option>
<option value="0" selected="selected">{{text_disabled}}</option>
{% endif %}
</select>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{{ footer }}

View File

@ -0,0 +1,123 @@
<?php
class ControllerExtensionModuleDreamkas extends Controller
{
public function check($data)
{
//
}
public function index($route, $data)
{
// fn_write_r($this->session->data, $route, $data);
if (!empty($data[0])) {
$this->load->language('extension/module/dreamkas');
$order_id = $data[0];
$query = $this->db->query("SELECT order_status_id FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int) $order_id . "'");
$status = $query->row['order_status_id'];
$query = $this->db->query("SELECT payment_code FROM `" . DB_PREFIX . "order` o WHERE o.order_id = '" . (int) $order_id . "'");
$payment_code = $query->row['payment_code'];
// fn_write_r($data, $status, $this->config->get('dreamkas_paid_order'), $payment_code, $this->config->get('dreamkas_payments_ids'));
// if (in_array($status, $this->config->get('sms_alert_processing_status'))) {
if ($status == $this->config->get('dreamkas_paid_order') && in_array($payment_code, $this->config->get('dreamkas_payments_ids'))) {
$this->load->model('checkout/order');
$order_info = $this->model_checkout_order->getOrder($order_id);
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int) $order_id . "'");
$products = $query->rows;
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'shipping' ORDER BY sort_order");
$shipping = $query->rows;
$tax_type = $this->config->get('dreamkas_tax_type');
$tax_sum = 0;
$items = array();
foreach ($products as $product) {
$query = $this->db->query("SELECT dk_tax_type FROM " . DB_PREFIX . "product WHERE product_id = '" . (int) $product['product_id'] . "'");
$dk_tax_type = $query->row;
$product_tax_type = empty($dk_tax_type['dk_tax_type']) ? $tax_type : $dk_tax_type['dk_tax_type'];
$items[] = array(
"name" => $product['name'],
"type" => "COUNTABLE",
"quantity" => $product['quantity'],
"price" => ($product['price'] + $product['tax']) * 100,
"priceSum" => ($product['total'] + $product['tax'] * $product['quantity']) * 100,
"tax" => "$product_tax_type",
"taxSum" => 0 // $product['tax'] * 100 * $product['quantity']
);
$tax_sum += $product['tax'] * $product['quantity'];
}
if (!empty($shipping)) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'tax' ORDER BY sort_order");
$tax_total = reset($query->rows);
if (!empty($tax_total['value'])) {
$shipping_tax = $tax_total['value'] - $tax_sum;
} else {
$shipping_tax = 0;
}
foreach ($shipping as $_shipping) {
if ($_shipping['value'] > 0) {
$items[] = array(
"name" => 'Доставка',
"type" => "COUNTABLE",
"quantity" => 1,
"price" => ($_shipping['value'] + $shipping_tax) * 100,
"priceSum" => ($_shipping['value'] + $shipping_tax) * 100,
"tax" => "$tax_type",
"taxSum" => 0 // $shipping_tax * 100
);
}
}
}
// fn_write_die($order_id, $tax_sum, $query, $items, $shipping);
$request = array(
"deviceId" => $this->config->get('dreamkas_device_id'),
"type" => "SALE",
"timeout" => 180,
"taxMode" => $this->config->get('dreamkas_tax_mode'),
"positions" => $items,
"payments" => array(
array(
"sum" => $order_info['total'] * 100,
"type" => "CASHLESS"
)
),
"attributes" => array(
"email" => $order_info['email'],
"phone" => $order_info['telephone'] // "+71239994499"
),
"total" => array(
"priceSum" => $order_info['total'] * 100
)
);
// fn_write_die($request, $products, $shipping, $order_info);
$ch = curl_init();
$access_token = $this->config->get('dreamkas_access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer " . $access_token
));
curl_setopt($ch, CURLOPT_URL, "https://kabinet.dreamkas.ru/api/receipts");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
$response = curl_exec($ch);
curl_close($ch);
if (!empty($response)) {
$response = json_decode($response, true);
// $response = json_decode('{"id": "5956889136fdd7733f19cfe6","createdAt": "2017-06-20 12:01:47.990Z","status": "PENDING"}', true);
if ((substr($response['status'], 0, 1) == 4)) {
$this->log->write('Dreamkas debug: ' . json_encode($response));
} else {
$dk_date = empty($response['createdAt']) ? $response['completedAt'] : $response['createdAt'];
$query = $this->db->query("SELECT order_id FROM " . DB_PREFIX . "dreamkas WHERE order_id = '" . (int) $order_id . "'");
$exist_order_id = $query->rows;
if (empty($exist_order_id)) {
$this->db->query("INSERT INTO `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int) $order_id . "', `dk_id` = '" . $response['id'] . "', `dk_date` ='" . $dk_date . "', `dk_status` = '" . $response['status'] . "'");
} else {
$this->db->query("UPDATE `" . DB_PREFIX . "dreamkas` SET `order_id` = '" . (int) $order_id . "', `dk_id` = '" . $response['id'] . "', `dk_date` ='" . $dk_date . "', `dk_status` = '" . $response['status'] . "' WHERE order_id = '" . (int) $order_id . "'");
}
}
}
}
}
}
}