cost/price/margin

This commit is contained in:
Thanakorn S
2026-05-06 09:37:28 +07:00
parent 6501d326ca
commit d8131a01b7
10 changed files with 130 additions and 27 deletions
+29 -9
View File
@@ -276,13 +276,14 @@ class ReportManager
a.product_sku,
SUM(a.total_in) AS total_in,
SUM(a.total_out) AS total_out,
b.min_stock
b.min_stock,
b.cost_price
FROM warehouse_balance a
LEFT JOIN md_product b
ON a.company_id = b.company_id
AND a.product_sku = b.sku
WHERE a.company_id = :company_id
GROUP BY a.product_sku, b.min_stock";
GROUP BY a.product_sku, b.min_stock, b.cost_price";
return $this->fetchAll($sql);
}
@@ -324,6 +325,7 @@ class ReportManager
mp.min_stock,
mp.reorder_point,
mp.product_image,
mp.cost_price,
ROUND(SUM(wb.total_in) - SUM(wb.total_out), 2) AS balance
FROM warehouse_balance wb
INNER JOIN md_product mp
@@ -336,7 +338,7 @@ class ReportManager
AND mp.reorder_point > 0
GROUP BY
wb.warehouse_id, wb.product_sku, mw.warehouse_name,
mp.product_name, mp.min_stock, mp.reorder_point, mp.product_image
mp.product_name, mp.min_stock, mp.reorder_point, mp.product_image, mp.cost_price
HAVING balance <= mp.reorder_point
ORDER BY mp.product_name ASC, mw.warehouse_name ASC";
@@ -352,6 +354,7 @@ class ReportManager
'product_sku' => $row['product_sku'],
'product_name' => $row['product_name'],
'product_image' => $row['product_image'],
'cost_price' => (float) ($row['cost_price'] ?? 0),
'balance' => max(0, round($balance, 2)),
'min_stock' => (float) $row['min_stock'],
'reorder_point' => (float) $row['reorder_point'],
@@ -1407,7 +1410,9 @@ class ReportManager
$product_name = $product_row['product_name'] ?: $product_sku;
$product_uom = $product_row['uom'] ?? '';
// All transactions for this SKU in range, sorted by date then id
// All transactions for this SKU in range, sorted by date then id.
// For stock-out rows, si.price is the purchase cost from the source stock-in (via ref_id).
// p.cost_price is the product-level fallback when si.price is 0 or ref_id is absent.
$sth = $this->pdo->prepare(
"SELECT
s.id,
@@ -1421,12 +1426,20 @@ class ReportManager
s.rack,
ROUND(COALESCE(s.`in`, 0), 2) AS stock_in,
ROUND(COALESCE(s.`out`, 0), 2) AS stock_out,
ROUND(s.price, 4) AS price,
ROUND(COALESCE(NULLIF(si.price, 0), p.cost_price, 0), 4) AS unit_cost,
c.contact_name,
s.description
FROM `{$table}` s
LEFT JOIN `{$table}` si
ON si.id = s.ref_id
AND s.`out` > 0
LEFT JOIN md_product p
ON p.company_id = s.company_id
AND p.sku = s.product_sku
LEFT JOIN md_contact c
ON c.company_id = s.company_id
AND c.id = s.contact_id
ON c.company_id = s.company_id
AND c.id = s.contact_id
WHERE s.company_id = :company_id
AND s.product_sku = :sku
AND s.status = 1
@@ -1436,11 +1449,18 @@ class ReportManager
$sth->execute([':company_id' => $this->companyId, ':sku' => $product_sku, ':date_from' => $date_from, ':date_to' => $date_to]);
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
// Append running_total to each row (carried forward from brought-forward balance)
// Append running_total and margin to each row.
// Margin is only meaningful for stock-out rows with both sell price and cost.
$running = $bf_bal;
foreach ($rows as &$row) {
$running += (float)$row['stock_in'] - (float)$row['stock_out'];
$row['running_total'] = round($running, 2);
$running += (float)$row['stock_in'] - (float)$row['stock_out'];
$row['running_total'] = round($running, 2);
$sell = (float)$row['price'];
$cost = (float)$row['unit_cost'];
$row['margin'] = ($row['stock_out'] > 0 && $sell > 0)
? round(($sell - $cost) / $sell * 100, 2)
: null;
}
unset($row);