first commit
This commit is contained in:
796
admin/stockIn.php
Normal file
796
admin/stockIn.php
Normal file
@@ -0,0 +1,796 @@
|
||||
<?php
|
||||
|
||||
use KupShop\AdminBundle\Util\StockInProductOfSupplierService;
|
||||
use KupShop\CatalogBundle\Util\Product\ProductPriceWeigher;
|
||||
use KupShop\KupShopBundle\Context\ContextManager;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\StoresBundle\Utils\StoresInStore;
|
||||
use Query\Operator;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
$main_class = 'StockIn';
|
||||
|
||||
class StockIn extends Window
|
||||
{
|
||||
use DatabaseCommunication;
|
||||
|
||||
protected $defaults = [
|
||||
'paid' => '0',
|
||||
'vatDisplay' => '0',
|
||||
'payment_method' => 'prevodem',
|
||||
'multiplier' => '1',
|
||||
'id_index' => 'invoice',
|
||||
];
|
||||
|
||||
protected $required = [
|
||||
'number' => true,
|
||||
'code' => true,
|
||||
];
|
||||
|
||||
protected $tableName = 'stock_in';
|
||||
|
||||
private $index;
|
||||
protected $index_old;
|
||||
|
||||
protected ?StoresInStore $storesInStore = null;
|
||||
protected ContextManager $contextManager;
|
||||
protected StockInProductOfSupplierService $stockInProductOfSupplierService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (findModule(Modules::STORES)) {
|
||||
$this->storesInStore = ServiceContainer::getService(StoresInStore::class);
|
||||
}
|
||||
$this->contextManager = ServiceContainer::getService(ContextManager::class);
|
||||
$this->stockInProductOfSupplierService = ServiceContainer::getService(StockInProductOfSupplierService::class);
|
||||
}
|
||||
|
||||
public function recalcTotalPrice()
|
||||
{
|
||||
sqlQuery('UPDATE '.getTableName('stock_in').' s
|
||||
SET total_price=(
|
||||
SELECT COALESCE(SUM(si.quantity*si.price), 0)+s.transport_price-s.discount
|
||||
FROM '.getTableName('stock_in_items').' si
|
||||
WHERE si.id_stock_in=s.id
|
||||
)
|
||||
WHERE s.id=:id', ['id' => $this->getID()]);
|
||||
}
|
||||
|
||||
public function get_vars()
|
||||
{
|
||||
$vars = parent::get_vars();
|
||||
$pageVars = getVal('body', $vars);
|
||||
$acn = $this->getAction();
|
||||
$pageVars['paid'] = [
|
||||
'1' => translate('priceType_withVat', 'stockIn'),
|
||||
'2' => translate('priceType_withoutVat', 'stockIn'),
|
||||
'0' => translate('priceType_bothVat', 'stockIn'),
|
||||
'3' => translate('priceType_foreignCurrency', 'stockIn'),
|
||||
];
|
||||
|
||||
$sql = sqlQuery('SELECT id, name FROM '.getTableName('suppliers'));
|
||||
$pageVars['suppliers'] = ['' => '- Vyber dodavatele -'];
|
||||
foreach ($sql as $row) {
|
||||
$pageVars['suppliers'][$row['id']] = $row['name'];
|
||||
}
|
||||
|
||||
if (findModule(Modules::STORES)) {
|
||||
$pageVars['stores'] = $this->storesInStore->getStoresNames();
|
||||
}
|
||||
|
||||
$pageVars['paymentMethods'] = [
|
||||
'dobirka' => translate('cod', 'stockIn'),
|
||||
'prevodem' => translate('bankTransfer', 'stockIn'),
|
||||
];
|
||||
|
||||
$ID = $this->getID();
|
||||
if ($ID) {
|
||||
global $cfg;
|
||||
$id_supplier = $pageVars['data']['id_supplier'];
|
||||
$date_issued = $pageVars['data']['date_issued'];
|
||||
$fields = 'si.id, si.id_product, si.name, si.id_variation, si.quantity,
|
||||
p.title as product_title, pv.title variation_title, si.price, COALESCE(v.vat, si.vat) as vat, p.figure,
|
||||
COALESCE(pv.price, p.price) as web_price, COALESCE(pv.in_store, p.in_store) as web_in_store,
|
||||
p.discount as web_discount, COALESCE(pv.ean, p.ean) as ean, pos.code as code_supplier, pos.note as products_of_suppliers_note';
|
||||
|
||||
if (!empty($cfg['Modules']['products_variations']['variationCode'])) {
|
||||
$fields .= ', COALESCE(pv.code, p.code) as code';
|
||||
} else {
|
||||
$fields .= ', p.code as code';
|
||||
}
|
||||
|
||||
if (!empty($cfg['Modules']['products']['note'])) {
|
||||
$fields .= ', COALESCE(pv.note, p.note) as note';
|
||||
}
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$fields .= ', si.additional_costs';
|
||||
}
|
||||
|
||||
$fields .= ',
|
||||
(SELECT si2.price FROM stock_in_items si2
|
||||
LEFT JOIN stock_in st2 ON si2.id_stock_in = st2.id
|
||||
WHERE st2.id_index = "invoice" AND st2.date_issued <= "'.$date_issued.'" AND st2.id != si.id_stock_in
|
||||
AND si2.id_product = si.id_product AND ((si.id_variation IS NULL AND si2.id_variation IS NULL) OR si2.id_variation = si.id_variation)
|
||||
ORDER BY st2.date_issued DESC, st2.id DESC LIMIT 1) AS prev_price';
|
||||
|
||||
$orderBy = 'p.id > 0, si.id DESC';
|
||||
if ($this->getIndex() == 'future') {
|
||||
$orderBy = 'IF(products_of_suppliers_note IS NULL, 1, 0) ASC, '.$orderBy;
|
||||
}
|
||||
|
||||
$SQL = sqlQuery("SELECT {$fields}
|
||||
FROM stock_in_items si
|
||||
LEFT JOIN products p ON p.id=si.id_product
|
||||
LEFT JOIN products_variations pv ON pv.id=si.id_variation
|
||||
LEFT JOIN products_of_suppliers pos ON p.id = pos.id_product AND pos.id_supplier = '".$id_supplier."' AND ((pv.id IS NULL AND pos.id_variation IS NULL) OR pos.id_variation = pv.id)
|
||||
LEFT JOIN vats v ON v.id=p.vat
|
||||
WHERE si.id_stock_in='".$ID."' GROUP BY si.id ORDER BY ".$orderBy.' ');
|
||||
|
||||
$vat = getAdminVat()['value'];
|
||||
|
||||
$data = &$pageVars['data'];
|
||||
$data['transportVat'] = $vat;
|
||||
|
||||
$data['transport_price_vat'] = $data['transport_price'] * (1 + ($vat / 100));
|
||||
$data['total_price_vat'] = $data['transport_price_vat'] - ($data['discount'] * (1 + ($vat / 100)));
|
||||
|
||||
$this->unserializeCustomData($data);
|
||||
if (!empty($data['data']['parent_stock_in'])) {
|
||||
$data['data']['parent_stock_in'] = sqlQueryBuilder()
|
||||
->select('*')
|
||||
->from('stock_in')
|
||||
->where(Operator::equals(['id' => $data['data']['parent_stock_in']]))
|
||||
->execute()->fetch();
|
||||
}
|
||||
|
||||
if (findModule(Modules::STORES) && ($data['data']['id_store'] ?? false)) {
|
||||
$data['isExternalStore'] = ($this->storesInStore->getStores()[$data['data']['id_store']]['type'] ?? false) == StoresInStore::TYPE_EXTERNAL_STORE;
|
||||
}
|
||||
|
||||
$totalQuantity = 0;
|
||||
$items = [];
|
||||
foreach ($SQL as $row) {
|
||||
$row['web_price'] = calcPrice($row['web_price'], 0, $row['web_discount'])->asFloat();
|
||||
$row['price'] = floatval($row['price']);
|
||||
if ($row['web_price'] && $row['price']) {
|
||||
$row['rabat'] = ($row['web_price'] - $row['price']) / $row['price'] * 100;
|
||||
if ($row['rabat'] < 2) {
|
||||
$row['color'] = '#9b313b';
|
||||
$row['bg_color'] = '#FDD7DB';
|
||||
} elseif ($row['rabat'] < 10) {
|
||||
$row['color'] = '#9a7a2c';
|
||||
$row['bg_color'] = '#fceecd';
|
||||
} else {
|
||||
$row['color'] = '#699b31';
|
||||
$row['bg_color'] = '#E5FCCD';
|
||||
}
|
||||
|
||||
if ($row['web_price'] > 0 && $row['web_price'] <= $row['price']) {
|
||||
$row['bg_color'] = '#FCC479';
|
||||
}
|
||||
|
||||
if ($row['rabat'] > 100) {
|
||||
$row['bg_color'] = '#DADDFC';
|
||||
}
|
||||
}
|
||||
|
||||
if ($row['figure'] != 'Y') {
|
||||
$row['bg_color'] = '#FF858D';
|
||||
}
|
||||
|
||||
$row['web_price_vat'] = $row['web_price'] * (1 + $row['vat'] / 100);
|
||||
$row['price_vat'] = $row['price'] * (1 + $row['vat'] / 100);
|
||||
$row['price_all'] = $row['price'] * $row['quantity'];
|
||||
$row['price_all_vat'] = $row['price'] * $row['quantity'] * (1 + $row['vat'] / 100);
|
||||
$row['additional_costs'] = floatval($row['additional_costs'] ?? null);
|
||||
$items[$row['id']] = $row;
|
||||
$data['total_price_vat'] += ($row['price'] * $row['quantity']) * (1 + $row['vat'] / 100);
|
||||
|
||||
$totalQuantity += $row['quantity'];
|
||||
}
|
||||
$data['total_price_vat'] = round($data['total_price_vat'], 4); // to fix values like -9.0949470177293E-13
|
||||
$pageVars['items'] = $items;
|
||||
$pageVars['totalQuantity'] = $totalQuantity;
|
||||
$pageVars['itemsCount'] = count($items);
|
||||
}
|
||||
|
||||
// Import from file
|
||||
if (empty($pageVars['items']) && !empty($data['id_supplier'])) {
|
||||
$pageVars['import'] = new StockInImport($data);
|
||||
}
|
||||
|
||||
$pageVars['paid2'] = ['1' => 'ANO', '0' => 'NE'];
|
||||
|
||||
$pageVars['vatDisplay'] = getVal('vatDisplay');
|
||||
|
||||
if (isset($data['data']['currency_symbol']) && !empty($data['data']['currency_symbol'])) {
|
||||
$pageVars['data']['currency_symbol'] = $data['data']['currency_symbol'];
|
||||
} else {
|
||||
$pageVars['data']['currency_symbol'] = '€';
|
||||
}
|
||||
|
||||
if (is_string($pageVars['data']['data'] ?? false)) {
|
||||
$this->unserializeCustomData($pageVars['data']);
|
||||
}
|
||||
|
||||
$vars['body'] = $pageVars;
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
protected function getFields()
|
||||
{
|
||||
$index = $this->getIndex();
|
||||
if (in_array($index, ['closure', 'future', 'preorder'])) {
|
||||
$this->required = [];
|
||||
}
|
||||
|
||||
parent::getFields();
|
||||
}
|
||||
|
||||
public function createObject()
|
||||
{
|
||||
$data = parent::createObject();
|
||||
|
||||
if (empty($data['date_created'])) {
|
||||
$data['date_created'] = date('d-m-Y H:i:s');
|
||||
}
|
||||
if (empty($data['date_issued'])) {
|
||||
if (in_array($data['id_index'], ['future', 'preorder'])) {
|
||||
$data['date_issued'] = date('d-m-Y', time() + 86400);
|
||||
} else {
|
||||
$data['date_issued'] = date('d-m-Y', time() - 86400);
|
||||
}
|
||||
}
|
||||
if (empty($data['date_expiration'])) {
|
||||
$data['date_expiration'] = date('d-m-Y', time() + (13 * 86400));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
$data = parent::getData();
|
||||
|
||||
if (!empty($data['date_issued'])) {
|
||||
$data['date_issued'] = $this->prepareDate($data['date_issued']);
|
||||
}
|
||||
if (!empty($data['date_expiration'])) {
|
||||
$data['date_expiration'] = $this->prepareDate($data['date_expiration']);
|
||||
}
|
||||
|
||||
if (isset($data['multiplier'])) {
|
||||
$this->preparePrice($data['multiplier']);
|
||||
}
|
||||
|
||||
if (getVal('Submit') == 'recieved') {
|
||||
if ($this->getIndex() == 'future') {
|
||||
$this->index_old = 'future';
|
||||
$this->index = 'invoice';
|
||||
}
|
||||
$data['id_index'] = $this->index;
|
||||
}
|
||||
|
||||
if (getVal('Submit')) {
|
||||
$this->serializeCustomData($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function handleUpdate()
|
||||
{
|
||||
$acn = $this->getAction();
|
||||
$data = $this->getData();
|
||||
$ID = $this->getID();
|
||||
|
||||
$oldMultiplier = null;
|
||||
$multiplier = $data['multiplier'];
|
||||
|
||||
if ($acn == 'edit' && !empty($ID)) {
|
||||
$closed = returnSQLResult('SELECT closed
|
||||
FROM '.getTableName('stock_in')." s
|
||||
WHERE s.id='{$ID}' ");
|
||||
|
||||
if ($closed) {
|
||||
$this->returnError('Nelze upravovat uzavřenou fakturu');
|
||||
}
|
||||
|
||||
// kvůli přepočtu CZK ceny při změně kurzu u naskladnění v cizí měně
|
||||
$vatDisplay = json_decode($data['data'], true)['vatDisplay'] ?? null;
|
||||
if ($vatDisplay and $vatDisplay == 3) {
|
||||
$oldMultiplier = sqlQueryBuilder()
|
||||
->select('multiplier')
|
||||
->from('stock_in')
|
||||
->andWhere(Operator::equals(['id' => $ID]))
|
||||
->execute()->fetchOne();
|
||||
}
|
||||
}
|
||||
parent::handleUpdate();
|
||||
if ($this->index_old == 'future' && $this->index == 'invoice') {
|
||||
// Naskladnění aktualizovat pouze v případě naskladnění, ne aktualizace faktury
|
||||
sqlQueryBuilder()
|
||||
->update('stock_in')
|
||||
->set('date_stock_in', 'NOW()')
|
||||
->andWhere(Operator::equals(['id' => $ID]))
|
||||
->execute();
|
||||
}
|
||||
$object = $this->getObject();
|
||||
if (empty($object['number']) && $object['id_index'] == 'invoice') {
|
||||
$number = returnSQLResult('SELECT MAX(number)+1 FROM '.getTableName('stock_in').' WHERE id_index="invoice"');
|
||||
if (empty($number)) {
|
||||
$number = 1;
|
||||
}
|
||||
$this->updateSQL('stock_in', ['number' => $number], ['id' => $this->getID()]);
|
||||
}
|
||||
|
||||
$stockin = getVal('stockin', $data, []);
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$this->appendAdditionalCosts($stockin, $object);
|
||||
}
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$this->productPriceWeigher = ServiceContainer::getService(ProductPriceWeigher::class);
|
||||
}
|
||||
|
||||
if (isset($oldMultiplier) && $oldMultiplier != 0 && ($oldMultiplier != $multiplier)) {
|
||||
foreach ($stockin as $id => &$item) {
|
||||
$item['price'] = ($item['price'] / $oldMultiplier) * $multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
krsort($stockin, SORT_NUMERIC);
|
||||
|
||||
sqlGetConnection()->transactional(function () use ($stockin) {
|
||||
foreach ($stockin as $id => $item) {
|
||||
$item['id'] = intval($id);
|
||||
|
||||
if (!$id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item['quantity'] = str_replace(',', '.', $item['quantity']);
|
||||
|
||||
$item = array_merge($this->getItem($item), $item);
|
||||
if ($this->index_old == 'future' && $this->index == 'invoice') {
|
||||
// naskladneni
|
||||
$item['recieved'] = true;
|
||||
}
|
||||
$this->recalculateWeightedPrice($item);
|
||||
|
||||
if (!empty($item['delete'])) {
|
||||
$this->handleDeleteValue($item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($id < 0) {
|
||||
$this->handleAddValue($item);
|
||||
} else {
|
||||
$this->handleUpdateValue($item);
|
||||
}
|
||||
}
|
||||
$this->recalcTotalPrice();
|
||||
});
|
||||
|
||||
$vatDisplay = '0';
|
||||
if (getVal('vatDisplay')) {
|
||||
$vatDisplay = getVal('vatDisplay');
|
||||
}
|
||||
|
||||
$this->redirect(['vatDisplay' => $vatDisplay, 'ErrStr' => $this->getErrors()[0]]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getItem($item)
|
||||
{
|
||||
$row = sqlFetchAssoc(sqlQuery('SELECT si.id_product, si.id_variation, si.quantity as old_quantity
|
||||
FROM stock_in_items si
|
||||
WHERE si.id=:id AND si.id_product IS NOT NULL', ['id' => $item['id']]));
|
||||
|
||||
return $row ? $row : [];
|
||||
}
|
||||
|
||||
/** Předefinováno na Lashes **/
|
||||
public function appendAdditionalCosts(&$stockin, $stockInRow)
|
||||
{
|
||||
$additionalsCosts = toDecimal($stockInRow['transport_price']);
|
||||
$totalPrice = \DecimalConstants::zero();
|
||||
|
||||
foreach ($stockin as $id => &$item) {
|
||||
$item['price'] = $this->preparePrice($item['price']);
|
||||
// fix Division by zero - convert string to float (quantity muze byt napr. "0.0000")
|
||||
$item['quantity'] = $this->preparePrice($item['quantity']);
|
||||
$item['additional_costs'] = 0;
|
||||
|
||||
if (!$item['price'] || !$item['quantity']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalPrice = $totalPrice->add(toDecimal($item['price'])->mul(toDecimal($item['quantity']))->abs());
|
||||
}
|
||||
|
||||
foreach ($stockin as $id => &$item) {
|
||||
if (!$item['price'] || !$item['quantity']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$itemsPrice = toDecimal($item['price'])->mul(toDecimal($item['quantity']))->abs();
|
||||
$itemsPiecesPerc = $itemsPrice->div($totalPrice);
|
||||
|
||||
$item['additional_costs'] = $additionalsCosts->mul($itemsPiecesPerc)->div(toDecimal($item['quantity']))->asFloat();
|
||||
}
|
||||
|
||||
return $stockin;
|
||||
}
|
||||
|
||||
public function handleDelete()
|
||||
{
|
||||
if (!findRight('INSTORE_STOCKIN_ERASE')) {
|
||||
redirect('launch.php?s=error.php&id=1');
|
||||
}
|
||||
|
||||
$ID = $this->getID();
|
||||
$SQL = sqlQuery('SELECT si.id_product, si.id_variation, si.quantity
|
||||
FROM '.getTableName('stock_in_items')." si
|
||||
WHERE si.id_stock_in={$ID} AND si.id_product IS NOT NULL");
|
||||
|
||||
while (($row = sqlFetchAssoc($SQL)) !== false) {
|
||||
$this->storeIn($row['id_product'], $row['id_variation'], -$row['quantity']);
|
||||
}
|
||||
|
||||
writeDownActivity(sprintf(translate('activityDeleted'), $ID));
|
||||
// smazat
|
||||
|
||||
sqlQuery('DELETE FROM '.getTableName('stock_in')." WHERE id='{$ID}' ");
|
||||
|
||||
redirect("launch.php?s={$this->getName()}.php&acn=erased");
|
||||
}
|
||||
|
||||
public function handleDeleteValue($item)
|
||||
{
|
||||
if (!empty($item['id_product'])) {
|
||||
$this->storeIn($item['id_product'], $item['id_variation'], -$item['old_quantity']);
|
||||
}
|
||||
|
||||
sqlQuery('DELETE FROM stock_in_items WHERE id=:id', ['id' => $item['id']]);
|
||||
}
|
||||
|
||||
public function handleAddValue($item)
|
||||
{
|
||||
$data = $this->getData();
|
||||
$ID = $this->getID();
|
||||
$item['id_stock_in'] = $ID;
|
||||
|
||||
$this->preparePrice($item['price']);
|
||||
$this->preparePrice($item['price_vat']);
|
||||
|
||||
if (empty($item['price'])) {
|
||||
$item['price'] = 0;
|
||||
}
|
||||
if (empty($item['price_vat'])) {
|
||||
$item['price_vat'] = 0;
|
||||
}
|
||||
if (empty($item['quantity'])) {
|
||||
$item['quantity'] = 0;
|
||||
}
|
||||
|
||||
$fields = ['id_stock_in', 'quantity', 'price', 'name', 'vat'];
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$fields[] = 'additional_costs';
|
||||
}
|
||||
|
||||
if (!empty($item['id_product'])) {
|
||||
if (empty(intval($item['id_product']))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields[] = 'id_product';
|
||||
$fields[] = 'id_variation';
|
||||
|
||||
if (!empty($item['id_product_text'])) {
|
||||
$item['name'] = $item['id_product_text'];
|
||||
}
|
||||
|
||||
if (empty($item['id_variation'])) {
|
||||
$item['id_variation'] = null;
|
||||
} else {
|
||||
$item['name'] = Variations::fillInProductTitle($item['id_variation'], $item['name']);
|
||||
}
|
||||
|
||||
$vat = returnSQLResult('SELECT v.vat
|
||||
FROM '.getTableName('products').' p
|
||||
JOIN '.getTableName('vats')." v ON v.id=p.vat
|
||||
WHERE p.id={$item['id_product']} ");
|
||||
|
||||
$item['vat'] = (float) $vat;
|
||||
|
||||
if (empty($item['price'])) {
|
||||
$item['price'] = $item['price_vat'] / (1 + ($vat / 100));
|
||||
}
|
||||
} else {
|
||||
if (empty($item['product_text'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$vat = getAdminVat()['value'];
|
||||
|
||||
if (empty($item['quantity'])) {
|
||||
$item['quantity'] = 1;
|
||||
}
|
||||
|
||||
if (empty($price)) {
|
||||
$item['price'] = $item['price_vat'] / (1 + ($vat / 100));
|
||||
}
|
||||
|
||||
$item['name'] = $item['product_text'];
|
||||
$fields[] = 'name';
|
||||
$item['vat'] = $vat;
|
||||
}
|
||||
|
||||
$SQLfields = $this->getSQLFields($item, $fields);
|
||||
|
||||
$this->insertSQL('stock_in_items', $SQLfields);
|
||||
|
||||
if (!empty($item['id_product'])) {
|
||||
// Update store
|
||||
$this->storeIn($item['id_product'], $item['id_variation'], $item['quantity']);
|
||||
|
||||
// Update suppliers code
|
||||
$item['supplier_code'] = trim($item['supplier_code']) ?: null;
|
||||
$GLOBALS['code'] = $item['supplier_code'];
|
||||
|
||||
try {
|
||||
$this->stockInProductOfSupplierService->updateOrInsertProductSupplier($item, $data);
|
||||
} catch (Exception|\Doctrine\DBAL\Driver\Exception) {
|
||||
$this->addError("Nepodařilo se uložit kód dodavatele: {$item['supplier_code']}, položky: {$item['name']}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleUpdateValue($item)
|
||||
{
|
||||
if (empty($item['price']) && $item['id_product']) {
|
||||
$vat = returnSQLResult('SELECT v.vat
|
||||
FROM products p
|
||||
JOIN vats v ON v.id=p.vat
|
||||
WHERE p.id=:id_product', $item);
|
||||
$item['price'] = $item['price_vat'] / (1 + ($vat / 100));
|
||||
} else {
|
||||
$this->preparePrice($item['price']);
|
||||
}
|
||||
|
||||
if ($item['id_product']) {
|
||||
if ($this->index_old == 'future' && $this->index == 'invoice') {
|
||||
$quantity = $item['quantity'];
|
||||
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)
|
||||
&& findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY) !== 'do_not_update'
|
||||
&& !findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)
|
||||
) {
|
||||
$qb = sqlQueryBuilder()
|
||||
->update(($item['id_variation'] ?? false) ? 'products_variations' : 'products')
|
||||
->set('price_buy', $item['price']);
|
||||
if ($item['id_variation'] ?? false) {
|
||||
$qb->andWhere(Operator::equals(['id' => $item['id_variation']]));
|
||||
} else {
|
||||
$qb->andWhere(Operator::equals(['id' => $item['id_product']]));
|
||||
}
|
||||
$qb->execute();
|
||||
}
|
||||
// Naskladnění aktualizovat pouze v případě naskladnění, ne aktualizace faktury
|
||||
sqlQueryBuilder()
|
||||
->update('products')
|
||||
->set('date_stock_in', 'NOW()')
|
||||
->andWhere(Operator::equals(['id' => $item['id_product']]))
|
||||
->execute();
|
||||
} else {
|
||||
$quantity = $item['quantity'] - $item['old_quantity'];
|
||||
}
|
||||
|
||||
$this->storeIn($item['id_product'], $item['id_variation'], $quantity);
|
||||
}
|
||||
|
||||
$SQLFields = [
|
||||
'quantity' => $item['quantity'],
|
||||
'price' => $item['price'],
|
||||
];
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$SQLFields['additional_costs'] = $item['additional_costs'];
|
||||
}
|
||||
|
||||
$this->updateSQL('stock_in_items', $SQLFields, ['id' => $item['id']]);
|
||||
$this->recalcTotalPrice();
|
||||
}
|
||||
|
||||
public function recalculateWeightedPrice($item)
|
||||
{
|
||||
$index = $this->getIndex();
|
||||
if (in_array($index, ['closure', 'future', 'preorder']) || empty($item['price'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (findModule(Modules::STOCK_IN, Modules::SUB_WEIGHTED_PURCHASE_PRICE)) {
|
||||
$this->productPriceWeigher->updateWeightedPurchasePrice($item);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleClose()
|
||||
{
|
||||
$ID = $this->getID();
|
||||
sqlQuery('UPDATE '.getTableName('stock_in')." s
|
||||
SET s.closed=1
|
||||
WHERE s.id={$ID}");
|
||||
|
||||
$ErrStr = "Záznam číslo {$ID} uzavřen.";
|
||||
|
||||
// presmerovani
|
||||
redirect('launch.php?s=stockIn.php&acn=edit&refresh=parent&ID='.$ID.'&ErrStr='.$ErrStr);
|
||||
}
|
||||
|
||||
public function handleImport()
|
||||
{
|
||||
$data = $this->getData();
|
||||
$data['id'] = $this->getID();
|
||||
|
||||
$import = new StockInImport($data, $this->getIndex());
|
||||
try {
|
||||
$import->load_supplier_settings();
|
||||
} catch (Exception $e) {
|
||||
$this->returnError('Chyba importu: '.$e->getMessage());
|
||||
}
|
||||
if (!$import->import($_FILES['import'])) {
|
||||
$this->returnError('Chyba importu: '.join(', ', $import->errors));
|
||||
}
|
||||
|
||||
$this->recalcTotalPrice();
|
||||
|
||||
$this->returnOK('Import proběhl: '.join(', ', $import->errors));
|
||||
}
|
||||
|
||||
public function handleCreateProduct()
|
||||
{
|
||||
$stockInID = $this->getID();
|
||||
$itemID = getVal('itemID');
|
||||
$success = false;
|
||||
|
||||
if ($stockInID && $itemID) {
|
||||
try {
|
||||
sqlGetConnection()->transactional(function () use ($itemID, $stockInID, &$success) {
|
||||
if ($item = $this->selectSQL('stock_in_items', ['id' => $itemID])->fetch()) {
|
||||
$stockIn = $this->selectSQL('stock_in', ['id' => $stockInID])->fetch();
|
||||
|
||||
$name = $item['name'];
|
||||
preg_match('/\(kód: (.*?)\)/', $name, $match);
|
||||
if (!empty($match)) {
|
||||
$name = str_replace($match[0], '', $name);
|
||||
$code = $match[1];
|
||||
$vatID = getAdminVat()['id'];
|
||||
$vat = getAdminVat()['value'];
|
||||
|
||||
$insert = [
|
||||
'title' => $name,
|
||||
// 'code' => $code,
|
||||
'vat' => $vatID,
|
||||
'figure' => 'N',
|
||||
'date_added' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
if ($this->getIndex() == 'invoice') {
|
||||
$insert['in_store'] = $item['quantity'] ? $item['quantity'] : 0;
|
||||
}
|
||||
|
||||
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
|
||||
$insert['price_buy'] = toDecimal($item['price'])->addVat($vat);
|
||||
}
|
||||
|
||||
$this->insertSQL('products', $insert);
|
||||
$productID = sqlInsertId();
|
||||
|
||||
$this->updateSQL(
|
||||
'stock_in_items',
|
||||
[
|
||||
'id_product' => $productID,
|
||||
'vat' => $vat,
|
||||
],
|
||||
['id' => $itemID]
|
||||
);
|
||||
|
||||
$this->insertSQL(
|
||||
'products_of_suppliers',
|
||||
[
|
||||
'id_product' => $productID,
|
||||
'id_supplier' => $stockIn['id_supplier'],
|
||||
'code' => $code,
|
||||
]
|
||||
);
|
||||
|
||||
$success = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if ($success) {
|
||||
$this->returnOK('Produkt byl úspěšně vytvořen');
|
||||
} else {
|
||||
$this->returnError('Produkt se nepodařilo vytvořit');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (strpos($e->getMessage(), '1062 Duplicate entry')) {
|
||||
$this->returnError('Nepodařilo se vytvořit produkt, protože produkt s takovým kódem už existuje.');
|
||||
} else {
|
||||
$this->returnError('Při vytváření produktu se vyskytla chyba: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getIndex()
|
||||
{
|
||||
if (is_null($this->index)) {
|
||||
try {
|
||||
$this->index = $this->getObject()['id_index'];
|
||||
} catch (NotFoundHttpException) {
|
||||
$this->index = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
public function storeIn($id_product, $id_variation, $quantity)
|
||||
{
|
||||
$index = $this->getIndex();
|
||||
if (in_array($index, ['closure', 'future', 'preorder'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlGetConnection()->transactional(function () use ($quantity, $id_variation, $id_product) {
|
||||
$stockIn = true;
|
||||
|
||||
if (findModule(Modules::STORES)) {
|
||||
$data = $this->getCustomData();
|
||||
$store_id = ($data['id_store'] ?? 1);
|
||||
$SQLfields = [
|
||||
'id_store' => $store_id,
|
||||
'id_product' => $id_product,
|
||||
'id_variation' => $id_variation,
|
||||
'quantity' => $quantity,
|
||||
];
|
||||
|
||||
ServiceContainer::getService(\KupShop\KupShopBundle\Util\LoggingContext::class)->activateStockIn($this->getID(), function () use ($SQLfields) {
|
||||
$this->storesInStore->updateStoreItem($SQLfields);
|
||||
});
|
||||
|
||||
$stores = $this->storesInStore->getStores();
|
||||
$store = $stores[$store_id];
|
||||
if ($store['type'] == StoresInStore::TYPE_EXTERNAL_STORE) {
|
||||
$stockIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($stockIn) {
|
||||
$prod = new Product($id_product);
|
||||
$prod->storeIn($id_variation, $quantity);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function hasRights($name = null)
|
||||
{
|
||||
switch ($name) {
|
||||
case Window::RIGHT_DUPLICATE:
|
||||
return false;
|
||||
case Window::RIGHT_DELETE:
|
||||
return findRight('INSTORE_STOCKIN_ERASE');
|
||||
default:
|
||||
return parent::hasRights($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user