first commit
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
$txt_str['productsSerialNumbers'] = [
|
||||
'requireSerialNumber' => 'Požadovat sériové číslo',
|
||||
'searchProduct' => 'Produkt',
|
||||
'flapMain' => 'Sériové číslo',
|
||||
'searchNameCode' => 'Název / Kód produktu',
|
||||
'filterByProduct' => 'Podle produktu',
|
||||
'filterBasic' => 'Základní vyhledávání',
|
||||
'searchVariation' => 'Varianty',
|
||||
'searchBtn' => 'Hledat',
|
||||
'delete' => 'Vymazat',
|
||||
'search' => 'Vyhledávání',
|
||||
'serialNumber' => 'Sériové číslo',
|
||||
'searchOrder' => 'Objednávka',
|
||||
'navigation' => 'Sériové čísla',
|
||||
'activityEdited' => 'Upravena doprava',
|
||||
'titleEdit' => 'Upravit sériové číslo',
|
||||
];
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
$txt_str['productsSerialNumbers'] = [
|
||||
'requireSerialNumber' => 'Require serial number',
|
||||
'searchProduct' => 'Search product',
|
||||
'flapMain' => 'Serial number',
|
||||
'searchNameCode' => 'Name / code',
|
||||
'filterByProduct' => 'By product',
|
||||
'filterBasic' => 'Basic search',
|
||||
'searchVariation' => 'Variations',
|
||||
'searchBtn' => 'Search',
|
||||
'delete' => 'Delete',
|
||||
'search' => 'Search',
|
||||
'serialNumber' => 'Serial number',
|
||||
'searchOrder' => 'Order',
|
||||
'navigation' => 'Serial numbers',
|
||||
'titleEdit' => 'Edit serial number',
|
||||
];
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\Admin\lists;
|
||||
|
||||
use KupShop\AdminBundle\AdminList\BaseList;
|
||||
use KupShop\AdminBundle\Query\Invert;
|
||||
use KupShop\CatalogBundle\Query\Search;
|
||||
use KupShop\DevelopmentBundle\Query\QueryBuilder;
|
||||
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
|
||||
use Query\Operator;
|
||||
|
||||
class ProductsSerialNumbersList extends BaseList
|
||||
{
|
||||
protected $tableDef = [
|
||||
'id' => 'psn_id',
|
||||
'fields' => [
|
||||
'ID' => ['field' => 'psn_id', 'size' => 0.3],
|
||||
'Sériové číslo' => ['field' => 'psn_serial_number', 'size' => 0.8],
|
||||
'Tisk' => ['render' => 'renderPrint', 'size' => 0.3],
|
||||
'Produkt' => ['field' => 'p_title', 'render' => 'renderName', 'size' => 2, 'type' => 'product', 'type_id' => 'p_id'],
|
||||
'Dodavatel' => ['field' => 'sup_name', 'size' => 1, 'type' => 'suppliers', 'type_id' => 'sup_id'],
|
||||
'Naskladnění' => ['field' => 'psn_id_stock_in', 'size' => 0.5, 'type' => 'stockIn', 'type_id' => 'psn_id_stock_in'],
|
||||
'Objednávka' => ['field' => 'o_order_no', 'size' => 0.5, 'type' => 'order', 'type_id' => 'o_id'],
|
||||
],
|
||||
];
|
||||
|
||||
public function renderName($values, $column)
|
||||
{
|
||||
$name = [$values['p_title'], $values['pv_title']];
|
||||
|
||||
return join(' - ', array_filter($name));
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
/** @var QueryBuilder $qb */
|
||||
$qb = sqlQueryBuilder()->select(
|
||||
'psn.id psn_id',
|
||||
'psn.serial_number psn_serial_number',
|
||||
'psn.id_stock_in psn_id_stock_in',
|
||||
'p.title p_title',
|
||||
'p.id p_id',
|
||||
'pv.title pv_title',
|
||||
'pv.id pv_id',
|
||||
'oi.id si_id',
|
||||
'o.id o_id',
|
||||
'o.order_no o_order_no',
|
||||
'sup.name sup_name',
|
||||
'sup.id sup_id',
|
||||
)->from('products_serial_numbers', 'psn')
|
||||
->innerJoin('psn', 'products', 'p', 'p.id = psn.id_product')
|
||||
->leftJoin('psn', 'products_variations', 'pv', 'pv.id = psn.id_variation')
|
||||
->leftJoin('psn', 'order_items', 'oi', 'oi.id = psn.id_order_item')
|
||||
->leftJoin('oi', 'orders', 'o', 'o.id = oi.id_order')
|
||||
->leftJoin('psn', 'stock_in', 'si', 'si.id = psn.id_stock_in')
|
||||
->leftJoin('si', 'suppliers', 'sup', 'si.id_supplier = sup.id');
|
||||
|
||||
if ($serialNumber = getVal('serialNumber')) {
|
||||
$qb->andWhere(
|
||||
Invert::checkInvert(\Query\Operator::equals(['psn.serial_number' => $serialNumber]), getVal('serialNumber_invert'))
|
||||
);
|
||||
}
|
||||
|
||||
if ($orderId = getVal('idOrder')) {
|
||||
$searchFields = [
|
||||
['field' => 'o.id', 'match' => 'both', 'order' => '1'],
|
||||
['field' => 'o.order_no', 'match' => 'both', 'order' => '1'],
|
||||
];
|
||||
$qb->andWhere(Invert::checkInvert(Search::searchFields($orderId, $searchFields), getVal('idOrder_invert')));
|
||||
}
|
||||
|
||||
if ($productId = getVal('idProduct')) {
|
||||
$qb->andWhere(Operator::equals(['psn.id_product' => $productId]));
|
||||
|
||||
if ($variationId = getVal('idVariation')) {
|
||||
if (intval($variationId) > 0) {
|
||||
$qb->andWhere(Operator::equals(['psn.id_variation ' => $variationId]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function renderPrint($values, $column)
|
||||
{
|
||||
$href = 'launch.php?s=printCenter.php&type=product&template_type=serialNumber&ID='.$values['p_id'].
|
||||
'&IDv='.$values['pv_id'].
|
||||
'&sn='.$values['psn_serial_number'];
|
||||
|
||||
return HTML::create('a')
|
||||
->attr('title', 'Vytisknout')
|
||||
->attr('href', $href)
|
||||
->tag('span')
|
||||
->class('badge')
|
||||
->tag('i')
|
||||
->class('glyphicon glyphicon-print')
|
||||
->end()
|
||||
->end();
|
||||
}
|
||||
}
|
||||
|
||||
$main_class = ProductsSerialNumbersList::class;
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\Admin;
|
||||
|
||||
class productsSerialNumbers extends \Window
|
||||
{
|
||||
protected $template = 'window/productsSerialNumbers.tpl';
|
||||
|
||||
protected $tableName = 'products_serial_numbers';
|
||||
|
||||
protected $nameField = 'serial_number';
|
||||
}
|
||||
|
||||
return productsSerialNumbers::class;
|
||||
@@ -0,0 +1,64 @@
|
||||
{extends "[shared]/menu.tpl"}
|
||||
|
||||
|
||||
{block name="menu-items" }
|
||||
<li class="nav-header"><i class="glyphicon glyphicon-tags"></i><span>{translate_type type=$type}</span></li>
|
||||
|
||||
|
||||
<li class="nav-header smaller"><i class="glyphicon glyphicon-search"></i><span>{'search'|translate}</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="productsSerialNumbers"/><input type="hidden" name="s" value="list.php">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<input type="text" class="form-control input-sm" name="serialNumber" maxlength="20" value=""
|
||||
placeholder="{'serialNumber'|translate}"/>
|
||||
{inversion field="serialNumber"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group invert">
|
||||
<input type="text" class="form-control input-sm" name="idOrder" maxlength="20" value=""
|
||||
placeholder="{'searchOrder'|translate}"/>
|
||||
{inversion field="idOrder"}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="reset" 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="idProduct" maxlength="100" value="" onKeyPress="checkInputData('int')"
|
||||
placeholder="{'searchNameCode'|translate}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="idVariation" class="input-sm form-control"></select>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
initAutocompleteVariation('[name=idProduct]', '[name=idVariation]');
|
||||
});
|
||||
</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,111 @@
|
||||
<style type="text/css" media="all">
|
||||
@media print {
|
||||
@page {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.stitek {
|
||||
float: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.stitek {
|
||||
width: 92mm;
|
||||
height: 62mm;
|
||||
float: left;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
page-break-after: always;
|
||||
border: dimgrey dashed 1px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 2mm;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.stitek > div {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.stitek > hr {
|
||||
border-top: 1px solid black;
|
||||
position: absolute;
|
||||
top: 8mm;
|
||||
width: 85mm;
|
||||
left: 3mm;
|
||||
}
|
||||
|
||||
.barcode {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 10mm;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.barcode>svg{
|
||||
max-width:85%;
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
height: 25mm;
|
||||
width: 85mm;
|
||||
position: absolute;
|
||||
top: 17mm;
|
||||
left: 3mm;
|
||||
}
|
||||
|
||||
.product {
|
||||
top: 7mm;
|
||||
height: 10mm;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.variation {
|
||||
top: 18mm;
|
||||
height: 8mm;
|
||||
}
|
||||
|
||||
|
||||
.title table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
{get_contexts language=1 assign='context'}
|
||||
{$languageContext = $context.language}
|
||||
{$languages = $languageContext->getSupported()}
|
||||
|
||||
{foreach $products as $key => $product}
|
||||
{for $repeat = 1 to $product.pieces}
|
||||
{block stitek}
|
||||
<div class="stitek">
|
||||
{block descr}
|
||||
<div class="title product">{$product.product_title}</div>
|
||||
<div class="title variation">{$product.variation_title}</div>
|
||||
{/block}
|
||||
{block barcode}
|
||||
<div class="barcode">
|
||||
{if !empty($smarty.request.sn)}
|
||||
{insert_barcode type="C128" code=$smarty.request.sn height=45 width=2}
|
||||
<br>
|
||||
Sériové číslo: {$smarty.request.sn}
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
||||
</div>
|
||||
{/block}
|
||||
{/for}
|
||||
{/foreach}
|
||||
@@ -0,0 +1,47 @@
|
||||
{extends "[shared]/window.tpl"}
|
||||
|
||||
{block tabs}
|
||||
{windowTab id='flapMain'}
|
||||
{/block}
|
||||
|
||||
{block tabsContent}
|
||||
<div id="flapMain" class="tab-pane fade active in boxFlex">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="serial_number" class="col-md-2 control-label">
|
||||
{'serialNumber'|translate}
|
||||
</label>
|
||||
<div class="col-md-5">
|
||||
<input type="text" class="form-control" id="serial_number" maxlength="100" name="data[serial_number]" value="{$body.data.serial_number}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{$data = json_decode($body.data.data, true)}
|
||||
{if $data.orders}
|
||||
<div class="form-group">
|
||||
<label for="serial_number" class="col-md-2 control-label">
|
||||
{'history'|translate:'Reclamations'}
|
||||
</label>
|
||||
<div class="col-md-5">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{'id_order'|translate:'Reclamations'}</td>
|
||||
<td>{'action'|translate:'Returns'}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $data.orders as $order}
|
||||
<tr>
|
||||
<td><a href="javascript:nw('order', '{$order.id_order}');">{$order.id_order}</a></td>
|
||||
<td>{$order.action}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\AdminRegister;
|
||||
|
||||
use KupShop\AdminBundle\AdminRegister\AdminRegister;
|
||||
use KupShop\AdminBundle\AdminRegister\IAdminRegisterDynamic;
|
||||
use KupShop\AdminBundle\AdminRegister\IAdminRegisterStatic;
|
||||
|
||||
class ProductsSerialNumbersAdminRegister extends AdminRegister implements IAdminRegisterDynamic, IAdminRegisterStatic
|
||||
{
|
||||
public function getDynamicMenu(): array
|
||||
{
|
||||
return [
|
||||
static::createMenuItem(
|
||||
'stockMenu',
|
||||
[
|
||||
'name' => 'ProductsSerialNumbers',
|
||||
'title' => translate('navigation', 'productsSerialNumbers'),
|
||||
'left' => 's=menu.php&type=productsSerialNumbers',
|
||||
'right' => 's=list.php&type=productsSerialNumbers',
|
||||
]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array
|
||||
{
|
||||
return [
|
||||
static::createPermissions('ProductsSerialNumbers', [\Modules::PRODUCTS_SERIAL_NUMBERS], ['PSERNUM']),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\EventListener;
|
||||
|
||||
use KupShop\OrderingBundle\Event\OrderEvent;
|
||||
use KupShop\ProductsSerialNumbersBundle\Util\ProductsSerialNumbersUtil;
|
||||
use Query\Operator;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class OrderEventListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var ProductsSerialNumbersUtil
|
||||
*/
|
||||
private $productsSerialNumbersUtil;
|
||||
|
||||
public function __construct(ProductsSerialNumbersUtil $productsSerialNumbersUtil)
|
||||
{
|
||||
$this->productsSerialNumbersUtil = $productsSerialNumbersUtil;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
OrderEvent::ORDER_STORNO => [
|
||||
['stornoProductsSerialNumbers', 200],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function stornoProductsSerialNumbers(OrderEvent $event)
|
||||
{
|
||||
$order = $event->getOrder();
|
||||
|
||||
$serialNumbers = sqlQueryBuilder()
|
||||
->select('psn.*, oi.id_order')
|
||||
->from('products_serial_numbers', 'psn')->join('psn', 'order_items', 'oi', 'psn.id_order_item = oi.id')
|
||||
->where(Operator::equals(['oi.id_order' => $order->id]))
|
||||
->execute()->fetchAll();
|
||||
|
||||
$this->productsSerialNumbersUtil->stornoProductsSerialNumbers($serialNumbers, 'storno');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class ProductsSerialNumbersBundle extends Bundle
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
KupShop\ProductsSerialNumbersBundle\:
|
||||
resource: ../../{AdminRegister,EventListener,Util}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\Resources\upgrade;
|
||||
|
||||
class ProductsSerialNumbersUpgrade extends \UpgradeNew
|
||||
{
|
||||
public function check_productsSerialNumber()
|
||||
{
|
||||
return $this->checkColumnExists('products', 'serial_number_require');
|
||||
}
|
||||
|
||||
/** Add field 'serial_number_require' to products */
|
||||
public function upgrade_productsSerialNumber()
|
||||
{
|
||||
sqlQuery("alter table products add serial_number_require enum('Y', 'N') default 'N' null;");
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_productsSerialNumbersTable()
|
||||
{
|
||||
return $this->checkTableExists('products_serial_numbers');
|
||||
}
|
||||
|
||||
/** Create 'products_serial_numbers' table */
|
||||
public function upgrade_productsSerialNumbersTable()
|
||||
{
|
||||
sqlQuery('create table products_serial_numbers
|
||||
(
|
||||
id int auto_increment,
|
||||
id_product int(11) not null,
|
||||
id_variation int(11) null,
|
||||
serial_number varchar(100) not null,
|
||||
id_order_item int(10) unsigned null,
|
||||
id_stock_in int(11) null,
|
||||
constraint products_serial_numbers_pk
|
||||
primary key (id),
|
||||
constraint products_serial_numbers_pk_2
|
||||
unique (id_product, serial_number),
|
||||
constraint products_serial_numbers_order_items_id_fk
|
||||
foreign key (id_order_item) references order_items (id)
|
||||
on update cascade on delete set null,
|
||||
constraint products_serial_numbers_products_id_fk
|
||||
foreign key (id_product) references products (id)
|
||||
on update cascade on delete cascade,
|
||||
constraint products_serial_numbers_products_variations_id_fk
|
||||
foreign key (id_variation) references products_variations (id)
|
||||
on update cascade on delete set null,
|
||||
constraint products_serial_numbers_stock_in_id_fk
|
||||
foreign key (id_stock_in) references stock_in (id)
|
||||
on update cascade on delete set null
|
||||
|
||||
);
|
||||
|
||||
');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_CustomData()
|
||||
{
|
||||
return $this->checkColumnExists('products_serial_numbers', 'data');
|
||||
}
|
||||
|
||||
/** Add custom data to products_serial_numbers */
|
||||
public function upgrade_CustomData()
|
||||
{
|
||||
sqlQuery('ALTER TABLE products_serial_numbers ADD COLUMN data TEXT NULL');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\Util\PrintCenter;
|
||||
|
||||
use KupShop\AdminBundle\Util\PrintCenter\PrintLabelsBase;
|
||||
|
||||
class SerialNumberLabel extends PrintLabelsBase
|
||||
{
|
||||
protected $template = 'printCenter/serialNumberLabel.tpl';
|
||||
protected $label = 'Sériové číslo';
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\ProductsSerialNumbersBundle\Util;
|
||||
|
||||
use Query\Operator;
|
||||
|
||||
class ProductsSerialNumbersUtil
|
||||
{
|
||||
public function stornoProductsSerialNumbers($serialNumbers = [], $action = 'storno')
|
||||
{
|
||||
foreach ($serialNumbers as $serialNumber) {
|
||||
$data = json_decode($serialNumber['data'] ?? '', true);
|
||||
$data['orders'][] = [
|
||||
'id_order' => $serialNumber['id_order'],
|
||||
'id_order_item' => $serialNumber['id_order_item'],
|
||||
'action' => $action,
|
||||
];
|
||||
sqlQueryBuilder()->update('products_serial_numbers')
|
||||
->directValues(['id_order_item' => null, 'data' => json_encode($data)])
|
||||
->where(Operator::equals(['id' => $serialNumber['id']]))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user