@lodashventure/medusa-parcel-shipping 0.4.3 → 0.4.4

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.
@@ -1,11 +1,232 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
- const adminSdk = require("@medusajs/admin-sdk");
4
- const ui = require("@medusajs/ui");
5
3
  const react = require("react");
6
- const lucideReact = require("lucide-react");
4
+ const ui = require("@medusajs/ui");
5
+ const adminSdk = require("@medusajs/admin-sdk");
7
6
  const icons = require("@medusajs/icons");
7
+ const lucideReact = require("lucide-react");
8
8
  require("@medusajs/admin-shared");
9
+ const OrderPackingSlipWidget = ({ data }) => {
10
+ const [packingSlip, setPackingSlip] = react.useState(null);
11
+ const [loading, setLoading] = react.useState(true);
12
+ const [generating, setGenerating] = react.useState(false);
13
+ const [error, setError] = react.useState(null);
14
+ const order = data;
15
+ react.useEffect(() => {
16
+ fetchPackingSlip();
17
+ }, [order.id]);
18
+ const fetchPackingSlip = async () => {
19
+ setLoading(true);
20
+ setError(null);
21
+ try {
22
+ const response = await fetch(
23
+ `/admin/documents/packing-slip?orderId=${order.id}`,
24
+ {
25
+ credentials: "include"
26
+ }
27
+ );
28
+ if (!response.ok) {
29
+ throw new Error("Failed to fetch packing slip");
30
+ }
31
+ const data2 = await response.json();
32
+ setPackingSlip(data2.packingSlip || null);
33
+ } catch (err) {
34
+ console.error("Error fetching packing slip:", err);
35
+ setError(err.message);
36
+ } finally {
37
+ setLoading(false);
38
+ }
39
+ };
40
+ const generatePackingSlip = async () => {
41
+ setGenerating(true);
42
+ setError(null);
43
+ try {
44
+ const response = await fetch("/admin/documents/packing-slip", {
45
+ method: "POST",
46
+ headers: {
47
+ "Content-Type": "application/json"
48
+ },
49
+ credentials: "include",
50
+ body: JSON.stringify({
51
+ order_id: order.id
52
+ })
53
+ });
54
+ if (!response.ok) {
55
+ const errorData = await response.json().catch(() => ({
56
+ message: `HTTP ${response.status}: ${response.statusText}`
57
+ }));
58
+ throw new Error(errorData.message || "Failed to generate packing slip");
59
+ }
60
+ const data2 = await response.json();
61
+ setPackingSlip(data2.packingSlip);
62
+ ui.toast.success("สร้างใบแพ็คสินค้าสำเร็จ", {
63
+ description: `หมายเลขเอกสาร: ${data2.packingSlip.number}`
64
+ });
65
+ } catch (err) {
66
+ setError(err.message);
67
+ ui.toast.error("เกิดข้อผิดพลาด", {
68
+ description: err.message
69
+ });
70
+ } finally {
71
+ setGenerating(false);
72
+ }
73
+ };
74
+ const downloadPackingSlip = async () => {
75
+ var _a;
76
+ try {
77
+ const response = await fetch(
78
+ `/admin/documents/packing-slip?orderId=${order.id}&includeBuffer=true`,
79
+ {
80
+ credentials: "include"
81
+ }
82
+ );
83
+ if (!response.ok) {
84
+ throw new Error("Failed to fetch packing slip");
85
+ }
86
+ const data2 = await response.json();
87
+ if ((_a = data2.packingSlip) == null ? void 0 : _a.pdfBase64) {
88
+ const byteCharacters = atob(data2.packingSlip.pdfBase64);
89
+ const byteNumbers = new Array(byteCharacters.length);
90
+ for (let i = 0; i < byteCharacters.length; i++) {
91
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
92
+ }
93
+ const byteArray = new Uint8Array(byteNumbers);
94
+ const blob = new Blob([byteArray], { type: "application/pdf" });
95
+ const url = window.URL.createObjectURL(blob);
96
+ const link = document.createElement("a");
97
+ link.href = url;
98
+ link.download = `packing-slip-${data2.packingSlip.number}.pdf`;
99
+ document.body.appendChild(link);
100
+ link.click();
101
+ document.body.removeChild(link);
102
+ window.URL.revokeObjectURL(url);
103
+ ui.toast.success("ดาวน์โหลดสำเร็จ");
104
+ } else {
105
+ throw new Error("PDF data not available");
106
+ }
107
+ } catch (err) {
108
+ ui.toast.error("เกิดข้อผิดพลาดในการดาวน์โหลด", {
109
+ description: err.message
110
+ });
111
+ }
112
+ };
113
+ const formatDateTime = (dateString) => {
114
+ const date = new Date(dateString);
115
+ return new Intl.DateTimeFormat("th-TH", {
116
+ year: "numeric",
117
+ month: "short",
118
+ day: "numeric",
119
+ hour: "2-digit",
120
+ minute: "2-digit"
121
+ }).format(date);
122
+ };
123
+ if (loading) {
124
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
125
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
126
+ /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, { className: "text-ui-fg-subtle" }),
127
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "ใบแพ็คสินค้า" })
128
+ ] }) }),
129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "กำลังโหลด..." }) })
130
+ ] });
131
+ }
132
+ if (error && !packingSlip) {
133
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
134
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
135
+ /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, { className: "text-ui-fg-subtle" }),
136
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "ใบแพ็คสินค้า" })
137
+ ] }) }),
138
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-red-500", children: error }) })
139
+ ] });
140
+ }
141
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
142
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {}),
143
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
144
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
146
+ /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, { className: "text-ui-fg-subtle" }),
147
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "ใบแพ็คสินค้า" }),
148
+ packingSlip && /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", size: "small", children: "สร้างแล้ว" })
149
+ ] }),
150
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
151
+ packingSlip && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
152
+ /* @__PURE__ */ jsxRuntime.jsx(
153
+ ui.Button,
154
+ {
155
+ size: "small",
156
+ variant: "transparent",
157
+ onClick: fetchPackingSlip,
158
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: 16 })
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsxRuntime.jsxs(
162
+ ui.Button,
163
+ {
164
+ size: "small",
165
+ variant: "secondary",
166
+ onClick: downloadPackingSlip,
167
+ children: [
168
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 16 }),
169
+ "ดาวน์โหลด"
170
+ ]
171
+ }
172
+ )
173
+ ] }),
174
+ !packingSlip && /* @__PURE__ */ jsxRuntime.jsxs(
175
+ ui.Button,
176
+ {
177
+ size: "small",
178
+ onClick: generatePackingSlip,
179
+ isLoading: generating,
180
+ children: [
181
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 16 }),
182
+ "สร้างใบแพ็คสินค้า"
183
+ ]
184
+ }
185
+ )
186
+ ] })
187
+ ] }),
188
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: packingSlip ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
189
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
190
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: "หมายเลขเอกสาร" }),
192
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "font-mono", children: packingSlip.number })
193
+ ] }),
194
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
195
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: "สร้างเมื่อ" }),
196
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: formatDateTime(packingSlip.created_at) })
197
+ ] })
198
+ ] }),
199
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-4 border-t", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
200
+ "Document ID: ",
201
+ packingSlip.id
202
+ ] }) }),
203
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t", children: [
204
+ /* @__PURE__ */ jsxRuntime.jsxs(
205
+ ui.Button,
206
+ {
207
+ size: "small",
208
+ variant: "secondary",
209
+ onClick: generatePackingSlip,
210
+ isLoading: generating,
211
+ children: [
212
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: 16 }),
213
+ "สร้างใหม่"
214
+ ]
215
+ }
216
+ ),
217
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted mt-2", children: "การสร้างใหม่จะแทนที่ใบแพ็คสินค้าเดิม" })
218
+ ] })
219
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
220
+ /* @__PURE__ */ jsxRuntime.jsx(icons.DocumentText, { className: "text-ui-fg-muted mb-4" }),
221
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mb-2", children: "ยังไม่มีใบแพ็คสินค้าสำหรับคำสั่งซื้อนี้" }),
222
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted mb-4", children: "คลิกปุ่มด้านบนเพื่อสร้างใบแพ็คสินค้า" })
223
+ ] }) })
224
+ ] })
225
+ ] });
226
+ };
227
+ adminSdk.defineWidgetConfig({
228
+ zone: "order.details.after"
229
+ });
9
230
  const OrderShippingQuoteWidget = ({ data }) => {
10
231
  const [quote, setQuote] = react.useState(null);
11
232
  const [loading, setLoading] = react.useState(false);
@@ -44,16 +265,18 @@ const OrderShippingQuoteWidget = ({ data }) => {
44
265
  },
45
266
  allow_split_boxes: true
46
267
  };
