@things-factory/operato-wms 4.3.822 → 4.3.824

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.
@@ -1878,6 +1878,13 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1878
1878
  },
1879
1879
  ...(this.enableDirectInbound
1880
1880
  ? [
1881
+ {
1882
+ type: 'date',
1883
+ name: 'expDate',
1884
+ header: i18next.t('field.exp_date'),
1885
+ imex: { header: i18next.t('field.exp_date'), key: 'expDate', width: 25, type: 'string' },
1886
+ width: 120
1887
+ },
1881
1888
  {
1882
1889
  type: 'object',
1883
1890
  name: 'location',
@@ -1966,6 +1973,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1966
1973
  palletQty
1967
1974
  palletId
1968
1975
  manufactureDate
1976
+ expDate
1969
1977
  batchId
1970
1978
  batchIdRef
1971
1979
  unitPrice
@@ -1992,6 +2000,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1992
2000
  primaryUnit
1993
2001
  primaryValue
1994
2002
  costPrice
2003
+ isRequiredCheckExpiry
1995
2004
  }
1996
2005
  productDetail {
1997
2006
  id
@@ -508,10 +508,12 @@ class ReleaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
508
508
  <label ?hidden="${!this._ownTransport}">${i18next.t('label.co_no')}</label>
509
509
  <input name="collectionOrderNo" ?hidden="${!this._ownTransport}" ?readonly="${!this?._editable}" />
510
510
 
511
- <label ?hidden="${this.roType === 'b2b'}">${i18next.t('label.order_remark')}</label>
511
+ <label ?hidden="${this.roType === 'b2b' && !this._beforeRemark}"
512
+ >${i18next.t('label.order_remark')}</label
513
+ >
512
514
  <textarea
513
515
  name="remark"
514
- ?hidden="${this.roType === 'b2b'}"
516
+ ?hidden="${this.roType === 'b2b' && !this._beforeRemark}"
515
517
  rows="5"
516
518
  ?readonly="${!this?._editable}"
517
519
  ></textarea>
@@ -1216,7 +1218,9 @@ class ReleaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1216
1218
  this.inventoryGristConfig = {
1217
1219
  pagination: { infinite: true },
1218
1220
  rows: { selectable: { multiple: true }, appendable: false },
1219
- list: { fields: ['sku', 'productName', 'batchId', 'invStatus', 'packingType', 'releaseQty', 'releaseUomValue'] },
1221
+ list: {
1222
+ fields: ['sku', 'productName', 'batchId', 'invStatus', 'packingType', 'releaseQty', 'releaseUomValue', 'remark']
1223
+ },
1220
1224
  columns: [
1221
1225
  { name: 'releaseUomValue', hidden: true },
1222
1226
  { name: 'remainUomValue', hidden: true },
@@ -1288,6 +1292,12 @@ class ReleaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1288
1292
  name: 'batchIdRef',
1289
1293
  header: i18next.t('field.batch_no_ref'),
1290
1294
  width: 100
1295
+ },
1296
+ {
1297
+ type: 'string',
1298
+ name: 'remark',
1299
+ header: i18next.t('field.remark'),
1300
+ width: 200
1291
1301
  }
1292
1302
  ]
1293
1303
  }
@@ -1617,6 +1627,7 @@ class ReleaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1617
1627
  releaseQty
1618
1628
  releaseUomValue
1619
1629
  status
1630
+ remark
1620
1631
  }
1621
1632
  inventoryInfos {
1622
1633
  id
@@ -1650,6 +1661,7 @@ class ReleaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1650
1661
  }
1651
1662
  status
1652
1663
  refWorksheetId
1664
+ remark
1653
1665
  }
1654
1666
  shippingOrderInfo {
1655
1667
  id
@@ -722,11 +722,11 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
722
722
  this.focusOnReleaseQtyInput()
723
723
  }
724
724
 
