feat(frontend): fulfillment split, API-driven topics, hub-and-spoke nav, stock-count modal, FOUND ceiling, semantic colors
- bug1: quote header fulfillment counter («رسید: X از Y قلم» amber / «تکمیل شد» green / «در راه»); expanded line items visually split into the received part (رسید شده ✓ + date + target warehouse from the receipt allocations) and the in-transit remainder — quantities always sum to the original line (invariant D holds, display-only split) - bug2: 8-topic grids (suppliers/wizard/units) now come from /material-categories via the store (new lib/topics.ts; fixed the mismatched «ابزار و تجهیزات ساخت» label); suppliers topic->category resolution no longer falls back to an arbitrary category; duplicate month/status lists reuse the shared dictionaries; TopicGrid gained a loading EmptyState - bug3: hub-and-spoke — the tab strip renders only on the warehouse dashboard; sub-views hide it and navigate back via «بازگشت به داشبورد»; «افزایش موجود» became the «تغییر موجودی» entry button - bug4: stock count goes through a confirmation modal (current vs counted vs variance with کسری/مازاد badges) before posting STOCK_COUNT; numbers parsed defensively - bug5: found qty is capped client-side (red input + inline warning, submit disabled) and backend returns 422 when exceeding the missing balance; fully-recovered losses drop off the pending list - bug6+7: quantities render as absolute values with semantic color coding (emerald inflow / rose outflow / blue neutral) across dashboard timeline, daily control and the change-inventory form
This commit is contained in:
@@ -13,17 +13,18 @@ import type { InventoryRow, InventoryTransaction, TransactionType } from "../../
|
||||
import { faNum } from "../../lib/formatters";
|
||||
import { isoToJalaliStr } from "../../lib/jalali";
|
||||
|
||||
// رنگبندی معنایی: سبز زمردی = ورود/افزایش، رز = خروج/کاهش، آبی = خنثی/جابهجایی
|
||||
const TX_META: Record<TransactionType, { label: string; color: string; icon: string }> = {
|
||||
PURCHASE: { label: "خرید", color: "#16a34a", icon: "🛒" },
|
||||
WITHDRAWAL: { label: "برداشت", color: "#1d4ed8", icon: "➖" },
|
||||
RETURN: { label: "برگشت", color: "#16a34a", icon: "↩️" },
|
||||
TRANSFER_IN: { label: "انتقال (ورودی)", color: "#16a34a", icon: "⬅️" },
|
||||
TRANSFER_OUT: { label: "انتقال (خروجی)", color: "#1d4ed8", icon: "➡️" },
|
||||
DAMAGE: { label: "ضایعات", color: "#1d4ed8", icon: "⚠️" },
|
||||
WASTE: { label: "اتلاف", color: "#1d4ed8", icon: "🗑️" },
|
||||
LOSS: { label: "مفقودی", color: "#1d4ed8", icon: "📦" },
|
||||
FOUND: { label: "پیدا شده", color: "#16a34a", icon: "🔍" },
|
||||
STOCK_COUNT: { label: "شمارش موجودی", color: "#64748b", icon: "✅" },
|
||||
PURCHASE: { label: "خرید", color: "#10b981", icon: "🛒" },
|
||||
WITHDRAWAL: { label: "برداشت", color: "#e11d48", icon: "➖" },
|
||||
RETURN: { label: "برگشت", color: "#10b981", icon: "↩️" },
|
||||
TRANSFER_IN: { label: "انتقال (ورودی)", color: "#2563eb", icon: "⬅️" },
|
||||
TRANSFER_OUT: { label: "انتقال (خروجی)", color: "#2563eb", icon: "➡️" },
|
||||
DAMAGE: { label: "ضایعات", color: "#e11d48", icon: "⚠️" },
|
||||
WASTE: { label: "اتلاف", color: "#e11d48", icon: "🗑️" },
|
||||
LOSS: { label: "مفقودی", color: "#e11d48", icon: "📦" },
|
||||
FOUND: { label: "پیدا شده", color: "#10b981", icon: "🔍" },
|
||||
STOCK_COUNT: { label: "شمارش موجودی", color: "#2563eb", icon: "✅" },
|
||||
};
|
||||
|
||||
interface Group {
|
||||
@@ -151,11 +152,11 @@ export function InventoryPage() {
|
||||
<InventoryTopNav pathname={location.pathname} variant={isAdmin ? "admin" : "pm"} />
|
||||
{isPM && (
|
||||
<Link
|
||||
to="/inventory/change?type=PURCHASE"
|
||||
to="/inventory/change"
|
||||
className="btn-line-file no-underline bg-accent text-white hover:bg-accent-dark"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
افزایش موجود
|
||||
تغییر موجودی
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
@@ -301,7 +302,7 @@ export function InventoryPage() {
|
||||
)}
|
||||
</div>
|
||||
<div className="text-[11px] text-muted">
|
||||
۱۰ نوع تراکنش استاندارد • افزایش موجودی سبز، کاهش آبی • کلیک روی هر سطر: خط زمانی با «مانده» لحظهبهلحظه و تفکیک برندها
|
||||
۱۰ نوع تراکنش استاندارد • سبز زمردی = ورود به انبار · رز = خروج/کاهش · آبی = انتقال و شمارش • کلیک روی هر سطر: خط زمانی با «مانده» لحظهبهلحظه و تفکیک برندها
|
||||
</div>
|
||||
</PageLayout>
|
||||
</div>
|
||||
@@ -377,7 +378,7 @@ function Timeline({ g, txs, allTxs, brandTxs, selTx, setSelTx, expBrand, setExpB
|
||||
>
|
||||
<span className="text-[11px] font-bold" style={{ color: meta.color }}>{meta.icon} {meta.label}</span>
|
||||
<span className="text-[12px] font-bold" style={{ color: meta.color }}>
|
||||
{t.quantity_number >= 0 ? "+" : "−"}{faNum(Math.abs(t.quantity_number))} {unit}
|
||||
{faNum(Math.abs(t.quantity_number))} {unit}
|
||||
</span>
|
||||
<span className="text-[10.5px] text-muted">مانده: <b>{faNum(bal)}</b> {unit}</span>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user