47
- const response = await fetch("/store/quote", {
268
+ const response = await fetch("/admin/quote", {
48
269
  method: "POST",
49
270
  headers: {
50
- "Content-Type": "application/json",
51
- "x-publishable-api-key": "pk_99d0d47048eaf52697f42d149a7f58c1661652292b9e1ea1445f519cd16dc071"
271
+ "Content-Type": "application/json"
52
272
  },
273
+ credentials: "include",
53
274
  body: JSON.stringify(payload)
54
275
  });
55
276
  if (!response.ok) {
56
- const errorData = await response.json();
277
+ const errorData = await response.json().catch(() => ({
278
+ message: `HTTP ${response.status}: ${response.statusText}`
279
+ }));
57
280
  throw new Error(errorData.message || "Failed to fetch quote");
58
281
  }
59
282
  const data2 = await response.json();
@@ -651,7 +874,7 @@ const AreasPage = () => {
651
874
  /* @__PURE__ */ jsxRuntime.jsx(ServiceAreasTable, {})
652
875
  ] }) });
653
876
  };
654
- const config$3 = adminSdk.defineRouteConfig({
877
+ const config$4 = adminSdk.defineRouteConfig({
655
878
  icon: icons.MapPin,
656
879
  label: "พื้นที่บริการ"
657
880
  });
@@ -1059,7 +1282,7 @@ const BoxesPage = () => {
1059
1282
  /* @__PURE__ */ jsxRuntime.jsx(ParcelBoxesTable, {})
1060
1283
  ] }) });
1061
1284
  };
1062
- const config$2 = adminSdk.defineRouteConfig({
1285
+ const config$3 = adminSdk.defineRouteConfig({
1063
1286
  icon: icons.ArchiveBox,
1064
1287
  label: "กล่องพัสดุ"
1065
1288
  });
@@ -1502,10 +1725,225 @@ const MaterialCostsPage = () => {
1502
1725
  /* @__PURE__ */ jsxRuntime.jsx(MaterialCostsTable, {})
1503
1726
  ] }) });
1504
1727
  };
