ProductionPlanning - new way raw materials

This commit is contained in:
Michał Zieliński
2025-07-29 12:55:27 +02:00
parent f0e0a3dce1
commit e90640594d
2 changed files with 174 additions and 44 deletions

View File

@@ -132,6 +132,7 @@ function SetTab(tab_name) {
tabs[i].getElementsByTagName('a')[0].className = '';
}
}
var prevTabId = SelectedTab;
var prev = document.getElementById(SelectedTab);
var curr = document.getElementById(tab_name);
prev.style.display = 'none';
@@ -142,7 +143,7 @@ function SetTab(tab_name) {
$("#toogleReadyProducts").val("Ukryj gotowe");
$("#toogleServices").val("Ukryj usługi");
if (SelectedTab == '3') {
getRawMaterials();
getRawMaterials(prevTabId);
$("#toogleReadyProducts").show();
$("#toogleServices").show();
}
@@ -258,25 +259,33 @@ function filterComponents() {
drawComponents(filtered);
updateComponentsPositions();
}
function getRawMaterials() {
function getRawMaterials(previousTab) {
var ids = [];
$('input.allCheck:checkbox:checked').each(function () {
ids.push($(this).val());
});
if (previousTab === '1') {
$('input.allCheck:checkbox:checked').each(function () {
ids.push($(this).val());
});
}
if (previousTab === '2') {
$('input.componentCheck:checkbox:checked').each(function () {
ids.push($(this).val());
});
var tmp = [];
ids.forEach(el => {
var qty = parseFloat($("#qty-" + el).html().trim());
var prod = {};
prod.ecmproduct_id = el;
prod.quantity = qty;
tmp.push(prod);
});
ids = tmp;
}
if (ids.length === 0) {
alert('Wybierz pozycje zamówień');
SetTab('1');
return;
}
var cids = [];
$('input.componentCheck:checkbox:checked').each(function () {
cids.push($(this).val());
});
if (cids.length === 0) {
alert('Wybierz komponenty');
SetTab('2');
alert('Wybierz pozycje.');
SetTab(previousTab);
return;
}
showLoader();
var url = $(location).attr('href') + "&to_pdf=1&ajaxAction=getRawMaterials";
@@ -285,7 +294,7 @@ function getRawMaterials() {
url: url,
data: {
ids,
cids
type: previousTab === '1' ? 'sales' : 'components'
},
success: function (data) {
var result = JSON.parse(data);

View File

@@ -109,7 +109,7 @@ if (!isset($_GET['ajaxAction'])) {
}
$orderTypes = [];
$res = $db->query("SELECT distinct s.type FROM ecmsales AS s WHERE s.delivery_date > '$dateFrom' $typesWhere");
$res = $db->query("SELECT distinct s.type FROM ecmsales AS s WHERE s.delivery_date > '$dateFrom' $typesWhere");
while ($r = $db->fetchByAssoc($res)) {
$orderTypes[] = $r['type'];
}
@@ -136,7 +136,7 @@ if (!isset($_GET['ajaxAction'])) {
echo getComponents2($_POST['ids']);
break;
case 'getRawMaterials':
echo getRawMaterials($_POST['ids'], $_POST['cids']);
echo getRawMaterials2($_POST['ids'], $_POST['type']);;
break;
case 'saveProductDescription':
saveProductDescription($_GET['itemId'], $_GET['description']);
@@ -236,6 +236,104 @@ function getComponents($ids, $dateFrom, $dateTo)
echo json_encode($componentsData);
}
function getRawMaterials2($ids, $type)
{
global $app_list_strings;
$db = $GLOBALS['db'];
$idsString = join("','", $ids);
$products = array();
$response = array();
if ($type == 'sales') {
$productsQuery = "SELECT si.ecmproduct_id, SUM(si.quantity) as quantity
FROM ecmsaleitems AS si
WHERE si.id IN ('" . $idsString . "')";
$prows = $db->query($productsQuery);
while ($p = $db->fetchByAssoc($prows)) {
$prod = array();
$prod['ecmproduct_id'] = $p['ecmproduct_id'];
$prod['quantity'] = $p['quantity'];
$products[] = $prod;
}
} else if ($type == 'components') {
$products = $ids;
}
$grouppedProducts = array_reduce($products, function ($carry, $item) {
if (isset($carry[$item['ecmproduct_id']])) {
$carry[$item['ecmproduct_id']]['productQty'] += $item['quantity'];
} else {
$carry[$item['ecmproduct_id']] = $item;
}
return $carry;
});
$rawMaterialsData = array();
foreach ($grouppedProducts as $product) {
$rawMaterialsData = array_merge(
$rawMaterialsData,
getProductRawMaterials($product['ecmproduct_id'], $product['quantity'])
);
}
$grouppedRawMaterials = array_reduce($rawMaterialsData, function ($carry, $item) {
if (isset($carry[$item['ecmproduct_id']])) {
$carry[$item['ecmproduct_id']]['productQty'] += $item['quantity'];
} else {
$carry[$item['ecmproduct_id']] = $item;
}
return $carry;
});
foreach ($grouppedRawMaterials as $material) {
$product = $db->fetchByAssoc($db->query("
SELECT p.id, p.code, p.name, p.group_ks, p.unit_id, p.ems_qty_in_stock as stockState
FROM ecmproducts AS p
WHERE p.id='" . $material['ecmproduct_id'] . "'
"));
$ordered = $db->fetchByAssoc($db->query("SELECT SUM(poi.quantity) as ordered, GROUP_CONCAT(poi.ecmpurchaseorder_id SEPARATOR '|') AS orders
FROM ecmpurchaseorderitems as poi
INNER JOIN ecmpurchaseorders as po
ON poi.ecmpurchaseorder_id = po.id AND (po.status='registered' OR po.status='accepted') AND po.deleted=0
WHERE poi.deleted=0 AND poi.ecmproduct_id = '" . $material['ecmproduct_id'] . "'"));
$orders = array();
$ordersIds = explode('|', $ordered['orders']);
$ordersRes = $db->query("SELECT id, document_no, delivery_date FROM ecmpurchaseorders WHERE id IN ('" . join("','", $ordersIds) . "') ORDER BY date_entered DESC");
while ($o = $db->fetchByAssoc($ordersRes)) {
$orders[] = array(
'orderId' => $o['id'],
'orderNr' => $o['document_no'],
'orderDeliveryDate' => isset($o['delivery_date']) ? explode(' ', $o['delivery_date'])[0] : ''
);
}
$vendor = $db->fetchByAssoc($db->query("SELECT d.parent_id, a.name
FROM ecmstockdocinitems AS i
INNER JOIN ecmstockdocins AS d
ON d.id = i.ecmstockdocin_id
INNER JOIN accounts AS a
ON a.id = d.parent_id
WHERE i.ecmproduct_id = '" . $material['ecmproduct_id'] . "'
ORDER BY d.register_date DESC
LIMIT 0,1"));
$row = array();
$row['productId'] = $product['id'];
$row['productName'] = strlen($product['name']) > 55 ? substr($product['name'], 0, 55) . "..." : $product['name'];
$row['productFullName'] = $product['name'];
$row['productCode'] = strlen($product['code']) > 20 ? substr($product['code'], 0, 20) . "..." : $product['code'];
$row['productFullCode'] = $product['code'];
$row['productUnit'] = $app_list_strings['ecmproducts_unit_dom'][$product['unit_id']];
$row['productOrdered'] = (!empty($ordered['ordered'])) ? $ordered['ordered'] : 0;
$row['productVendorName'] = $vendor ? $vendor['name'] : '';
$row['productVendorId'] = $vendor ? $vendor['parent_id'] : '';
$row['productQty'] = $material['quantity'];
$row['productGroupKS'] = $product['group_ks'];
$row['orders'] = $orders;
$row['productStockState'] = (!empty($product['stockState'])) ? $product['stockState'] : 0;
$response[] = $row;
}
return json_encode($response);
}
function getRawMaterials($ids, $cids)
{
$db = $GLOBALS['db'];
@@ -306,7 +404,7 @@ function getRawMaterials($ids, $cids)
}
}
}
// group rawMaterialsData by productId and sum quantity and ordered
$tmp = array_reduce($rawMaterialsData, function ($carry, $item) {
if (isset($carry[$item['productId']])) {
@@ -318,32 +416,47 @@ function getRawMaterials($ids, $cids)
}, array());
// flat tmp array
$rawMaterialsData = array_values($tmp);
echo json_encode($rawMaterialsData);
}
function getProductRawMaterials($productId, $quantity)
{
$db = $GLOBALS['db'];
$response = array();
$componentsQuery = "SELECT c.ecmcomponent_id, c.quantity
FROM ecmproductcomponents as c
WHERE c.ecmproduct_id = '$productId'";
$crows = $db->query($componentsQuery);
if ($crows->num_rows == 0) {
return array(
array(
'ecmproduct_id' => $productId,
'quantity' => $quantity
)
);
} else {
while ($c = $db->fetchByAssoc($crows)) {
$response = array_merge($response, getProductRawMaterials($c['ecmcomponent_id'], $quantity * $c['quantity']));
$rawMaterialsQuery = "SELECT
c.ecmcomponent_id,
c.quantity,
(
SELECT COUNT(*)
FROM ecmproductcomponents as nested
WHERE nested.ecmproduct_id = c.ecmcomponent_id
) as nested_components_count
FROM
ecmproductcomponents as c
WHERE
c.ecmproduct_id = '$productId'";
$rows = $db->query($rawMaterialsQuery);
while ($r = $db->fetchByAssoc($rows)) {
if ($r['nested_components_count'] == 0) {
$response[] = array(
'ecmproduct_id' => $r['ecmcomponent_id'],
'quantity' => $r['quantity'] * $quantity
);
} else {
$response = array_merge(
$response,
getProductRawMaterials($r['ecmcomponent_id'], $r['quantity'] * $quantity)
);
}
return $response;
}
return $response;
}
function addToProductionScheduler($orderItemId) {
function addToProductionScheduler($orderItemId)
{
$db = $GLOBALS['db'];
global $current_user;
$saleInfo = $db->fetchByAssoc($db->query("SELECT quantity, ecmproduct_id, description, ecmsale_id FROM ecmsaleitems WHERE id ='$orderItemId'"));
@@ -370,14 +483,18 @@ function addToProductionScheduler($orderItemId) {
$db->query($query);
}
}
function addComponentToProductionScheduler($productId, $qty) {
function addComponentToProductionScheduler($productId, $qty)
{
$db = $GLOBALS['db'];
global $current_user;
$query = sprintf("INSERT INTO productionScheduler VALUES ('%s', null, null, null, '%d', NOW(), NOW(), '%s', '%s', 0, '%s', 1, null, null);",
generateUuidV4(), $qty, $current_user->id, $current_user->id, $productId);
$db->query($query);
}
function getComponents2($ids) {
function getComponents2($ids)
{
$db = $GLOBALS['db'];
global $app_list_strings;
$idsString = join("','", $ids);
@@ -457,7 +574,9 @@ function getComponents2($ids) {
*
*/
}
function getProductComponents($productId, $quantity) {
function getProductComponents($productId, $quantity)
{
$db = $GLOBALS['db'];
$response = array();
$componentsQuery = "SELECT
@@ -486,16 +605,18 @@ HAVING
} else {
// always add component to response
$response[] = array(
'ecmproduct_id' => $productId,
'quantity' => $quantity
'ecmproduct_id' => $productId,
'quantity' => $quantity
);
while ($c = $db->fetchByAssoc($crows)) {
$response = array_merge($response, getProductComponents($c['ecmcomponent_id'], $quantity * $c['quantity']));
$response = array_merge($response, getProductComponents($c['ecmcomponent_id'], $quantity * $c['quantity']));
}
return $response;
}
}
function generateUuidV4() {
function generateUuidV4()
{
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);