ts-glitter 21.3.8 → 21.4.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.
Files changed (134) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-line.js +12 -1
  4. package/lowcode/backend-manager/bg-line.ts +16 -1
  5. package/lowcode/backend-manager/bg-notify.js +13 -2
  6. package/lowcode/backend-manager/bg-notify.ts +17 -2
  7. package/lowcode/backend-manager/bg-product.js +81 -30
  8. package/lowcode/backend-manager/bg-product.ts +95 -34
  9. package/lowcode/backend-manager/bg-recommend.js +109 -141
  10. package/lowcode/backend-manager/bg-recommend.ts +122 -144
  11. package/lowcode/backend-manager/bg-sns.js +14 -4
  12. package/lowcode/backend-manager/bg-sns.ts +18 -4
  13. package/lowcode/backend-manager/bg-widget.js +176 -12
  14. package/lowcode/backend-manager/bg-widget.ts +198 -13
  15. package/lowcode/cms-plugin/auto-fcm-advertise.js +13 -2
  16. package/lowcode/cms-plugin/auto-fcm-advertise.ts +16 -2
  17. package/lowcode/cms-plugin/auto-fcm-history.js +13 -2
  18. package/lowcode/cms-plugin/auto-fcm-history.ts +16 -2
  19. package/lowcode/cms-plugin/model/order.d.ts +1 -0
  20. package/lowcode/cms-plugin/module/order-excel.js +18 -2
  21. package/lowcode/cms-plugin/module/order-excel.ts +20 -9
  22. package/lowcode/cms-plugin/module/product-setting.js +2 -1
  23. package/lowcode/cms-plugin/module/product-setting.ts +2 -1
  24. package/lowcode/cms-plugin/module/user-excel.js +1 -1
  25. package/lowcode/cms-plugin/module/user-excel.ts +2 -2
  26. package/lowcode/cms-plugin/pos-pages/payment-page.js +3 -2
  27. package/lowcode/cms-plugin/pos-pages/payment-page.ts +11 -5
  28. package/lowcode/cms-plugin/pos-pages/products-page.ts +0 -1
  29. package/lowcode/cms-plugin/shopping-allowance-manager.js +3 -2
  30. package/lowcode/cms-plugin/shopping-allowance-manager.ts +3 -2
  31. package/lowcode/cms-plugin/shopping-discount-setting.js +2 -0
  32. package/lowcode/cms-plugin/shopping-discount-setting.ts +2 -0
  33. package/lowcode/cms-plugin/shopping-invoice-manager.js +7 -4
  34. package/lowcode/cms-plugin/shopping-invoice-manager.ts +12 -11
  35. package/lowcode/cms-plugin/shopping-order-manager.js +21 -4
  36. package/lowcode/cms-plugin/shopping-order-manager.ts +30 -11
  37. package/lowcode/cms-plugin/shopping-product-setting.js +45 -41
  38. package/lowcode/cms-plugin/shopping-product-setting.ts +55 -48
  39. package/lowcode/cms-plugin/shopping-rebate.js +52 -46
  40. package/lowcode/cms-plugin/shopping-rebate.ts +402 -396
  41. package/lowcode/cms-plugin/shopping-setting-advance.js +6 -6
  42. package/lowcode/cms-plugin/shopping-setting-advance.ts +7 -7
  43. package/lowcode/cms-plugin/shopping-setting-basic.js +44 -0
  44. package/lowcode/cms-plugin/shopping-setting-basic.ts +63 -1
  45. package/lowcode/cms-plugin/shopping-setting-stock-log.js +57 -0
  46. package/lowcode/cms-plugin/shopping-setting-stock-log.ts +101 -0
  47. package/lowcode/cms-plugin/user-list.js +10 -9
  48. package/lowcode/cms-plugin/user-list.ts +11 -8
  49. package/lowcode/css/editor.css +1 -1
  50. package/lowcode/form-view/editor/image-selector.js +83 -82
  51. package/lowcode/form-view/editor/image-selector.ts +115 -107
  52. package/lowcode/glitter-base/route/user.js +27 -34
  53. package/lowcode/glitter-base/route/user.ts +31 -40
  54. package/lowcode/glitterBundle/dialog/ShareDialog.js +1 -0
  55. package/lowcode/glitterBundle/dialog/ShareDialog.ts +2 -0
  56. package/lowcode/glitterBundle/dialog/dialog.js +2 -2
  57. package/lowcode/glitterBundle/dialog/dialog.ts +2 -2
  58. package/lowcode/glitterBundle/plugins/editor-elem.js +5 -11
  59. package/lowcode/glitterBundle/plugins/editor-elem.ts +11 -11
  60. package/lowcode/modules/image-library.js +836 -486
  61. package/lowcode/modules/image-library.ts +1760 -1418
  62. package/lowcode/modules/tool.js +10 -9
  63. package/lowcode/modules/tool.ts +11 -10
  64. package/lowcode/public-components/checkout/index.js +4 -2
  65. package/lowcode/public-components/checkout/index.ts +5 -3
  66. package/lowcode/public-models/product.ts +13 -0
  67. package/nxv0ptv53w.json +1 -0
  68. package/package.json +1 -1
  69. package/src/api-public/controllers/shop.js +2 -2
  70. package/src/api-public/controllers/shop.js.map +1 -1
  71. package/src/api-public/controllers/shop.ts +5 -2
  72. package/src/api-public/controllers/stock.js +1 -1
  73. package/src/api-public/controllers/stock.js.map +1 -1
  74. package/src/api-public/controllers/stock.ts +93 -81
  75. package/src/api-public/models/glitter-finance.js +2 -1
  76. package/src/api-public/models/glitter-finance.js.map +1 -1
  77. package/src/api-public/services/checkout-event.js +1 -0
  78. package/src/api-public/services/checkout-event.js.map +1 -1
  79. package/src/api-public/services/checkout-event.ts +2 -2
  80. package/src/api-public/services/data-analyze.d.ts +1 -1
  81. package/src/api-public/services/diff-record.d.ts +25 -0
  82. package/src/api-public/services/diff-record.js +158 -0
  83. package/src/api-public/services/diff-record.js.map +1 -0
  84. package/src/api-public/services/diff-record.ts +217 -0
  85. package/src/api-public/services/ezpay/tool.d.ts +1 -0
  86. package/src/api-public/services/financial-serviceV2.js +7 -17
  87. package/src/api-public/services/financial-serviceV2.js.map +1 -1
  88. package/src/api-public/services/public-table-check.js +25 -7
  89. package/src/api-public/services/public-table-check.js.map +1 -1
  90. package/src/api-public/services/public-table-check.ts +53 -31
  91. package/src/api-public/services/shopping.d.ts +2 -12
  92. package/src/api-public/services/shopping.js +16 -7
  93. package/src/api-public/services/shopping.js.map +1 -1
  94. package/src/api-public/services/shopping.ts +33 -7
  95. package/src/api-public/services/stock.d.ts +1 -1
  96. package/src/api-public/services/stock.js +19 -17
  97. package/src/api-public/services/stock.js.map +1 -1
  98. package/src/api-public/services/stock.ts +711 -696
  99. package/src/api-public/services/user.d.ts +1 -1
  100. package/src/api-public/services/user.js +25 -25
  101. package/src/api-public/services/user.js.map +1 -1
  102. package/src/api-public/services/user.ts +34 -27
  103. package/src/app-project/serverless/src/index.js +7 -17
  104. package/src/app-project/serverless/src/index.js.map +1 -1
  105. package/src/app-project/serverless/src/modules/CryptoJS.js +7 -17
  106. package/src/app-project/serverless/src/modules/CryptoJS.js.map +1 -1
  107. package/src/app-project/serverless/src/modules/database.d.ts +1 -1
  108. package/src/app-project/serverless/src/modules/redis.d.ts +1 -1
  109. package/src/app-project/serverless/src/modules/ssh.js +7 -17
  110. package/src/app-project/serverless/src/modules/ssh.js.map +1 -1
  111. package/src/firebase/message.js +2 -1
  112. package/src/firebase/message.js.map +1 -1
  113. package/src/helper/app_creater.js +2 -1
  114. package/src/helper/app_creater.js.map +1 -1
  115. package/src/helper/glitter-util.d.ts +1 -0
  116. package/src/lambda/interface.js +2 -2
  117. package/src/lambda/interface.js.map +1 -1
  118. package/src/modules/CryptoJS.js +7 -17
  119. package/src/modules/CryptoJS.js.map +1 -1
  120. package/src/modules/database.d.ts +1 -1
  121. package/src/modules/ssh.js +7 -17
  122. package/src/modules/ssh.js.map +1 -1
  123. package/src/modules/tool.d.ts +5 -0
  124. package/src/modules/tool.js +19 -0
  125. package/src/modules/tool.js.map +1 -1
  126. package/src/modules/tool.ts +27 -0
  127. package/src/run.js +2 -1
  128. package/src/run.js.map +1 -1
  129. package/src/services/app.js +7 -17
  130. package/src/services/app.js.map +1 -1
  131. package/src/services/saas-table-check.js +2 -2
  132. package/src/services/saas-table-check.js.map +1 -1
  133. package/src/services/ses.js +2 -1
  134. package/src/services/ses.js.map +1 -1