1505
- const config$1 = adminSdk.defineRouteConfig({
1728
+ const config$2 = adminSdk.defineRouteConfig({
1506
1729
  icon: icons.CurrencyDollarSolid,
1507
1730
  label: "ต้นทุนวัสดุ"
1508
1731
  });
1732
+ const PackingSlipSettingsPage = () => {
1733
+ const [settings, setSettings] = react.useState(null);
1734
+ const [loading, setLoading] = react.useState(true);
1735
+ const [saving, setSaving] = react.useState(false);
1736
+ const [formatNumber, setFormatNumber] = react.useState("");
1737
+ const [forcedNumber, setForcedNumber] = react.useState("");
1738
+ const [template, setTemplate] = react.useState("BASIC");
1739
+ react.useEffect(() => {
1740
+ fetchSettings();
1741
+ }, []);
1742
+ const fetchSettings = async () => {
1743
+ setLoading(true);
1744
+ try {
1745
+ const response = await fetch(
1746
+ "/admin/documents/document-packing-slip-settings",
1747
+ {
1748
+ credentials: "include"
1749
+ }
1750
+ );
1751
+ if (!response.ok) {
1752
+ throw new Error("Failed to fetch settings");
1753
+ }
1754
+ const data = await response.json();
1755
+ if (data.settings) {
1756
+ setSettings(data.settings);
1757
+ setFormatNumber(data.settings.formatNumber || "");
1758
+ setForcedNumber(data.settings.forcedNumber || "");
1759
+ setTemplate(data.settings.template || "BASIC");
1760
+ }
1761
+ } catch (err) {
1762
+ ui.toast.error("เกิดข้อผิดพลาด", {
1763
+ description: err.message
1764
+ });
1765
+ } finally {
1766
+ setLoading(false);
1767
+ }
1768
+ };
1769
+ const handleSave = async () => {
1770
+ setSaving(true);
1771
+ try {
1772
+ const response = await fetch(
1773
+ "/admin/documents/document-packing-slip-settings",
1774
+ {
1775
+ method: "POST",
1776
+ headers: {
1777
+ "Content-Type": "application/json"
1778
+ },
1779
+ credentials: "include",
1780
+ body: JSON.stringify({
1781
+ formatNumber: formatNumber || void 0,
1782
+ forcedNumber: forcedNumber || void 0,
1783
+ template
1784
+ })
1785
+ }
1786
+ );
1787
+ if (!response.ok) {
1788
+ const errorData = await response.json().catch(() => ({
1789
+ message: `HTTP ${response.status}: ${response.statusText}`
1790
+ }));
1791
+ throw new Error(errorData.message || "Failed to save settings");
1792
+ }
1793
+ const data = await response.json();
1794
+ setSettings(data.settings);
1795
+ ui.toast.success("บันทึกสำเร็จ", {
1796
+ description: "ตั้งค่าใบแพ็คสินค้าได้รับการบันทึกแล้ว"
1797
+ });
1798
+ } catch (err) {
1799
+ ui.toast.error("เกิดข้อผิดพลาดในการบันทึก", {
1800
+ description: err.message
1801
+ });
1802
+ } finally {
1803
+ setSaving(false);
1804
+ }
1805
+ };
1806
+ const handlePreview = async () => {
1807
+ var _a;
1808
+ try {
1809
+ const response = await fetch(
1810
+ `/admin/documents/packing-slip/preview?template=${template}`,
1811
+ {
1812
+ credentials: "include"
1813
+ }
1814
+ );
1815
+ if (!response.ok) {
1816
+ const errorData = await response.json().catch(() => ({
1817
+ message: `HTTP ${response.status}: ${response.statusText}`
1818
+ }));
1819
+ throw new Error(errorData.message || "Failed to generate preview");
1820
+ }
1821
+ const data = await response.json();
1822
+ if ((_a = data.packingSlip) == null ? void 0 : _a.pdfBase64) {
1823
+ const byteCharacters = atob(data.packingSlip.pdfBase64);
1824
+ const byteNumbers = new Array(byteCharacters.length);
1825
+ for (let i = 0; i < byteCharacters.length; i++) {
1826
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
1827
+ }
1828
+ const byteArray = new Uint8Array(byteNumbers);
1829
+ const blob = new Blob([byteArray], { type: "application/pdf" });
1830
+ const url = window.URL.createObjectURL(blob);
1831
+ window.open(url, "_blank");
1832
+ ui.toast.success("เปิดตัวอย่างในแท็บใหม่");
1833
+ } else {
1834
+ throw new Error("PDF data not available");
1835
+ }
1836
+ } catch (err) {
1837
+ ui.toast.error("เกิดข้อผิดพลาดในการแสดงตัวอย่าง", {
1838
+ description: err.message
1839
+ });
1840
+ }
1841
+ };
1842
+ if (loading) {
1843
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
1844
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "ตั้งค่าใบแพ็คสินค้า" }),
1845
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "กำลังโหลด..." })
1846
+ ] }) });
1847
+ }
1848
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1849
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {}),
1850
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
1851
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1852
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "ตั้งค่าใบแพ็คสินค้า" }),
1853
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle mt-1", children: "กำหนดรูปแบบและเทมเพลตสำหรับใบแพ็คสินค้า" })
1854
+ ] }) }),
1855
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-6", children: [
1856
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
1857
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "template", weight: "plus", children: "เทมเพลต" }),
1858
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: template, onValueChange: setTemplate, children: [
1859
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { id: "template", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
1860
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
1861
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "BASIC", children: "Basic - ใบแพ็คมาตรฐาน" }),
1862
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "BASIC_SMALL", children: "Basic Small - ใบแพ็คขนาดเล็ก" })
1863
+ ] })
1864
+ ] }),
1865
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "เลือกรูปแบบเทมเพลตสำหรับใบแพ็คสินค้า" }),
1866
+ /* @__PURE__ */ jsxRuntime.jsxs(
1867
+ ui.Button,
1868
+ {
1869
+ size: "small",
1870
+ variant: "secondary",
1871
+ onClick: handlePreview,
1872
+ className: "mt-2 w-fit",
1873
+ children: [
1874
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 16 }),
1875
+ "ดูตัวอย่างเทมเพลต"
1876
+ ]
1877
+ }
1878
+ )
1879
+ ] }),
1880
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
1881
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "formatNumber", weight: "plus", children: "รูปแบบหมายเลขเอกสาร" }),
1882
+ /* @__PURE__ */ jsxRuntime.jsx(
1883
+ ui.Input,
1884
+ {
1885
+ id: "formatNumber",
1886
+ placeholder: "เช่น PS-{YYYY}-{0000}",
1887
+ value: formatNumber,
1888
+ onChange: (e) => setFormatNumber(e.target.value)
1889
+ }
1890
+ ),
1891
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
1892
+ "กำหนดรูปแบบหมายเลขใบแพ็คสินค้า ใช้ ",
1893
+ "{YYYY}",
1894
+ " สำหรับปี และ",
1895
+ " ",
1896
+ "{0000}",
1897
+ " สำหรับเลขที่เอกสาร"
1898
+ ] })
1899
+ ] }),
1900
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
1901
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "forcedNumber", weight: "plus", children: "กำหนดหมายเลขเริ่มต้น" }),
1902
+ /* @__PURE__ */ jsxRuntime.jsx(
1903
+ ui.Input,
1904
+ {
1905
+ id: "forcedNumber",
1906
+ type: "number",
1907
+ placeholder: "เช่น 1",
1908
+ value: forcedNumber,
1909
+ onChange: (e) => setForcedNumber(e.target.value)
1910
+ }
1911
+ ),
1912
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "กำหนดหมายเลขเริ่มต้นสำหรับเอกสารใหม่ (ถ้าไม่ระบุจะนับต่อจากเอกสารล่าสุด)" })
1913
+ ] }),
1914
+ settings && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4 bg-ui-bg-subtle", children: [
1915
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", size: "small", className: "mb-2", children: "ข้อมูลการตั้งค่าปัจจุบัน" }),
1916
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm text-ui-fg-subtle", children: [
1917
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "อัปเดตล่าสุด:" }),
1918
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: new Date(settings.updated_at).toLocaleString("th-TH") }),
1919
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "สร้างเมื่อ:" }),
1920
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: new Date(settings.created_at).toLocaleString("th-TH") })
1921
+ ] })
1922
+ ] }),
1923
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4", children: [
1924
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", size: "small", className: "mb-2", children: "ตัวอย่างหมายเลขเอกสาร" }),
1925
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-lg", children: formatNumber ? formatNumber.replace("{YYYY}", (/* @__PURE__ */ new Date()).getFullYear().toString()).replace("{0000}", (forcedNumber || "1").padStart(4, "0")) : "ยังไม่ได้กำหนดรูปแบบ" })
1926
+ ] }),
1927
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 justify-end", children: [
1928
+ /* @__PURE__ */ jsxRuntime.jsx(
1929
+ ui.Button,
1930
+ {
1931
+ variant: "secondary",
1932
+ onClick: fetchSettings,
1933
+ disabled: saving,
1934
+ children: "รีเซ็ต"
1935
+ }
1936
+ ),
1937
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSave, isLoading: saving, children: "บันทึกการตั้งค่า" })
1938
+ ] })
1939
+ ] })
1940
+ ] }) })
1941
+ ] });
1942
+ };
1943
+ const config$1 = adminSdk.defineRouteConfig({
1944
+ icon: icons.DocumentText,
1945
+ label: "ตั้งค่าใบแพ็คสินค้า"
1946
+ });
1509
1947
  const CARRIER_TYPES$1 = [
1510
1948
  { value: "COMPANY_FLEET", label: "บริษัทรถส่งของ (Messenger)" },
1511
1949
  { value: "COMPANY_TRUCK", label: "รถบริษัท (Same Day)" },
@@ -1994,6 +2432,10 @@ const config = adminSdk.defineRouteConfig({
1994
2432
  label: "อัตราค่าขนส่ง"
1995
2433
  });
1996
2434
  const widgetModule = { widgets: [
2435
+ {
2436
+ Component: OrderPackingSlipWidget,
2437
+ zone: ["order.details.after"]
2438
+ },
1997
2439
  {
1998
2440
  Component: OrderShippingQuoteWidget,
1999
2441
  zone: ["order.details.after"]
@@ -2013,6 +2455,10 @@ const routeModule = {
2013
2455
  Component: MaterialCostsPage,
2014
2456
  path: "/material-costs"
2015
2457
  },
2458
+ {
2459
+ Component: PackingSlipSettingsPage,
2460
+ path: "/packing-slip-settings"
2461
+ },
2016
2462
  {
2017
2463
  Component: RatesPage,
2018
2464
  path: "/rates"
@@ -2021,22 +2467,28 @@ const routeModule = {
2021
2467
  };
2022
2468
  const menuItemModule = {
2023
2469
  menuItems: [
2470
+ {
2471
+ label: config$4.label,
2472
+ icon: config$4.icon,
2473
+ path: "/areas",
2474
+ nested: void 0
2475
+ },
2024
2476
  {
2025
2477
  label: config$3.label,
2026
2478
  icon: config$3.icon,
2027
- path: "/areas",
2479
+ path: "/boxes",
2028
2480
  nested: void 0
2029
2481
  },
2030
2482
  {
2031
2483
  label: config$2.label,
2032
2484
  icon: config$2.icon,
2033
- path: "/boxes",
2485
+ path: "/material-costs",
2034
2486
  nested: void 0
2035
2487
  },
2036
2488
  {
2037
2489
  label: config$1.label,
2038
2490
  icon: config$1.icon,
2039
- path: "/material-costs",
2491
+ path: "/packing-slip-settings",
2040
2492
  nested: void 0
2041
2493
  },
2042
2494
  {
@@ -1,10 +1,231 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
3
- import { Container, Heading, Button, Text, Badge, Drawer, Label, Select, Input, Switch, toast, Table, Prompt, Textarea } from "@medusajs/ui";
4
2
  import { useState, useEffect } from "react";
5
- import { Package, AlertCircle, Truck, Clock, Plus, Edit, Trash } from "lucide-react";
6
- import { MapPin, ArchiveBox, CurrencyDollarSolid, HandTruck } from "@medusajs/icons";
3
+ import { Container, Heading, Text, Toaster, Badge, Button, toast, Drawer, Label, Select, Input, Switch, Table, Prompt, Textarea } from "@medusajs/ui";
4
+ import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
5
+ import { DocumentText, MapPin, ArchiveBox, CurrencyDollarSolid, HandTruck } from "@medusajs/icons";
6
+ import { RefreshCw, Download, Plus, Package, AlertCircle, Truck, Clock, Edit, Trash, Eye } from "lucide-react";
7
7
  import "@medusajs/admin-shared";
8
+ const OrderPackingSlipWidget = ({ data }) => {
9
+ const [packingSlip, setPackingSlip] = useState(null);
10
+ const [loading, setLoading] = useState(true);
11
+ const [generating, setGenerating] = useState(false);
12
+ const [error, setError] = useState(null);
13
+ const order = data;
14
+ useEffect(() => {
15
+ fetchPackingSlip();
16
+ }, [order.id]);
17
+ const fetchPackingSlip = async () => {
18
+ setLoading(true);
19
+ setError(null);
20
+ try {
21
+ const response = await fetch(
22
+ `/admin/documents/packing-slip?orderId=${order.id}`,
23
+ {
24
+ credentials: "include"
25
+ }
26
+ );
27
+ if (!response.ok) {
28
+ throw new Error("Failed to fetch packing slip");
29
+ }
30
+ const data2 = await response.json();
31
+ setPackingSlip(data2.packingSlip || null);
32
+ } catch (err) {
33
+ console.error("Error fetching packing slip:", err);
34
+ setError(err.message);
35
+ } finally {
36
+ setLoading(false);
37
+ }
38
+ };
39
+ const generatePackingSlip = async () => {
40
+ setGenerating(true);
41
+ setError(null);
42
+ try {
43
+ const response = await fetch("/admin/documents/packing-slip", {
44
+ method: "POST",
45
+ headers: {
46
+ "Content-Type": "application/json"
47
+ },
48
+ credentials: "include",
49
+ body: JSON.stringify({
50
+ order_id: order.id
51
+ })
52
+ });
53
+ if (!response.ok) {
54
+ const errorData = await response.json().catch(() => ({
55
+ message: `HTTP ${response.status}: ${response.statusText}`
56
+ }));
57
+ throw new Error(errorData.message || "Failed to generate packing slip");
58
+ }
59
+ const data2 = await response.json();
60
+ setPackingSlip(data2.packingSlip);
61
+ toast.success("สร้างใบแพ็คสินค้าสำเร็จ", {
62
+ description: `หมายเลขเอกสาร: ${data2.packingSlip.number}`
63
+ });
64
+ } catch (err) {
65
+ setError(err.message);
66
+ toast.error("เกิดข้อผิดพลาด", {
67
+ description: err.message
68
+ });
69
+ } finally {
70
+ setGenerating(false);
71
+ }
72
+ };
73
+ const downloadPackingSlip = async () => {
74
+ var _a;
75
+ try {
76
+ const response = await fetch(
77
+ `/admin/documents/packing-slip?orderId=${order.id}&includeBuffer=true`,
78
+ {
79
+ credentials: "include"
80
+ }
81
+ );
82
+ if (!response.ok) {
83
+ throw new Error("Failed to fetch packing slip");
84
+ }
85
+ const data2 = await response.json();
86
+ if ((_a = data2.packingSlip) == null ? void 0 : _a.pdfBase64) {
87
+ const byteCharacters = atob(data2.packingSlip.pdfBase64);
88
+ const byteNumbers = new Array(byteCharacters.length);
89
+ for (let i = 0; i < byteCharacters.length; i++) {
90
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
91
+ }
92
+ const byteArray = new Uint8Array(byteNumbers);
93
+ const blob = new Blob([byteArray], { type: "application/pdf" });
94
+ const url = window.URL.createObjectURL(blob);
95
+ const link = document.createElement("a");
96
+ link.href = url;
97
+ link.download = `packing-slip-${data2.packingSlip.number}.pdf`;
98
+ document.body.appendChild(link);
99
+ link.click();
100
+ document.body.removeChild(link);
101
+ window.URL.revokeObjectURL(url);
102
+ toast.success("ดาวน์โหลดสำเร็จ");
103
+ } else {
104
+ throw new Error("PDF data not available");
105
+ }
106
+ } catch (err) {
107
+ toast.error("เกิดข้อผิดพลาดในการดาวน์โหลด", {
108
+ description: err.message
109
+ });
110
+ }
111
+ };
112
+ const formatDateTime = (dateString) => {
113
+ const date = new Date(dateString);
114
+ return new Intl.DateTimeFormat("th-TH", {
115
+ year: "numeric",
116
+ month: "short",
117
+ day: "numeric",
118
+ hour: "2-digit",
119
+ minute: "2-digit"
120
+ }).format(date);
121
+ };
122
+ if (loading) {
123
+ return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
124
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
125
+ /* @__PURE__ */ jsx(DocumentText, { className: "text-ui-fg-subtle" }),
126
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: "ใบแพ็คสินค้า" })
127
+ ] }) }),
128
+ /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "กำลังโหลด..." }) })
129
+ ] });
130
+ }
131
+ if (error && !packingSlip) {
132
+ return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
133
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
134
+ /* @__PURE__ */ jsx(DocumentText, { className: "text-ui-fg-subtle" }),
135
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: "ใบแพ็คสินค้า" })
136
+ ] }) }),
137
+ /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-red-500", children: error }) })
138
+ ] });
139
+ }
140
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
141
+ /* @__PURE__ */ jsx(Toaster, {}),
142
+ /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
143
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
144
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
145
+ /* @__PURE__ */ jsx(DocumentText, { className: "text-ui-fg-subtle" }),
146
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: "ใบแพ็คสินค้า" }),
147
+ packingSlip && /* @__PURE__ */ jsx(Badge, { color: "green", size: "small", children: "สร้างแล้ว" })
148
+ ] }),
149
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
150
+ packingSlip && /* @__PURE__ */ jsxs(Fragment, { children: [
151
+ /* @__PURE__ */ jsx(
152
+ Button,
153
+ {
154
+ size: "small",
155
+ variant: "transparent",
156
+ onClick: fetchPackingSlip,
157
+ children: /* @__PURE__ */ jsx(RefreshCw, { size: 16 })
158
+ }
159
+ ),
160
+ /* @__PURE__ */ jsxs(
161
+ Button,
162
+ {
163
+ size: "small",
164
+ variant: "secondary",
165
+ onClick: downloadPackingSlip,
166
+ children: [
167
+ /* @__PURE__ */ jsx(Download, { size: 16 }),
168
+ "ดาวน์โหลด"
169
+ ]
170
+ }
171
+ )
172
+ ] }),
173
+ !packingSlip && /* @__PURE__ */ jsxs(
174
+ Button,
175
+ {
176
+ size: "small",
177
+ onClick: generatePackingSlip,
178
+ isLoading: generating,
179
+ children: [
180
+ /* @__PURE__ */ jsx(Plus, { size: 16 }),
181
+ "สร้างใบแพ็คสินค้า"
182
+ ]
183
+ }
184
+ )
185
+ ] })
186
+ ] }),
187
+ /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: packingSlip ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
188
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
189
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
190
+ /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-subtle", children: "หมายเลขเอกสาร" }),
191
+ /* @__PURE__ */ jsx(Text, { weight: "plus", className: "font-mono", children: packingSlip.number })
192
+ ] }),
193
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
194
+ /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-subtle", children: "สร้างเมื่อ" }),
195
+ /* @__PURE__ */ jsx(Text, { size: "small", children: formatDateTime(packingSlip.created_at) })
196
+ ] })
197
+ ] }),
198
+ /* @__PURE__ */ jsx("div", { className: "pt-4 border-t", children: /* @__PURE__ */ jsxs(Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
199
+ "Document ID: ",
200
+ packingSlip.id
201
+ ] }) }),
202
+ /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
203
+ /* @__PURE__ */ jsxs(
204
+ Button,
205
+ {
206
+ size: "small",
207
+ variant: "secondary",
208
+ onClick: generatePackingSlip,
209
+ isLoading: generating,
210
+ children: [
211
+ /* @__PURE__ */ jsx(RefreshCw, { size: 16 }),
212
+ "สร้างใหม่"
213
+ ]
214
+ }
215
+ ),
216
+ /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted mt-2", children: "การสร้างใหม่จะแทนที่ใบแพ็คสินค้าเดิม" })
217
+ ] })
218
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
219
+ /* @__PURE__ */ jsx(DocumentText, { className: "text-ui-fg-muted mb-4" }),
220
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mb-2", children: "ยังไม่มีใบแพ็คสินค้าสำหรับคำสั่งซื้อนี้" }),
221
+ /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted mb-4", children: "คลิกปุ่มด้านบนเพื่อสร้างใบแพ็คสินค้า" })
222
+ ] }) })
223
+ ] })
224
+ ] });
225
+ };
226
+ defineWidgetConfig({
227
+ zone: "order.details.after"
228
+ });
8
229
  const OrderShippingQuoteWidget = ({ data }) => {
9
230
  const [quote, setQuote] = useState(null);
10
231
  const [loading, setLoading] = useState(false);
@@ -43,16 +264,18 @@ const OrderShippingQuoteWidget = ({ data }) => {
43
264
  },
44
265
  allow_split_boxes: true
45
266
  };
