first commit
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Admin;
|
||||
|
||||
use KupShop\BalikonosBundle\Balikobot;
|
||||
use KupShop\BalikonosBundle\Exception\BalikonosException;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\ReclamationsBundle\Util\ReclamationsUtil;
|
||||
use KupShop\ReclamationsSuppliersBundle\Attachment\ReclamationSuppliersPDF;
|
||||
use KupShop\ReclamationsSuppliersBundle\Exception\InvalidSupplierInfo;
|
||||
use KupShop\ReclamationsSuppliersBundle\Util\ReclamationsSuppliersUtil;
|
||||
use Query\Operator;
|
||||
|
||||
class ReclamationsSuppliers extends \Window
|
||||
{
|
||||
protected $template = 'window/reclamations_suppliers.tpl';
|
||||
|
||||
protected $nameField = 'code';
|
||||
protected $tableName = 'reclamations_suppliers';
|
||||
|
||||
/** @var ReclamationsSuppliersUtil */
|
||||
protected $reclamationsSuppliersUtil;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->reclamationsSuppliersUtil = ServiceContainer::getService(ReclamationsSuppliersUtil::class);
|
||||
}
|
||||
|
||||
public function createSQLFields($tablename)
|
||||
{
|
||||
parent::createSQLFields($tablename);
|
||||
|
||||
foreach ($this->fields as $key => $field) {
|
||||
if ($field == 'status') {
|
||||
unset($this->fields[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_vars()
|
||||
{
|
||||
$vars = parent::get_vars();
|
||||
|
||||
if ($this->getAction() == 'add') {
|
||||
$vars['body']['items'] = [];
|
||||
} else {
|
||||
$reclamationsUtil = ServiceContainer::getService(ReclamationsUtil::class);
|
||||
|
||||
$vars['body']['items'] = $this->reclamationsSuppliersUtil->getItems($this->getID());
|
||||
$vars['body']['data']['history'] = $this->reclamationsSuppliersUtil->parseHistory($vars['body']['data']['history'] ?? null);
|
||||
$vars['body']['data']['reclamationStatuses'] = $reclamationsUtil->getStatuses();
|
||||
|
||||
$vars['body']['items'] = array_map(function ($object) {
|
||||
$this->unserializeCustomData($object);
|
||||
|
||||
return $object;
|
||||
}, $vars['body']['items']);
|
||||
}
|
||||
|
||||
$vars['body']['statuses'] = $this->reclamationsSuppliersUtil->getStatuses();
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function handlePrintLabel()
|
||||
{
|
||||
if (!findModule(\Modules::BALIKONOS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$balikobot = ServiceContainer::getService(Balikobot::class);
|
||||
|
||||
$reclamationSupplier = $this->reclamationsSuppliersUtil->getReclamationSupplier($this->getID());
|
||||
|
||||
if (empty($reclamationSupplier['id_balikonos'])) {
|
||||
$this->returnError('Štítek nelze vytisknout, protože reklamace není v balíkobotu! Zkuste reklamaci odeslat do balíkobotu znovu tím, že na detailu reklamace dodavateli kliknete na tlačítko "OK"');
|
||||
}
|
||||
|
||||
try {
|
||||
$balikobot->printTickets(null, 1, 'default', [], false, [$reclamationSupplier['id_balikonos']]);
|
||||
} catch (\KupShop\BalikonosBundle\Exception\BalikonosException $e) {
|
||||
$this->returnError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function handlePrintReclamationSupplier()
|
||||
{
|
||||
/** @var ReclamationSuppliersPDF $reclamationAttachment */
|
||||
$reclamationAttachment = ServiceContainer::getService(ReclamationSuppliersPDF::class);
|
||||
$reclamationAttachment->setReclamationSupplier($this->reclamationsSuppliersUtil->getReclamationSupplier($this->getID()));
|
||||
|
||||
header('Content-type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="'.$reclamationAttachment->getFilename().'"');
|
||||
|
||||
echo $reclamationAttachment->getContent();
|
||||
}
|
||||
|
||||
public function handleUpdate()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
if ($this->getAction() == 'add') {
|
||||
$idSupplier = $data['id_supplier'];
|
||||
|
||||
$alreadyExists = sqlQueryBuilder()->select('id')->from('reclamations_suppliers')
|
||||
->where(Operator::equals(['id_supplier' => $idSupplier, 'status' => 0]))->execute()->fetchOne();
|
||||
if ($alreadyExists) {
|
||||
$this->returnError('Otevřená reklamace tomuto dodavateli už existuje.', '', $alreadyExists);
|
||||
}
|
||||
|
||||
$id = $this->reclamationsSuppliersUtil->createReclamation($data['id_supplier']);
|
||||
$this->setID($id);
|
||||
} elseif ($this->getAction() == 'edit') {
|
||||
$return = parent::handleUpdate();
|
||||
|
||||
$reclamationSupplier = $this->reclamationsSuppliersUtil->getReclamationSupplier($this->getID());
|
||||
|
||||
$this->updateItems($data['items']);
|
||||
|
||||
if ($reclamationSupplier['status'] != $data['status']) {
|
||||
if (empty($data['id_delivery'])) {
|
||||
$this->returnError('Není vyplněný způsob dopravy!');
|
||||
}
|
||||
try {
|
||||
$this->reclamationsSuppliersUtil->changeStatus($this->getID(), $data['status']);
|
||||
$this->reclamationsSuppliersUtil->logHistory($this->getID(), $data['comment'] ?: 'Změna stavu', $data['status']);
|
||||
} catch (InvalidSupplierInfo|BalikonosException $e) {
|
||||
$this->returnError($e->getMessage());
|
||||
}
|
||||
} elseif (!empty($data['comment'])) {
|
||||
$this->reclamationsSuppliersUtil->logHistory($this->getID(), $data['comment']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
$data = parent::getData();
|
||||
|
||||
if (getVal('Submit')) {
|
||||
if (empty($data['status'])) {
|
||||
$data['status'] = 0;
|
||||
}
|
||||
|
||||
$dates = ['date_created', 'date_accepted', 'date_handle'];
|
||||
foreach ($dates as $date) {
|
||||
if (!empty($data[$date])) {
|
||||
$data[$date] = $this->prepareDateTime($data[$date]);
|
||||
}
|
||||
}
|
||||
|
||||
if (($data['handle_type'] ?? -1) < 0) {
|
||||
$data['handle_type'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function updateItems($items)
|
||||
{
|
||||
$itemsToRemove = array_filter($items, function ($value, $key) {
|
||||
return $key > 0 && $value['delete'] == 'on';
|
||||
}, ARRAY_FILTER_USE_BOTH);
|
||||
|
||||
$itemsToAdd = array_filter($items, function ($_, $key) {
|
||||
return $key < 0;
|
||||
}, ARRAY_FILTER_USE_BOTH);
|
||||
|
||||
foreach ($itemsToAdd as $item) {
|
||||
$this->reclamationsSuppliersUtil->addItem($this->getID(), $item['product'], $item['variation'] ?: null, $item['pieces'], $item['data']);
|
||||
}
|
||||
|
||||
foreach ($itemsToRemove as $id => $_) {
|
||||
$this->reclamationsSuppliersUtil->removeItem(['id' => $id]);
|
||||
}
|
||||
|
||||
$oldItems = $this->reclamationsSuppliersUtil->getItems($this->getID());
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (!$id || empty($item['data']['reclamation_reason'])) {
|
||||
continue;
|
||||
}
|
||||
$item['data'] = array_merge($oldItems[$id]['data'] ?? [], $item['data']);
|
||||
$item['data']['reclamation_reason'] = trim($item['data']['reclamation_reason']);
|
||||
$this->serializeCustomData($item);
|
||||
sqlQueryBuilder()->update('reclamations_suppliers_items')
|
||||
->directValues(['data' => $item['data']])
|
||||
->where(Operator::equals(['id' => $id]))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getObject()
|
||||
{
|
||||
$data = sqlQueryBuilder()->select('rs.*, s.name supplier_name, s.id supplier_id')
|
||||
->from($this->getTableName(), 'rs')
|
||||
->where(Operator::equals(['rs.id' => $this->getID()]))
|
||||
->leftJoin('rs', 'suppliers', 's', 's.id = rs.id_supplier')
|
||||
->execute()->fetchAssociative();
|
||||
|
||||
$data['status_name'] = $this->reclamationsSuppliersUtil->getStatuses()[$data['status']];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
return ReclamationsSuppliers::class;
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
$txt_str['ReclamationsSuppliers'] = [
|
||||
'navigation' => 'Reklamace dodavatelům',
|
||||
'toolbar_list' => 'Reklamace dodavatelům',
|
||||
'toolbar_add' => 'Přidat reklamaci dodavateli',
|
||||
'titleEdit' => 'Úprava reklamace dodavateli',
|
||||
'titleAdd' => 'Přidat reklamaci dodavateli',
|
||||
|
||||
'status_0' => 'Rozpracováno',
|
||||
'status_1' => 'Odesláno dodavateli',
|
||||
'status_2' => 'Vyřízeno',
|
||||
|
||||
'ReclamationsSuppliers' => 'Reklamace dodavatelům',
|
||||
|
||||
'code' => 'Číslo reklamace',
|
||||
'supplier' => 'Dodavatel',
|
||||
'pieces' => 'Počet položek',
|
||||
'status' => 'Stav',
|
||||
'date_created' => 'Datum vytvoření',
|
||||
'date_accepted' => 'Datum odeslání',
|
||||
'date_handle' => 'Datum vyřízení',
|
||||
'delivery' => 'Doprava',
|
||||
'reclamationSupplier' => 'Reklamace dodavateli',
|
||||
'productCodeEan' => 'Kód / EAN',
|
||||
'history' => 'Historie',
|
||||
'comment' => 'Komentář',
|
||||
'note' => 'Poznámka',
|
||||
|
||||
'customersReclamation' => 'Reklamace zákazníka',
|
||||
'sticker' => 'Polepka',
|
||||
'productCount' => 'Počet',
|
||||
'product' => 'Produkt',
|
||||
'addProduct' => 'Přidat produkt',
|
||||
'items_list' => 'Seznam produktů',
|
||||
|
||||
'search' => 'Vyhledávání',
|
||||
'searchCode' => 'Zadejte číslo / kód reklamace dod.',
|
||||
'selectStatus' => 'Vyberte status',
|
||||
'selectSuppliers' => 'Vyberte dodavatele',
|
||||
'surname' => 'Vyberte zákazníka',
|
||||
'reclamation_code' => 'Kód reklamace',
|
||||
'delete' => 'Smazat',
|
||||
'searchBtn' => 'Hledat',
|
||||
'filterBasic' => 'Základní vyhledávání',
|
||||
'filterByProduct' => 'Podle produktu',
|
||||
'stockInCheck' => 'Kontrola',
|
||||
];
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
$txt_str['ReclamationsSuppliers'] = [
|
||||
];
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Admin\lists;
|
||||
|
||||
use KupShop\AdminBundle\AdminList\BaseList;
|
||||
use KupShop\AdminBundle\Query\Invert;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
|
||||
use KupShop\ReclamationsSuppliersBundle\Util\ReclamationsSuppliersUtil;
|
||||
use Query\Operator;
|
||||
|
||||
class ReclamationsSuppliersList extends BaseList
|
||||
{
|
||||
protected $tableName = 'reclamations_suppliers';
|
||||
protected ?string $tableAlias = 'rs';
|
||||
protected $tableDef = [
|
||||
'id' => 'rs.id',
|
||||
'fields' => [
|
||||
'code' => ['translate' => true, 'field' => 'rs.code', 'size' => 0.8],
|
||||
'supplier' => ['translate' => true, 'field' => 's.name'],
|
||||
'pieces' => ['translate' => true, 'field' => 'pieces', 'size' => 0.6],
|
||||
'status' => ['translate' => true, 'render' => 'renderStatus', 'field' => 'rs.status', 'size' => 0.8],
|
||||
'date_created' => ['translate' => true, 'field' => 'rs.date_created', 'render' => 'renderDateTime'],
|
||||
'date_accepted' => ['translate' => true, 'field' => 'rs.date_accepted', 'render' => 'renderDateTime'],
|
||||
'date_handle' => ['translate' => true, 'field' => 'rs.date_handle', 'render' => 'renderDateTime'],
|
||||
],
|
||||
'class' => 'getRowClass',
|
||||
];
|
||||
|
||||
protected $orderParam = [
|
||||
'sort' => 'code',
|
||||
'direction' => 'DESC',
|
||||
];
|
||||
|
||||
/** @var ReclamationsSuppliersUtil */
|
||||
protected $reclamationsSuppliersUtil;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->reclamationsSuppliersUtil = ServiceContainer::getService(ReclamationsSuppliersUtil::class);
|
||||
}
|
||||
|
||||
public function customizeTableDef($tableDef)
|
||||
{
|
||||
if (findModule(\Modules::WAREHOUSE) || findModule(\Modules::CHECK_APP)) {
|
||||
$tableDef['fields']['stockInCheck'] = ['translate' => true, 'field' => 'rs.id', 'size' => 1, 'class' => 'right', 'render' => 'renderAutomaticStockIn'];
|
||||
}
|
||||
|
||||
return $tableDef;
|
||||
}
|
||||
|
||||
public function renderStatus($values, $column)
|
||||
{
|
||||
return $this->reclamationsSuppliersUtil->getStatuses()[$values['status']];
|
||||
}
|
||||
|
||||
public function renderAutomaticStockIn($values)
|
||||
{
|
||||
if ($values['status'] != 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$output = HTML::create('a');
|
||||
$output
|
||||
->attr('href', "javascript:nw('reclamationSupplierCheck', '{$values['id']}')")
|
||||
->tag('span')
|
||||
->class('badge badge-primary')
|
||||
->tag('span')
|
||||
->class('glyphicon glyphicon-barcode')
|
||||
->text(' Kontrola')
|
||||
->end()
|
||||
->end();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
$qb = sqlQueryBuilder()
|
||||
->select('rs.id, rs.status, rs.code, rs.date_created, rs.date_accepted, rs.date_handle, SUM(rsi.pieces) pieces, s.name')
|
||||
->from($this->getTableName(), 'rs')
|
||||
->leftJoin('rs', 'reclamations_suppliers_items', 'rsi', 'rs.id = rsi.id_reclamation_supplier')
|
||||
->join('rs', 'suppliers', 's', 'rs.id_supplier = s.id')
|
||||
->groupBy('rs.id');
|
||||
|
||||
if ($status = getVal('status')) {
|
||||
$qb->andWhere(
|
||||
Invert::checkInvert(Operator::inIntArray($status, 'rs.status'), getVal('status_invert'))
|
||||
);
|
||||
}
|
||||
|
||||
if ($code = getVal('code')) {
|
||||
$qb->andWhere(
|
||||
Invert::checkInvert(
|
||||
Operator::orX(
|
||||
[
|
||||
Operator::equals(['rs.id' => $code]),
|
||||
Operator::equals(['rs.code' => $code]),
|
||||
]
|
||||
),
|
||||
getVal('code_invert')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($productId = getVal('id_product')) {
|
||||
$qb->andWhere('rsi.id_product = :id_product')
|
||||
->setParameter('id_product', $productId);
|
||||
|
||||
if ($variationId = getVal('id_variation')) {
|
||||
if (intval($variationId) > 0) {
|
||||
$qb->andWhere('rsi.id_variation = :id_variation')
|
||||
->setParameter('id_variation', $variationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($suppliers = getVal('suppliers')) {
|
||||
$qb->andWhere(
|
||||
Invert::checkInvert(
|
||||
Operator::inIntArray($suppliers, 'rs.id_supplier'),
|
||||
getVal('suppliers_invert')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($name = getVal('surname')) {
|
||||
$qb->leftJoin('rsi', 'reclamations', 'r', 'rsi.id_reclamation = r.id');
|
||||
$qb->andWhere(Invert::checkInvert(Operator::like(['r.surname' => "%{$name}%", 'r.name' => "%{$name}%"], 'OR'), getVal('surname_invert')));
|
||||
}
|
||||
|
||||
if ($reclamationCode = getVal('reclamation_code')) {
|
||||
$qb->leftJoin('rsi', 'reclamations', 'r', 'rsi.id_reclamation = r.id');
|
||||
$qb->andWhere(Invert::checkInvert(Operator::equals(['r.code' => $reclamationCode]), getVal('reclamation_code_invert')));
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
|
||||
return ReclamationsSuppliersList::class;
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\ReclamationsSuppliersBundle\Util\ReclamationsSuppliersUtil;
|
||||
|
||||
class ReclamationsSuppliersMenu extends \Menu
|
||||
{
|
||||
public function get_vars()
|
||||
{
|
||||
$vars = parent::get_vars();
|
||||
$reclamations = ServiceContainer::getService(ReclamationsSuppliersUtil::class);
|
||||
$vars['statuses'] = $reclamations->getStatuses();
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{extends file="menu.tpl"}
|
||||
|
||||
{block name="menu-items"}
|
||||
<li class="nav-header"><i class="glyphicon glyphicon-tags"></i><span>{translate_type type=$type}</span></li>
|
||||
<li><a href="javascript:nf('launch.php?s=menu.php&type=ReclamationsSuppliers', 'launch.php?s=list.php&type=ReclamationsSuppliers');"><i class="glyphicon glyphicon-list"></i> <span>{'toolbar_list'|translate}</span></a></li>
|
||||
|
||||
<li><a href="javascript:nw('{$type}');"><i class="glyphicon glyphicon-plus"></i> <span>{'toolbar_add'|translate}</span></a></li>
|
||||
|
||||
<li class="nav-header smaller"><i class="glyphicon glyphicon-search"></i><span>{'search'|translate:'ReclamationsSuppliers'}</span></li>
|
||||
|
||||
<li class="with_caret "><a href="#" class="opener"><span>{'filterBasic'|translate}</span></a></li>
|
||||
<li class="pill-content">
|
||||
<ul class="nav-sub nav-pills">
|
||||
<form id='search' target="mainFrame" method="get" action="launch.php" class="form-inline">
|
||||
<input type="hidden" name="type" value="{$type}" /><input type="hidden" name="s" value="list.php">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<input type="text" name="code" class="form-control input-sm" placeholder="{'searchCode'|translate}">
|
||||
{inversion field="code"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<select name="status[]" multiple="multiple" class="selecter" data-placeholder="{'selectStatus'|translate}">
|
||||
{foreach $statuses as $key => $value}
|
||||
<option value="{$key}">{$value}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
{inversion field="status"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<select name="suppliers[]" multiple="multiple" class="selecter"
|
||||
data-placeholder="{'selectSuppliers'|translate}" data-autocomplete="suppliers"></select>
|
||||
{inversion field="suppliers"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<input type="text" name="surname" class="form-control input-sm" placeholder="{'surname'|translate}">
|
||||
{inversion field="surname"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<input type="text" name="reclamation_code" class="form-control input-sm" placeholder="{'reclamation_code'|translate}">
|
||||
{inversion field="reclamation_code"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="reset" id="resetBtn" value="{'delete'|translate}" class="btn btn-danger btn-sm"/>
|
||||
<input type="submit" value="{'searchBtn'|translate}" class="btn btn-primary btn-sm"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="with_caret "><a href="#" class="opener"><span>{'filterByProduct'|translate}</span></a></li>
|
||||
<li class="pill-content">
|
||||
<ul class="nav-sub nav-pills">
|
||||
<form id='search' target="mainFrame" method="get" action="launch.php" class="form-inline">
|
||||
<input type="hidden" name="type" value="{$type}" /><input type="hidden" name="s" value="list.php">
|
||||
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control input-sm" name="id_product" maxlength="100" value="" onKeyPress="checkInputData('int')" placeholder="{'searchNameCode'|translate:'orders'}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="id_variation" class="input-sm form-control"></select>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
initAutocompleteVariation('[name=id_product]', '[name=id_variation]');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="reset" id="resetBtn" value="{'delete'|translate}" class="btn btn-danger btn-sm"/>
|
||||
<input type="submit" value="{'searchBtn'|translate}" class="btn btn-primary btn-sm"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</ul>
|
||||
</li>
|
||||
{/block}
|
||||
@@ -0,0 +1,358 @@
|
||||
{extends file="[shared]/window.tpl"}
|
||||
|
||||
{block size}
|
||||
width = 1220;
|
||||
height = 900;
|
||||
{/block}
|
||||
|
||||
{block tabs}
|
||||
{windowTab id='flapReclamationSupplier' label=translate('reclamationSupplier')|cat:' '|cat:$body.data.code}
|
||||
{/block}
|
||||
|
||||
{block tabsContent}
|
||||
<div id="flapReclamationSupplier" class="tab-pane fade active in boxStatic box" data-form>
|
||||
|
||||
{if $body.acn == 'add'}
|
||||
<div class="row bottom-space">
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'supplier'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<select name="data[id_supplier]" class="selecter" data-autocomplete="suppliers">
|
||||
<option value="">-- Vyberte dodavatele --</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
|
||||
|
||||
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'supplier'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<a href="javascript:nw('suppliers', {$body.data.supplier_id})">
|
||||
{$body.data.supplier_name}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'status'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
{$body.data.status_name}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'delivery'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<select name="data[id_delivery]" class="selecter" data-autocomplete="deliveries" data-preload="deliveries">
|
||||
{if $body.data.id_delivery}
|
||||
<option value="{$body.data.id_delivery}">{$body.data.id_delivery}</option>
|
||||
{else}
|
||||
<option value="">-- Vyberte dopravu --</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'date_created'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input id="date_created" class="form-control input-sm" type="text" name="data[date_created]"
|
||||
value="{$body.data.date_created|format_datetime}">
|
||||
{insert_calendar selector='#date_created' format='datetime'}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'date_accepted'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input id="date_accepted" class="form-control input-sm" type="text" name="data[date_accepted]"
|
||||
value="{$body.data.date_accepted|format_datetime}">
|
||||
{insert_calendar selector='#date_accepted' format='datetime'}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-flex">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>{'date_handle'|translate}</label>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input id="date_handle" class="form-control input-sm" type="text" name="data[date_handle]"
|
||||
value="{$body.data.date_handle|format_datetime}">
|
||||
{insert_calendar selector='#date_handle' format='datetime'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-{if $body.data.status == 0}7{else}12{/if}">
|
||||
<h4 class="main-panel-title">{'items_list'|translate}</h4>
|
||||
</div>
|
||||
{if $body.data.status == 0}
|
||||
<div class="col-md-5 text-right">
|
||||
<input type="text" data-autocomplete-search="products" autocomplete="off"
|
||||
class="form-control input-sm autocomplete-control" name="addProduct"
|
||||
placeholder="{'addProduct'|translate}">
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="panel-group panel-group-lists" data-values="items">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-1 text-center">
|
||||
<small><strong>{'productCount'|translate}</strong></small>
|
||||
</div>
|
||||
<div class="col-md-4 text-left">
|
||||
<small><strong>{'product'|translate}</strong></small>
|
||||
</div>
|
||||
<div class="col-md-2 text-left">
|
||||
<small><strong>{'productCodeEan'|translate}</strong></small>
|
||||
</div>
|
||||
<div class="col-md-2 text-left">
|
||||
<small><strong>{'customersReclamation'|translate}</strong></small>
|
||||
</div>
|
||||
<div class="col-md-1 text-left">
|
||||
<small><strong>{'sticker'|translate}</strong></small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{foreach [-1=>[]] + $body.items as $key => $row}
|
||||
|
||||
<div class="panel" {if $key == -1} data-form-new style="display: none"{else}data-form-item{/if}>
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<input type="text" name="data[items][0][product]" hidden="hidden" data-new-product>
|
||||
<input type="text" name="data[items][0][variation]" hidden="hidden" data-new-variation>
|
||||
|
||||
<div class="col-md-1 text-center">
|
||||
{if $key == -1}
|
||||
<input class="form-control input-sm" type="number" min="0" placeholder="ks" name="data[items][0][pieces]" value="1">
|
||||
{else}
|
||||
{$row.pieces}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a href="javascript:nw('product', '{$row.product_id}', 'noopener');" data-new-title data-new-href>
|
||||
{$row.product_title}
|
||||
{if $row.variation_title}
|
||||
({$row.variation_title})
|
||||
{/if}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-2" data-new-code>
|
||||
{$row.product_code} <b>/</b> {$row.product_ean}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<a href="javascript:nw('Reclamations', '{$row.reclamation_id}', 'noopener');">
|
||||
{$row.reclamation_code}
|
||||
</a> {if $row.reclamation_id} - {$body.data.reclamationStatuses[$row.reclamation_status]} {/if}
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
{if $row.reclamation_id}
|
||||
<a href="launch.php?s=printCenter.php&type=order&set=Reclamations&ID={$row.reclamation_id}&id_supplier={$body.data.id_supplier}" target="_blank" class="btn btn-sm">
|
||||
<span class="glyphicon glyphicon-print"></span>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="col-md-1 col-md-offset-1">
|
||||
<input class="hidden" type="checkbox" name="data[items][{$row.id}][delete]">
|
||||
<a class="btn-sm btn btn-danger" title="{'buttonDeleteValue'|translate}" data-form-delete>
|
||||
<input class="hidden" type="checkbox" name="data[items][{$row.id}][delete]">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
</div>
|
||||
{* </div>*}
|
||||
</div>
|
||||
{if !$row.reclamation_id}
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-1">
|
||||
{if $key == -1}
|
||||
<textarea class="form-control input" placeholder="Důvod reklamace" name="data[items][0][data][reclamation_reason]" rows="1" ></textarea>
|
||||
{else}
|
||||
|
||||
|
||||
<textarea class="form-control input" placeholder="Důvod reklamace" name="data[items][{$row.id}][data][reclamation_reason]" rows="1" >{$row.data.reclamation_reason}</textarea>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{* </div>*}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default panel-sm">
|
||||
<div class="panel-heading"><h3 class="panel-title">{'history'|translate}</h3></div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="13%">{'date'|translate:'base'}</th>
|
||||
<th width="15%">{'status'|translate}</th>
|
||||
<th width="55%">{'note'|translate}</th>
|
||||
<th scope="col">admin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $body.data.history as $key => $row}
|
||||
<tr style="border-bottom: thin; {if $row.notified == 3}background-color: #bfec55;{/if}">
|
||||
<td>{$row.date|format_datetime}</td>
|
||||
<td>{$row.status_name}</td>
|
||||
<td>{$row.comment nofilter}</td>
|
||||
<td>{$row.admin_name}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="data[status]" value="{$body.data.status}" id="status_combo">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group" id="statusButtons">
|
||||
{foreach $body.statuses as $key => $status}
|
||||
{* {if $body.data.handle_type === null && $key == 2}*}
|
||||
{* {continue}*}
|
||||
{* {/if}*}
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-block btn-status {if $body.data.status == $key}btn-active{/if}"
|
||||
style="background-color:#BBEECC;" data-status="{$key}" title="{$status}">
|
||||
{$status}
|
||||
</button>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<a href="launch.php?s=ReclamationsSuppliers.php&acn=printReclamationSupplier&ID={$body.data.id}" target="_blank" class="btn btn-block btn-primary">
|
||||
<span class="glyphicon glyphicon-print"></span>
|
||||
Tisk reklam. dod.
|
||||
</a>
|
||||
</div>
|
||||
{if $body.data.status != 0}
|
||||
<div class="col-md-4">
|
||||
<a href="launch.php?s=ReclamationsSuppliers.php&acn=printLabel&ID={$body.data.id}" target="_blank" class="btn btn-block btn-primary">
|
||||
<span class="glyphicon glyphicon-print"></span>
|
||||
Tisk štítku
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
{if $body.data.status == 0}
|
||||
<div class="col-md-4">
|
||||
<a href="javascript:nw('reclamationSupplierCheck', '{$body.data.id}')"
|
||||
class="btn btn-primary btn-block">
|
||||
Výstupní kontrola</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h1 class="h4 main-panel-title">{'comment'|translate} <span data-attachment="" class="badge badge-default pull-right"></span></h1>
|
||||
<textarea id="comments" name="data[comment]" wrap="soft"></textarea>
|
||||
{insert_wysiwyg target="comments" type="BasicTable"
|
||||
config="toolbarStartupExpanded : false,startupFocus : false,removePlugins : 'elementspath', height:'100px', resize_minHeight:'100px', resize_enabled:false, ignoreEmptyParagraph:true, startupOutlineBlocks:false"}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
{block initForm}
|
||||
initForm({
|
||||
beforeAdd: function (original) {
|
||||
var $form = original();
|
||||
initAutocompleteVariation($form.find('#id_product'), $form.find('#id_variation'));
|
||||
|
||||
}
|
||||
});
|
||||
{/block}
|
||||
|
||||
var config = {
|
||||
allowSelectProduct: false,
|
||||
$menu: null,
|
||||
minLength: 2,
|
||||
xhr: null,
|
||||
data: null,
|
||||
templateContext: null,
|
||||
select: function(e, item) {
|
||||
var $item = $('[data-form-new]');
|
||||
|
||||
var $newItem = addNewItem($item);
|
||||
|
||||
var title = item.product.title;
|
||||
var variationId = item.variation?.id;
|
||||
if (!variationId && item.product.value_variation) {
|
||||
variationId = item.product.value_variation;
|
||||
}
|
||||
|
||||
if (variationId) {
|
||||
var variationTitle = null;
|
||||
var variations = item.product.variations;
|
||||
$.each(variations, function(index, variation) {
|
||||
if (variation.id == variationId) {
|
||||
variationTitle = variation.title;
|
||||
}
|
||||
});
|
||||
|
||||
title += ' (' + variationTitle + ')';
|
||||
}
|
||||
|
||||
$newItem.find('[data-new-title]').text(title);
|
||||
$newItem.find('[data-new-href]').attr('href', 'javascript:nw(\'product\', \'' + item.product.value + '\')');
|
||||
$newItem.find('[data-new-product]').val(item.product.value);
|
||||
$newItem.find('[data-new-variation]').val(variationId);
|
||||
$('[data-autocomplete-search]').val('');
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var addProductsAutocomplete = $('[data-autocomplete-search="products"]');
|
||||
addProductsAutocomplete.adminVariationAutoComplete(config);
|
||||
|
||||
$('#statusButtons').on('click', '[data-status]', function (e) {
|
||||
var status = $(this).data('status');
|
||||
$(this).closest('#statusButtons').find('.btn-active').removeClass('btn-active');
|
||||
$(this).closest('div').find('button').addClass('btn-active');
|
||||
$('#status_combo').val(status);
|
||||
return true;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\AdminRegister;
|
||||
|
||||
use KupShop\AdminBundle\AdminRegister\AdminRegister;
|
||||
use KupShop\AdminBundle\AdminRegister\IAdminRegisterDynamic;
|
||||
use KupShop\AdminBundle\AdminRegister\IAdminRegisterStatic;
|
||||
|
||||
class ReclamationsSuppliersAdminRegister extends AdminRegister implements IAdminRegisterDynamic, IAdminRegisterStatic
|
||||
{
|
||||
public function getDynamicMenu(): array
|
||||
{
|
||||
return [
|
||||
static::createMenuItem('stockMenu', [
|
||||
'name' => 'ReclamationsSuppliers',
|
||||
'title' => translate('ReclamationsSuppliers', 'ReclamationsSuppliers'),
|
||||
'left' => 's=menu.php&type=ReclamationsSuppliers',
|
||||
'right' => 's=list.php&type=ReclamationsSuppliers',
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array
|
||||
{
|
||||
return [
|
||||
static::createPermissions('ReclamationsSuppliers', [\Modules::RECLAMATIONS], ['RECLAMATIONS']),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Attachment;
|
||||
|
||||
use KupShop\KupShopBundle\Util\Pdf\HTMLToPDF;
|
||||
use KupShop\OrderingBundle\Attachment\BaseAttachment;
|
||||
use KupShop\OrderingBundle\Util\Invoice\PdfGenerator;
|
||||
use KupShop\ReclamationsBundle\Util\ReclamationsUtil;
|
||||
use KupShop\ReclamationsSuppliersBundle\Util\ReclamationsSuppliersUtil;
|
||||
use Query\Operator;
|
||||
|
||||
class ReclamationSuppliersPDF extends BaseAttachment
|
||||
{
|
||||
protected static $name = 'Reklamace dodavateli';
|
||||
protected static $type = 'reclamationSupplier';
|
||||
|
||||
protected $filename = 'ReklamaceDodavateli_{KOD}.pdf';
|
||||
protected $template = 'pdf/reclamationSupplierPDF.tpl';
|
||||
|
||||
private $reclamationSupplier;
|
||||
|
||||
private $pdfGenerator;
|
||||
private $reclamationsUtil;
|
||||
|
||||
private ReclamationsSuppliersUtil $reclamationsSuppliersUtil;
|
||||
|
||||
public function __construct(PdfGenerator $pdfGenerator, ReclamationsUtil $reclamationsUtil, ReclamationsSuppliersUtil $reclamationsSuppliersUtil)
|
||||
{
|
||||
$this->pdfGenerator = $pdfGenerator;
|
||||
$this->reclamationsUtil = $reclamationsUtil;
|
||||
$this->reclamationsSuppliersUtil = $reclamationsSuppliersUtil;
|
||||
}
|
||||
|
||||
public static function isAllowed()
|
||||
{
|
||||
// aby se nezobrazovala v prilohach k emailum
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->reclamationsUtil->replacePlaceholders($this->filename, ['KOD' => $this->reclamationSupplier['code']]);
|
||||
}
|
||||
|
||||
public function setReclamationSupplier($reclamationSupplier)
|
||||
{
|
||||
$this->reclamationSupplier = $reclamationSupplier;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
$supplier = sqlQueryBuilder()->select('*')
|
||||
->from('suppliers', 's')
|
||||
->where(Operator::equals(['id' => $this->reclamationSupplier['id_supplier']]))
|
||||
->execute()->fetchAssociative();
|
||||
|
||||
$items = $this->reclamationsSuppliersUtil->getItems($this->reclamationSupplier['id']);
|
||||
|
||||
$smarty = createSmarty(false, true);
|
||||
$smarty->assign([
|
||||
'reclamationSupplier' => $this->reclamationSupplier,
|
||||
'supplier' => $supplier,
|
||||
'items' => $items,
|
||||
]);
|
||||
|
||||
$content = $smarty->fetch($this->template);
|
||||
|
||||
$html2pdf = new HTMLToPDF();
|
||||
|
||||
return $html2pdf->generatePDF($content, null, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Exception;
|
||||
|
||||
class InvalidSupplierInfo extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class ReclamationsSuppliersBundle extends Bundle
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
public: false
|
||||
|
||||
KupShop\ReclamationsSuppliersBundle\:
|
||||
resource: ../../{AdminRegister,Util,Attachment}
|
||||
@@ -0,0 +1,90 @@
|
||||
{extends '[common]pdf/invoicePDF.tpl'}
|
||||
|
||||
{block "header-table"}
|
||||
<td align="right" valign="bottom" width="136"><pdf:barcode value="{$reclamationSupplier.code}" type="code128" humanreadable="0" barheight="27" barWidth="1" /></td>
|
||||
{/block}
|
||||
|
||||
{block "header-title"}
|
||||
{t}Reklamace dodavateli{/t}: {$reclamation.code}
|
||||
{/block}
|
||||
|
||||
{block "invoice-title"}
|
||||
<h1 class="bordered">{t}Reklamace dodavateli{/t} {$reclamationSupplier.code}</h1>
|
||||
{/block}
|
||||
|
||||
{block "invoice-dates"}
|
||||
<table width="100%" class="dates">
|
||||
<tr>
|
||||
<td width="60%">
|
||||
{get_datetime assign="now"}
|
||||
<strong>{t}Vytvoření{/t}:</strong>
|
||||
</td>
|
||||
<td align="right" width="40%" style="padding-right: 1mm;">{$reclamationSupplier.date_created|format_date:'d.m.Y'}</td>
|
||||
</tr>
|
||||
|
||||
{if $reclamationSupplier.date_handle}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{t}Vyřízení{/t}:</strong>
|
||||
</td>
|
||||
<td align="right" style="padding-right: 1mm;"> {$reclamationSupplier.date_handle|format_date:'d.m.Y'}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</table>
|
||||
{/block}
|
||||
|
||||
{block "bank"}
|
||||
{/block}
|
||||
|
||||
{block "customer-address"}
|
||||
<table class="address">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<h2>{t}Dodavatel{/t}:</h2>
|
||||
{$supplier.name}<br>
|
||||
{$supplier.address|nl2br nofilter}<br>
|
||||
{if $supplier.ico}{t}IČO{/t}: {$supplier.ico} {/if}<br>
|
||||
{if $supplier.dic}{t}DIČ{/t}: {$supplier.dic}{/if}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{/block}
|
||||
|
||||
{block "delivery"}{/block}
|
||||
|
||||
|
||||
{block "items"}
|
||||
{* repeat znamena ze se bude opakovat hlavicka tabulky v pripade, ze se rozdeli na 2 stranky *}
|
||||
<table class="product-list" repeat="1">
|
||||
<tr>
|
||||
<th style="text-align: center; width: 10mm;">{t}Ks{/t}</th>
|
||||
|
||||
<th style="text-align: left; width: 100%;">{t}Položky{/t}</th>
|
||||
<th style="text-align: center; width: 60mm;">{t}EAN/Kód{/t}</th>
|
||||
|
||||
<th style="text-align: right; width: 35mm">{t}Reklamace zákazníka{/t}</th>
|
||||
<th style="text-align: right; width: 60mm">{t}Kód u dodavatele{/t}</th>
|
||||
<th style="text-align: left; width: 100mm">{t}Popis reklamace{/t}</th>
|
||||
|
||||
|
||||
</tr>
|
||||
{foreach $items as $item}
|
||||
<tr {if $item@last && !$item.id_product}class="last"{/if}>
|
||||
<td align="center">{$item.pieces}</td>
|
||||
<td align="left">{$item.product_title}</td>
|
||||
<td align="center" class="code"><div>{$item.product_ean|default:'-'} <b>/</b> {$item.product_code|default:'-'}</div></td>
|
||||
<td align="center" class="code"><div>{$item.reclamation_code}</div></td>
|
||||
<td align="center" class="code"><div>{$item.supplier_code}</div></td>
|
||||
<td align="left"><div>
|
||||
{if $item.data.reclamation_reason}
|
||||
{substr($item.data.reclamation_reason|default:'',0,100)}
|
||||
{else}
|
||||
{substr($item.reclamation_reason|default:'',0,100)}
|
||||
{/if}
|
||||
</div></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
{/block}
|
||||
|
||||
{block "invoice-bottom"}{/block}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Resources\upgrade;
|
||||
|
||||
class ReclamationsSuppliersUpgrade extends \UpgradeNew
|
||||
{
|
||||
public function check_ReclamationsSuppliers()
|
||||
{
|
||||
return $this->checkTableExists('reclamations_suppliers');
|
||||
}
|
||||
|
||||
/** Create table 'reclamations_suppliers' */
|
||||
public function upgrade_ReclamationsSuppliers()
|
||||
{
|
||||
sqlQuery('create table reclamations_suppliers
|
||||
(
|
||||
id int auto_increment
|
||||
primary key,
|
||||
code varchar(20) null,
|
||||
id_supplier int null,
|
||||
date_created datetime default current_timestamp() null,
|
||||
date_handle datetime null,
|
||||
status int not null,
|
||||
history longtext null,
|
||||
date_accepted datetime null,
|
||||
id_delivery int null,
|
||||
id_balikonos int null,
|
||||
constraint code
|
||||
unique (code),
|
||||
constraint reclamations_suppliers_balikonos_id_fk
|
||||
foreign key (id_balikonos) references balikonos (id)
|
||||
on update cascade on delete set null,
|
||||
constraint reclamations_suppliers_delivery_type_delivery_id_fk
|
||||
foreign key (id_delivery) references delivery_type_delivery (id)
|
||||
on update cascade on delete set null
|
||||
);
|
||||
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_ReclamationsSuppliersItems()
|
||||
{
|
||||
return $this->checkTableExists('reclamations_suppliers_items');
|
||||
}
|
||||
|
||||
/** Create table 'reclamations_suppliers_items' */
|
||||
public function upgrade_ReclamationsSuppliersItems()
|
||||
{
|
||||
sqlQuery('
|
||||
create table reclamations_suppliers_items
|
||||
(
|
||||
id int auto_increment
|
||||
primary key,
|
||||
id_reclamation_supplier int not null,
|
||||
id_reclamation int null,
|
||||
id_product int not null,
|
||||
id_variation int null,
|
||||
pieces int not null,
|
||||
constraint reclamations_suppliers_items_reclamations_id_fk
|
||||
foreign key (id_reclamation) references reclamations (id)
|
||||
on update cascade on delete set null,
|
||||
constraint reclamations_suppliers_items_reclamations_suppliers_id_fk
|
||||
foreign key (id_reclamation_supplier) references reclamations_suppliers (id)
|
||||
on update cascade on delete cascade
|
||||
);
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_ReclamationsSuppliersSuppliersForeignKey()
|
||||
{
|
||||
return $this->checkForeignKeyExists('reclamations_suppliers', 'id_supplier');
|
||||
}
|
||||
|
||||
public function upgrade_ReclamationsSuppliersSuppliersForeignKey()
|
||||
{
|
||||
sqlQuery('
|
||||
alter table reclamations_suppliers add
|
||||
constraint reclamations_suppliers_suppliers_id_fk
|
||||
foreign key (id_supplier) references suppliers (id)
|
||||
on update cascade on delete cascade
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_ReclamationsSuppliersItemsCustomData()
|
||||
{
|
||||
return $this->checkColumnExists('reclamations_suppliers_items', 'data');
|
||||
}
|
||||
|
||||
public function upgrade_ReclamationsSuppliersItemsCustomData()
|
||||
{
|
||||
sqlQuery('
|
||||
alter table reclamations_suppliers_items
|
||||
add data longtext null;
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_ReclamationsSuppliersCustomData()
|
||||
{
|
||||
return $this->checkColumnExists('reclamations_suppliers', 'data');
|
||||
}
|
||||
|
||||
public function upgrade_ReclamationsSuppliersCustomData()
|
||||
{
|
||||
sqlQuery('
|
||||
alter table reclamations_suppliers
|
||||
add data longtext null;
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ReclamationsSuppliersBundle\Util;
|
||||
|
||||
use KupShop\BalikonosBundle\Balikobot;
|
||||
use KupShop\BalikonosBundle\Exception\BalikonosException;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\KupShopBundle\Util\Suppliers\SuppliersUtil;
|
||||
use KupShop\ReclamationsSuppliersBundle\Exception\InvalidSupplierInfo;
|
||||
use Query\Operator;
|
||||
|
||||
class ReclamationsSuppliersUtil
|
||||
{
|
||||
public function addItemFromReclamation($supplierId, $reclamation)
|
||||
{
|
||||
$supplierReclamationId = sqlQueryBuilder()->select('id')
|
||||
->from('reclamations_suppliers', 'rs')
|
||||
->where(Operator::equals([
|
||||
'status' => 0,
|
||||
'id_supplier' => $supplierId,
|
||||
]))->execute()->fetchOne();
|
||||
|
||||
if (!$supplierReclamationId) {
|
||||
$supplierReclamationId = $this->createReclamation($supplierId);
|
||||
}
|
||||
|
||||
$item = $reclamation->getItem();
|
||||
|
||||
sqlQueryBuilder()->insert('reclamations_suppliers_items')
|
||||
->directValues([
|
||||
'id_reclamation_supplier' => $supplierReclamationId,
|
||||
'id_reclamation' => $reclamation['id'],
|
||||
'pieces' => $reclamation['pieces'],
|
||||
'id_product' => $item['id_product'],
|
||||
'id_variation' => $item['id_variation'],
|
||||
])->execute();
|
||||
|
||||
$this->logHistory($supplierReclamationId, 'Přidán produkt z reklamace '.$reclamation['code']);
|
||||
}
|
||||
|
||||
public function addItem($supplierReclamationId, $productId, $variationId, $pieces, $data = null)
|
||||
{
|
||||
sqlQueryBuilder()->insert('reclamations_suppliers_items')
|
||||
->directValues([
|
||||
'id_reclamation_supplier' => $supplierReclamationId,
|
||||
'pieces' => $pieces,
|
||||
'id_product' => $productId,
|
||||
'id_variation' => $variationId,
|
||||
'data' => json_encode($data ?: ''),
|
||||
])->execute();
|
||||
}
|
||||
|
||||
public function getItems($supplierReclamationId)
|
||||
{
|
||||
$items = sqlFetchAll(sqlQueryBuilder()
|
||||
->select('rsi.id, COALESCE(pv.code, p.code) product_code, COALESCE(pv.ean, p.ean) product_ean, p.id product_id, pv.id variation_id,
|
||||
r.id reclamation_id, r.code reclamation_code, r.status reclamation_status, rsi.pieces, p.title product_title, pv.title variation_title, r.user_note reclamation_reason,
|
||||
pos.code supplier_code, rsi.data')
|
||||
->from('reclamations_suppliers_items', 'rsi')
|
||||
->innerJoin('rsi', 'reclamations_suppliers', 'rs', 'rsi.id_reclamation_supplier = rs.id')
|
||||
->leftJoin('rsi', 'reclamations', 'r', 'rsi.id_reclamation = r.id')
|
||||
->leftJoin('rsi', 'products', 'p', 'p.id = rsi.id_product')
|
||||
->leftJoin('rsi', 'products_variations', 'pv', 'pv.id = rsi.id_variation')
|
||||
->leftJoin('rs', 'products_of_suppliers', 'pos', 'pos.id_product = rsi.id_product AND pos.id_variation <=> rsi.id_variation AND pos.id_supplier = rs.id_supplier')
|
||||
->where(Operator::equals(['id_reclamation_supplier' => $supplierReclamationId]))
|
||||
->orWhere(Operator::equals(['rs.code' => $supplierReclamationId]))
|
||||
->execute(), 'id');
|
||||
|
||||
$items = array_map(function ($item) {
|
||||
$item['data'] = json_decode($item['data'] ?? '', true);
|
||||
|
||||
return $item;
|
||||
}, $items);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function removeItem($where)
|
||||
{
|
||||
sqlQueryBuilder()->delete('reclamations_suppliers_items')
|
||||
->where(Operator::equalsNullable($where))
|
||||
->execute();
|
||||
}
|
||||
|
||||
public function getReclamationSupplier(int $reclamationSupplierId)
|
||||
{
|
||||
$reclamationSupplier = sqlQueryBuilder()->select('*')->from('reclamations_suppliers')
|
||||
->where(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute()->fetchAssociative();
|
||||
|
||||
$reclamationSupplier['data'] = json_decode($reclamationSupplier['data'] ?? '', true);
|
||||
|
||||
return $reclamationSupplier;
|
||||
}
|
||||
|
||||
public function createReclamation($supplierId): int
|
||||
{
|
||||
$deliveries = \Delivery::getAll(false);
|
||||
|
||||
sqlQueryBuilder()->insert('reclamations_suppliers')
|
||||
->directValues([
|
||||
'status' => 0,
|
||||
'id_supplier' => $supplierId,
|
||||
'id_delivery' => $deliveries ? reset($deliveries)['id'] : null,
|
||||
])->execute();
|
||||
|
||||
$reclamationSupplierId = sqlInsertId();
|
||||
|
||||
sqlQueryBuilder()->update('reclamations_suppliers')
|
||||
->directValues([
|
||||
'code' => $this->getCode($reclamationSupplierId),
|
||||
])
|
||||
->where(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute();
|
||||
|
||||
return $reclamationSupplierId;
|
||||
}
|
||||
|
||||
public function getCode($reclamationSupplierId)
|
||||
{
|
||||
return 'RD'.sprintf('%03d', $reclamationSupplierId);
|
||||
}
|
||||
|
||||
public function getStatuses(): array
|
||||
{
|
||||
return [
|
||||
0 => translate('status_0', 'ReclamationsSuppliers'),
|
||||
1 => translate('status_1', 'ReclamationsSuppliers'),
|
||||
2 => translate('status_2', 'ReclamationsSuppliers'),
|
||||
];
|
||||
}
|
||||
|
||||
public function logHistory(int $reclamationSupplierId, $comment, $status = 0, ?\DateTime $date = null)
|
||||
{
|
||||
global $adminID;
|
||||
|
||||
if ($date === null) {
|
||||
$date = new \DateTime();
|
||||
}
|
||||
|
||||
$history = $this->getHistory($reclamationSupplierId);
|
||||
$history[] = [
|
||||
'comment' => $comment,
|
||||
'status' => $status,
|
||||
'date' => $date->format('Y-m-d H:i:s'),
|
||||
'admin' => !empty($adminID) ? $adminID : null,
|
||||
];
|
||||
|
||||
sqlQueryBuilder()->update('reclamations_suppliers')->directValues([
|
||||
'history' => json_encode($history),
|
||||
])->andWhere(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHistory(int $reclamationSupplierId)
|
||||
{
|
||||
$history = sqlQueryBuilder()->select('history')->from('reclamations_suppliers')
|
||||
->where(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute()->fetchColumn();
|
||||
|
||||
return $this->parseHistory($history);
|
||||
}
|
||||
|
||||
public function parseHistory(?string $historyJson)
|
||||
{
|
||||
if (!$historyJson) {
|
||||
return [];
|
||||
}
|
||||
$history = json_decode($historyJson, true);
|
||||
|
||||
if (!empty($history)) {
|
||||
$admins = sqlFetchAll(sqlQueryBuilder()->select('id, login')->from('admins')
|
||||
->execute(),
|
||||
'id');
|
||||
|
||||
foreach ($history as &$h) {
|
||||
$h['status_name'] = $this->getStatuses()[$h['status']] ?? null;
|
||||
$h['admin_name'] = $admins[$h['admin']]['login'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return $history;
|
||||
}
|
||||
|
||||
public function changeStatus($reclamationSupplierId, $newStatusId)
|
||||
{
|
||||
$reclamationSupplier = $this->getReclamationSupplier($reclamationSupplierId);
|
||||
|
||||
if (!$reclamationSupplier || $reclamationSupplier['status'] == $newStatusId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$values = ['status' => $newStatusId];
|
||||
|
||||
if ($newStatusId == 1) {
|
||||
$values['date_accepted'] = (new \DateTime())->format('Y-m-d H:i:s');
|
||||
if (!$this->isAlreadyInBalikobot($reclamationSupplierId)) {
|
||||
$balikonosId = $this->sendToBalikobot($reclamationSupplierId);
|
||||
$values['id_balikonos'] = $balikonosId;
|
||||
}
|
||||
}
|
||||
if ($newStatusId == 2) {
|
||||
$values['date_handle'] = (new \DateTime())->format('Y-m-d H:i:s');
|
||||
}
|
||||
sqlQueryBuilder()->update('reclamations_suppliers')
|
||||
->directValues($values)
|
||||
->andWhere(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute();
|
||||
}
|
||||
|
||||
protected function isAlreadyInBalikobot($reclamationSupplierId)
|
||||
{
|
||||
$idBalikobot = sqlQueryBuilder()->select('id_balikonos')
|
||||
->from('reclamations_suppliers', 'rs')
|
||||
->where(Operator::equals(['id' => $reclamationSupplierId]))
|
||||
->execute()->fetchOne();
|
||||
|
||||
if ($idBalikobot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidSupplierInfo
|
||||
*/
|
||||
public function sendToBalikobot($reclamationSupplierId)
|
||||
{
|
||||
$balikobot = ServiceContainer::getService(Balikobot::class);
|
||||
$suppliersUtil = ServiceContainer::getService(SuppliersUtil::class);
|
||||
$data = $this->getReclamationSupplier($reclamationSupplierId);
|
||||
|
||||
$supplier = sqlQueryBuilder()->select('s.*')
|
||||
->from('reclamations_suppliers', 'rs')
|
||||
->leftJoin('rs', 'suppliers', 's', 's.id = rs.id_supplier')
|
||||
->where(Operator::equals(['rs.id' => $reclamationSupplierId]))
|
||||
->execute()->fetchAssociative();
|
||||
|
||||
$address = $suppliersUtil->parseAddress($supplier);
|
||||
|
||||
if (!$suppliersUtil->validateAddress($address)) {
|
||||
throw new InvalidSupplierInfo('Dodavatel nemá vyplněné údaje!');
|
||||
}
|
||||
|
||||
$balikobot->setIDs([
|
||||
0 => [
|
||||
'type' => Balikobot::TYPE_CUSTOM,
|
||||
'invoice_email' => $supplier['email'],
|
||||
'invoice_name' => $address['name'],
|
||||
'invoice_surname' => $address['surname'],
|
||||
'invoice_street' => $address['street'],
|
||||
'invoice_city' => $address['city'],
|
||||
'invoice_zip' => $address['zip'],
|
||||
'invoice_country' => $address['country'] ? $address['country'] : 'CZ',
|
||||
'invoice_phone' => $supplier['phone'],
|
||||
'total_price' => 0,
|
||||
'id_delivery' => $data['id_delivery'],
|
||||
'cod_price' => 0,
|
||||
'order_id' => '9999'.$reclamationSupplierId,
|
||||
'id_supplier' => $supplier['id'],
|
||||
// 'weight' => $data['weight'],
|
||||
],
|
||||
]);
|
||||
|
||||
$balikobot->sendDeliveries();
|
||||
|
||||
$result = $balikobot->getResult();
|
||||
$result = reset($result);
|
||||
|
||||
if (!empty($result['error_message']) && $result['error_message'] != 'OK') {
|
||||
throw new BalikonosException('Chyba při odesílání do balíkobotu: '.$result['error_message']);
|
||||
}
|
||||
|
||||
return $result['id_balikonos'] ?? null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user