@@ -6,200 +6,200 @@ import { Shopping } from './shopping';
6
6
  import { SharePermission } from './share-permission';
7
7
 
8
8
  type StockList = {
9
- [key: string]: { count: number };
9
+ [key: string]: { count: number };
10
10
  };
11
11
 
12
12
  export type StockHistoryType = 'restocking' | 'transfer' | 'checking';
13
13
 
14
14
  type ContentProduct = {
15
- variant_id: number;
16
- cost: number;
17
- note: string;
18
- transfer_count: number; // 預計進貨數, 預計調入數
19
- recent_count?: number; // 實際進貨數, 實際調入數
20
- check_count: number; // 盤點數
21
- replenishment_count?: number; // 此次補貨數
22
- title?: string;
23
- spec?: string;
24
- sku?: '';
25
- barcode?: '';
15
+ variant_id: number;
16
+ cost: number;
17
+ note: string;
18
+ transfer_count: number; // 預計進貨數, 預計調入數
19
+ recent_count?: number; // 實際進貨數, 實際調入數
20
+ check_count: number; // 盤點數
21
+ replenishment_count?: number; // 此次補貨數
22
+ title?: string;
23
+ spec?: string;
24
+ sku?: '';
25
+ barcode?: '';
26
26
  };
27
27
 
28
28
  type StockHistoryData = {
29
- id: string;
30
- type: StockHistoryType;
31
- status: number;
32
- order_id: string;
33
- created_time: string;
34
- content: {
35
- vendor: string;
36
- store_in: string; // 調入庫存點
37
- store_out: string; // 調出庫存點、盤點庫存點
38
- check_member: string; // 盤點人
39
- check_according: '' | 'all' | 'collection' | 'product'; // 商品盤點類型
40
- note: string;
41
- total_price?: number;
42
- product_list: ContentProduct[];
43
- changeLogs: {
44
- time: string;
45
- text: string;
46
- user: number;
47
- status: number;
48
- user_name?: string;
49
- product_list?: ContentProduct[];
50
- }[];
51
- };
29
+ id: string;
30
+ type: StockHistoryType;
31
+ status: number;
32
+ order_id: string;
33
+ created_time: string;
34
+ content: {
35
+ vendor: string;
36
+ store_in: string; // 調入庫存點
37
+ store_out: string; // 調出庫存點、盤點庫存點
38
+ check_member: string; // 盤點人
39
+ check_according: '' | 'all' | 'collection' | 'product'; // 商品盤點類型
40
+ note: string;
41
+ total_price?: number;
42
+ product_list: ContentProduct[];
43
+ changeLogs: {
44
+ time: string;
45
+ text: string;
46
+ user: number;
47
+ status: number;
48
+ user_name?: string;
49
+ product_list?: ContentProduct[];
50
+ }[];
51
+ };
52
52
  };
53
53
 