46
- const response = await fetch("/store/quote", {
267
+ const response = await fetch("/admin/quote", {
47
268
  method: "POST",
48
269
  headers: {
49
- "Content-Type": "application/json",
50
- "x-publishable-api-key": "pk_99d0d47048eaf52697f42d149a7f58c1661652292b9e1ea1445f519cd16dc071"
270
+ "Content-Type": "application/json"
51
271
  },
272
+ credentials: "include",
52
273
  body: JSON.stringify(payload)
53
274
  });
54
275
  if (!response.ok) {
55
- const errorData = await response.json();
276
+ const errorData = await response.json().catch(() => ({
277
+ message: `HTTP ${response.status}: ${response.statusText}`
278
+ }));
56
279
  throw new Error(errorData.message || "Failed to fetch quote");
57
280
  }
58
281
  const data2 = await response.json();
@@ -650,7 +873,7 @@ const AreasPage = () => {
650
873
  /* @__PURE__ */ jsx(ServiceAreasTable, {})
651
874
  ] }) });
652
875
  };
653
- const config$3 = defineRouteConfig({
876
+ const config$4 = defineRouteConfig({
654
877
  icon: MapPin,
655
878
  label: "พื้นที่บริการ"
656
879
  });
@@ -1058,7 +1281,7 @@ const BoxesPage = () => {
1058
1281
  /* @__PURE__ */ jsx(ParcelBoxesTable, {})
1059
1282
  ] }) });