725
- if (worksheetInfo.source == 'POWRUP') {
725
+ if (worksheetInfo.source == 'POWRUP' && !releaseGood.lmdOption) {
726
726
  this.fetchPowrupOrderDocument(worksheetInfo.orderPackage.id)
727
727
  }
728
728
 
729
- if (worksheetInfo.source == 'WEBSPERT') {
729
+ if (worksheetInfo.source == 'WEBSPERT' && !releaseGood.lmdOption) {
730
730
  this.fetchWebspertOrderDocument(worksheetInfo.orderPackage.id)
731
731
  }
732
732
 
@@ -1536,6 +1536,14 @@ class PackingProduct extends connect(store)(localize(i18next)(PageView)) {
1536
1536
  }
1537
1537
 
1538
1538
  async complete() {
1539
+ if (this._isLmdOption && (!this.airwayBill || String(this.airwayBill).trim() === '')) {
1540
+ this.showToast({
1541
+ message:
1542
+ 'It appears that we are unable to retrieve the AWB from the platform. Please reach out to support for assistance.'
1543
+ })
1544
+ return
1545
+ }
1546
+
1539
1547
  if (this._enablePackingGrossWeight) {
1540
1548
  const grossWeightValue = this.grossWeightInput.value
1541
1549
 
@@ -6,18 +6,29 @@ module.exports = {
6
6
  subdomainOffset: 2,
7
7
  port: 4000,
8
8
  inspect: '9330',
9
-
10
- storage: {
11
- type: 's3',
12
- accessKeyId: 'AKIAUQEOPWEJHCE4MTH4',
13
- secretAccessKey: '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',
14
- bucketName: 'opa-one',
15
- region: 'ap-southeast-1'
16
- },
17
- // arif
18
9
  // ormconfig: {
19
10
  // name: 'default',
20
11
  // type: 'postgres',
12
+ // database: 'postgres',
13
+ // username: 'izzah',
14
+ // password: 'hatio1234',
15
+ // host: 'my-operato-pg.cjcso4qmeuq0.ap-southeast-5.rds.amazonaws.com',
16
+ // port: 55432,
17
+ // synchronize: false,
18
+ // logging: true
19
+ // },
20
+ // postgres2
21
+ // ormconfig: {
22
+ // name: 'default',
23
+ // type: 'postgres',
24
+ // database: 'postgres',
25
+ // username: 'postgres',
26
+ // password: 'hatio',
27
+ // host: '192.168.0.151',
28
+ // port: 15432,
29
+ // synchronize: false,debug
30
+ // name: 'default',
31
+ // type: 'postgres',
21
32
  // database: 'arif',
22
33
  // username: 'postgres',
23
34
  // password: 'hatio',
@@ -26,7 +37,51 @@ module.exports = {
26
37
  // synchronize: false,
27
38
  // logging: true
28
39
  // },
29
-
40
+ // ormconfig: {
41
+ // name: 'default',
42
+ // type: 'postgres',
43
+ // database: 'operato-eric',
44
+ // username: 'postgres',
45
+ // password: 'hatio',
46
+ // host: '192.168.0.248',
47
+ // port: 15432,
48
+ // synchronize: false,
49
+ // logging: true
50
+ // },
51
+ //operato
52
+ // ormconfig: {
53
+ // name: 'default',
54
+ // type: 'postgres',
55
+ // database: 'operato',
56
+ // username: 'postgres',
57
+ // password: 'hatio',
58
+ // host: '192.168.0.151',
59
+ // port: 15432,
60
+ // synchronize: false,
61
+ // logging: true
62
+ // },
63
+ //153 - operatodebug
64
+ // type: 'postgres',
65
+ // database: 'operato',
66
+ // username: 'postgres',
67
+ // password: 'hatio',
68
+ // host: '192.168.0.153',
69
+ // port: 15432,
70
+ // synchronize: false,
71
+ // logging: true
72
+ // },
73
+ //eric2
74
+ // ormconfig: {
75
+ // name: 'default',
76
+ // type: 'postgres',
77
+ // database: 'eric2',
78
+ // username: 'postgres',
79
+ // password: 'hatio',
80
+ // host: '192.168.0.153',
81
+ // port: 15432,
82
+ // synchronize: false,
83
+ // logging: true
84
+ // },
30
85
  // STAGING DATABASE
31
86
  ormconfig: {
32
87
  name: 'default',
@@ -39,46 +94,30 @@ module.exports = {
39
94
  synchronize: false,
40
95
  logging: true
41
96
  },
42
-
97
+ //EMS
43
98
  // ormconfig: {
44
99
  // name: 'default',
45
100
  // type: 'postgres',
46
- // host: 'operatov3.cluster-cijhm4n1hbst.ap-southeast-1.rds.amazonaws.com',
47
- // port: 55432,
48
- // database: 'postgres',
49
- // username: 'postgres',
50
- // password: 'abcd1234',
51
- // synchronize: false,
52
- // logging: true,
53
- // connectTimeoutMS: 30000,
54
- // extra: { poolSize: 30 }
55
- // },
56
-
57
- //db izzah
58
- // ormconfig: {
59
- // name: 'default',
60
- // type: 'postgres',
61
- // database: '06072023',
101
+ // database: 'EMS',
62
102
  // username: 'postgres',
63
103
  // password: 'hatio',
64
- // host: '192.168.0.153',
65
- // port: 15432,f
66
- // synchronize: true,
104
+ // host: '192.168.0.161',
105
+ // port: 15432,
106
+ // synchronize: false,
67
107
  // logging: true
68
108
  // },
109
+ //db nora
69
110
  // ormconfig: {
70
111
  // name: 'default',
71
112
  // type: 'postgres',
72
113
  // database: 'postgres',
73
114
  // username: 'postgres',
74
115
  // password: 'hatio',
75
- // host: '192.168.0.151',
116
+ // host: '192.168.0.36',
76
117
  // port: 15432,
77
- // synchronize: false,
118
+ // synchronize: true,
78
119
  // logging: true
79
120
  // },
80
-
81
- // //ERIC
82
121
  // ormconfig: {
83
122
  // name: 'default',
84
123
  // type: 'postgres',
@@ -87,15 +126,14 @@ module.exports = {
87
126
  // password: 'hatio',
88
127
  // host: '192.168.0.153',
89
128
  // port: 15432,
90
- // synchronize: false,
129
+ // synchronize: true,
91
130
  // logging: true
92
131
  // },
93
-
94
- //eric 2
132
+ //db izzah
95
133
  // ormconfig: {
96
134
  // name: 'default',
97
135
  // type: 'postgres',
98
- // database: 'eric2',
136
+ // database: '06072023',
99
137
  // username: 'postgres',
100
138
  // password: 'hatio',
101
139
  // host: '192.168.0.153',
@@ -103,21 +141,20 @@ module.exports = {
103
141
  // synchronize: false,
104
142
  // logging: true
105
143
  // },
106
-
107
144
  // ormconfig: {
108
145
  // name: 'default',
109
146
  // type: 'postgres',
110
- // host: 'operatov3.cluster-cijhm4n1hbst.ap-southeast-1.rds.amazonaws.com',
111
- // port: 55432,
147
+ // host: 'a6cf0bb5671f54555985dede599d5a87-649005352.ap-southeast-1.elb.amazonaws.com',
148
+ // port: 15432,
112
149
  // database: 'postgres',
113
- // username: 'postgres',
114
- // password: 'abcd1234',
150
+ // username: 'operato-hub-app',
151
+ // password: 'a5Z(7|6n$Zti',
115
152
  // synchronize: false,
116
153
  // logging: true,
117
154
  // connectTimeoutMS: 30000,
118
155
  // extra: { poolSize: 30 }
119
156
  // },
120
- //ormconfig: {
157
+ // //ormconfig: {
121
158
  // name: 'default',
122
159
  // type: 'postgres',
123
160
  // database: 'dev2',
@@ -145,16 +182,7 @@ module.exports = {
145
182
  },
146
183
  uploads: 'uploads',
147
184
  attachmentsPath: 'attachments',
148
- logger: {
149
- file: {
150
- filename: 'logs/application-%DATE%.log',
151
- datePattern: 'YYYY-MM-DD-HH',
152
- zippedArchive: true,
153
- maxSize: '200m',
154
- maxFiles: '1m',
155
- level: 'info'
156
- }
157
- },
185
+ logger: {},
158
186
  email: {
159
187
  host: 'smtp.office365.com',
160
188
  port: 587,
@@ -192,30 +220,72 @@ module.exports = {
192
220
  // privateKey: '4pmlt3Wk019u7nqU3Q_oGZE6LbUDjjf8DpmAcn9-iss'
193
221
  // }
194
222
  },
195
- // reportApiUrl:
196
- // 'http://k8s-default-operator-8eeba2e246-3e3a5ee7979bcd57.elb.ap-southeast-1.amazonaws.com/rest/report/show_html',
197
- // reportApiUrl: 'http://192.168.0.153:8888/rest/report/show_html',
198
- // reportApiUrl: 'http://192.168.0.153:8888/rest/report/show_html',
223
+ fulfillmentIntegrationOperato: {
224
+ host: '192.168.0.161:3000',
225
+ protocol: 'http',
226
+ platform: 'operato',
227
+ application: 'Operato MMS',
228
+ appKey: 'a9bf751e622bf146662b240d58971051',
229
+ appSecret: '1c385935dc131c4b902b9bbf6a4798af',
230
+ callback: 'http://192.168.0.161:5000/callback-operato'
231
+ },
232
+ lmdIntegrationNinjavan: {
233
+ clientId: 'P8WCEwMo0FHNlPECwTLetwN3diAmt5KF',
234
+ secretKey: '1D0yNZGseOjhxnwri29xmuZiiuRp131L',
235
+ refreshThreshold: 43200
236
+ },
237
+
238
+ lmdIntegrationEms: { refreshThreshold: 43200 },
239
+ marketplaceIntegrationShopee: {
240
+ platform: 'shopee',
241
+ isUAT: false,
242
+ application: 'Operato MMS',
243
+ partnerId: 846025,
244
+ partnerKey: 'd34cfd85a603f196a0d74ebe08043280c1a27788bb36bdffd61e7e0bb1c90b64',
245
+ v2: true
246
+ },
247
+ marketplaceIntegrationLazada: {
248
+ platform: 'lazada',
249
+ application: 'operato-mms',
250
+ appKey: '120961',
251
+ appSecret: 'HB3RTNEXHlVSlBr9SmWF8AjbSUT7a825',
252
+ callback: 'https://maybank.operato-m.com/lazada-callback'
253
+ },
254
+
255
+ //testinglazada
256
+ // marketplaceIntegrationLazada: {
257
+ // platform: 'lazada',
258
+ // application: 'powrup_bi',
259
+ // appKey: '117890',
260
+ // appSecret: 'tQVllnUa7irAHoNxAwXEVxoP1we1bUjE',
261
+ // callback: 'https://73c5-175-141-30-142.ngrok-free.app/lazada-callback'
262
+ // },
263
+ reportApiUrl: 'http://localhost:8090/rest/report/show_html',
264
+ // reportApiUrl: 'http://192.168.0.153:8888/rest/report/show_html'
199
265
  // reportApiUrl: 'http://10.100.109.66:8090/rest/report/show_html',
200
266
  awbFileStorage: {
201
267
  type: 's3',
202
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
203
- secretAccessKey: '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',
268
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
269
+ secretAccessKey: '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',
204
270
  bucketName: 'operato-awb',
205
271
  region: 'ap-southeast-1'
206
272
  },
207
- invoiceFileStorage: {
208
- type: 's3',
209
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
210
- secretAccessKey: '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',
211
- invoiceBucket: 'operato-invoice',
212
- region: 'ap-southeast-1'
213
- },
214
273
  lambda: {
215
274
  region: 'ap-southeast-1',
216
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
217
- secretAccessKey: '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'
275
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
276
+ secretAccessKey: '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'
218
277
  },
219
- reportApiUrl:
220
- 'http://k8s-default-operator-8eeba2e246-3e3a5ee7979bcd57.elb.ap-southeast-1.amazonaws.com/rest/report/show_html'
278
+ lmdIntegrationConfig: {
279
+ version: {
280
+ v1: 'lmdMiddleware',
281
+ v2: 'lmdMiddlewareV2'
282
+ }
283
+ },
284
+ awsSesEmail: {
285
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
286
+ secretAccessKey: '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',
287
+ email: 'support@hatio.asia'
288
+ }
289
+ // reportApiUrl:
290
+ // 'http://k8s-default-operator-2fd6178d98-66c66a0f76c09575.elb.ap-southeast-1.amazonaws.com/rest/report/show_html'
221
291
  }
@@ -31,28 +31,38 @@ exports.getLoadingTask = {
31
31
  .andWhere('wsd.status NOT IN (:...status)', { status: [worksheet_base_1.WORKSHEET_STATUS.DONE, worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED] })
32
32
  .getOne();
33
33
  // 2. If no assigned worksheet, find and assign next available one
34
+ // FOR UPDATE OF ws SKIP LOCKED: under concurrent clicks, two callers
35
+ // used to SELECT the same row and the second UPDATE would re-evaluate,
36
+ // find sorter_id no longer NULL, update zero rows, and the user would
37
+ // see a confusing "no suitable worksheet found" error even though other
38
+ // unassigned rows existed. SKIP LOCKED makes concurrent callers pick
39
+ // different rows. `OF ws` scopes the row lock to the worksheets table
40
+ // only (not the joined release_goods / worksheet_details rows). Inner
41
+ // transaction is independent so the row lock is released as soon as
42
+ // the UPDATE commits.
34
43
  if (!worksheet) {
35
44
  let updatedWorksheets = await (0, typeorm_1.getConnection)().transaction(async (tx2) => {
36
45
  let x = await tx2.query(`
37
- UPDATE worksheets ws SET
46
+ UPDATE worksheets ws SET
38
47
  sorter_id = $2,
39
48
  updated_at = NOW(),
40
49
  updater_id = $2
41
50
  FROM (
42
- SELECT ws.id
51
+ SELECT ws.id
43
52
  FROM worksheets ws
44
53
  INNER JOIN release_goods rg ON rg.id = ws.release_good_id
45
54
  INNER JOIN worksheet_details wsd ON wsd.worksheet_id = ws.id
46
- WHERE ws.domain_id = $1
55
+ WHERE ws.domain_id = $1
47
56
  AND ws.type = 'LOADING'
48
57
  AND ws.status IN ('EXECUTING', 'DEACTIVATED')
49
58
  AND ws.sorter_id IS NULL
50
59
  AND rg.status IN ('LOADING', 'PROCESSING', 'PARTIAL_PROCESSING')
51
60
  AND wsd.status NOT IN ('DONE', 'DEACTIVATED')
52
61
  AND (rg.sorted_by_id = $2 OR rg.sorted_by_id IS NULL)
53
- ORDER BY rg.created_at
62
+ ORDER BY rg.created_at
54
63
  LIMIT 1
55
- ) src
64
+ FOR UPDATE OF ws SKIP LOCKED
65
+ ) src
56
66
  WHERE src.id = ws.id
57
67
  RETURNING ws.id
58
68
  `, [domain.id, user.id]);
@@ -1 +1 @@
1
- {"version":3,"file":"get-loading-task.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/outbound/get-loading-task.ts"],"names":[],"mappings":";;;AAAA,qCAA0D;AAI1D,2DAAsE;AACtE,mEAA4F;AAC5F,iEAA2D;AAE9C,QAAA,cAAc,GAAG;IAC5B,KAAK,CAAC,cAAc,CAAC,CAAM,EAAE,EAAE,EAAE,OAAY;QAC3C,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAsD,OAAO,CAAC,KAAK,CAAA;QAE7F,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,EAAE;YACzC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;SAC/B;QACD,IAAI;YACF,6BAA6B;YAC7B,IAAI,SAAS,GAAc,MAAM,EAAE;iBAChC,aAAa,CAAC,0BAAS,CAAC;iBACxB,kBAAkB,CAAC,IAAI,CAAC;iBACxB,kBAAkB,CAAC,aAAa,EAAE,KAAK,CAAC;iBACxC,kBAAkB,CAAC,gBAAgB,EAAE,IAAI,CAAC;iBAC1C,SAAS,CAAC,qBAAqB,EAAE,KAAK,CAAC;iBACvC,KAAK,CAAC;gBACL,MAAM;gBACN,IAAI,EAAE,+BAAc,CAAC,OAAO;gBAC5B,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAA,YAAE,EAAC,CAAC,iCAAgB,CAAC,SAAS,EAAE,iCAAgB,CAAC,WAAW,CAAC,CAAC;aACvE,CAAC;iBACD,QAAQ,CAAC,2BAA2B,EAAE;gBACrC,MAAM,EAAE,CAAC,yBAAY,CAAC,OAAO,EAAE,yBAAY,CAAC,UAAU,EAAE,yBAAY,CAAC,kBAAkB,CAAC;aACzF,CAAC;iBACD,QAAQ,CAAC,gCAAgC,EAAE,EAAE,MAAM,EAAE,CAAC,iCAAgB,CAAC,IAAI,EAAE,iCAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;iBAC7G,MAAM,EAAE,CAAA;YAEX,kEAAkE;YAClE,IAAI,CAAC,SAAS,EAAE;gBACd,IAAI,iBAAiB,GAAG,MAAM,IAAA,uBAAa,GAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAkB,EAAE,EAAE;oBACrF,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CACrB;;;;;;;;;;;;;;;;;;;;;;WAsBD,EACC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CACrB,CAAA;oBAED,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;gBACb,CAAC,CAAC,CAAA;gBAEF,IAAI,iBAAiB,CAAC,MAAM,IAAI,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;gBAEjF,kBAAkB;gBAClB,SAAS,GAAG,MAAM,EAAE;qBACjB,aAAa,CAAC,0BAAS,CAAC;qBACxB,kBAAkB,CAAC,IAAI,CAAC;qBACxB,kBAAkB,CAAC,gBAAgB,EAAE,IAAI,CAAC;qBAC1C,KAAK,CAAC,aAAa,EAAE,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;qBACrD,QAAQ,CAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;qBACvD,MAAM,EAAE,CAAA;aACZ;YAED,wCAAwC;YACxC,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;YAErF,IAAI,SAAS,CAAC,MAAM,IAAI,iCAAgB,CAAC,WAAW,EAAE;gBACpD,MAAM,EAAE,CAAC,aAAa,CAAC,0BAAS,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE;oBACrD,MAAM,EAAE,iCAAgB,CAAC,SAAS;oBAClC,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAA;aACH;YAED,8BAA8B;YAC9B,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,CAAC,QAAQ,KAAI,IAAI,EAAE;gBAC3C,MAAM,EAAE,CAAC,aAAa,CAAC,wBAAW,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,EAAE;oBACnE,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAA;aACH;YAED,OAAO,yCAAkB,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAA;SACjH;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACpB,MAAM,KAAK,CAAA;SACZ;gBAAS;YACR,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,EAAE;gBACzC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;aAClC;SACF;IACH,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"get-loading-task.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/outbound/get-loading-task.ts"],"names":[],"mappings":"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"}
@@ -35,19 +35,34 @@ exports.getZonePickingTask = {
35
35
  worksheet = await worksheetQb.getOne();
36
36
  if (!worksheet) {
37
37
  //find a worksheet and update assignee to user
38
+ // Claim a single oldest unassigned worksheet. The LIMIT 1 + FOR UPDATE
39
+ // SKIP LOCKED inside the subquery makes this safe under concurrent clicks:
40
+ // - LIMIT 1 prevents bulk-claiming every unassigned worksheet for one user
41
+ // (the previous version assigned ALL of them to the clicker and only
42
+ // returned x[0], silently mis-assigning the rest to whoever clicked first).
43
+ // - FOR UPDATE SKIP LOCKED makes concurrent callers pick different rows
44
+ // instead of waiting on each other and then failing with "no suitable
45
+ // worksheet found" because the first user already grabbed everything.
46
+ //
47
+ // Use an independent inner transaction (not the outer `tx`) so the UPDATE
48
+ // commits before the surrounding resolver transaction finishes. Otherwise
49
+ // the row lock acquired by the UPDATE would persist for the whole resolver,
50
+ // defeating SKIP LOCKED for any concurrent click that arrives mid-flight.
38
51
  let updatedWorksheets = await (0, typeorm_1.getConnection)().transaction(async (tx2) => {
39
52
  let x = await tx2.getRepository(worksheet_base_1.Worksheet).query(`
40
- UPDATE worksheets ws SET
53
+ UPDATE worksheets ws SET
41
54
  assignee_id = $2,
42
55
  updated_at = NOW(),
43
56
  updater_id = $2
44
57
  FROM (
45
- SELECT ws.id, ws.name, ws.status, ws.release_good_id FROM worksheets ws
58
+ SELECT ws.id FROM worksheets ws
46
59
  WHERE ws.domain_id = $1
47
60
  AND ws.type = 'ZONE_PICKING'
48
61
  AND ws.status IN ('EXECUTING', 'DEACTIVATED')
49
62
  AND ws.assignee_id IS NULL
50
63
  ORDER BY ws.created_at
64
+ LIMIT 1
65
+ FOR UPDATE SKIP LOCKED
51
66
  ) src where src.id = ws.id
52
67
  RETURNING ws.id;
53
68
  `, [domain.id, assignee.id]);
@@ -1 +1 @@
1
- {"version":3,"file":"get-zone-picking-task.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/zone-worksheet/get-zone-picking-task.ts"],"names":[],"mappings":";;;AAAA,qCAA0D;AAE1D,yDAAgD;AAEhD,2DAA8G;AAE9G,mEAA6G;AAC7G,+DAAsD;AACtD,qDAAuD;AAE1C,QAAA,kBAAkB,GAAG;IAChC,KAAK,CAAC,kBAAkB,CAAC,CAAM,EAAE,EAAE,EAAE,OAAY;QAC/C,IAAI;YACF,IAAI,SAAoB,CAAA;YACxB,IAAI,oBAA6B,CAAA;YACjC,MAAM,IAAA,uBAAa,GAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAiB,EAAE,EAAE;gBAC5D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAmC,OAAO,CAAC,KAAK,CAAA;gBACtE,MAAM,QAAQ,GAAS,MAAM,EAAE,CAAC,aAAa,CAAC,gBAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;gBAChG,IAAI,CAAC,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,KAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,UAAkB,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC;oBACtF,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;gBAEhE,IAAI,CAAC,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;gBAE5D,IAAI,WAAW,GAAG,MAAM,EAAE;qBACvB,aAAa,CAAC,0BAAS,CAAC;qBACxB,kBAAkB,CAAC,IAAI,CAAC;qBACxB,MAAM,CAAC,OAAO,CAAC;qBACf,SAAS,CAAC,SAAS,CAAC;qBACpB,SAAS,CAAC,WAAW,CAAC;qBACtB,KAAK,CACJ,mIAAmI,EACnI;oBACE,SAAS,EAAE,MAAM,CAAC,EAAE;oBACpB,IAAI,EAAE,+BAAc,CAAC,YAAY;oBACjC,QAAQ,EAAE,QAAQ,CAAC,EAAE;oBACrB,OAAO,EAAE,iCAAgB,CAAC,SAAS;oBACnC,OAAO,EAAE,iCAAgB,CAAC,WAAW;iBACtC,CACF,CAAA;gBACH,SAAS,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAA;gBAEtC,IAAI,CAAC,SAAS,EAAE;oBACd,8CAA8C;oBAC9C,IAAI,iBAAiB,GAAG,MAAM,IAAA,uBAAa,GAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAkB,EAAE,EAAE;wBACrF,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,0BAAS,CAAC,CAAC,KAAK,CAC9C;;;;;;;;;;;;;;aAcD,EACC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CACzB,CAAA;wBAED,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;oBACb,CAAC,CAAC,CAAA;oBACF,IAAI,iBAAiB,CAAC,MAAM,IAAI,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;oBAEjF,kBAAkB;oBAClB,SAAS,GAAG,MAAM,EAAE;yBACjB,aAAa,CAAC,0BAAS,CAAC;yBACxB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;iBAC3E;gBAED,wCAAwC;gBACxC,IAAI,CAAC,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;gBAErF,IAAI,SAAS,CAAC,MAAM,IAAI,iCAAgB,CAAC,WAAW,EAAE;oBACpD,MAAM,EAAE,CAAC,aAAa,CAAC,0BAAS,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE;wBACrD,MAAM,EAAE,iCAAgB,CAAC,SAAS;wBAClC,SAAS,EAAE,IAAI,IAAI,EAAE;qBACtB,CAAC,CAAA;oBACF,MAAM,gBAAgB,GAAsB,MAAM,EAAE,CAAC,aAAa,CAAC,gCAAe,CAAC,CAAC,IAAI,CAAC;wBACvF,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;wBAC/B,SAAS,EAAE,CAAC,iBAAiB,CAAC;qBAC/B,CAAC,CAAA;oBAEF,MAAM,EAAE;yBACL,aAAa,CAAC,gCAAe,CAAC;yBAC9B,MAAM,CACL,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,iCAAgB,CAAC,WAAW,EAAE,EAC9D,EAAE,MAAM,EAAE,iCAAgB,CAAC,SAAS,EAAE,CACvC,CAAA;oBAEH,MAAM,iBAAiB,GAAG,gBAAgB;yBACvC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC;yBACrC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,mCAAsB,CAAC,aAAa,CAAC;yBAChE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBAEnB,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;wBAChC,MAAM,EAAE;6BACL,aAAa,CAAC,2BAAc,CAAC;6BAC7B,MAAM,CAAC,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,mCAAsB,CAAC,UAAU,EAAE,CAAC,CAAA;wBAEvF,MAAM,cAAc,GAAG,gBAAgB;6BACpC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC;6BACnD,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;wBAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;4BAC7B,MAAM,EAAE;iCACP,aAAa,CAAC,wBAAW,CAAC;iCAC1B,MAAM,CAAC,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,cAAc,CAAC,EAAE,MAAM,EAAE,yBAAY,CAAC,aAAa,EAAE,EAAE,EAAE,MAAM,EAAE,yBAAY,CAAC,UAAU,EAAE,CAAC,CAAA;yBAC7G;qBACF;iBACF;gBAED,oBAAoB,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,sBAAO,CAAC,CAAC,OAAO,CAAC;oBAC7D,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,EAAE;iBACpD,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;YACF,2BAA2B;YAC3B,OAAO,qCAAoB,CAAC,oBAAoB,CAC9C,CAAC,EACD,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,EAAE,EACjE,OAAO,CACR,CAAA;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,CAAA;SACR;IACH,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"get-zone-picking-task.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/zone-worksheet/get-zone-picking-task.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,15 @@ exports.zonePickingWorksheet = {
55
55
  zoneWorksheet.worksheetDetail = await (0, typeorm_1.getRepository)(worksheet_base_1.WorksheetDetail).find({
56
56
  where: { worksheet }
57
57
  });
58
+ // Lightweight pre-pass: only the columns needed to compute invIds, roIds, and
59
+ // isCompletable. Avoids running the heavy joined SELECT (product/inventory/
60
+ // location/productDetail/...) twice — the second, filtered getMany() below
61
+ // produces the rows actually returned to the client.
62
+ const orderInventories = await (0, typeorm_1.getRepository)(sales_base_1.OrderInventory)
63
+ .createQueryBuilder('oi')
64
+ .select(['oi.id', 'oi.inventoryId', 'oi.releaseGoodId', 'oi.status'])
65
+ .where('oi.ref_worksheet_id = :worksheetId', { worksheetId: worksheet.id })
66
+ .getMany();
58
67
  //fetch order inventories
59
68
  let qb = (0, typeorm_1.getRepository)(sales_base_1.OrderInventory)
60
69
  .createQueryBuilder('oi')
@@ -66,8 +75,6 @@ exports.zonePickingWorksheet = {
66
75
  .leftJoinAndSelect('pd.childProductDetail', 'cpd')
67
76
  .leftJoinAndSelect('pd.parentProductDetails', 'ppd')
68
77
  .where('ref_worksheet_id = :worksheetId', { worksheetId: worksheet.id });
69
- //get all oi to find inventory changes and determine if the worksheet is completable
70
- const orderInventories = await qb.getMany();
71
78
  //item assigned to obsolete inventories will not be displayed during picking
72
79
  if (filter) {
73
80
  qb.andWhere('rg.status != :orderStatus', { orderStatus: sales_base_1.ORDER_STATUS.OBSOLETE });
@@ -136,6 +143,10 @@ exports.zonePickingWorksheet = {
136
143
  }
137
144
  };
138
145
  function isCompletable(oi, ic) {
146
+ // NOTE: callers may pass a partial OrderInventory with only id/inventoryId/
147
+ // releaseGoodId/status populated (see the lightweight pre-pass in
148
+ // zonePickingWorksheet). Don't reference other fields here without first
149
+ // widening that SELECT.
139
150
  //find processing oi and check if there is any pending inventory adjustment
140
151
  let processingOi = oi.filter(item => item.status === sales_base_1.ORDER_INVENTORY_STATUS.PROCESSING);
141
152
  processingOi = processingOi.filter(item => !ic.filter(change => change.status === 'APPROVED').some(change => change.inventory.id === item.inventoryId));
@@ -1 +1 @@
1
- {"version":3,"file":"zone-worksheet.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/zone-worksheet/zone-worksheet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zone-worksheet.js","sourceRoot":"","sources":["../../../../server/graphql/resolvers/zone-worksheet/zone-worksheet.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,11 @@ exports.Mutation = `
16
16
  assignSorter(releaseGoodId: [String]!, userId: String): Boolean @transaction
17
17
  completeZonePicking(worksheetId: String!): Boolean @transaction
18
18
  completeZonePickingPartially(worksheetId: String!): Boolean @transaction
19
- getZonePickingTask: ZonePickingWorksheet @privilege(category: "worksheet_control", privilege: "mutation") @transaction
19
+ # Intentionally NOT @transaction the resolver opens its own
20
+ # getConnection().transaction() and uses an independent inner transaction
21
+ # to commit the worksheet-claim UPDATE early (releases the row lock so
22
+ # SKIP LOCKED works for concurrent clicks). See get-zone-picking-task.ts.
23
+ getZonePickingTask: ZonePickingWorksheet @privilege(category: "worksheet_control", privilege: "mutation")
20
24
  `;
21
25
  exports.Types = [zone_worksheet_overview_1.ZoneWorksheetOverview, zone_worksheet_overview_list_1.ZoneWorksheetOverviewList, zone_picking_worksheet_1.ZonePickingWorksheet];
22
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/zone-worksheet/index.ts"],"names":[],"mappings":";;;AAAA,uEAAiE;AACjE,iFAA0E;AAC1E,qEAA+D;AAElD,QAAA,KAAK,GAAG;;;CAGpB,CAAA;AAEY,QAAA,QAAQ,GAAG;;;;;;;;;CASvB,CAAA;AAEY,QAAA,KAAK,GAAG,CAAC,+CAAqB,EAAE,wDAAyB,EAAE,6CAAoB,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/zone-worksheet/index.ts"],"names":[],"mappings":";;;AAAA,uEAAiE;AACjE,iFAA0E;AAC1E,qEAA+D;AAElD,QAAA,KAAK,GAAG;;;CAGpB,CAAA;AAEY,QAAA,QAAQ,GAAG;;;;;;;;;;;;;CAavB,CAAA;AAEY,QAAA,KAAK,GAAG,CAAC,+CAAqB,EAAE,wDAAyB,EAAE,6CAAoB,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-wms",
3
- "version": "4.3.822",
3
+ "version": "4.3.824",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -66,7 +66,7 @@
66
66
  "@things-factory/attachment-ui": "^4.3.815",
67
67
  "@things-factory/auth-ui": "^4.3.815",
68
68
  "@things-factory/barcode-ui": "^4.3.815",
69
- "@things-factory/biz-ui": "^4.3.819",
69
+ "@things-factory/biz-ui": "^4.3.823",
70
70
  "@things-factory/board-service": "^4.3.815",
71
71
  "@things-factory/board-ui": "^4.3.815",
72
72
  "@things-factory/code-ui": "^4.3.815",
@@ -81,17 +81,17 @@
81
81
  "@things-factory/help": "^4.3.815",
82
82
  "@things-factory/i18n-base": "^4.3.815",
83
83
  "@things-factory/id-rule-base": "^4.3.815",
84
- "@things-factory/import-ui": "^4.3.815",
85
- "@things-factory/import-ui-excel": "^4.3.815",
84
+ "@things-factory/import-ui": "^4.3.823",
85
+ "@things-factory/import-ui-excel": "^4.3.823",
86
86
  "@things-factory/menu-ui": "^4.3.815",
87
87
  "@things-factory/more-ui": "^4.3.815",
88
88
  "@things-factory/notification": "^4.3.815",
89
89
  "@things-factory/pdf": "^4.3.815",
90
90
  "@things-factory/print-proxy-service": "^4.3.815",
91
91
  "@things-factory/print-ui": "^4.3.815",
92
- "@things-factory/product-base": "^4.3.822",
93
- "@things-factory/resource-ui": "^4.3.815",
94
- "@things-factory/sales-ui": "^4.3.822",
92
+ "@things-factory/product-base": "^4.3.824",
93
+ "@things-factory/resource-ui": "^4.3.823",
94
+ "@things-factory/sales-ui": "^4.3.824",
95
95
  "@things-factory/scene-data-transform": "^4.3.815",
96
96
  "@things-factory/scene-excel": "^4.3.815",
97
97
  "@things-factory/scene-firebase": "^4.3.815",
@@ -107,8 +107,8 @@
107
107
  "@things-factory/system-ui": "^4.3.815",
108
108
  "@things-factory/transport-base": "^4.3.819",
109
109
  "@things-factory/tutorial-ui": "^4.3.815",
110
- "@things-factory/warehouse-base": "^4.3.822",
111
- "@things-factory/worksheet-base": "^4.3.822"
110
+ "@things-factory/warehouse-base": "^4.3.824",
111
+ "@things-factory/worksheet-base": "^4.3.824"
112
112
  },
113
113
  "devDependencies": {
114
114
  "@things-factory/builder": "^4.3.815",
@@ -117,5 +117,5 @@
117
117
  "cypress-localstorage-commands": "^1.6.1",
118
118
  "eslint-plugin-cypress": "^2.12.1"
119
119
  },
120
- "gitHead": "a3d4a456e624f2ec794324e0f395d737df34e554"
120
+ "gitHead": "7c6aa626b0ce0ce8ab988710b0e8fc2ed0bba5c2"
121
121
  }
@@ -34,29 +34,39 @@ export const getLoadingTask = {
34
34
  .getOne()
35
35
 
36
36
  // 2. If no assigned worksheet, find and assign next available one
37
+ // FOR UPDATE OF ws SKIP LOCKED: under concurrent clicks, two callers
38
+ // used to SELECT the same row and the second UPDATE would re-evaluate,
39
+ // find sorter_id no longer NULL, update zero rows, and the user would
40
+ // see a confusing "no suitable worksheet found" error even though other
41
+ // unassigned rows existed. SKIP LOCKED makes concurrent callers pick
42
+ // different rows. `OF ws` scopes the row lock to the worksheets table
43
+ // only (not the joined release_goods / worksheet_details rows). Inner
44
+ // transaction is independent so the row lock is released as soon as
45
+ // the UPDATE commits.
37
46
  if (!worksheet) {
38
47
  let updatedWorksheets = await getConnection().transaction(async (tx2: EntityManager) => {
39
48
  let x = await tx2.query(
40
49
  `
41
- UPDATE worksheets ws SET
50
+ UPDATE worksheets ws SET
42
51
  sorter_id = $2,
43
52
  updated_at = NOW(),
44
53
  updater_id = $2
45
54
  FROM (
46
- SELECT ws.id
55
+ SELECT ws.id
47
56
  FROM worksheets ws
48
57
  INNER JOIN release_goods rg ON rg.id = ws.release_good_id
49
58
  INNER JOIN worksheet_details wsd ON wsd.worksheet_id = ws.id
50
- WHERE ws.domain_id = $1
59
+ WHERE ws.domain_id = $1
51
60
  AND ws.type = 'LOADING'
52
61
  AND ws.status IN ('EXECUTING', 'DEACTIVATED')
53
62
  AND ws.sorter_id IS NULL
54
63
  AND rg.status IN ('LOADING', 'PROCESSING', 'PARTIAL_PROCESSING')
55
64
  AND wsd.status NOT IN ('DONE', 'DEACTIVATED')
56
65
  AND (rg.sorted_by_id = $2 OR rg.sorted_by_id IS NULL)
57
- ORDER BY rg.created_at
66
+ ORDER BY rg.created_at
58
67
  LIMIT 1
59
- ) src
68
+ FOR UPDATE OF ws SKIP LOCKED
69
+ ) src
60
70
  WHERE src.id = ws.id
61
71
  RETURNING ws.id
62
72
  `,
@@ -41,20 +41,35 @@ export const getZonePickingTask = {
41
41
 
42
42
  if (!worksheet) {
43
43
  //find a worksheet and update assignee to user
44
+ // Claim a single oldest unassigned worksheet. The LIMIT 1 + FOR UPDATE
45
+ // SKIP LOCKED inside the subquery makes this safe under concurrent clicks:
46
+ // - LIMIT 1 prevents bulk-claiming every unassigned worksheet for one user
47
+ // (the previous version assigned ALL of them to the clicker and only
48
+ // returned x[0], silently mis-assigning the rest to whoever clicked first).
49
+ // - FOR UPDATE SKIP LOCKED makes concurrent callers pick different rows
50
+ // instead of waiting on each other and then failing with "no suitable
51
+ // worksheet found" because the first user already grabbed everything.
52
+ //
53
+ // Use an independent inner transaction (not the outer `tx`) so the UPDATE
54
+ // commits before the surrounding resolver transaction finishes. Otherwise
55
+ // the row lock acquired by the UPDATE would persist for the whole resolver,
56
+ // defeating SKIP LOCKED for any concurrent click that arrives mid-flight.
44
57
  let updatedWorksheets = await getConnection().transaction(async (tx2: EntityManager) => {
45
58
  let x = await tx2.getRepository(Worksheet).query(
46
59
  `
47
- UPDATE worksheets ws SET
60
+ UPDATE worksheets ws SET
48
61
  assignee_id = $2,
49
62
  updated_at = NOW(),
50
63
  updater_id = $2
51
64
  FROM (
52
- SELECT ws.id, ws.name, ws.status, ws.release_good_id FROM worksheets ws
65
+ SELECT ws.id FROM worksheets ws
53
66
  WHERE ws.domain_id = $1
54
67
  AND ws.type = 'ZONE_PICKING'
55
68
  AND ws.status IN ('EXECUTING', 'DEACTIVATED')
56
69
  AND ws.assignee_id IS NULL
57
70
  ORDER BY ws.created_at
71
+ LIMIT 1
72
+ FOR UPDATE SKIP LOCKED
58
73
  ) src where src.id = ws.id
59
74
  RETURNING ws.id;
60
75
  `,
@@ -1,7 +1,7 @@
1
- import { EntityManager, getRepository, In, Not } from 'typeorm'
1
+ import { EntityManager, getRepository, In } from 'typeorm'
2
2
  import { Domain } from '@things-factory/biz-base'
3
- import { Worksheet, WorksheetDetail, WORKSHEET_TYPE, computeConversionString } from '@things-factory/worksheet-base'
4
- import { Inventories, InventoryChange } from '@things-factory/warehouse-base'
3
+ import { Worksheet, WorksheetDetail, computeConversionString } from '@things-factory/worksheet-base'
4
+ import { InventoryChange } from '@things-factory/warehouse-base'
5
5
  import { OrderInventory, ReleaseGood, ORDER_STATUS, ORDER_INVENTORY_STATUS } from '@things-factory/sales-base'
6
6
 
7
7
  export const zoneWorksheetOverview = {
@@ -75,6 +75,16 @@ export const zonePickingWorksheet = {
75
75
  where: { worksheet }
76
76
  })
77
77
 
78
+ // Lightweight pre-pass: only the columns needed to compute invIds, roIds, and
79
+ // isCompletable. Avoids running the heavy joined SELECT (product/inventory/
80
+ // location/productDetail/...) twice — the second, filtered getMany() below
81
+ // produces the rows actually returned to the client.
82
+ const orderInventories: OrderInventory[] = await getRepository(OrderInventory)
83
+ .createQueryBuilder('oi')
84
+ .select(['oi.id', 'oi.inventoryId', 'oi.releaseGoodId', 'oi.status'])
85
+ .where('oi.ref_worksheet_id = :worksheetId', { worksheetId: worksheet.id })
86
+ .getMany()
87
+
78
88
  //fetch order inventories
79
89
  let qb = getRepository(OrderInventory)
80
90
  .createQueryBuilder('oi')
@@ -87,9 +97,6 @@ export const zonePickingWorksheet = {
87
97
  .leftJoinAndSelect('pd.parentProductDetails', 'ppd')
88
98
  .where('ref_worksheet_id = :worksheetId', { worksheetId: worksheet.id })
89
99
 
90
- //get all oi to find inventory changes and determine if the worksheet is completable
91
- const orderInventories: OrderInventory[] = await qb.getMany()
92
-
93
100
  //item assigned to obsolete inventories will not be displayed during picking
94
101
  if (filter) {
95
102
  qb.andWhere('rg.status != :orderStatus', { orderStatus: ORDER_STATUS.OBSOLETE })
@@ -174,6 +181,10 @@ export const zonePickingWorksheet = {
174
181
  }
175
182
 
176
183
  function isCompletable(oi: OrderInventory[], ic: InventoryChange[]): String {
184
+ // NOTE: callers may pass a partial OrderInventory with only id/inventoryId/
185
+ // releaseGoodId/status populated (see the lightweight pre-pass in
186
+ // zonePickingWorksheet). Don't reference other fields here without first
187
+ // widening that SELECT.
177
188
  //find processing oi and check if there is any pending inventory adjustment
178
189
  let processingOi = oi.filter(item => item.status === ORDER_INVENTORY_STATUS.PROCESSING)
179
190
 
@@ -15,7 +15,11 @@ export const Mutation = `
15
15
  assignSorter(releaseGoodId: [String]!, userId: String): Boolean @transaction
16
16
  completeZonePicking(worksheetId: String!): Boolean @transaction
17
17
  completeZonePickingPartially(worksheetId: String!): Boolean @transaction
18
- getZonePickingTask: ZonePickingWorksheet @privilege(category: "worksheet_control", privilege: "mutation") @transaction
18
+ # Intentionally NOT @transaction the resolver opens its own
19
+ # getConnection().transaction() and uses an independent inner transaction
20
+ # to commit the worksheet-claim UPDATE early (releases the row lock so
21
+ # SKIP LOCKED works for concurrent clicks). See get-zone-picking-task.ts.
22
+ getZonePickingTask: ZonePickingWorksheet @privilege(category: "worksheet_control", privilege: "mutation")
19
23
  `
20
24
 
21
25
  export const Types = [ZoneWorksheetOverview, ZoneWorksheetOverviewList, ZonePickingWorksheet]