54
54
  const typeConfig: {
55
- [key in StockHistoryType]: {
56
- name: string;
57
- prefixId: string;
58
- status: {
59
- [key in number]: {
60
- title: string;
61
- badge: string;
62
- };
63
- };
55
+ [key in StockHistoryType]: {
56
+ name: string;
57
+ prefixId: string;
58
+ status: {
59
+ [key in number]: {
60
+ title: string;
61
+ badge: string;
62
+ };
64
63
  };
64
+ };
65
65
  } = {
66
- restocking: {
67
- name: '進貨',
68
- prefixId: 'IC',
69
- status: {
70
- 0: {
71
- title: '已完成',
72
- badge: 'info',
73
- },
74
- 1: {
75
- title: '已補貨',
76
- badge: 'info',
77
- },
78
- 2: {
79
- title: '待進貨',
80
- badge: 'warning',
81
- },
82
- 3: {
83
- title: '核對中',
84
- badge: 'warning',
85
- },
86
- 4: {
87
- title: '已暫停',
88
- badge: 'normal',
89
- },
90
- 5: {
91
- title: '待補貨',
92
- badge: 'notify',
93
- },
94
- 6: {
95
- title: '已取消',
96
- badge: 'notify',
97
- },
98
- },
66
+ restocking: {
67
+ name: '進貨',
68
+ prefixId: 'IC',
69
+ status: {
70
+ 0: {
71
+ title: '已完成',
72
+ badge: 'info',
73
+ },
74
+ 1: {
75
+ title: '已補貨',
76
+ badge: 'info',
77
+ },
78
+ 2: {
79
+ title: '待進貨',
80
+ badge: 'warning',
81
+ },
82
+ 3: {
83
+ title: '核對中',
84
+ badge: 'warning',
85
+ },
86
+ 4: {
87
+ title: '已暫停',
88
+ badge: 'normal',
89
+ },
90
+ 5: {
91
+ title: '待補貨',
92
+ badge: 'notify',
93
+ },
94
+ 6: {
95
+ title: '已取消',
96
+ badge: 'notify',
97
+ },
99
98
  },
100
- transfer: {
101
- name: '調撥',
102
- prefixId: 'TB',
103
- status: {
104
- 0: {
105
- title: '已完成',
106
- badge: 'info',
107
- },
108
- 1: {
109
- title: '已補貨',
110
- badge: 'info',
111
- },
112
- 2: {
113
- title: '待調撥',
114
- badge: 'warning',
115
- },
116
- 3: {
117
- title: '核對中',
118
- badge: 'warning',
119
- },
120
- 4: {
121
- title: '已暫停',
122
- badge: 'normal',
123
- },
124
- 5: {
125
- title: '待補貨',
126
- badge: 'notify',
127
- },
128
- 6: {
129
- title: '已取消',
130
- badge: 'notify',
131
- },
132
- },
99
+ },
100
+ transfer: {
101
+ name: '調撥',
102
+ prefixId: 'TB',
103
+ status: {
104
+ 0: {
105
+ title: '已完成',
106
+ badge: 'info',
107
+ },
108
+ 1: {
109
+ title: '已補貨',
110
+ badge: 'info',
111
+ },
112
+ 2: {
113
+ title: '待調撥',
114
+ badge: 'warning',
115
+ },
116
+ 3: {
117
+ title: '核對中',
118
+ badge: 'warning',
119
+ },
120
+ 4: {
121
+ title: '已暫停',
122
+ badge: 'normal',
123
+ },
124
+ 5: {
125
+ title: '待補貨',
126
+ badge: 'notify',
127
+ },
128
+ 6: {
129
+ title: '已取消',
130
+ badge: 'notify',
131
+ },
133
132
  },
134
- checking: {
135
- name: '盤點',
136
- prefixId: 'PD',
137
- status: {
138
- 0: {
139
- title: '已完成',
140
- badge: 'info',
141
- },
142
- 1: {
143
- title: '已修正',
144
- badge: 'info',
145
- },
146
- 2: {
147
- title: '待盤點',
148
- badge: 'warning',
149
- },
150
- 3: {
151
- title: '盤點中',
152
- badge: 'warning',
153
- },
154
- 4: {
155
- title: '已暫停',
156
- badge: 'normal',
157
- },
158
- 5: {
159
- title: '異常',
160
- badge: 'notify',
161
- },
162
- 6: {
163
- title: '已取消',
164
- badge: 'notify',
165
- },
166
- },
133
+ },
134
+ checking: {
135
+ name: '盤點',
136
+ prefixId: 'PD',
137
+ status: {
138
+ 0: {
139
+ title: '已完成',
140
+ badge: 'info',
141
+ },
142
+ 1: {
143
+ title: '已修正',
144
+ badge: 'info',
145
+ },
146
+ 2: {
147
+ title: '待盤點',
148
+ badge: 'warning',
149
+ },
150
+ 3: {
151
+ title: '盤點中',
152
+ badge: 'warning',
153
+ },
154
+ 4: {
155
+ title: '已暫停',
156
+ badge: 'normal',
157
+ },
158
+ 5: {
159
+ title: '異常',
160
+ badge: 'notify',
161
+ },
162
+ 6: {
163
+ title: '已取消',
164
+ badge: 'notify',
165
+ },
167
166
  },
167
+ },
168
168
  };
169
169
 
170
170
  export class Stock {
171
- public app;
172
- public token;
173
-
174
- constructor(app: string, token?: IToken) {
175
- this.app = app;
176
- this.token = token;
177
- }
178
-
179
- async productList(json: { page: string; limit: string; search: string; variant_id_list?: string }) {
180
- const page = json.page ? parseInt(`${json.page}`, 10) : 0;
181
- const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
182
-
183
- try {
184
- const sqlArr = ['1=1'];
185
- if (json.variant_id_list) {
186
- sqlArr.push(`(v.id in (${json.variant_id_list}))`);
187
- }
188
- const sqlText = sqlArr.join(' AND ');
189
-
190
- const getStockTotal = await db.query(
191
- `SELECT count(v.id) as c
171
+ public app;
172
+ public token;
173
+
174
+ constructor(app: string, token?: IToken) {
175
+ this.app = app;
176
+ this.token = token;
177
+ }
178
+
179
+ async productList(json: { page: string; limit: string; search: string; variant_id_list?: string }) {
180
+ const page = json.page ? parseInt(`${json.page}`, 10) : 0;
181
+ const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
182
+
183
+ try {
184
+ const sqlArr = ['1=1'];
185
+ if (json.variant_id_list) {
186
+ sqlArr.push(`(v.id in (${json.variant_id_list}))`);
187
+ }
188
+ const sqlText = sqlArr.join(' AND ');
189
+
190
+ const getStockTotal = await db.query(
191
+ `SELECT count(v.id) as c
192
192
  FROM \`${this.app}\`.t_variants as v,
193
193
  \`${this.app}\`.t_manager_post as p
194
194
  WHERE v.content ->>'$.stockList.${json.search || 'store'}.count' > 0
195
195
  AND v.product_id = p.id
196
196
  AND ${sqlText}
197
197
  `,
198
- []
199
- );
198
+ []
199
+ );
200
200
 
201
- let data = await db.query(
202
- `SELECT v.*, p.content as product_content
201
+ let data = await db.query(
202
+ `SELECT v.*, p.content as product_content
203
203
  FROM \`${this.app}\`.t_variants as v,
204
204
  \`${this.app}\`.t_manager_post as p
205
205
  WHERE v.content ->>'$.stockList.${json.search || 'store'}.count' > 0
@@ -208,57 +208,57 @@ export class Stock {
208
208
  LIMIT ${page * limit}
209
209
  , ${limit};
210
210
  `,
211
- []
212
- );
213
-
214
- data.map((item: any) => {
215
- item.count = item.content.stockList[json.search].count;
216
- item.title = (() => {
217
- try {
218
- return item.product_content.language_data['zh-TW'].title;
219
- } catch (error) {
220
- console.error(`product id ${item.product_id} 沒有 zh-TW 的標題,使用原標題`);
221
- return item.product_content.title;
222
- }
223
- })();
224
- return item;
225
- });
226
-
227
- return {
228
- total: getStockTotal[0].c,
229
- data,
230
- };
231
- } catch (error) {
232
- console.error(error);
233
- if (error instanceof Error) {
234
- throw exception.BadRequestError('stock productList Error: ', error.message, null);
235
- }
236
- }
211
+ []
212
+ );
213
+
214
+ data.map((item: any) => {
215
+ item.count = item.content.stockList[json.search].count;
216
+ item.title = (() => {
217
+ try {
218
+ return item.product_content.language_data['zh-TW'].title;
219
+ } catch (error) {
220
+ console.error(`product id ${item.product_id} 沒有 zh-TW 的標題,使用原標題`);
221
+ return item.product_content.title;
222
+ }
223
+ })();
224
+ return item;
225
+ });
226
+
227
+ return {
228
+ total: getStockTotal[0].c,
229
+ data,
230
+ };
231
+ } catch (error) {
232
+ console.error(error);
233
+ if (error instanceof Error) {
234
+ throw exception.BadRequestError('stock productList Error: ', error.message, null);
235
+ }
237
236
  }
237
+ }
238
238
 
239
- async productStock(json: { page: string; limit: string; variant_id_list: string }) {
240
- const page = json.page ? parseInt(`${json.page}`, 10) : 0;
241
- const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
239
+ async productStock(json: { page: string; limit: string; variant_id_list: string }) {
240
+ const page = json.page ? parseInt(`${json.page}`, 10) : 0;
241
+ const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
242
242
 
243
- try {
244
- const sqlArr = ['1=1'];
245
- if (json.variant_id_list) {
246
- sqlArr.push(`(v.id in (${json.variant_id_list}))`);
247
- }
248
- const sqlText = sqlArr.join(' AND ');
243
+ try {
244
+ const sqlArr = ['1=1'];
245
+ if (json.variant_id_list) {
246
+ sqlArr.push(`(v.id in (${json.variant_id_list}))`);
247
+ }
248
+ const sqlText = sqlArr.join(' AND ');
249
249
 
250
- const getStockTotal = await db.query(
251
- `SELECT count(v.id) as c
250
+ const getStockTotal = await db.query(
251
+ `SELECT count(v.id) as c
252
252
  FROM \`${this.app}\`.t_variants as v,
253
253
  \`${this.app}\`.t_manager_post as p
254
254
  WHERE v.product_id = p.id
255
255
  AND ${sqlText}
256
256
  `,
257
- []
258
- );
257
+ []
258
+ );
259
259
 
260
- let data = await db.query(
261
- `SELECT v.*, p.content as product_content
260
+ let data = await db.query(
261
+ `SELECT v.*, p.content as product_content
262
262
  FROM \`${this.app}\`.t_variants as v,
263
263
  \`${this.app}\`.t_manager_post as p
264
264
  WHERE v.product_id = p.id
@@ -266,561 +266,576 @@ export class Stock {
266
266
  LIMIT ${page * limit}
267
267
  , ${limit};
268
268
  `,
269
- []
270
- );
271
-
272
- data.map((item: any) => {
273
- item.count = Object.values(item.content.stockList).reduce((sum: number, stock: any) => sum + stock.count, 0);
274
- item.title = (() => {
275
- try {
276
- return item.product_content.language_data['zh-TW'].title;
277
- } catch (error) {
278
- console.error(`product id ${item.product_id} 沒有 zh-TW 的標題,使用原標題`);
279
- return item.product_content.title;
280
- }
281
- })();
282
- return item;
283
- });
284
-
285
- return {
286
- total: getStockTotal[0].c,
287
- data,
288
- };
289
- } catch (error) {
290
- console.error(error);
291
- if (error instanceof Error) {
292
- throw exception.BadRequestError('stock productList Error: ', error.message, null);
293
- }
294
- }
269
+ []
270
+ );
271
+
272
+ data.map((item: any) => {
273
+ item.count = Object.values(item.content.stockList).reduce((sum: number, stock: any) => sum + stock.count, 0);
274
+ item.title = (() => {
275
+ try {
276
+ return item.product_content.language_data['zh-TW'].title;
277
+ } catch (error) {
278
+ console.error(`product id ${item.product_id} 沒有 zh-TW 的標題,使用原標題`);
279
+ return item.product_content.title;
280
+ }
281
+ })();
282
+ return item;
283
+ });
284
+
285
+ return {
286
+ total: getStockTotal[0].c,
287
+ data,
288
+ };
289
+ } catch (error) {
290
+ console.error(error);
291
+ if (error instanceof Error) {
292
+ throw exception.BadRequestError('stock productList Error: ', error.message, null);
293
+ }
295
294
  }
295
+ }
296
296
 
297
- async deleteStoreProduct(store_id: string) {
298
- try {
299
- const productList: { [k: string]: any } = {};
300
- const variants = await db.query(
301
- `SELECT *
297
+ async deleteStoreProduct(store_id: string) {
298
+ try {
299
+ const productList: { [k: string]: any } = {};
300
+ const variants = await db.query(
301
+ `SELECT *
302
302
  FROM \`${this.app}\`.t_variants
303
303
  WHERE content ->>'$.stockList.${store_id}.count' is not null;
304
304
  `,
305
- []
306
- );
307
-
308
- if (variants.length == 0) {
309
- return { data: true, process: '' };
310
- }
311
-
312
- const promise = await new Promise<void>((resolve) => {
313
- let n = 0;
314
- for (const variant of variants) {
315
- delete variant.content.stockList[store_id];
316
- db.query(
317
- `UPDATE \`${this.app}\`.t_variants
305
+ []
306
+ );
307
+
308
+ if (variants.length == 0) {
309
+ return { data: true, process: '' };
310
+ }
311
+
312
+ const promise = await new Promise<void>(resolve => {
313
+ let n = 0;
314
+ for (const variant of variants) {
315
+ delete variant.content.stockList[store_id];
316
+ db.query(
317
+ `UPDATE \`${this.app}\`.t_variants
318
318
  SET ?
319
319
  WHERE id = ?
320
320
  `,
321
- [{ content: JSON.stringify(variant.content) }, variant.id]
322
- ).then(() => {
323
- const p = productList[`${variant.product_id}`];
324
- if (p) {
325
- p.push(variant.content);
326
- } else {
327
- productList[`${variant.product_id}`] = [variant.content];
328
- }
329
- n++;
330
- if (n === variants.length) {
331
- resolve();
332
- }
333
- });
334
- }
335
- }).then(async () => {
336
- const idString = Object.keys(productList)
337
- .map((item) => `"${item}"`)
338
- .join(',');
339
-
340
- if (idString.length > 0) {
341
- const products = await db.query(
342
- `SELECT *
321
+ [{ content: JSON.stringify(variant.content) }, variant.id]
322
+ ).then(() => {
323
+ const p = productList[`${variant.product_id}`];
324
+ if (p) {
325
+ p.push(variant.content);
326
+ } else {
327
+ productList[`${variant.product_id}`] = [variant.content];
328
+ }
329
+ n++;
330
+ if (n === variants.length) {
331
+ resolve();
332
+ }
333
+ });
334
+ }
335
+ }).then(async () => {
336
+ const idString = Object.keys(productList)
337
+ .map(item => `"${item}"`)
338
+ .join(',');
339
+
340
+ if (idString.length > 0) {
341
+ const products = await db.query(
342
+ `SELECT *
343
343
  FROM \`${this.app}\`.t_manager_post
344
344
  WHERE id in (${idString});
345
345
  `,
346
- []
347
- );
348
-
349
- return await new Promise<void>((resolve) => {
350
- let n = 0;
351
- for (const product of products) {
352
- product.content.variants = productList[`${product.id}`];
353
- db.query(
354
- `UPDATE \`${this.app}\`.t_manager_post
346
+ []
347
+ );
348
+
349
+ return await new Promise<void>(resolve => {
350
+ let n = 0;
351
+ for (const product of products) {
352
+ product.content.variants = productList[`${product.id}`];
353
+ db.query(
354
+ `UPDATE \`${this.app}\`.t_manager_post
355
355
  SET ?
356
356
  WHERE id = ?`,
357
- [{ content: JSON.stringify(product.content) }, product.id]
358
- ).then(() => {
359
- n++;
360
- if (n === products.length) {
361
- resolve();
362
- }
363
- });
364
- }
365
- }).then(() => {
366
- return { data: true, process: 't_variants, t_manager_post' };
367
- });
357
+ [{ content: JSON.stringify(product.content) }, product.id]
358
+ ).then(() => {
359
+ n++;
360
+ if (n === products.length) {
361
+ resolve();
368
362
  }
369
- return { data: true, process: 't_variants' };
370
- });
371
-
372
- return promise;
373
- } catch (error) {
374
- console.error(error);
375
- if (error instanceof Error) {
376
- throw exception.BadRequestError('stock deleteStore Error: ', error.message, null);
363
+ });
377
364
  }
365
+ }).then(() => {
366
+ return { data: true, process: 't_variants, t_manager_post' };
367
+ });
378
368
  }