1060
1283
  };
1061
- const config$2 = defineRouteConfig({
1284
+ const config$3 = defineRouteConfig({
1062
1285
  icon: ArchiveBox,
1063
1286
  label: "กล่องพัสดุ"
1064
1287
  });
@@ -1501,10 +1724,225 @@ const MaterialCostsPage = () => {
1501
1724
  /* @__PURE__ */ jsx(MaterialCostsTable, {})
1502
1725
  ] }) });
1503
1726
  };
1504
- const config$1 = defineRouteConfig({
1727
+ const config$2 = defineRouteConfig({
1505
1728
  icon: CurrencyDollarSolid,
1506
1729
  label: "ต้นทุนวัสดุ"
1507
1730
  });
1731
+ const PackingSlipSettingsPage = () => {
1732
+ const [settings, setSettings] = useState(null);
1733
+ const [loading, setLoading] = useState(true);
1734
+ const [saving, setSaving] = useState(false);
1735
+ const [formatNumber, setFormatNumber] = useState("");
1736
+ const [forcedNumber, setForcedNumber] = useState("");
1737
+ const [template, setTemplate] = useState("BASIC");
1738
+ useEffect(() => {
1739
+ fetchSettings();
1740
+ }, []);
1741
+ const fetchSettings = async () => {
1742
+ setLoading(true);
1743
+ try {
1744
+ const response = await fetch(
1745
+ "/admin/documents/document-packing-slip-settings",
1746
+ {
1747
+ credentials: "include"
1748
+ }
1749
+ );
1750
+ if (!response.ok) {
1751
+ throw new Error("Failed to fetch settings");
1752
+ }
1753
+ const data = await response.json();
1754
+ if (data.settings) {
1755
+ setSettings(data.settings);
1756
+ setFormatNumber(data.settings.formatNumber || "");
1757
+ setForcedNumber(data.settings.forcedNumber || "");
1758
+ setTemplate(data.settings.template || "BASIC");
1759
+ }
1760
+ } catch (err) {
1761
+ toast.error("เกิดข้อผิดพลาด", {
1762
+ description: err.message
1763
+ });
1764
+ } finally {
1765
+ setLoading(false);
1766
+ }
1767
+ };
1768
+ const handleSave = async () => {
1769
+ setSaving(true);
1770
+ try {
1771
+ const response = await fetch(
1772
+ "/admin/documents/document-packing-slip-settings",
1773
+ {
1774
+ method: "POST",
1775
+ headers: {
1776
+ "Content-Type": "application/json"
1777
+ },
1778
+ credentials: "include",
1779
+ body: JSON.stringify({
1780
+ formatNumber: formatNumber || void 0,
1781
+ forcedNumber: forcedNumber || void 0,
1782
+ template
1783
+ })
1784
+ }
1785
+ );
1786
+ if (!response.ok) {
1787
+ const errorData = await response.json().catch(() => ({
1788
+ message: `HTTP ${response.status}: ${response.statusText}`
1789
+ }));
1790
+ throw new Error(errorData.message || "Failed to save settings");
1791
+ }
1792
+ const data = await response.json();
1793
+ setSettings(data.settings);
1794
+ toast.success("บันทึกสำเร็จ", {
1795
+ description: "ตั้งค่าใบแพ็คสินค้าได้รับการบันทึกแล้ว"
1796
+ });
1797
+ } catch (err) {
1798
+ toast.error("เกิดข้อผิดพลาดในการบันทึก", {
1799
+ description: err.message
1800
+ });
1801
+ } finally {
1802
+ setSaving(false);
1803
+ }
1804
+ };
1805
+ const handlePreview = async () => {
1806
+ var _a;
1807
+ try {
1808
+ const response = await fetch(
1809
+ `/admin/documents/packing-slip/preview?template=${template}`,
1810
+ {
1811
+ credentials: "include"
1812
+ }
1813
+ );
1814
+ if (!response.ok) {
1815
+ const errorData = await response.json().catch(() => ({
1816
+ message: `HTTP ${response.status}: ${response.statusText}`
1817
+ }));
1818
+ throw new Error(errorData.message || "Failed to generate preview");
1819
+ }
1820
+ const data = await response.json();
1821
+ if ((_a = data.packingSlip) == null ? void 0 : _a.pdfBase64) {
1822
+ const byteCharacters = atob(data.packingSlip.pdfBase64);
1823
+ const byteNumbers = new Array(byteCharacters.length);
1824
+ for (let i = 0; i < byteCharacters.length; i++) {
1825
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
1826
+ }
1827
+ const byteArray = new Uint8Array(byteNumbers);
1828
+ const blob = new Blob([byteArray], { type: "application/pdf" });
1829
+ const url = window.URL.createObjectURL(blob);
1830
+ window.open(url, "_blank");
1831
+ toast.success("เปิดตัวอย่างในแท็บใหม่");
1832
+ } else {
1833
+ throw new Error("PDF data not available");
1834
+ }
1835
+ } catch (err) {
1836
+ toast.error("เกิดข้อผิดพลาดในการแสดงตัวอย่าง", {
1837
+ description: err.message
1838
+ });
1839
+ }
1840
+ };
1841
+ if (loading) {
1842
+ return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
1843
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "ตั้งค่าใบแพ็คสินค้า" }),
1844
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "กำลังโหลด..." })
1845
+ ] }) });
1846
+ }
1847
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1848
+ /* @__PURE__ */ jsx(Toaster, {}),
1849
+ /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
1850
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs("div", { children: [
1851
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "ตั้งค่าใบแพ็คสินค้า" }),
1852
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle mt-1", children: "กำหนดรูปแบบและเทมเพลตสำหรับใบแพ็คสินค้า" })
1853
+ ] }) }),
1854
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-6", children: [
1855
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-2", children: [
1856
+ /* @__PURE__ */ jsx(Label, { htmlFor: "template", weight: "plus", children: "เทมเพลต" }),
1857
+ /* @__PURE__ */ jsxs(Select, { value: template, onValueChange: setTemplate, children: [
1858
+ /* @__PURE__ */ jsx(Select.Trigger, { id: "template", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
1859
+ /* @__PURE__ */ jsxs(Select.Content, { children: [
1860
+ /* @__PURE__ */ jsx(Select.Item, { value: "BASIC", children: "Basic - ใบแพ็คมาตรฐาน" }),
1861
+ /* @__PURE__ */ jsx(Select.Item, { value: "BASIC_SMALL", children: "Basic Small - ใบแพ็คขนาดเล็ก" })
1862
+ ] })
1863
+ ] }),
1864
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "เลือกรูปแบบเทมเพลตสำหรับใบแพ็คสินค้า" }),
1865
+ /* @__PURE__ */ jsxs(
1866
+ Button,
1867
+ {
1868
+ size: "small",
1869
+ variant: "secondary",
1870
+ onClick: handlePreview,
1871
+ className: "mt-2 w-fit",
1872
+ children: [
1873
+ /* @__PURE__ */ jsx(Eye, { size: 16 }),
1874
+ "ดูตัวอย่างเทมเพลต"
1875
+ ]
1876
+ }
1877
+ )
1878
+ ] }),
1879
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-2", children: [
1880
+ /* @__PURE__ */ jsx(Label, { htmlFor: "formatNumber", weight: "plus", children: "รูปแบบหมายเลขเอกสาร" }),
1881
+ /* @__PURE__ */ jsx(
1882
+ Input,
1883
+ {
1884
+ id: "formatNumber",
1885
+ placeholder: "เช่น PS-{YYYY}-{0000}",
1886
+ value: formatNumber,
1887
+ onChange: (e) => setFormatNumber(e.target.value)
1888
+ }
1889
+ ),
1890
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
1891
+ "กำหนดรูปแบบหมายเลขใบแพ็คสินค้า ใช้ ",
1892
+ "{YYYY}",
1893
+ " สำหรับปี และ",
1894
+ " ",
1895
+ "{0000}",
1896
+ " สำหรับเลขที่เอกสาร"
1897
+ ] })
1898
+ ] }),
1899
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-2", children: [
1900
+ /* @__PURE__ */ jsx(Label, { htmlFor: "forcedNumber", weight: "plus", children: "กำหนดหมายเลขเริ่มต้น" }),
1901
+ /* @__PURE__ */ jsx(
1902
+ Input,
1903
+ {
1904
+ id: "forcedNumber",
1905
+ type: "number",
1906
+ placeholder: "เช่น 1",
1907
+ value: forcedNumber,
1908
+ onChange: (e) => setForcedNumber(e.target.value)
1909
+ }
1910
+ ),
1911
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "กำหนดหมายเลขเริ่มต้นสำหรับเอกสารใหม่ (ถ้าไม่ระบุจะนับต่อจากเอกสารล่าสุด)" })
1912
+ ] }),
1913
+ settings && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4 bg-ui-bg-subtle", children: [
1914
+ /* @__PURE__ */ jsx(Text, { weight: "plus", size: "small", className: "mb-2", children: "ข้อมูลการตั้งค่าปัจจุบัน" }),
1915
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm text-ui-fg-subtle", children: [
1916
+ /* @__PURE__ */ jsx("div", { children: "อัปเดตล่าสุด:" }),
1917
+ /* @__PURE__ */ jsx("div", { children: new Date(settings.updated_at).toLocaleString("th-TH") }),
1918
+ /* @__PURE__ */ jsx("div", { children: "สร้างเมื่อ:" }),
1919
+ /* @__PURE__ */ jsx("div", { children: new Date(settings.created_at).toLocaleString("th-TH") })
1920
+ ] })
1921
+ ] }),
1922
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4", children: [
1923
+ /* @__PURE__ */ jsx(Text, { weight: "plus", size: "small", className: "mb-2", children: "ตัวอย่างหมายเลขเอกสาร" }),
1924
+ /* @__PURE__ */ jsx("div", { className: "font-mono text-lg", children: formatNumber ? formatNumber.replace("{YYYY}", (/* @__PURE__ */ new Date()).getFullYear().toString()).replace("{0000}", (forcedNumber || "1").padStart(4, "0")) : "ยังไม่ได้กำหนดรูปแบบ" })
1925
+ ] }),
1926
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-end", children: [
1927
+ /* @__PURE__ */ jsx(
1928
+ Button,
1929
+ {
1930
+ variant: "secondary",
1931
+ onClick: fetchSettings,
1932
+ disabled: saving,
1933
+ children: "รีเซ็ต"
1934
+ }
1935
+ ),
1936
+ /* @__PURE__ */ jsx(Button, { onClick: handleSave, isLoading: saving, children: "บันทึกการตั้งค่า" })
1937
+ ] })
1938
+ ] })
1939
+ ] }) })
1940
+ ] });
1941
+ };
1942
+ const config$1 = defineRouteConfig({
1943
+ icon: DocumentText,
1944
+ label: "ตั้งค่าใบแพ็คสินค้า"
1945
+ });
1508
1946
  const CARRIER_TYPES$1 = [
1509
1947
  { value: "COMPANY_FLEET", label: "บริษัทรถส่งของ (Messenger)" },
1510
1948
  { value: "COMPANY_TRUCK", label: "รถบริษัท (Same Day)" },
@@ -1993,6 +2431,10 @@ const config = defineRouteConfig({
1993
2431
  label: "อัตราค่าขนส่ง"
1994
2432
  });
1995
2433
  const widgetModule = { widgets: [
2434
+ {
2435
+ Component: OrderPackingSlipWidget,
2436
+ zone: ["order.details.after"]
2437
+ },
1996
2438
  {
1997
2439
  Component: OrderShippingQuoteWidget,
1998
2440
  zone: ["order.details.after"]
@@ -2012,6 +2454,10 @@ const routeModule = {
2012
2454
  Component: MaterialCostsPage,
2013
2455
  path: "/material-costs"
2014
2456
  },
2457
+ {
2458
+ Component: PackingSlipSettingsPage,
2459
+ path: "/packing-slip-settings"
2460
+ },
2015
2461
  {
2016
2462
  Component: RatesPage,
2017
2463
  path: "/rates"
@@ -2020,22 +2466,28 @@ const routeModule = {
2020
2466
  };
2021
2467
  const menuItemModule = {
2022
2468
  menuItems: [
2469
+ {
2470
+ label: config$4.label,
2471
+ icon: config$4.icon,
2472
+ path: "/areas",
2473
+ nested: void 0
2474
+ },
2023
2475
  {
2024
2476
  label: config$3.label,
2025
2477
  icon: config$3.icon,
2026
- path: "/areas",
2478
+ path: "/boxes",
2027
2479
  nested: void 0
2028
2480
  },
2029
2481
  {
2030
2482
  label: config$2.label,
2031
2483
  icon: config$2.icon,
2032
- path: "/boxes",
2484
+ path: "/material-costs",
2033
2485
  nested: void 0
2034
2486
  },
2035
2487
  {
2036
2488
  label: config$1.label,
2037
2489
  icon: config$1.icon,
2038
- path: "/material-costs",
2490
+ path: "/packing-slip-settings",
2039
2491
  nested: void 0
2040
2492
  },
2041
2493
  {
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = POST;
4
+ const framework_1 = require("@medusajs/framework");
5
+ const parcel_shipping_1 = require("../../../modules/parcel-shipping");
6
+ const zod_1 = require("zod");
7
+ const QuoteItemSchema = zod_1.z.object({
8
+ sku: zod_1.z.string(),
9
+ width: zod_1.z.number().positive(),
10
+ length: zod_1.z.number().positive(),
11
+ height: zod_1.z.number().positive(),
12
+ weight: zod_1.z.number().positive(),
13
+ quantity: zod_1.z.number().int().positive(),
14
+ attributes: zod_1.z
15
+ .object({
16
+ noStack: zod_1.z.boolean().optional(),
17
+ fragile: zod_1.z.boolean().optional(),
18
+ stackable: zod_1.z.number().optional(),
19
+ })
20
+ .optional(),
21
+ });
22
+ const ShippingAddressSchema = zod_1.z.object({
23
+ address_line_1: zod_1.z.string().optional(), // House number, building, floor
24
+ address_line_2: zod_1.z.string().optional(), // Additional address info
25
+ street: zod_1.z.string().optional(), // Street name (ถนน)
26
+ sub_district: zod_1.z.string().optional(), // Sub-district (ตำบล/แขวง)
27
+ district: zod_1.z.string().optional(), // District (อำเภอ/เขต)
28
+ city: zod_1.z.string().optional(), // City
29
+ province: zod_1.z.string().optional(), // Province (จังหวัด)
30
+ postcode: zod_1.z.string().optional(), // Postal code
31
+ country: zod_1.z.string().default("TH"),
32
+ });
33
+ const PreferredServiceSchema = zod_1.z.object({
34
+ carrier_type: zod_1.z.enum(["COMPANY_FLEET", "COMPANY_TRUCK", "PRIVATE_CARRIER"]),
35
+ service_code: zod_1.z.enum([
36
+ "MESSENGER_3H",
37
+ "SAME_DAY",
38
+ "STANDARD_3_5D",
39
+ "EXPRESS_1_2D",
40
+ ]),
41
+ });
42
+ const QuoteRequestSchema = zod_1.z.object({
43
+ items: zod_1.z.array(QuoteItemSchema).min(1),
44
+ shipping_address: ShippingAddressSchema,
45
+ origin_address: ShippingAddressSchema.optional(),
46
+ preferred_service: PreferredServiceSchema.optional(),
47
+ allow_split_boxes: zod_1.z.boolean().optional().default(true),
48
+ });
49
+ /**
50
+ * POST /store/quote
51
+ * Get shipping quote with box selection and multiple service options
52
+ *
53
+ * Request Body:
54
+ * - items: Array of items to ship
55
+ * - shipping_address: Destination address
56
+ * - origin_address: Origin address (optional, for distance calculation)
57
+ * - preferred_service: Preferred carrier/service (optional)
58
+ * - allow_split_boxes: Allow splitting items across multiple boxes (default: true)
59
+ *
60
+ * Returns:
61
+ * - best_box: First box (for backward compatibility)
62
+ * - packing: First box packing details (for backward compatibility)
63
+ * - boxes: Array of all boxes with packing details
64
+ * - shipping_options: All available shipping options with cost breakdown
65
+ * - selected: Selected/preferred option
66
+ * - distance: Distance calculation result (if origin_address provided)
67
+ */
68
+ async function POST(req, res) {
69
+ const parcelService = framework_1.container.resolve(parcel_shipping_1.PARCEL_SHIPPING_MODULE);
70
+ try {
71
+ const validated = QuoteRequestSchema.parse(req.body);
72
+ console.log("Quote request validated:", {
73
+ items_count: validated.items.length,
74
+ shipping_address: validated.shipping_address,
75
+ preferred_service: validated.preferred_service,
76
+ });
77
+ const result = await parcelService.quote(validated);
78
+ res.json({
79
+ best_box: result.best_box,
80
+ packing: result.packing,
81
+ boxes: result.boxes,
82
+ shipping_options: result.shipping_options,
83
+ selected: result.selected,
84
+ distance: result.distance,
85
+ });
86
+ }
87
+ catch (error) {
88
+ if (error.name === "ZodError" && error.errors) {
89
+ console.error("Zod validation errors:", JSON.stringify(error.errors, null, 2));
90
+ return res.status(400).json({
91
+ code: "invalid_request",
92
+ message: "Invalid request data",
93
+ errors: error.errors,
94
+ details: error.errors.map((e) => ({
95
+ path: e.path.join("."),
96
+ message: e.message,
97
+ received: e.received,
98
+ })),
99
+ });
100
+ }
101
+ console.error("Quote API error:", {
102
+ name: error.name,
103
+ message: error.message,
104
+ stack: error.stack,
105
+ });
106
+ return res.status(400).json({
107
+ code: error.code || "quote_failed",
108
+ message: error.message || "Failed to generate quote",
109
+ error_details: {
110
+ name: error.name,
111
+ stack: error.stack?.split("\n").slice(0, 5).join("\n"),
112
+ },
113
+ });
114
+ }
115
+ }
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3F1b3RlL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBc0VBLG9CQXVEQztBQTVIRCxtREFBZ0Q7QUFDaEQsc0VBQTBFO0FBQzFFLDZCQUF3QjtBQUV4QixNQUFNLGVBQWUsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQy9CLEdBQUcsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO0lBQ2YsS0FBSyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDNUIsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDckMsVUFBVSxFQUFFLE9BQUM7U0FDVixNQUFNLENBQUM7UUFDTixPQUFPLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUMvQixPQUFPLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUMvQixTQUFTLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtLQUNqQyxDQUFDO1NBQ0QsUUFBUSxFQUFFO0NBQ2QsQ0FBQyxDQUFDO0FBRUgsTUFBTSxxQkFBcUIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3JDLGNBQWMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsZ0NBQWdDO0lBQ3ZFLGNBQWMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFF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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodashventure/medusa-parcel-shipping",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Parcel box selection and Thailand shipping quotes for Medusa.",
5
5
  "author": "LodashVenture",
6
6
  "license": "MIT",