@argusoft/medplat-product-management 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BrandsPage-DCMCVvDY.js +334 -0
- package/dist/BrandsPage-DCMCVvDY.js.map +1 -0
- package/dist/CategoriesPage-BpRhwfrc.js +284 -0
- package/dist/CategoriesPage-BpRhwfrc.js.map +1 -0
- package/dist/DashboardPage-BNKUQj46.js +436 -0
- package/dist/DashboardPage-BNKUQj46.js.map +1 -0
- package/dist/FacilityPicker-Coi8I3yE.js +79 -0
- package/dist/FacilityPicker-Coi8I3yE.js.map +1 -0
- package/dist/InventoryPage-BR6jOzg2.js +517 -0
- package/dist/InventoryPage-BR6jOzg2.js.map +1 -0
- package/dist/MemberProfileCard-DbHZCS5n.js +272 -0
- package/dist/MemberProfileCard-DbHZCS5n.js.map +1 -0
- package/dist/PaymentCreatePage-Ci3ERnby.js +487 -0
- package/dist/PaymentCreatePage-Ci3ERnby.js.map +1 -0
- package/dist/PaymentsPage-sdg902zX.js +157 -0
- package/dist/PaymentsPage-sdg902zX.js.map +1 -0
- package/dist/PickupCreatePage-CieMsgWV.js +310 -0
- package/dist/PickupCreatePage-CieMsgWV.js.map +1 -0
- package/dist/PickupsPage-Ci2Ll0Kn.js +566 -0
- package/dist/PickupsPage-Ci2Ll0Kn.js.map +1 -0
- package/dist/PmGuard-CjJBisaN.js +1195 -0
- package/dist/PmGuard-CjJBisaN.js.map +1 -0
- package/dist/PmTable-BuXZQZCU.js +302 -0
- package/dist/PmTable-BuXZQZCU.js.map +1 -0
- package/dist/ProductEditPage-DL8gy85Y.js +666 -0
- package/dist/ProductEditPage-DL8gy85Y.js.map +1 -0
- package/dist/ProductsPage-BANTKxLb.js +221 -0
- package/dist/ProductsPage-BANTKxLb.js.map +1 -0
- package/dist/PurchaseCreatePage-C3KMfBxJ.js +626 -0
- package/dist/PurchaseCreatePage-C3KMfBxJ.js.map +1 -0
- package/dist/PurchaseRequestDetailPage-C0GYFJDl.js +586 -0
- package/dist/PurchaseRequestDetailPage-C0GYFJDl.js.map +1 -0
- package/dist/PurchaseRequestsPage-DvFH_tWe.js +265 -0
- package/dist/PurchaseRequestsPage-DvFH_tWe.js.map +1 -0
- package/dist/PurchasesPage-BCvLvSp4.js +295 -0
- package/dist/PurchasesPage-BCvLvSp4.js.map +1 -0
- package/dist/SaleCreatePage-DpkQMoTq.js +548 -0
- package/dist/SaleCreatePage-DpkQMoTq.js.map +1 -0
- package/dist/SalesPage-DUwgkEO-.js +315 -0
- package/dist/SalesPage-DUwgkEO-.js.map +1 -0
- package/dist/SettingsPage-CusC0jqJ.js +710 -0
- package/dist/SettingsPage-CusC0jqJ.js.map +1 -0
- package/dist/StorageUnitsPage-BlC2AgrJ.js +469 -0
- package/dist/StorageUnitsPage-BlC2AgrJ.js.map +1 -0
- package/dist/TransactionsPage-DDaK4VyY.js +714 -0
- package/dist/TransactionsPage-DDaK4VyY.js.map +1 -0
- package/dist/TransferCreatePage-BxudLfhS.js +363 -0
- package/dist/TransferCreatePage-BxudLfhS.js.map +1 -0
- package/dist/TransfersPage-zgmt7teZ.js +480 -0
- package/dist/TransfersPage-zgmt7teZ.js.map +1 -0
- package/dist/VialsPage-CjqPfgpV.js +855 -0
- package/dist/VialsPage-CjqPfgpV.js.map +1 -0
- package/dist/constants-BrA_hfAI.js +254 -0
- package/dist/constants-BrA_hfAI.js.map +1 -0
- package/dist/currency-BDDCDgeE.js +169 -0
- package/dist/currency-BDDCDgeE.js.map +1 -0
- package/dist/format-UOyOu75i.js +52 -0
- package/dist/format-UOyOu75i.js.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/useFieldErrors-hDG8ox_x.js +29 -0
- package/dist/useFieldErrors-hDG8ox_x.js.map +1 -0
- package/dist/validation-Ba7puFIO.js +109 -0
- package/dist/validation-Ba7puFIO.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import { A as e, E as t, P as n, a as r, c as i, i as a, n as ee, r as te, t as ne, y as re } from "./PmGuard-CjJBisaN.js";
|
|
2
|
+
import { t as ie } from "./currency-BDDCDgeE.js";
|
|
3
|
+
import { n as o } from "./PmTable-BuXZQZCU.js";
|
|
4
|
+
import { d as s, m as c, o as ae, t as l } from "./validation-Ba7puFIO.js";
|
|
5
|
+
import { t as oe } from "./useFieldErrors-hDG8ox_x.js";
|
|
6
|
+
import { i as se, r as u } from "./format-UOyOu75i.js";
|
|
7
|
+
import { n as ce } from "./constants-BrA_hfAI.js";
|
|
8
|
+
import { t as le } from "./MemberProfileCard-DbHZCS5n.js";
|
|
9
|
+
import { useMemo as d, useState as f } from "react";
|
|
10
|
+
import { Fragment as ue, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
11
|
+
import { v4 as h } from "uuid";
|
|
12
|
+
import { Alert as g, Box as de, Button as _, Card as v, CardContent as y, Divider as b, FormControl as x, FormHelperText as fe, Grid as S, IconButton as pe, InputAdornment as C, InputLabel as w, MenuItem as T, Select as E, Stack as D, TextField as O, Typography as k } from "@mui/material";
|
|
13
|
+
import me from "@mui/icons-material/AddRounded";
|
|
14
|
+
import { showToast as he } from "@/common/toaster/toaster";
|
|
15
|
+
import { useNavigate as ge, useParams as _e } from "react-router-dom";
|
|
16
|
+
import ve from "@mui/icons-material/SaveRounded";
|
|
17
|
+
import ye from "@mui/icons-material/DeleteOutlineRounded";
|
|
18
|
+
//#region src/views/SaleCreatePage.jsx
|
|
19
|
+
function A() {
|
|
20
|
+
return {
|
|
21
|
+
key: h(),
|
|
22
|
+
batchId: "",
|
|
23
|
+
quantity: 1,
|
|
24
|
+
salePrice: ""
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function j() {
|
|
28
|
+
let j = ge(), { memberId: M } = _e(), N = ie(i()?.currencyCode), [P, be] = f([]), [F, xe] = f([]), [Se, Ce] = f({}), [I, we] = f(""), [L, R] = f(""), Te = a().has("view.manage.productManagement.dues"), z = oe(), Ee = (/* @__PURE__ */ new Date()).toISOString().substring(0, 10), [B, V] = f({
|
|
29
|
+
id: h(),
|
|
30
|
+
saleDate: Ee,
|
|
31
|
+
paymentMode: "CASH",
|
|
32
|
+
collectingNow: "",
|
|
33
|
+
notes: "",
|
|
34
|
+
items: [A()]
|
|
35
|
+
});
|
|
36
|
+
te("update.manage.productManagement.sale", () => {
|
|
37
|
+
async function r() {
|
|
38
|
+
try {
|
|
39
|
+
let [r, i, a] = await Promise.all([
|
|
40
|
+
n(),
|
|
41
|
+
e().catch(() => []),
|
|
42
|
+
Te ? t().catch(() => []) : Promise.resolve([])
|
|
43
|
+
]);
|
|
44
|
+
be(r), xe(i), Ce(Object.fromEntries((a ?? []).map((e) => [e.memberId, Number(e.totalDue)])));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
R(e?.response?.data?.message ?? e?.message ?? "Failed to load reference data");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
r();
|
|
50
|
+
}, []);
|
|
51
|
+
let H = (e) => P.find((t) => t.id === e), U = d(() => {
|
|
52
|
+
let e = new Set(F.filter((e) => e.notForSale === !0).map((e) => e.id));
|
|
53
|
+
return P.filter((t) => !(t.qtyRemaining <= 0 || t.isQuarantined || e.has(t.productId) || se(t.expiryDate)));
|
|
54
|
+
}, [P, F]);
|
|
55
|
+
function W(e, t, n) {
|
|
56
|
+
V((r) => {
|
|
57
|
+
let i = r.items.slice();
|
|
58
|
+
return i[e] = {
|
|
59
|
+
...i[e],
|
|
60
|
+
[t]: n
|
|
61
|
+
}, {
|
|
62
|
+
...r,
|
|
63
|
+
items: i
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
let G = d(() => B.items.reduce((e, t) => !t.salePrice || !t.quantity ? e : e + Number(t.salePrice) * Number(t.quantity), 0), [B.items]), K = Number(M ? Se[M] ?? 0 : 0), De = Number(B.collectingNow || 0), q = Math.min(Math.max(De, 0), G), J = Math.max(G - q, 0), Y = J + K, X = {
|
|
68
|
+
saleDate: c(B.saleDate, "Sale date"),
|
|
69
|
+
member: M ? "" : "No member selected"
|
|
70
|
+
}, Z = B.collectingNow === "" ? "" : s(B.collectingNow);
|
|
71
|
+
!Z && B.collectingNow !== "" && Number(B.collectingNow) > G ? X.collectingNow = `Cannot collect more than the sale amount (${u(G)}). Settle old dues via Payments.` : Z && (X.collectingNow = Z);
|
|
72
|
+
let Oe = new Set(U.map((e) => e.id)), Q = B.items.map((e) => {
|
|
73
|
+
let t = H(e.batchId), n = ae(e.quantity, "Quantity", {
|
|
74
|
+
required: !0,
|
|
75
|
+
min: 1
|
|
76
|
+
});
|
|
77
|
+
!n && t && Number(e.quantity) > t.qtyRemaining && (n = `Only ${t.qtyRemaining} available in selected batch`);
|
|
78
|
+
let r = c(e.batchId, "Batch");
|
|
79
|
+
return !r && e.batchId && !Oe.has(e.batchId) && (r = "Batch is not available for sale (expired, quarantined, out of stock, or not-for-sale)."), {
|
|
80
|
+
batchId: r,
|
|
81
|
+
quantity: n,
|
|
82
|
+
salePrice: s(e.salePrice) || c(e.salePrice, "Unit price")
|
|
83
|
+
};
|
|
84
|
+
}), $ = l(X) && Q.every(l) && B.items.length > 0 && G > 0;
|
|
85
|
+
async function ke() {
|
|
86
|
+
if (!$) {
|
|
87
|
+
z.markAllTouched(), R("Please fix the highlighted fields and try again.");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
await re({
|
|
92
|
+
id: B.id,
|
|
93
|
+
saleDate: B.saleDate,
|
|
94
|
+
memberId: M,
|
|
95
|
+
paymentMode: B.paymentMode || null,
|
|
96
|
+
totalAmount: Number(G.toFixed(2)),
|
|
97
|
+
paidAmount: Number(q.toFixed(2)),
|
|
98
|
+
dueAmount: Number(J.toFixed(2)),
|
|
99
|
+
notes: B.notes || null,
|
|
100
|
+
items: B.items.map((e) => {
|
|
101
|
+
let t = H(e.batchId);
|
|
102
|
+
return {
|
|
103
|
+
batchId: e.batchId,
|
|
104
|
+
productId: t?.productId,
|
|
105
|
+
quantity: Number(e.quantity),
|
|
106
|
+
salePrice: Number(e.salePrice)
|
|
107
|
+
};
|
|
108
|
+
})
|
|
109
|
+
}), he({
|
|
110
|
+
message: "Sale recorded.",
|
|
111
|
+
type: "success"
|
|
112
|
+
}), j("/ui/medplat/manage/pm/sales");
|
|
113
|
+
} catch (e) {
|
|
114
|
+
R(e?.response?.data?.message ?? e?.message ?? "Failed to record sale");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return /* @__PURE__ */ m(de, { children: [/* @__PURE__ */ p(ee, {}), /* @__PURE__ */ p(ne, {
|
|
118
|
+
perm: "update.manage.productManagement.sale",
|
|
119
|
+
title: "You don’t have permission to record sales",
|
|
120
|
+
children: /* @__PURE__ */ m(r, {
|
|
121
|
+
title: "Record Sale",
|
|
122
|
+
actions: /* @__PURE__ */ m(D, {
|
|
123
|
+
direction: "row",
|
|
124
|
+
spacing: 1,
|
|
125
|
+
children: [/* @__PURE__ */ p(_, {
|
|
126
|
+
variant: "outlined",
|
|
127
|
+
onClick: () => j("/ui/medplat/manage/pm/sales"),
|
|
128
|
+
children: "Cancel"
|
|
129
|
+
}), /* @__PURE__ */ p(_, {
|
|
130
|
+
variant: "contained",
|
|
131
|
+
startIcon: /* @__PURE__ */ p(ve, {}),
|
|
132
|
+
disabled: !$,
|
|
133
|
+
onClick: () => void ke(),
|
|
134
|
+
children: "Save"
|
|
135
|
+
})]
|
|
136
|
+
}),
|
|
137
|
+
children: [
|
|
138
|
+
L ? /* @__PURE__ */ p(g, {
|
|
139
|
+
severity: "error",
|
|
140
|
+
sx: { mb: 2 },
|
|
141
|
+
children: L
|
|
142
|
+
}) : null,
|
|
143
|
+
/* @__PURE__ */ p(v, {
|
|
144
|
+
sx: {
|
|
145
|
+
borderRadius: 4,
|
|
146
|
+
mb: 2,
|
|
147
|
+
border: "1px solid",
|
|
148
|
+
borderColor: "divider",
|
|
149
|
+
boxShadow: "0 12px 32px rgba(15, 23, 42, 0.045)"
|
|
150
|
+
},
|
|
151
|
+
children: /* @__PURE__ */ m(y, {
|
|
152
|
+
sx: { p: 2.5 },
|
|
153
|
+
children: [/* @__PURE__ */ p(o, {
|
|
154
|
+
eyebrow: "Step 1",
|
|
155
|
+
title: "Customer",
|
|
156
|
+
hint: "The customer is set from the link you opened. Their balance shows below.",
|
|
157
|
+
sx: { mb: 2 }
|
|
158
|
+
}), M ? /* @__PURE__ */ p(le, {
|
|
159
|
+
memberId: M,
|
|
160
|
+
previousDue: K,
|
|
161
|
+
currencySymbol: N,
|
|
162
|
+
onLoad: (e) => we(e?.name ?? "")
|
|
163
|
+
}) : /* @__PURE__ */ p(g, {
|
|
164
|
+
severity: "warning",
|
|
165
|
+
children: "No member selected"
|
|
166
|
+
})]
|
|
167
|
+
})
|
|
168
|
+
}),
|
|
169
|
+
/* @__PURE__ */ p(v, {
|
|
170
|
+
sx: {
|
|
171
|
+
borderRadius: 4,
|
|
172
|
+
mb: 2,
|
|
173
|
+
border: "1px solid",
|
|
174
|
+
borderColor: "divider",
|
|
175
|
+
boxShadow: "0 12px 32px rgba(15, 23, 42, 0.045)"
|
|
176
|
+
},
|
|
177
|
+
children: /* @__PURE__ */ m(y, {
|
|
178
|
+
sx: { p: 2.5 },
|
|
179
|
+
children: [
|
|
180
|
+
/* @__PURE__ */ m(D, {
|
|
181
|
+
direction: "row",
|
|
182
|
+
justifyContent: "space-between",
|
|
183
|
+
alignItems: "flex-start",
|
|
184
|
+
sx: { mb: 2 },
|
|
185
|
+
children: [/* @__PURE__ */ p(o, {
|
|
186
|
+
eyebrow: "Step 2",
|
|
187
|
+
title: "Line items",
|
|
188
|
+
hint: "Each item comes from a batch. Buy price is shown as a cost reference."
|
|
189
|
+
}), /* @__PURE__ */ p(_, {
|
|
190
|
+
variant: "outlined",
|
|
191
|
+
startIcon: /* @__PURE__ */ p(me, {}),
|
|
192
|
+
onClick: () => V({
|
|
193
|
+
...B,
|
|
194
|
+
items: [...B.items, A()]
|
|
195
|
+
}),
|
|
196
|
+
children: "Add Line"
|
|
197
|
+
})]
|
|
198
|
+
}),
|
|
199
|
+
/* @__PURE__ */ p(b, { sx: { mb: 2 } }),
|
|
200
|
+
/* @__PURE__ */ p(D, {
|
|
201
|
+
spacing: 2,
|
|
202
|
+
children: B.items.map((e, t) => {
|
|
203
|
+
let n = H(e.batchId), r = Q[t] || {}, i = e.salePrice && e.quantity ? Number(e.salePrice) * Number(e.quantity) : 0;
|
|
204
|
+
return /* @__PURE__ */ p(v, {
|
|
205
|
+
variant: "outlined",
|
|
206
|
+
sx: {
|
|
207
|
+
p: 2,
|
|
208
|
+
borderRadius: 3
|
|
209
|
+
},
|
|
210
|
+
children: /* @__PURE__ */ m(S, {
|
|
211
|
+
container: !0,
|
|
212
|
+
spacing: 2,
|
|
213
|
+
alignItems: "center",
|
|
214
|
+
children: [
|
|
215
|
+
/* @__PURE__ */ p(S, {
|
|
216
|
+
item: !0,
|
|
217
|
+
xs: 12,
|
|
218
|
+
md: 5,
|
|
219
|
+
children: /* @__PURE__ */ m(x, {
|
|
220
|
+
required: !0,
|
|
221
|
+
fullWidth: !0,
|
|
222
|
+
size: "small",
|
|
223
|
+
error: z.show(`items.${t}.batchId`) && !!r.batchId,
|
|
224
|
+
children: [
|
|
225
|
+
/* @__PURE__ */ p(w, { children: "Batch" }),
|
|
226
|
+
/* @__PURE__ */ p(E, {
|
|
227
|
+
label: "Batch",
|
|
228
|
+
value: e.batchId,
|
|
229
|
+
onChange: (e) => W(t, "batchId", e.target.value),
|
|
230
|
+
onBlur: z.onBlur(`items.${t}.batchId`),
|
|
231
|
+
children: U.map((e) => /* @__PURE__ */ m(T, {
|
|
232
|
+
value: e.id,
|
|
233
|
+
children: [
|
|
234
|
+
e.productName,
|
|
235
|
+
" · lot ",
|
|
236
|
+
e.lotNumber || "—",
|
|
237
|
+
" ·",
|
|
238
|
+
" ",
|
|
239
|
+
e.qtyRemaining,
|
|
240
|
+
" left"
|
|
241
|
+
]
|
|
242
|
+
}, e.id))
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ p(fe, { children: z.show(`items.${t}.batchId`) && r.batchId ? r.batchId : n?.buyPrice == null ? " " : `Buy price: ${N}${u(n.buyPrice)} / unit` })
|
|
245
|
+
]
|
|
246
|
+
})
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ p(S, {
|
|
249
|
+
item: !0,
|
|
250
|
+
xs: 6,
|
|
251
|
+
md: 2,
|
|
252
|
+
children: /* @__PURE__ */ p(O, {
|
|
253
|
+
required: !0,
|
|
254
|
+
fullWidth: !0,
|
|
255
|
+
size: "small",
|
|
256
|
+
type: "number",
|
|
257
|
+
label: "Qty",
|
|
258
|
+
inputProps: {
|
|
259
|
+
min: 1,
|
|
260
|
+
max: n?.qtyRemaining
|
|
261
|
+
},
|
|
262
|
+
value: e.quantity,
|
|
263
|
+
onChange: (e) => W(t, "quantity", e.target.value),
|
|
264
|
+
onBlur: z.onBlur(`items.${t}.quantity`),
|
|
265
|
+
error: z.show(`items.${t}.quantity`) && !!r.quantity,
|
|
266
|
+
helperText: z.show(`items.${t}.quantity`) ? r.quantity : ""
|
|
267
|
+
})
|
|
268
|
+
}),
|
|
269
|
+
/* @__PURE__ */ p(S, {
|
|
270
|
+
item: !0,
|
|
271
|
+
xs: 6,
|
|
272
|
+
md: 2,
|
|
273
|
+
children: /* @__PURE__ */ p(O, {
|
|
274
|
+
required: !0,
|
|
275
|
+
fullWidth: !0,
|
|
276
|
+
size: "small",
|
|
277
|
+
type: "number",
|
|
278
|
+
inputProps: {
|
|
279
|
+
step: "0.01",
|
|
280
|
+
min: 0
|
|
281
|
+
},
|
|
282
|
+
label: "Unit Price",
|
|
283
|
+
InputProps: { startAdornment: /* @__PURE__ */ p(C, {
|
|
284
|
+
position: "start",
|
|
285
|
+
children: N
|
|
286
|
+
}) },
|
|
287
|
+
value: e.salePrice,
|
|
288
|
+
onChange: (e) => W(t, "salePrice", e.target.value),
|
|
289
|
+
onBlur: z.onBlur(`items.${t}.salePrice`),
|
|
290
|
+
error: z.show(`items.${t}.salePrice`) && !!r.salePrice,
|
|
291
|
+
helperText: z.show(`items.${t}.salePrice`) ? r.salePrice : ""
|
|
292
|
+
})
|
|
293
|
+
}),
|
|
294
|
+
/* @__PURE__ */ m(S, {
|
|
295
|
+
item: !0,
|
|
296
|
+
xs: 6,
|
|
297
|
+
md: 2,
|
|
298
|
+
sx: { textAlign: "right" },
|
|
299
|
+
children: [/* @__PURE__ */ p(k, {
|
|
300
|
+
variant: "caption",
|
|
301
|
+
color: "text.secondary",
|
|
302
|
+
sx: { display: "block" },
|
|
303
|
+
children: "Subtotal"
|
|
304
|
+
}), /* @__PURE__ */ m(k, {
|
|
305
|
+
variant: "body1",
|
|
306
|
+
sx: {
|
|
307
|
+
fontWeight: 800,
|
|
308
|
+
fontVariantNumeric: "tabular-nums"
|
|
309
|
+
},
|
|
310
|
+
children: [N, u(i)]
|
|
311
|
+
})]
|
|
312
|
+
}),
|
|
313
|
+
/* @__PURE__ */ p(S, {
|
|
314
|
+
item: !0,
|
|
315
|
+
xs: 6,
|
|
316
|
+
md: 1,
|
|
317
|
+
sx: { textAlign: "right" },
|
|
318
|
+
children: /* @__PURE__ */ p(pe, {
|
|
319
|
+
color: "error",
|
|
320
|
+
onClick: () => V({
|
|
321
|
+
...B,
|
|
322
|
+
items: B.items.filter((e, n) => n !== t)
|
|
323
|
+
}),
|
|
324
|
+
disabled: B.items.length === 1,
|
|
325
|
+
children: /* @__PURE__ */ p(ye, {})
|
|
326
|
+
})
|
|
327
|
+
})
|
|
328
|
+
]
|
|
329
|
+
})
|
|
330
|
+
}, e.key);
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
]
|
|
334
|
+
})
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ p(v, {
|
|
337
|
+
sx: {
|
|
338
|
+
borderRadius: 4,
|
|
339
|
+
bgcolor: "grey.50",
|
|
340
|
+
border: "1px solid",
|
|
341
|
+
borderColor: "divider",
|
|
342
|
+
boxShadow: "0 12px 32px rgba(15, 23, 42, 0.045)"
|
|
343
|
+
},
|
|
344
|
+
children: /* @__PURE__ */ m(y, {
|
|
345
|
+
sx: { p: 2.5 },
|
|
346
|
+
children: [
|
|
347
|
+
/* @__PURE__ */ p(o, {
|
|
348
|
+
eyebrow: "Step 3",
|
|
349
|
+
title: "Bill summary",
|
|
350
|
+
hint: "Shows totals, previous balance, and what you're collecting. Any remainder becomes a note of what they owe.",
|
|
351
|
+
sx: { mb: 2 }
|
|
352
|
+
}),
|
|
353
|
+
/* @__PURE__ */ m(S, {
|
|
354
|
+
container: !0,
|
|
355
|
+
spacing: 2,
|
|
356
|
+
children: [
|
|
357
|
+
/* @__PURE__ */ p(S, {
|
|
358
|
+
item: !0,
|
|
359
|
+
xs: 12,
|
|
360
|
+
md: 4,
|
|
361
|
+
children: /* @__PURE__ */ p(O, {
|
|
362
|
+
required: !0,
|
|
363
|
+
fullWidth: !0,
|
|
364
|
+
size: "small",
|
|
365
|
+
type: "date",
|
|
366
|
+
label: "Date",
|
|
367
|
+
InputLabelProps: { shrink: !0 },
|
|
368
|
+
value: B.saleDate,
|
|
369
|
+
onChange: (e) => V({
|
|
370
|
+
...B,
|
|
371
|
+
saleDate: e.target.value
|
|
372
|
+
}),
|
|
373
|
+
onBlur: z.onBlur("saleDate"),
|
|
374
|
+
error: z.show("saleDate") && !!X.saleDate,
|
|
375
|
+
helperText: z.show("saleDate") ? X.saleDate : ""
|
|
376
|
+
})
|
|
377
|
+
}),
|
|
378
|
+
/* @__PURE__ */ p(S, {
|
|
379
|
+
item: !0,
|
|
380
|
+
xs: 12,
|
|
381
|
+
md: 4,
|
|
382
|
+
children: /* @__PURE__ */ m(x, {
|
|
383
|
+
fullWidth: !0,
|
|
384
|
+
size: "small",
|
|
385
|
+
children: [/* @__PURE__ */ p(w, { children: "Payment Mode" }), /* @__PURE__ */ m(E, {
|
|
386
|
+
label: "Payment Mode",
|
|
387
|
+
value: B.paymentMode || "",
|
|
388
|
+
onChange: (e) => V({
|
|
389
|
+
...B,
|
|
390
|
+
paymentMode: e.target.value
|
|
391
|
+
}),
|
|
392
|
+
children: [/* @__PURE__ */ p(T, {
|
|
393
|
+
value: "",
|
|
394
|
+
children: /* @__PURE__ */ p("em", { children: "—" })
|
|
395
|
+
}), ce.map((e) => /* @__PURE__ */ p(T, {
|
|
396
|
+
value: e.value,
|
|
397
|
+
children: e.label
|
|
398
|
+
}, e.value))]
|
|
399
|
+
})]
|
|
400
|
+
})
|
|
401
|
+
}),
|
|
402
|
+
/* @__PURE__ */ p(S, {
|
|
403
|
+
item: !0,
|
|
404
|
+
xs: 12,
|
|
405
|
+
md: 4,
|
|
406
|
+
children: /* @__PURE__ */ p(O, {
|
|
407
|
+
fullWidth: !0,
|
|
408
|
+
size: "small",
|
|
409
|
+
label: "Notes",
|
|
410
|
+
value: B.notes,
|
|
411
|
+
onChange: (e) => V({
|
|
412
|
+
...B,
|
|
413
|
+
notes: e.target.value
|
|
414
|
+
})
|
|
415
|
+
})
|
|
416
|
+
})
|
|
417
|
+
]
|
|
418
|
+
}),
|
|
419
|
+
/* @__PURE__ */ p(b, { sx: { my: 2 } }),
|
|
420
|
+
/* @__PURE__ */ m(D, {
|
|
421
|
+
spacing: 1.25,
|
|
422
|
+
children: [
|
|
423
|
+
/* @__PURE__ */ m(D, {
|
|
424
|
+
direction: "row",
|
|
425
|
+
justifyContent: "space-between",
|
|
426
|
+
alignItems: "baseline",
|
|
427
|
+
children: [/* @__PURE__ */ m(k, {
|
|
428
|
+
variant: "body2",
|
|
429
|
+
color: "text.secondary",
|
|
430
|
+
children: [
|
|
431
|
+
"Sale Amount (",
|
|
432
|
+
B.items.length,
|
|
433
|
+
" ",
|
|
434
|
+
B.items.length === 1 ? "line" : "lines",
|
|
435
|
+
")"
|
|
436
|
+
]
|
|
437
|
+
}), /* @__PURE__ */ m(k, {
|
|
438
|
+
variant: "h5",
|
|
439
|
+
sx: {
|
|
440
|
+
fontWeight: 800,
|
|
441
|
+
fontVariantNumeric: "tabular-nums"
|
|
442
|
+
},
|
|
443
|
+
children: [N, u(G)]
|
|
444
|
+
})]
|
|
445
|
+
}),
|
|
446
|
+
/* @__PURE__ */ m(D, {
|
|
447
|
+
direction: "row",
|
|
448
|
+
justifyContent: "space-between",
|
|
449
|
+
alignItems: "baseline",
|
|
450
|
+
children: [/* @__PURE__ */ p(k, {
|
|
451
|
+
variant: "body2",
|
|
452
|
+
color: "text.secondary",
|
|
453
|
+
children: "Previous Due"
|
|
454
|
+
}), /* @__PURE__ */ m(k, {
|
|
455
|
+
variant: "body1",
|
|
456
|
+
sx: {
|
|
457
|
+
fontWeight: 700,
|
|
458
|
+
fontVariantNumeric: "tabular-nums",
|
|
459
|
+
color: K > 0 ? "warning.dark" : "text.primary"
|
|
460
|
+
},
|
|
461
|
+
children: [N, u(K)]
|
|
462
|
+
})]
|
|
463
|
+
}),
|
|
464
|
+
/* @__PURE__ */ p(b, { sx: { my: .5 } }),
|
|
465
|
+
/* @__PURE__ */ m(D, {
|
|
466
|
+
direction: "row",
|
|
467
|
+
justifyContent: "space-between",
|
|
468
|
+
alignItems: "center",
|
|
469
|
+
spacing: 2,
|
|
470
|
+
children: [/* @__PURE__ */ p(k, {
|
|
471
|
+
variant: "body2",
|
|
472
|
+
color: "text.secondary",
|
|
473
|
+
sx: { flexShrink: 0 },
|
|
474
|
+
children: "Amount Collecting Now"
|
|
475
|
+
}), /* @__PURE__ */ p(O, {
|
|
476
|
+
size: "small",
|
|
477
|
+
type: "number",
|
|
478
|
+
inputProps: {
|
|
479
|
+
step: "0.01",
|
|
480
|
+
min: 0,
|
|
481
|
+
max: G,
|
|
482
|
+
style: {
|
|
483
|
+
textAlign: "right",
|
|
484
|
+
fontWeight: 700
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
InputProps: { startAdornment: /* @__PURE__ */ p(C, {
|
|
488
|
+
position: "start",
|
|
489
|
+
children: N
|
|
490
|
+
}) },
|
|
491
|
+
sx: { width: 200 },
|
|
492
|
+
value: B.collectingNow,
|
|
493
|
+
placeholder: "0.00",
|
|
494
|
+
onChange: (e) => V({
|
|
495
|
+
...B,
|
|
496
|
+
collectingNow: e.target.value
|
|
497
|
+
}),
|
|
498
|
+
onBlur: z.onBlur("collectingNow"),
|
|
499
|
+
error: z.show("collectingNow") && !!X.collectingNow,
|
|
500
|
+
helperText: z.show("collectingNow") ? X.collectingNow : ""
|
|
501
|
+
})]
|
|
502
|
+
}),
|
|
503
|
+
/* @__PURE__ */ m(D, {
|
|
504
|
+
direction: "row",
|
|
505
|
+
justifyContent: "space-between",
|
|
506
|
+
alignItems: "baseline",
|
|
507
|
+
children: [/* @__PURE__ */ p(k, {
|
|
508
|
+
variant: "body2",
|
|
509
|
+
color: "text.secondary",
|
|
510
|
+
children: "Remaining Due (after this sale)"
|
|
511
|
+
}), /* @__PURE__ */ m(k, {
|
|
512
|
+
variant: "h5",
|
|
513
|
+
sx: {
|
|
514
|
+
fontWeight: 800,
|
|
515
|
+
fontVariantNumeric: "tabular-nums",
|
|
516
|
+
color: Y > 0 ? "warning.dark" : "success.dark"
|
|
517
|
+
},
|
|
518
|
+
children: [N, u(Y)]
|
|
519
|
+
})]
|
|
520
|
+
})
|
|
521
|
+
]
|
|
522
|
+
}),
|
|
523
|
+
M && Y > 0 ? /* @__PURE__ */ m(g, {
|
|
524
|
+
severity: "warning",
|
|
525
|
+
sx: { mt: 2 },
|
|
526
|
+
children: [
|
|
527
|
+
N,
|
|
528
|
+
u(Y),
|
|
529
|
+
" will be recorded as pending dues",
|
|
530
|
+
I ? /* @__PURE__ */ m(ue, { children: [
|
|
531
|
+
" ",
|
|
532
|
+
"for ",
|
|
533
|
+
/* @__PURE__ */ p("strong", { children: I })
|
|
534
|
+
] }) : null,
|
|
535
|
+
J > 0 && K > 0 ? ` (${N}${u(J)} from this sale + ${N}${u(K)} previously outstanding).` : J > 0 ? " from this sale." : " from previously outstanding dues."
|
|
536
|
+
]
|
|
537
|
+
}) : null
|
|
538
|
+
]
|
|
539
|
+
})
|
|
540
|
+
})
|
|
541
|
+
]
|
|
542
|
+
})
|
|
543
|
+
})] });
|
|
544
|
+
}
|
|
545
|
+
//#endregion
|
|
546
|
+
export { j as default };
|
|
547
|
+
|
|
548
|
+
//# sourceMappingURL=SaleCreatePage-DpkQMoTq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SaleCreatePage-DpkQMoTq.js","names":[],"sources":["../src/views/SaleCreatePage.jsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useNavigate, useParams } from \"react-router-dom\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardContent,\n Divider,\n FormControl,\n FormHelperText,\n Grid,\n IconButton,\n InputAdornment,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n TextField,\n Typography,\n} from \"@mui/material\";\nimport AddRoundedIcon from \"@mui/icons-material/AddRounded\";\nimport DeleteOutlineRoundedIcon from \"@mui/icons-material/DeleteOutlineRounded\";\nimport SaveRoundedIcon from \"@mui/icons-material/SaveRounded\";\nimport { showToast } from \"@/common/toaster/toaster\";\nimport PmPageShell from \"@pm/components/PmPageShell\";\nimport PmNav from \"@pm/components/PmNav\";\nimport PmGuard from \"@pm/components/PmGuard\";\nimport { usePermissionedEffect, usePmPermissions } from \"@pm/utils/permissions\";\nimport {\n createSale,\n getMemberOutstandingDues,\n getProducts,\n listBatches,\n} from \"@pm/services/pmApi\";\nimport MemberProfileCard from \"@pm/components/MemberProfileCard\";\nimport { PAYMENT_MODES } from \"@pm/utils/constants\";\nimport { formatNumber, isPastExpiry } from \"@pm/utils/format\";\nimport { currencySymbol } from \"@pm/utils/currency\";\nimport { usePmSettings } from \"@pm/utils/settingsStore\";\nimport { PmFormSection } from \"@pm/components/PmTable\";\nimport {\n isClean,\n validateInteger,\n validatePrice,\n validateRequired,\n} from \"@pm/utils/validation\";\nimport { useFieldErrors } from \"@pm/utils/useFieldErrors\";\n\nfunction emptyLine() {\n return { key: uuidv4(), batchId: \"\", quantity: 1, salePrice: \"\" };\n}\n\nexport default function SaleCreatePage() {\n const navigate = useNavigate();\n const { memberId } = useParams();\n const settings = usePmSettings();\n const cur = currencySymbol(settings?.currencyCode);\n const [batches, setBatches] = useState([]);\n const [products, setProducts] = useState([]);\n // Map of memberId -> previousDue. The dues endpoint only returns members\n // with non-zero dues so the map stays small. Looked up by route memberId.\n const [duesByMember, setDuesByMember] = useState({});\n // Cached after MemberProfileCard fetches — used by the warning Alert that\n // references the member by name when remaining dues will be recorded.\n const [memberName, setMemberName] = useState(\"\");\n const [error, setError] = useState(\"\");\n const perms = usePmPermissions();\n // When the operator can't see dues, previousDue gracefully degrades to 0\n // instead of populating duesByMember from a 403'ing call.\n const canSeeDues = perms.has(\"view.manage.productManagement.dues\");\n const fieldErrors = useFieldErrors();\n const today = new Date().toISOString().substring(0, 10);\n const [form, setForm] = useState({\n id: uuidv4(),\n saleDate: today,\n paymentMode: \"CASH\",\n collectingNow: \"\",\n notes: \"\",\n items: [emptyLine()],\n });\n\n usePermissionedEffect(\n \"update.manage.productManagement.sale\",\n () => {\n async function load() {\n try {\n // Members are picked via async search now — no upfront load. Dues\n // come from the (aggregated) backend query and get attached to a\n // picked member by id.\n const [b, p, dues] = await Promise.all([\n listBatches(),\n getProducts().catch(() => []),\n // Silent degrade when the operator lacks the dues permission —\n // previousDue will stay 0 and the sale itself still works.\n canSeeDues\n ? getMemberOutstandingDues().catch(() => [])\n : Promise.resolve([]),\n ]);\n setBatches(b);\n setProducts(p);\n setDuesByMember(\n Object.fromEntries(\n (dues ?? []).map((d) => [d.memberId, Number(d.totalDue)]),\n ),\n );\n } catch (err) {\n setError(\n err?.response?.data?.message ??\n err?.message ??\n \"Failed to load reference data\",\n );\n }\n }\n void load();\n },\n [],\n );\n\n const batchById = (id) => batches.find((b) => b.id === id);\n\n // Batches that can be sold: stock on hand, not quarantined, not past expiry, and\n // the underlying product is not flagged as not-for-sale. Computed once per render.\n const sellableBatches = useMemo(() => {\n const notForSaleProductIds = new Set(\n products.filter((p) => p.notForSale === true).map((p) => p.id),\n );\n return batches.filter((b) => {\n if (b.qtyRemaining <= 0) return false;\n if (b.isQuarantined) return false;\n if (notForSaleProductIds.has(b.productId)) return false;\n // A batch is sellable on the day of its printed expiry; only the\n // following day counts as expired (matches the unit packaging rule).\n if (isPastExpiry(b.expiryDate)) return false;\n return true;\n });\n }, [batches, products]);\n\n function patchLine(idx, k, v) {\n setForm((f) => {\n const items = f.items.slice();\n items[idx] = { ...items[idx], [k]: v };\n return { ...f, items };\n });\n }\n\n // -------- Money math --------\n const saleAmount = useMemo(\n () =>\n form.items.reduce((sum, line) => {\n if (!line.salePrice || !line.quantity) return sum;\n return sum + Number(line.salePrice) * Number(line.quantity);\n }, 0),\n [form.items],\n );\n\n const previousDue = Number(memberId ? (duesByMember[memberId] ?? 0) : 0);\n const collectedRaw = Number(form.collectingNow || 0);\n // Clip the collected amount at the current sale's total — anything more would\n // need to be applied to the member's old dues, which is a separate Payment flow.\n const collected = Math.min(Math.max(collectedRaw, 0), saleAmount);\n const saleDue = Math.max(saleAmount - collected, 0);\n const remainingDue = saleDue + previousDue;\n\n // -------- Validation --------\n const headerErrors = {\n saleDate: validateRequired(form.saleDate, \"Sale date\"),\n member: memberId ? \"\" : \"No member selected\",\n };\n // Collecting Now: optional; if filled, must be a non-negative number ≤ sale amount.\n const collectingErr =\n form.collectingNow === \"\" ? \"\" : validatePrice(form.collectingNow);\n if (\n !collectingErr &&\n form.collectingNow !== \"\" &&\n Number(form.collectingNow) > saleAmount\n ) {\n headerErrors.collectingNow = `Cannot collect more than the sale amount (${formatNumber(saleAmount)}). Settle old dues via Payments.`;\n } else if (collectingErr) {\n headerErrors.collectingNow = collectingErr;\n }\n\n const sellableBatchIds = new Set(sellableBatches.map((b) => b.id));\n const lineErrors = form.items.map((line) => {\n const batch = batchById(line.batchId);\n const qty = validateInteger(line.quantity, \"Quantity\", {\n required: true,\n min: 1,\n });\n let qtyErr = qty;\n if (!qtyErr && batch && Number(line.quantity) > batch.qtyRemaining) {\n qtyErr = `Only ${batch.qtyRemaining} available in selected batch`;\n }\n let batchErr = validateRequired(line.batchId, \"Batch\");\n if (!batchErr && line.batchId && !sellableBatchIds.has(line.batchId)) {\n batchErr =\n \"Batch is not available for sale (expired, quarantined, out of stock, or not-for-sale).\";\n }\n return {\n batchId: batchErr,\n quantity: qtyErr,\n salePrice:\n validatePrice(line.salePrice) ||\n validateRequired(line.salePrice, \"Unit price\"),\n };\n });\n const formIsValid =\n isClean(headerErrors) &&\n lineErrors.every(isClean) &&\n form.items.length > 0 &&\n saleAmount > 0;\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError(\"Please fix the highlighted fields and try again.\");\n return;\n }\n try {\n await createSale({\n id: form.id,\n saleDate: form.saleDate,\n memberId,\n paymentMode: form.paymentMode || null,\n totalAmount: Number(saleAmount.toFixed(2)),\n paidAmount: Number(collected.toFixed(2)),\n dueAmount: Number(saleDue.toFixed(2)),\n notes: form.notes || null,\n items: form.items.map((l) => {\n const batch = batchById(l.batchId);\n return {\n batchId: l.batchId,\n productId: batch?.productId,\n quantity: Number(l.quantity),\n salePrice: Number(l.salePrice),\n };\n }),\n });\n showToast({ message: \"Sale recorded.\", type: \"success\" });\n navigate(\"/ui/medplat/manage/pm/sales\");\n } catch (err) {\n setError(\n err?.response?.data?.message ?? err?.message ?? \"Failed to record sale\",\n );\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard\n perm={\"update.manage.productManagement.sale\"}\n title=\"You don’t have permission to record sales\"\n >\n <PmPageShell\n title=\"Record Sale\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button\n variant=\"outlined\"\n onClick={() => navigate(\"/ui/medplat/manage/pm/sales\")}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n startIcon={<SaveRoundedIcon />}\n disabled={!formIsValid}\n onClick={() => void save()}\n >\n Save\n </Button>\n </Stack>\n }\n >\n {error ? (\n <Alert severity=\"error\" sx={{ mb: 2 }}>\n {error}\n </Alert>\n ) : null}\n\n {/* ---------- Member ---------- */}\n <Card\n sx={{\n borderRadius: 4,\n mb: 2,\n border: \"1px solid\",\n borderColor: \"divider\",\n boxShadow: \"0 12px 32px rgba(15, 23, 42, 0.045)\",\n }}\n >\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Step 1\"\n title=\"Customer\"\n hint=\"The customer is set from the link you opened. Their balance shows below.\"\n sx={{ mb: 2 }}\n />\n {memberId ? (\n <MemberProfileCard\n memberId={memberId}\n previousDue={previousDue}\n currencySymbol={cur}\n onLoad={(p) => setMemberName(p?.name ?? \"\")}\n />\n ) : (\n <Alert severity=\"warning\">No member selected</Alert>\n )}\n </CardContent>\n </Card>\n\n {/* ---------- Line items ---------- */}\n <Card\n sx={{\n borderRadius: 4,\n mb: 2,\n border: \"1px solid\",\n borderColor: \"divider\",\n boxShadow: \"0 12px 32px rgba(15, 23, 42, 0.045)\",\n }}\n >\n <CardContent sx={{ p: 2.5 }}>\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n sx={{ mb: 2 }}\n >\n <PmFormSection\n eyebrow=\"Step 2\"\n title=\"Line items\"\n hint=\"Each item comes from a batch. Buy price is shown as a cost reference.\"\n />\n <Button\n variant=\"outlined\"\n startIcon={<AddRoundedIcon />}\n onClick={() =>\n setForm({ ...form, items: [...form.items, emptyLine()] })\n }\n >\n Add Line\n </Button>\n </Stack>\n <Divider sx={{ mb: 2 }} />\n <Stack spacing={2}>\n {form.items.map((line, idx) => {\n const batch = batchById(line.batchId);\n const lerr = lineErrors[idx] || {};\n const subtotal =\n line.salePrice && line.quantity\n ? Number(line.salePrice) * Number(line.quantity)\n : 0;\n return (\n <Card\n key={line.key}\n variant=\"outlined\"\n sx={{ p: 2, borderRadius: 3 }}\n >\n <Grid container spacing={2} alignItems=\"center\">\n <Grid item xs={12} md={5}>\n <FormControl\n required\n fullWidth\n size=\"small\"\n error={\n fieldErrors.show(`items.${idx}.batchId`) &&\n !!lerr.batchId\n }\n >\n <InputLabel>Batch</InputLabel>\n <Select\n label=\"Batch\"\n value={line.batchId}\n onChange={(e) =>\n patchLine(idx, \"batchId\", e.target.value)\n }\n onBlur={fieldErrors.onBlur(\n `items.${idx}.batchId`,\n )}\n >\n {sellableBatches.map((b) => (\n <MenuItem key={b.id} value={b.id}>\n {b.productName} · lot {b.lotNumber || \"—\"} ·{\" \"}\n {b.qtyRemaining} left\n </MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {fieldErrors.show(`items.${idx}.batchId`) &&\n lerr.batchId\n ? lerr.batchId\n : batch?.buyPrice != null\n ? `Buy price: ${cur}${formatNumber(batch.buyPrice)} / unit`\n : \" \"}\n </FormHelperText>\n </FormControl>\n </Grid>\n <Grid item xs={6} md={2}>\n <TextField\n required\n fullWidth\n size=\"small\"\n type=\"number\"\n label=\"Qty\"\n inputProps={{ min: 1, max: batch?.qtyRemaining }}\n value={line.quantity}\n onChange={(e) =>\n patchLine(idx, \"quantity\", e.target.value)\n }\n onBlur={fieldErrors.onBlur(`items.${idx}.quantity`)}\n error={\n fieldErrors.show(`items.${idx}.quantity`) &&\n !!lerr.quantity\n }\n helperText={\n fieldErrors.show(`items.${idx}.quantity`)\n ? lerr.quantity\n : \"\"\n }\n />\n </Grid>\n <Grid item xs={6} md={2}>\n <TextField\n required\n fullWidth\n size=\"small\"\n type=\"number\"\n inputProps={{ step: \"0.01\", min: 0 }}\n label=\"Unit Price\"\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n {cur}\n </InputAdornment>\n ),\n }}\n value={line.salePrice}\n onChange={(e) =>\n patchLine(idx, \"salePrice\", e.target.value)\n }\n onBlur={fieldErrors.onBlur(\n `items.${idx}.salePrice`,\n )}\n error={\n fieldErrors.show(`items.${idx}.salePrice`) &&\n !!lerr.salePrice\n }\n helperText={\n fieldErrors.show(`items.${idx}.salePrice`)\n ? lerr.salePrice\n : \"\"\n }\n />\n </Grid>\n <Grid item xs={6} md={2} sx={{ textAlign: \"right\" }}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: \"block\" }}\n >\n Subtotal\n </Typography>\n <Typography\n variant=\"body1\"\n sx={{\n fontWeight: 800,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {cur}\n {formatNumber(subtotal)}\n </Typography>\n </Grid>\n <Grid item xs={6} md={1} sx={{ textAlign: \"right\" }}>\n <IconButton\n color=\"error\"\n onClick={() =>\n setForm({\n ...form,\n items: form.items.filter((_, i) => i !== idx),\n })\n }\n disabled={form.items.length === 1}\n >\n <DeleteOutlineRoundedIcon />\n </IconButton>\n </Grid>\n </Grid>\n </Card>\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n\n {/* ---------- Bill Summary footer ---------- */}\n <Card\n sx={{\n borderRadius: 4,\n bgcolor: \"grey.50\",\n border: \"1px solid\",\n borderColor: \"divider\",\n boxShadow: \"0 12px 32px rgba(15, 23, 42, 0.045)\",\n }}\n >\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Step 3\"\n title=\"Bill summary\"\n hint=\"Shows totals, previous balance, and what you're collecting. Any remainder becomes a note of what they owe.\"\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <TextField\n required\n fullWidth\n size=\"small\"\n type=\"date\"\n label=\"Date\"\n InputLabelProps={{ shrink: true }}\n value={form.saleDate}\n onChange={(e) =>\n setForm({ ...form, saleDate: e.target.value })\n }\n onBlur={fieldErrors.onBlur(\"saleDate\")}\n error={\n fieldErrors.show(\"saleDate\") && !!headerErrors.saleDate\n }\n helperText={\n fieldErrors.show(\"saleDate\") ? headerErrors.saleDate : \"\"\n }\n />\n </Grid>\n <Grid item xs={12} md={4}>\n <FormControl fullWidth size=\"small\">\n <InputLabel>Payment Mode</InputLabel>\n <Select\n label=\"Payment Mode\"\n value={form.paymentMode || \"\"}\n onChange={(e) =>\n setForm({ ...form, paymentMode: e.target.value })\n }\n >\n <MenuItem value=\"\">\n <em>—</em>\n </MenuItem>\n {PAYMENT_MODES.map((m) => (\n <MenuItem key={m.value} value={m.value}>\n {m.label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n <Grid item xs={12} md={4}>\n <TextField\n fullWidth\n size=\"small\"\n label=\"Notes\"\n value={form.notes}\n onChange={(e) =>\n setForm({ ...form, notes: e.target.value })\n }\n />\n </Grid>\n </Grid>\n\n <Divider sx={{ my: 2 }} />\n\n <Stack spacing={1.25}>\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"baseline\"\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n Sale Amount ({form.items.length}{\" \"}\n {form.items.length === 1 ? \"line\" : \"lines\"})\n </Typography>\n <Typography\n variant=\"h5\"\n sx={{ fontWeight: 800, fontVariantNumeric: \"tabular-nums\" }}\n >\n {cur}\n {formatNumber(saleAmount)}\n </Typography>\n </Stack>\n\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"baseline\"\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n Previous Due\n </Typography>\n <Typography\n variant=\"body1\"\n sx={{\n fontWeight: 700,\n fontVariantNumeric: \"tabular-nums\",\n color: previousDue > 0 ? \"warning.dark\" : \"text.primary\",\n }}\n >\n {cur}\n {formatNumber(previousDue)}\n </Typography>\n </Stack>\n\n <Divider sx={{ my: 0.5 }} />\n\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n spacing={2}\n >\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ flexShrink: 0 }}\n >\n Amount Collecting Now\n </Typography>\n <TextField\n size=\"small\"\n type=\"number\"\n inputProps={{\n step: \"0.01\",\n min: 0,\n max: saleAmount,\n style: { textAlign: \"right\", fontWeight: 700 },\n }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">{cur}</InputAdornment>\n ),\n }}\n sx={{ width: 200 }}\n value={form.collectingNow}\n placeholder=\"0.00\"\n onChange={(e) =>\n setForm({ ...form, collectingNow: e.target.value })\n }\n onBlur={fieldErrors.onBlur(\"collectingNow\")}\n error={\n fieldErrors.show(\"collectingNow\") &&\n !!headerErrors.collectingNow\n }\n helperText={\n fieldErrors.show(\"collectingNow\")\n ? headerErrors.collectingNow\n : \"\"\n }\n />\n </Stack>\n\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"baseline\"\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n Remaining Due (after this sale)\n </Typography>\n <Typography\n variant=\"h5\"\n sx={{\n fontWeight: 800,\n fontVariantNumeric: \"tabular-nums\",\n color: remainingDue > 0 ? \"warning.dark\" : \"success.dark\",\n }}\n >\n {cur}\n {formatNumber(remainingDue)}\n </Typography>\n </Stack>\n </Stack>\n\n {memberId && remainingDue > 0 ? (\n <Alert severity=\"warning\" sx={{ mt: 2 }}>\n {cur}\n {formatNumber(remainingDue)} will be recorded as pending dues\n {memberName ? (\n <>\n {\" \"}\n for <strong>{memberName}</strong>\n </>\n ) : null}\n {saleDue > 0 && previousDue > 0\n ? ` (${cur}${formatNumber(saleDue)} from this sale + ${cur}${formatNumber(previousDue)} previously outstanding).`\n : saleDue > 0\n ? \" from this sale.\"\n : \" from previously outstanding dues.\"}\n </Alert>\n ) : null}\n </CardContent>\n </Card>\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|