369
+ return { data: true, process: 't_variants' };
370
+ });
371
+
372
+ return promise;
373
+ } catch (error) {
374
+ console.error(error);
375
+ if (error instanceof Error) {
376
+ throw exception.BadRequestError('stock deleteStore Error: ', error.message, null);
377
+ }
379
378
  }
379
+ }
380
380
 
381
- public allocateStock(stockList: StockList, requiredCount: number) {
382
- let remainingCount = requiredCount;
383
- let totalDeduction = 0; // 紀錄所有扣除的總數
384
- const deductionLog: { [key: string]: number } = {}; // 記錄每個倉庫的扣除值
381
+ public allocateStock(stockList: StockList, requiredCount: number) {
382
+ let remainingCount = requiredCount;
383
+ let totalDeduction = 0; // 紀錄所有扣除的總數
384
+ const deductionLog: { [key: string]: number } = {}; // 記錄每個倉庫的扣除值
385
385
 
386
- // 按照 `count` 從大到小排序倉庫
387
- const sortedStock = Object.entries(stockList).sort(([, a], [, b]) => b.count - a.count);
386
+ // 按照 `count` 從大到小排序倉庫
387
+ const sortedStock = Object.entries(stockList).sort(([, a], [, b]) => b.count - a.count);
388
388
 
389
- for (let [key, stock] of sortedStock) {
390
- if (remainingCount === 0) break; // 如果需求已經滿足,停止迴圈
389
+ for (let [key, stock] of sortedStock) {
390
+ if (remainingCount === 0) break; // 如果需求已經滿足,停止迴圈
391
391
 
392
- const deduction = Math.min((stock as any).count, remainingCount); // 扣除的數量為倉庫數量或剩餘需求中的較小值
393
- remainingCount -= deduction; // 更新剩餘需求
394
- totalDeduction += deduction; // 累加扣除值
395
- (stock as any).count -= deduction;// 更新倉庫數量
392
+ const deduction = Math.min((stock as any).count, remainingCount); // 扣除的數量為倉庫數量或剩餘需求中的較小值
393
+ remainingCount -= deduction; // 更新剩餘需求
394
+ totalDeduction += deduction; // 累加扣除值
395
+ (stock as any).count -= deduction; // 更新倉庫數量
396
396
 
397
- deductionLog[key] = deduction; // 記錄本次扣除
398
- }
397
+ deductionLog[key] = deduction; // 記錄本次扣除
398
+ }
399
399
 
400
- // 紀錄最大扣除值
401
- const maxDeduction = Math.max(...Object.values(deductionLog), 0);
400
+ // 紀錄最大扣除值
401
+ const maxDeduction = Math.max(...Object.values(deductionLog), 0);
402
402
 
403
- return {
404
- stockList,
405
- deductionLog,
406
- totalDeduction,
407
- remainingCount, // 如果需求無法完全滿足,這裡會大於 0
408
- };
409
- }
403
+ return {
404
+ stockList,
405
+ deductionLog,
406
+ totalDeduction,
407
+ remainingCount, // 如果需求無法完全滿足,這裡會大於 0
408
+ };
409
+ }
410
+
411
+ public async recoverStock(variant: any) {
412
+ const sql =
413
+ variant.spec.length > 0
414
+ ? `AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${variant.spec
415
+ .map((data: string) => {
416
+ return `\"${data}\"`;
417
+ })
418
+ .join(',')}));`
419
+ : '';
410
420
 
411
- public async recoverStock(variant: any) {
412
- const sql =
413
- variant.spec.length > 0
414
- ? `AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${variant.spec
415
- .map((data: string) => {
416
- return `\"${data}\"`;
417
- })
418
- .join(',')}));`
419
- : '';
420
-
421
- let variantData = await db.query(
422
- `
421
+ let variantData = await db.query(
422
+ `
423
423
  SELECT *
424
424
  FROM \`${this.app}\`.t_variants
425
425
  WHERE \`product_id\` = "${variant.id}" ${sql}
426
426
  `,
427
- []
428
- );
429
- const pdDqlData = (
430
- await new Shopping(this.app, this.token).getProduct({
431
- page: 0,
432
- limit: 50,
433
- id: variant.id,
434
- status: 'inRange',
435
- })
436
- ).data;
437
- const pd = pdDqlData.content;
438
- const pbVariant = pd.variants.find((dd: any) => {
439
- return dd.spec.join('-') === variant.spec.join('-');
440
- });
441
- variantData = variantData[0];
442
- Object.entries(variant.deduction_log).forEach(([key, value]) => {
443
- pbVariant.stockList[key].count = parseInt(pbVariant.stockList[key].count as string) + parseInt(value as string);
444
- pbVariant.stock = parseInt(pbVariant.stock as string) + parseInt(value as string);
445
- variantData.content.stockList[key].count = parseInt(variantData.content.stockList[key].count) + parseInt(value as string);
446
- variantData.content.stock = parseInt(variantData.content.stock) + parseInt(value as string);
447
- });
448
- await new Shopping(this.app, this.token).updateVariantsWithSpec(variantData.content, variant.id, variant.spec);
449
- await db.query(
450
- `UPDATE \`${this.app}\`.\`t_manager_post\`
427
+ []
428
+ );
429
+ const pdDqlData = (
430
+ await new Shopping(this.app, this.token).getProduct({
431
+ page: 0,
432
+ limit: 50,
433
+ id: variant.id,
434
+ status: 'inRange',
435
+ })
436
+ ).data;
437
+ const pd = pdDqlData.content;
438
+ const pbVariant = pd.variants.find((dd: any) => {
439
+ return dd.spec.join('-') === variant.spec.join('-');
440
+ });
441
+ variantData = variantData[0];
442
+ Object.entries(variant.deduction_log).forEach(([key, value]) => {
443
+ pbVariant.stockList[key].count = parseInt(pbVariant.stockList[key].count as string) + parseInt(value as string);
444
+ pbVariant.stock = parseInt(pbVariant.stock as string) + parseInt(value as string);
445
+ variantData.content.stockList[key].count =
446
+ parseInt(variantData.content.stockList[key].count) + parseInt(value as string);
447
+ variantData.content.stock = parseInt(variantData.content.stock) + parseInt(value as string);
448
+ });
449
+ await new Shopping(this.app, this.token).updateVariantsWithSpec(variantData.content, variant.id, variant.spec);
450
+ await db.query(
451
+ `UPDATE \`${this.app}\`.\`t_manager_post\`
451
452
  SET ?
452
453
  WHERE 1 = 1
453
454
  and id = ${pdDqlData.id}`,
454
- [{ content: JSON.stringify(pd) }]
455
- );
456
- }
455
+ [{ content: JSON.stringify(pd) }]
456
+ );
457
+ }
458
+
459
+ public async shippingStock(variant: any) {
460
+ const sql =
461
+ variant.spec.length > 0
462
+ ? `AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${variant.spec
463
+ .map((data: string) => {
464
+ return `\"${data}\"`;
465
+ })
466
+ .join(',')}));`
467
+ : '';
457
468
 
458
- public async shippingStock(variant: any) {
459
- const sql =
460
- variant.spec.length > 0
461
- ? `AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${variant.spec
462
- .map((data: string) => {
463
- return `\"${data}\"`;
464
- })
465
- .join(',')}));`
466
- : '';
467
-
468
- let variantData = await db.query(
469
- `
469
+ let variantData = await db.query(
470
+ `
470
471
  SELECT *
471
472
  FROM \`${this.app}\`.t_variants
472
473
  WHERE \`product_id\` = "${variant.id}" ${sql}
473
474
  `,
474
- []
475
- );
476
- const pdDqlData = (
477
- await new Shopping(this.app, this.token).getProduct({
478
- page: 0,
479
- limit: 50,
480
- id: variant.id,
481
- status: 'inRange',
482
- })
483
- ).data;
484
- const pd = pdDqlData.content;
485
- const pbVariant = pd.variants.find((dd: any) => {
486
- return dd.spec.join('-') === variant.spec.join('-');
487
- });
488
- variantData = variantData[0];
489
- Object.entries(variant.deduction_log).forEach(([key, value]) => {
490
- pbVariant.stockList[key].count = parseInt(pbVariant.stockList[key].count as string) - parseInt(value as string);
491
- pbVariant.stock = parseInt(pbVariant.stock as string) - parseInt(value as string);
492
- variantData.content.stockList[key].count = parseInt(variantData.content.stockList[key].count) - parseInt(value as string);
493
- variantData.content.stock = parseInt(variantData.content.stock) - parseInt(value as string);
494
- });
495
- await new Shopping(this.app, this.token).updateVariantsWithSpec(variantData.content, variant.id, variant.spec);
496
- await db.query(
497
- `UPDATE \`${this.app}\`.\`t_manager_post\`
475
+ []
476
+ );
477
+ const pdDqlData = (
478
+ await new Shopping(this.app, this.token).getProduct({
479
+ page: 0,
480
+ limit: 50,
481
+ id: variant.id,
482
+ status: 'inRange',
483
+ })
484
+ ).data;
485
+ const pd = pdDqlData.content;
486
+ const pbVariant = pd.variants.find((dd: any) => {
487
+ return dd.spec.join('-') === variant.spec.join('-');
488
+ });
489
+ variantData = variantData[0];
490
+ Object.entries(variant.deduction_log).forEach(([key, value]) => {
491
+ pbVariant.stockList[key].count = parseInt(pbVariant.stockList[key].count as string) - parseInt(value as string);
492
+ pbVariant.stock = parseInt(pbVariant.stock as string) - parseInt(value as string);
493
+ variantData.content.stockList[key].count =
494
+ parseInt(variantData.content.stockList[key].count) - parseInt(value as string);
495
+ variantData.content.stock = parseInt(variantData.content.stock) - parseInt(value as string);
496
+ });
497
+ await new Shopping(this.app, this.token).updateVariantsWithSpec(variantData.content, variant.id, variant.spec);
498
+ await db.query(
499
+ `UPDATE \`${this.app}\`.\`t_manager_post\`
498
500
  SET ?
499
501
  WHERE 1 = 1
500
502
  and id = ${pdDqlData.id}`,
501
- [{ content: JSON.stringify(pd) }]
502
- );
503
+ [{ content: JSON.stringify(pd) }]
504
+ );
505
+ }
506
+
507
+ async getHistory(json: {
508
+ page: string;
509
+ limit: string;
510
+ search: string;
511
+ type: StockHistoryType;
512
+ order_id: string;
513
+ queryType: string;
514
+ }) {
515
+ const page = json.page ? parseInt(`${json.page}`, 10) : 0;
516
+ const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
517
+
518
+ function formatDate(sqlDatetime: string): string {
519
+ // 將 datetime 字串轉換為 JavaScript Date 物件
520
+ const date = new Date(sqlDatetime);
521
+
522
+ // 取得年、月、日
523
+ const year = date.getFullYear();
524
+ const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是從 0 開始的,需要加 1
525
+ const day = String(date.getDate()).padStart(2, '0');
526
+
527
+ // 組合成 'yyyy-mm-dd' 格式
528
+ const formattedDate = `${year}-${month}-${day}`;
529
+ return formattedDate;
503
530
  }
504
531
 
505
- async getHistory(json: { page: string; limit: string; search: string; type: StockHistoryType; order_id: string; queryType: string }) {
506
- const page = json.page ? parseInt(`${json.page}`, 10) : 0;
507
- const limit = json.limit ? parseInt(`${json.limit}`, 10) : 20;
508
-
509
- function formatDate(sqlDatetime: string): string {
510
- // 將 datetime 字串轉換為 JavaScript Date 物件
511
- const date = new Date(sqlDatetime);
512
-
513
- // 取得年、月、日
514
- const year = date.getFullYear();
515
- const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是從 0 開始的,需要加 1
516
- const day = String(date.getDate()).padStart(2, '0');
517
-
518
- // 組合成 'yyyy-mm-dd' 格式
519
- const formattedDate = `${year}-${month}-${day}`;
520
- return formattedDate;
521
- }
522
-
523
- const sqlArr: string[] = ['(status <> -1)', `(type = '${json.type}')`];
532
+ const sqlArr: string[] = ['(status <> -1)', `(type = '${json.type}')`];
524
533
 
525
- if (json.order_id) {
526
- sqlArr.push(`(order_id = '${json.order_id}')`);
527
- }
534
+ if (json.order_id) {
535
+ sqlArr.push(`(order_id = '${json.order_id}')`);
536
+ }
528
537
 
529
- if (json.queryType && json.search) {
530
- switch (json.queryType) {
531
- case 'order_id':
532
- sqlArr.push(`(order_id like '%${json.search}%')`);
533
- break;
534
- case 'note':
535
- sqlArr.push(`(JSON_EXTRACT(content, '$.note') like '%${json.search}%')`);
536
- break;
537
- }
538
- }
538
+ if (json.queryType && json.search) {
539
+ switch (json.queryType) {
540
+ case 'order_id':
541
+ sqlArr.push(`(order_id like '%${json.search}%')`);
542
+ break;
543
+ case 'note':
544
+ sqlArr.push(`(JSON_EXTRACT(content, '$.note') like '%${json.search}%')`);
545
+ break;
546
+ }
547
+ }
539
548
 
540
- const sqlString = sqlArr.join(' AND ');
549
+ const sqlString = sqlArr.join(' AND ');
541
550
 
542
- try {
543
- if (!this.token) {
544
- return {
545
- total: 0,
546
- data: [],
547
- };
548
- }
551
+ try {
552
+ if (!this.token) {
553
+ return {
554
+ total: 0,
555
+ data: [],
556
+ };
557
+ }
549
558
 
550
- const getHistoryTotal = await db.query(
551
- `SELECT count(id) as c FROM \`${this.app}\`.t_stock_history
559
+ const getHistoryTotal = await db.query(
560
+ `SELECT count(id) as c FROM \`${this.app}\`.t_stock_history
552
561
  WHERE 1=1 AND ${sqlString}
553
562
  `,
554
- []
555
- );
563
+ []
564
+ );
556
565
 
557
- const data = await db.query(
558
- `SELECT * FROM \`${this.app}\`.t_stock_history
566
+ const data = await db.query(
567
+ `SELECT * FROM \`${this.app}\`.t_stock_history
559
568
  WHERE 1=1 AND ${sqlString}
560
569
  ORDER BY order_id DESC
561
570
  LIMIT ${page * limit}, ${limit};
562
571
  `,
563
- []
564
- );
565
-
566
- const getPermission = (await new SharePermission(this.app, this.token).getPermission({
567
- page: 0,
568
- limit: 9999,
569
- })) as any;
570
-
571
- data.map((rowData: StockHistoryData) => {
572
- rowData.created_time = formatDate(rowData.created_time);
573
- rowData.content.changeLogs.map((log) => {
574
- const findManager = getPermission.data.find((m: any) => `${m.user}` === `${log.user}`);
575
- log.user_name = findManager ? findManager.config.name : '';
576
- return log;
577
- });
578
- });
579
-
580
- return {
581
- total: getHistoryTotal[0].c,
582
- data,
583
- };
584
- } catch (error) {
585
- console.error(error);
586
- if (error instanceof Error) {
587
- throw exception.BadRequestError('stock getHistory Error: ', error.message, null);
588
- }
589
- }
572
+ []
573
+ );
574
+
575
+ const getPermission = (await new SharePermission(this.app, this.token).getPermission({
576
+ page: 0,
577
+ limit: 9999,
578
+ })) as any;
579
+
580
+ data.map((rowData: StockHistoryData) => {
581
+ rowData.created_time = formatDate(rowData.created_time);
582
+ rowData.content.changeLogs.map(log => {
583
+ const findManager = getPermission.data.find((m: any) => `${m.user}` === `${log.user}`);
584
+ log.user_name = findManager ? findManager.config.name : '';
585
+ return log;
586
+ });
587
+ });
588
+
589
+ return {
590
+ total: getHistoryTotal[0].c,
591
+ data,
592
+ };
593
+ } catch (error) {
594
+ console.error(error);
595
+ if (error instanceof Error) {
596
+ throw exception.BadRequestError('stock getHistory Error: ', error.message, null);
597
+ }
590
598
  }
599
+ }
600
+
601
+ async postHistory(json: StockHistoryData) {
602
+ try {
603
+ const typeData = typeConfig[json.type];
604
+
605
+ json.content.product_list.map(item => {
606
+ // delete item.title;
607
+ // delete item.spec;
608
+ // delete item.sku;
609
+ return item;
610
+ });
611
+ json.content.changeLogs = [
612
+ {
613
+ time: Tool.getCurrentDateTime(),
614
+ status: json.status,
615
+ text: `${typeData.name}單建立`,
616
+ user: this.token ? this.token.userID : 0,
617
+ },
618
+ {
619
+ time: Tool.getCurrentDateTime({ addSeconds: 1 }),
620
+ status: json.status,
621
+ text: `${typeData.name}單狀態改為「${typeData.status[json.status].title}」`,
622
+ user: this.token ? this.token.userID : 0,
623
+ },
624
+ ];
591
625
 
592
- async postHistory(json: StockHistoryData) {
593
- try {
594
- const typeData = typeConfig[json.type];
626
+ const formatJson = JSON.parse(JSON.stringify(json));
627
+ formatJson.order_id = `${typeData.prefixId}${new Date().getTime()}`;
628
+ formatJson.content = JSON.stringify(json.content);
629
+ formatJson.created_time = `${json.created_time} 00:00:00`;
630
+ delete formatJson.id;
595
631
 
596
- json.content.product_list.map((item) => {
597
- // delete item.title;
598
- // delete item.spec;
599
- // delete item.sku;
600
- return item;
601
- });
602
- json.content.changeLogs = [
603
- {
604
- time: Tool.getCurrentDateTime(),
605
- status: json.status,
606
- text: `${typeData.name}單建立`,
607
- user: this.token ? this.token.userID : 0,
608
- },
609
- {
610
- time: Tool.getCurrentDateTime({ addSeconds: 1 }),
611
- status: json.status,
612
- text: `${typeData.name}單狀態改為「${typeData.status[json.status].title}」`,
613
- user: this.token ? this.token.userID : 0,
614
- },
615
- ];
616
-
617
- const formatJson = JSON.parse(JSON.stringify(json));
618
- formatJson.order_id = `${typeData.prefixId}${new Date().getTime()}`;
619
- formatJson.content = JSON.stringify(json.content);
620
- formatJson.created_time = `${json.created_time} 00:00:00`;
621
- delete formatJson.id;
622
-
623
- await db.query(
624
- `INSERT INTO \`${this.app}\`.\`t_stock_history\` SET ?;
632
+ await db.query(
633
+ `INSERT INTO \`${this.app}\`.\`t_stock_history\` SET ?;
625
634
  `,
626
- [formatJson]
627
- );
628
-
629
- return { data: formatJson };
630
- } catch (error) {
631
- console.error(error);
632
- if (error instanceof Error) {
633
- throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
634
- }
635
- }
635
+ [formatJson]
636
+ );
637
+
638
+ return { data: formatJson };
639
+ } catch (error) {
640
+ console.error(error);
641
+ if (error instanceof Error) {
642
+ throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
643
+ }
636
644
  }
637
-
638
- async putHistory(json: StockHistoryData) {
639
- try {
640
- if (!this.token) {
641
- return { data: false };
642
- }
643
- const typeData = typeConfig[json.type];
644
-
645
- // 取得原始資料
646
- const getHistory = await db.query(
647
- `SELECT * FROM \`${this.app}\`.t_stock_history WHERE order_id = ?;
645
+ }
646
+
647
+ async putHistory(token: any, json: StockHistoryData) {
648
+ try {
649
+ if (!this.token) {
650
+ return { data: false };
651
+ }
652
+ const typeData = typeConfig[json.type];
653
+
654
+ // 取得原始資料
655
+ const getHistory = await db.query(
656
+ `SELECT * FROM \`${this.app}\`.t_stock_history WHERE order_id = ?;
648
657
  `,
649
- [json.order_id]
650
- );
651
- if (!getHistory || getHistory.length !== 1) {
652
- return { data: false };
653
- }
654
- const originHistory = getHistory[0] as StockHistoryData;
655
- const originList = originHistory.content.product_list;
656
-
657
- // 格式化更新資料
658
- json.content.product_list.map((item) => {
659
- delete item.title;
660
- delete item.spec;
661
- delete item.sku;
662
- delete item.barcode;
663
- return item;
664
- });
665
-
666
- json.content.changeLogs.push({
667
- time: Tool.getCurrentDateTime(),
668
- status: json.status,
669
- text: `進貨單狀態改為「${typeData.status[json.status].title}」`,
670
- user: this.token.userID,
671
- product_list: (() => {
672
- if (json.status === 1 || json.status === 5) {
673
- const updateList = JSON.parse(JSON.stringify(json.content.product_list)) as ContentProduct[];
674
-
675
- return updateList.map((item1) => {
676
- const originVariant = originList.find((item2) => item1.variant_id === item2.variant_id);
677
- if (originVariant) {
678
- return {
679
- replenishment_count: (item1.recent_count ?? 0) - (originVariant.recent_count ?? 0),
680
- ...item1,
681
- };
682
- }
683
- return item1;
684
- });
685
- }
686
- return undefined;
687
- })(),
688
- });
689
-
690
- const formatJson = JSON.parse(JSON.stringify(json));
691
- formatJson.content = JSON.stringify(json.content);
692
- delete formatJson.id;
693
-
694
- // 改變商品與規格庫存
695
- const _shop = new Shopping(this.app, this.token);
696
- const variants = await _shop.getVariants({
697
- page: 0,
698
- limit: 9999,
699
- id_list: json.content.product_list.map((item) => item.variant_id).join(','),
700
- });
701
- const dataList: {
702
- id: number;
703
- product_id: number;
704
- product_content: any;
705
- variant_content: any;
706
- }[] = [];
707
-
708
- const createStockEntry = (type: 'plus' | 'minus' | 'equal', store: string, count: number, variant: any) => ({
709
- id: variant.id,
710
- product_id: variant.product_id,
711
- ...Stock.formatStockContent({
712
- type,
713
- store,
714
- count,
715
- product_content: variant.product_content,
716
- variant_content: variant.variant_content,
717
- }),
658
+ [json.order_id]
659
+ );
660
+ if (!getHistory || getHistory.length !== 1) {
661
+ return { data: false };
662
+ }
663
+ const originHistory = getHistory[0] as StockHistoryData;
664
+ const originList = originHistory.content.product_list;
665
+
666
+ // 格式化更新資料
667
+ json.content.product_list.map(item => {
668
+ delete item.title;
669
+ delete item.spec;
670
+ delete item.sku;
671
+ delete item.barcode;
672
+ return item;
673
+ });
674
+
675
+ json.content.changeLogs.push({
676
+ time: Tool.getCurrentDateTime(),
677
+ status: json.status,
678
+ text: `進貨單狀態改為「${typeData.status[json.status].title}」`,
679
+ user: this.token.userID,
680
+ product_list: (() => {
681
+ if (json.status === 1 || json.status === 5) {
682
+ const updateList = JSON.parse(JSON.stringify(json.content.product_list)) as ContentProduct[];
683
+
684
+ return updateList.map(item1 => {
685
+ const originVariant = originList.find(item2 => item1.variant_id === item2.variant_id);
686
+ if (originVariant) {
687
+ return {
688
+ replenishment_count: (item1.recent_count ?? 0) - (originVariant.recent_count ?? 0),
689
+ ...item1,
690
+ };
691
+ }
692
+ return item1;
718
693
  });
694
+ }
695
+ return undefined;
696
+ })(),
697
+ });
698
+
699
+ const formatJson = JSON.parse(JSON.stringify(json));
700
+ formatJson.content = JSON.stringify(json.content);
701
+ delete formatJson.id;
702
+
703
+ // 改變商品與規格庫存
704
+ const _shop = new Shopping(this.app, this.token);
705
+ const variants = await _shop.getVariants({
706
+ page: 0,
707
+ limit: 9999,
708
+ id_list: json.content.product_list.map(item => item.variant_id).join(','),
709
+ });
710
+ const dataList: {
711
+ id: number;
712
+ product_id: number;
713
+ product_content: any;
714
+ variant_content: any;
715
+ }[] = [];
716
+
717
+ const createStockEntry = (type: 'plus' | 'minus' | 'equal', store: string, count: number, variant: any) => ({
718
+ id: variant.id,
719
+ product_id: variant.product_id,
720
+ ...Stock.formatStockContent({
721
+ type,
722
+ store,
723
+ count,
724
+ product_content: variant.product_content,
725
+ variant_content: variant.variant_content,
726
+ }),
727
+ });
728
+
729
+ for (const variant of variants.data) {
730
+ const item = json.content.product_list.find(item => item.variant_id === variant.id);
731
+
732
+ if (item) {
733
+ const originVariant = originList.find(origin => item.variant_id === origin.variant_id);
734
+ const recent_count = item.recent_count ?? 0;
735
+ const count = originVariant ? recent_count - (originVariant.recent_count ?? 0) : recent_count;
736
+ const { type, content } = json;
737
+ const { store_in, store_out } = content;
738
+
739
+ if (type === 'restocking') {
740
+ dataList.push(createStockEntry('plus', store_in, count, variant));
741
+ } else if (type === 'transfer') {
742
+ dataList.push(createStockEntry('plus', store_in, count, variant));
743
+ dataList.push(createStockEntry('minus', store_out, count, variant));
744
+ } else if (type === 'checking' && (json.status === 0 || json.status === 1)) {
745
+ dataList.push(createStockEntry('equal', store_out, recent_count, variant));
746
+ }
747
+ }
748
+ }
719
749
 
720
- for (const variant of variants.data) {
721
- const item = json.content.product_list.find((item) => item.variant_id === variant.id);
722
-
723
- if (item) {
724
- const originVariant = originList.find((origin) => item.variant_id === origin.variant_id);
725
- const recent_count = item.recent_count ?? 0;
726
- const count = originVariant ? recent_count - (originVariant.recent_count ?? 0) : recent_count;
727
- const { type, content } = json;
728
- const { store_in, store_out } = content;
729
-
730
- if (type === 'restocking') {
731
- dataList.push(createStockEntry('plus', store_in, count, variant));
732
- } else if (type === 'transfer') {
733
- dataList.push(createStockEntry('plus', store_in, count, variant));
734
- dataList.push(createStockEntry('minus', store_out, count, variant));
735
- } else if (type === 'checking' && (json.status === 0 || json.status === 1)) {
736
- dataList.push(createStockEntry('equal', store_out, recent_count, variant));
737
- }
738
- }
739
- }
740
-
741
- // 更新產品與規格庫存
742
- await _shop.putVariants(dataList);
750
+ // 更新產品與規格庫存
751
+ await _shop.putVariants(token, dataList);
743
752
 
744
- // 更新庫存單
745
- await db.query(
746
- `UPDATE \`${this.app}\`.t_stock_history SET ? WHERE order_id = ?
747
- `,
748
- [formatJson, json.order_id]
749
- );
750
-
751
- return { data: true };
752
- } catch (error) {
753
- console.error(error);
754
- if (error instanceof Error) {
755
- throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
756
- }
757
- }
753
+ // 更新庫存單
754
+ await db.query(
755
+ `UPDATE \`${this.app}\`.t_stock_history SET ? WHERE order_id = ?
756
+ `,
757
+ [formatJson, json.order_id]
758
+ );
759
+
760
+ return { data: true };
761
+ } catch (error) {
762
+ console.error(error);
763
+ if (error instanceof Error) {
764
+ throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
765
+ }
758
766
  }
759
-
760
- static formatStockContent(data: { type: 'plus' | 'minus' | 'equal'; store: string; count: number; product_content: any; variant_content: any }) {
761
- const type = data.type;
762
- const store = data.store;
763
- const count = data.count;
764
- const product_content = data.product_content;
765
- const variant_content = data.variant_content;
766
- const stockList = variant_content.stockList;
767
-
768
- // 修改 variant stockList
769
- if (stockList[store]) {
770
- if (type === 'plus') {
771
- if (stockList[store].count) {
772
- stockList[store].count += count;
773
- } else {
774
- stockList[store].count = count;
775
- }
776
- } else if (type === 'minus') {
777
- if (stockList[store].count) {
778
- stockList[store].count -= count;
779
- } else {
780
- stockList[store].count = -count;
781
- }
782
- } else {
783
- stockList[store].count = count;
784
- }
767
+ }
768
+
769
+ static formatStockContent(data: {
770
+ type: 'plus' | 'minus' | 'equal';
771
+ store: string;
772
+ count: number;
773
+ product_content: any;
774
+ variant_content: any;
775
+ }) {
776
+ const type = data.type;
777
+ const store = data.store;
778
+ const count = data.count;
779
+ const product_content = data.product_content;
780
+ const variant_content = data.variant_content;
781
+ const stockList = variant_content.stockList;
782
+
783
+ // 修改 variant stockList
784
+ if (stockList[store]) {
785
+ if (type === 'plus') {
786
+ if (stockList[store].count) {
787
+ stockList[store].count += count;
788
+ } else {
789
+ stockList[store].count = count;
785
790
  }
786
-
787
- // 修改 variant stock
788
- variant_content.stock = Object.keys(stockList).reduce((sum: number, key: string) => {
789
- if (stockList[key] && stockList[key].count) {
790
- return sum + stockList[key].count;
791
- }
792
- return sum;
793
- }, 0);
794
-
795
- // 修改 product variant 的 stock, stockList
796
- const productVariant = product_content.variants.find((item: any) => {
797
- return item.spec.join(',') === variant_content.spec.join(',');
798
- });
799
- if (productVariant) {
800
- productVariant.stockList = variant_content.stockList;
801
- productVariant.stock = variant_content.stock;
791
+ } else if (type === 'minus') {
792
+ if (stockList[store].count) {
793
+ stockList[store].count -= count;
794
+ } else {
795
+ stockList[store].count = -count;
802
796
  }
797
+ } else {
798
+ stockList[store].count = count;
799
+ }
800
+ }
803
801
 
804
- return {
805
- product_content,
806
- variant_content,
807
- };
802
+ // 修改 variant stock
803
+ variant_content.stock = Object.keys(stockList).reduce((sum: number, key: string) => {
804
+ if (stockList[key] && stockList[key].count) {
805
+ return sum + stockList[key].count;
806
+ }
807
+ return sum;
808
+ }, 0);
809
+
810
+ // 修改 product variant 的 stock, stockList
811
+ const productVariant = product_content.variants.find((item: any) => {
812
+ return item.spec.join(',') === variant_content.spec.join(',');
813
+ });
814
+ if (productVariant) {
815
+ productVariant.stockList = variant_content.stockList;
816
+ productVariant.stock = variant_content.stock;
808
817
  }
809
818
 
810
- async deleteHistory(json: StockHistoryData) {
811
- try {
812
- await db.query(
813
- `UPDATE \`${this.app}\`.t_stock_history SET ? WHERE id = ?
814
- `,
815
- [{ status: -1 }, json.id]
816
- );
817
-
818
- return { data: false };
819
- } catch (error) {
820
- console.error(error);
821
- if (error instanceof Error) {
822
- throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
823
- }
824
- }
819
+ return {
820
+ product_content,
821
+ variant_content,
822
+ };
823
+ }
824
+
825
+ async deleteHistory(json: StockHistoryData) {
826
+ try {
827
+ await db.query(
828
+ `UPDATE \`${this.app}\`.t_stock_history SET ? WHERE id = ?
829
+ `,
830
+ [{ status: -1 }, json.id]
831
+ );
832
+
833
+ return { data: false };
834
+ } catch (error) {
835
+ console.error(error);
836
+ if (error instanceof Error) {
837
+ throw exception.BadRequestError('stock postHistory Error: ', error.message, null);
838
+ }
825
839
  }
840
+ }
826
841
  }