@things-factory/operato-wms 4.3.734 → 4.3.737

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.
@@ -35,6 +35,114 @@ const toFloatOrUndefined = v => {
35
35
  return Number.isFinite(n) ? n : undefined
36
36
  }
37
37
 
38
+ // Import UI may produce human headers (e.g. "packing type") instead of GraphQL input keys (e.g. "packingType").
39
+ // GraphQL rejects unknown fields, so normalize/sanitize patches before submitting.
40
+ const INVENTORY_PATCH_KEYS = new Set([
41
+ 'id',
42
+ 'name',
43
+ 'bizplace',
44
+ 'refInventory',
45
+ 'bizplaceName',
46
+ 'palletId',
47
+ 'cartonId',
48
+ 'batchId',
49
+ 'batchIdRef',
50
+ 'product',
51
+ 'productDetail',
52
+ 'sku',
53
+ 'brand',
54
+ 'productName',
55
+ 'productDetailName',
56
+ 'productDetailId',
57
+ 'reusablePallet',
58
+ 'reusablePalletId',
59
+ 'location',
60
+ 'locationName',
61
+ 'warehouse',
62
+ 'warehouseName',
63
+ 'packingType',
64
+ 'packingSize',
65
+ 'otherRef',
66
+ 'transactionType',
67
+ 'details',
68
+ 'zone',
69
+ 'weight',
70
+ 'uom',
71
+ 'uomValue',
72
+ 'qty',
73
+ 'status',
74
+ 'description',
75
+ 'remark',
76
+ 'expirationDate',
77
+ 'manufactureDate',
78
+ 'unitCost',
79
+ 'adjustmentCode',
80
+ 'adjustmentNote',
81
+ 'inventoryItemChangesJson',
82
+ 'serialNumbers',
83
+ 'updatedAt',
84
+ 'updater',
85
+ 'cuFlag',
86
+ 'transferQty',
87
+ 'transferUomValue',
88
+ 'obsolete'
89
+ ])
90
+
91
+ const toCamelKey = key =>
92
+ String(key)
93
+ .trim()
94
+ .replace(/[_-]+/g, ' ')
95
+ .replace(/\s+([a-zA-Z0-9])/g, (_, c) => String(c).toUpperCase())
96
+ .replace(/^\w/, c => c.toLowerCase())
97
+
98
+ const normalizeInventoryPatch = patch => {
99
+ if (!patch || typeof patch !== 'object') return patch
100
+
101
+ const headerKeyMap = {
102
+ 'packing type': 'packingType',
103
+ 'packing size': 'packingSize',
104
+ 'uom value': 'uomValue',
105
+ 'unit cost': 'unitCost',
106
+ 'batch id': 'batchId',
107
+ 'batch no': 'batchId',
108
+ 'batch no.': 'batchId',
109
+ 'batch id ref': 'batchIdRef',
110
+ 'batch no ref': 'batchIdRef',
111
+ 'batch no. ref': 'batchIdRef'
112
+ }
113
+
114
+ const normalized = {}
115
+
116
+ Object.entries(patch).forEach(([rawKey, value]) => {
117
+ const lower = String(rawKey).trim().toLowerCase()
118
+ let key = headerKeyMap[lower] || rawKey
119
+
120
+ if (!INVENTORY_PATCH_KEYS.has(key)) {
121
+ const camel = toCamelKey(rawKey)
122
+ if (INVENTORY_PATCH_KEYS.has(camel)) key = camel
123
+ }
124
+
125
+ if (!INVENTORY_PATCH_KEYS.has(key)) return
126
+
127
+ // prefer already-correct keys if both exist
128
+ if (normalized[key] === undefined) normalized[key] = value
129
+ })
130
+
131
+ // sanitize nested refs to what GraphQL expects
132
+ if (normalized.bizplace && normalized.bizplace.id) normalized.bizplace = { id: normalized.bizplace.id }
133
+ if (normalized.location && normalized.location.id) {
134
+ normalized.location = { id: normalized.location.id, name: normalized.location.name }
135
+ }
136
+ if (normalized.product && normalized.product.id) normalized.product = { id: normalized.product.id }
137
+ if (normalized.productDetail && normalized.productDetail.id)
138
+ normalized.productDetail = { id: normalized.productDetail.id }
139
+
140
+ // ScalarDate cannot parse empty string; treat blank as undefined.
141
+ if (normalized.manufactureDate === '') delete normalized.manufactureDate
142
+
143
+ return normalized
144
+ }
145
+
38
146
  class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
39
147
  static get styles() {
40
148
  return [
@@ -1161,17 +1269,19 @@ class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
1161
1269
 
1162
1270
  async importHandler(patches) {
1163
1271
  try {
1272
+ patches = patches.map(patch => normalizeInventoryPatch(patch))
1273
+
1164
1274
  patches.map(itm => {
1165
- if (itm?.uomValue < 0 || itm?.uommValue?.toString() == NaN.toString()) {
1275
+ if (toFloatOrUndefined(itm?.uomValue) < 0) {
1166
1276
  throw new Error(i18next.t('text.invalid_uom_value'))
1167
1277
  }
1168
- if (itm?.qty < 0) {
1278
+ if (toFloatOrUndefined(itm?.qty) < 0) {
1169
1279
  throw new Error(i18next.t('text.invalid_qty'))
1170
1280
  }
1171
1281
  if (itm?.packingType?.trim() == '') {
1172
1282
  throw new Error(i18next.t('text.invalid_packing_type'))
1173
1283
  }
1174
- if (itm?.unitCost < 0) {
1284
+ if (toFloatOrUndefined(itm?.unitCost) < 0) {
1175
1285
  throw new Error(i18next.t('text.invalid_unit_cost'))
1176
1286
  }
1177
1287
  if (new Date(itm?.manufactureDate) > new Date()) {
@@ -1211,9 +1321,9 @@ class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
1211
1321
  throw new Error(i18next.t('text.invalid_value_in_list'))
1212
1322
  }
1213
1323
  }
1214
- itm.qty = parseFloat(itm.qty)
1215
- itm.packingSize = parseFloat(itm.packingSize)
1216
- itm.uomValue = parseFloat(itm.uomValue)
1324
+ itm.qty = toFloatOrUndefined(itm.qty)
1325
+ itm.packingSize = toFloatOrUndefined(itm.packingSize)
1326
+ itm.uomValue = toFloatOrUndefined(itm.uomValue)
1217
1327
  itm.transferQty = toFloatOrUndefined(itm.transferQty)
1218
1328
  itm.transferUomValue = toFloatOrUndefined(itm.transferUomValue)
1219
1329
 
@@ -1221,7 +1331,7 @@ class InventoryAdjustment extends connect(store)(localize(i18next)(PageView)) {
1221
1331
  itm.unitCost = null
1222
1332
  }
1223
1333
  if (itm.unitCost != null) {
1224
- itm.unitCost = parseFloat(itm.unitCost)
1334
+ itm.unitCost = toFloatOrUndefined(itm.unitCost)
1225
1335
  if (isNaN(itm.unitCost)) {
1226
1336
  throw new Error(i18next.t('text.invalid_unit_cost'))
1227
1337
  }
@@ -118,12 +118,26 @@ class ReturnOrderInventoryPopup extends localize(i18next)(LitElement) {
118
118
  type: 'text',
119
119
  value: this.releaseOrderNo || this.releaseGoodNameInput || null,
120
120
  props: { searchOper: 'i_like' }
121
+ },
122
+ {
123
+ name: 'productSKU',
124
+ label: i18next.t('field.sku'),
125
+ type: 'text',
126
+ props: { searchOper: 'i_like' }
121
127
  }
122
128
  ]
123
129
 
124
130
  this.config = {
125
131
  list: {
126
- fields: ['releaseGoodName', 'batchId', 'productName', 'packingType', 'releaseQty', 'releaseUomValue']
132
+ fields: [
133
+ 'releaseGoodName',
134
+ 'batchId',
135
+ 'productSKU',
136
+ 'productName',
137
+ 'packingType',
138
+ 'releaseQty',
139
+ 'releaseUomValue'
140
+ ]
127
141
  },
128
142
  pagination: { pages: [10, 20, 50, 2500] },
129
143
  rows: { selectable: { multiple: true }, appendable: false },
@@ -166,6 +180,12 @@ class ReturnOrderInventoryPopup extends localize(i18next)(LitElement) {
166
180
  header: i18next.t('field.batch_id'),
167
181
  width: 120
168
182
  },
183
+ {
184
+ type: 'string',
185
+ name: 'productSKU',
186
+ header: i18next.t('field.sku'),
187
+ width: 150
188
+ },
169
189
  {
170
190
  type: 'string',
171
191
  name: 'productName',
@@ -257,6 +277,7 @@ class ReturnOrderInventoryPopup extends localize(i18next)(LitElement) {
257
277
  id
258
278
  }
259
279
  productName
280
+ productSKU
260
281
  productBrand
261
282
  packingType
262
283
  packingSize
@@ -4,118 +4,86 @@ module.exports = {
4
4
  useVirtualHostBasedDomain: false,
5
5
  fallbackRoute: '/',
6
6
  subdomainOffset: 2,
7
- port: 4000,
7
+ port: 4011,
8
8
  inspect: '9330',
9
-
10
-
11
- storage: {
12
- type: 's3',
13
- accessKeyId: 'AKIAUQEOPWEJHCE4MTH4',
14
- secretAccessKey: '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',
15
- bucketName: 'opa-one',
16
- region: 'ap-southeast-1'
17
- },
9
+ // ormconfig: {
10
+ // name: 'default',
11
+ // type: 'postgres',
12
+ // database: 'EMS',
13
+ // username: 'postgres',
14
+ // password: 'hatio',
15
+ // host: '192.168.0.161',
16
+ // port: 15432,
17
+ // synchronize: false,
18
+ // logging: true
19
+ // },
18
20
  ormconfig: {
19
21
  name: 'default',
20
22
  type: 'postgres',
21
- database: 'arif',
23
+ database: 'postgres',
22
24
  username: 'postgres',
23
- password: 'hatio',
24
- host: '10.254.29.189',
25
- port: 15432,
25
+ password: 't62dgT#Ns*GerhuZ9wnzm^',
26
+ host: 'my-operato-pg.cjcso4qmeuq0.ap-southeast-5.rds.amazonaws.com',
27
+ port: 55432,
26
28
  synchronize: false,
27
29
  logging: true
28
30
  },
29
31
  // ormconfig: {
30
32
  // name: 'default',
31
33
  // type: 'postgres',
32
- // host: 'operatov3.cluster-cijhm4n1hbst.ap-southeast-1.rds.amazonaws.com',
33
- // port: 55432,
34
- // database: 'postgres',
35
- // username: 'postgres',
36
- // password: 'abcd1234',
37
- // synchronize: false,
38
- // logging: true,
39
- // connectTimeoutMS: 30000,
40
- // extra: { poolSize: 30 }
41
- // },
42
- //db izzah
43
- // ormconfig: {
44
- // name: 'default',
45
- // type: 'postgres',
46
- // database: '06072023',
34
+ // database: 'operato',
47
35
  // username: 'postgres',
48
36
  // password: 'hatio',
49
37
  // host: '192.168.0.153',
50
- // port: 15432,f
51
- // synchronize: true,
38
+ // port: 15432,
39
+ // synchronize: false,
52
40
  // logging: true
53
41
  // },
54
42
  // ormconfig: {
55
43
  // name: 'default',
56
44
  // type: 'postgres',
57
- // database: 'postgres',
58
- // username: 'postgres',
59
- // password: 'hatio',
60
- // host: '192.168.0.151',
61
- // port: 15432,
45
+ // database: 'operato',
46
+ // username: 'operato',
47
+ // password: 'abcd1234',
48
+ // host: 'localhost',
49
+ // port: 25432,
62
50
  // synchronize: false,
63
51
  // logging: true
64
52
  // },
65
-
66
- // //ERIC
67
53
  // ormconfig: {
68
54
  // name: 'default',
69
55
  // type: 'postgres',
70
- // database: 'eric',
56
+ // database: 'operato',
71
57
  // username: 'postgres',
72
58
  // password: 'hatio',
73
- // host: '192.168.0.153',
59
+ // host: '192.168.0.151',
74
60
  // port: 15432,
75
61
  // synchronize: false,
76
62
  // logging: true
77
63
  // },
78
-
79
- //eric 2
64
+ //arif
80
65
  // ormconfig: {
81
66
  // name: 'default',
82
67
  // type: 'postgres',
83
- // database: 'eric2',
68
+ // database: 'arif',
84
69
  // username: 'postgres',
85
70
  // password: 'hatio',
86
- // host: '192.168.0.153',
71
+ // host: '10.254.29.189',
87
72
  // port: 15432,
88
73
  // synchronize: false,
89
74
  // logging: true
90
75
  // },
91
-
92
76
  // ormconfig: {
93
77
  // name: 'default',
94
78
  // type: 'postgres',
95
- // host: 'operatov3.cluster-cijhm4n1hbst.ap-southeast-1.rds.amazonaws.com',
96
- // port: 55432,
97
- // database: 'postgres',
79
+ // database: 'operato-eric',
98
80
  // username: 'postgres',
99
- // password: 'abcd1234',
81
+ // password: 'hatio',
82
+ // host: '192.168.0.249',
83
+ // port: 5432,
100
84
  // synchronize: false,
101
- // logging: true,
102
- // connectTimeoutMS: 30000,
103
- // extra: { poolSize: 30 }
85
+ // logging: true
104
86
  // },
105
- //ormconfig: {
106
- // name: 'default',
107
- // type: 'postgres',
108
- // database: 'dev2',
109
- // username: 'postgres',
110
- // password: 'hatio',
111
- // host: 'localhost',
112
- // port: 15432,
113
- // synchronize: false,
114
- // logging: true,
115
- // connectTimeoutMS: 30000,
116
- // extra: { poolSize: 30 }
117
- //},
118
- SECRET: '0xD58F835B69D207A76CC5F84a70a1D0d4C79dfC95',
119
87
  password: {
120
88
  lowerCase: true,
121
89
  upperCase: false,
@@ -128,8 +96,22 @@ module.exports = {
128
96
  looseCharacterLength: 4,
129
97
  history: 2
130
98
  },
99
+ sftpFileStorage: {
100
+ type: 's3',
101
+ accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
102
+ secretAccessKey: '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',
103
+ bucketName: 'operato-sftp'
104
+ },
105
+ // storage: {
106
+ // type: 's3',
107
+ // accessKeyId: 'AKIAUQEOPWEJCDH6AR5H',
108
+ // secretAccessKey: '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',
109
+ // bucketName: 'opa-one',
110
+ // region: 'ap-southeast-1'
111
+ // },
131
112
  uploads: 'uploads',
132
113
  attachmentsPath: 'attachments',
114
+ SECRET: '0xD58F835B69D207A76CC5F84a70a1D0d4C79dfC95',
133
115
  logger: {
134
116
  file: {
135
117
  filename: 'logs/application-%DATE%.log',
@@ -145,7 +127,7 @@ module.exports = {
145
127
  port: 587,
146
128
  secure: false, // true for 465, false for other ports
147
129
  auth: {
148
- user: 'no-reply@hatiolab.com', // generated ethereal user
130
+ user: 'noreply@hatiolab.com', // generated ethereal user
149
131
  pass: 'h@ti0LAB1008' // generated ethereal password
150
132
  },
151
133
  secureConnection: false,
@@ -153,7 +135,7 @@ module.exports = {
153
135
  ciphers: 'SSLv3'
154
136
  }
155
137
  },
156
- sender: 'no-reply@hatiolab.com',
138
+ sender: 'noreply@hatiolab.com',
157
139
  notification: {
158
140
  // fcm: {
159
141
  // serviceAccount: {
@@ -177,30 +159,80 @@ module.exports = {
177
159
  // privateKey: '4pmlt3Wk019u7nqU3Q_oGZE6LbUDjjf8DpmAcn9-iss'
178
160
  // }
179
161
  },
180
- // reportApiUrl:
181
- // 'http://k8s-default-operator-8eeba2e246-3e3a5ee7979bcd57.elb.ap-southeast-1.amazonaws.com/rest/report/show_html',
182
- // reportApiUrl: 'http://192.168.0.153:8888/rest/report/show_html',
183
- // reportApiUrl: 'http://192.168.0.153:8888/rest/report/show_html',
184
- // reportApiUrl: 'http://10.100.109.66:8090/rest/report/show_html',
162
+ fulfillmentIntegrationOperato: {
163
+ host: '192.168.0.161:3000',
164
+ protocol: 'http',
165
+ platform: 'operato',
166
+ application: 'Operato MMS',
167
+ appKey: 'a9bf751e622bf146662b240d58971051',
168
+ appSecret: '1c385935dc131c4b902b9bbf6a4798af',
169
+ callback: 'http://192.168.0.161:5000/callback-operato'
170
+ },
171
+ marketplaceIntegrationShopee: {
172
+ platform: 'shopee',
173
+ isUAT: false,
174
+ application: 'Operato MMS',
175
+ partnerId: 846025,
176
+ partnerKey: 'd34cfd85a603f196a0d74ebe08043280c1a27788bb36bdffd61e7e0bb1c90b64',
177
+ v2: true
178
+ },
179
+ marketplaceIntegrationLazada: {
180
+ platform: 'lazada',
181
+ application: 'operato-mms',
182
+ appKey: '120961',
183
+ appSecret: 'HB3RTNEXHlVSlBr9SmWF8AjbSUT7a825',
184
+ callback: 'https://maybank.operato-m.com/lazada-callback'
185
+ },
186
+
187
+ //testinglazada
188
+ // marketplaceIntegrationLazada: {
189
+ // platform: 'lazada',
190
+ // application: 'powrup_bi',
191
+ // appKey: '117890',
192
+ // appSecret: 'tQVllnUa7irAHoNxAwXEVxoP1we1bUjE',
193
+ // callback: 'https://73c5-175-141-30-142.ngrok-free.app/lazada-callback'
194
+ // },
195
+
196
+ accountingIntegrationXero: {
197
+ platform: 'xero',
198
+ application: 'Operato WMS',
199
+ apiKey: '6B12D1AAC05347DC92159C2AEC812859',
200
+ apiSecret: 'T139_ItMjObC82mmy7iwnNflhd2iV0kUvDBj0P_201EmA7Sj',
201
+ callback: 'http://operato-h.com:3000/callback-xero',
202
+ hostname: 'http://operato-h.com:3000/'
203
+ },
204
+ lmdIntegrationNinjavan: {
205
+ clientId: 'P8WCEwMo0FHNlPECwTLetwN3diAmt5KF',
206
+ secretKey: '1D0yNZGseOjhxnwri29xmuZiiuRp131L',
207
+ refreshThreshold: 43200
208
+ },
209
+
210
+ lmdIntegrationEms: { refreshThreshold: 43200 },
211
+
212
+ lmdIntegrationCitylink: { refreshThreshold: 172800000 },
185
213
  awbFileStorage: {
186
214
  type: 's3',
187
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
188
- secretAccessKey: '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',
215
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
216
+ secretAccessKey: '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',
189
217
  bucketName: 'operato-awb',
190
218
  region: 'ap-southeast-1'
191
219
  },
192
- invoiceFileStorage: {
193
- type: 's3',
194
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
195
- secretAccessKey: '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',
196
- invoiceBucket: 'operato-invoice',
197
- region: 'ap-southeast-1'
198
- },
199
220
  lambda: {
200
221
  region: 'ap-southeast-1',
201
- accessKeyId: 'AKIAUQEOPWEJKL43OMZA',
202
- secretAccessKey: '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'
222
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
223
+ secretAccessKey: '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'
224
+ },
225
+ lmdIntegrationConfig: {
226
+ version: {
227
+ v1: 'lmdMiddleware',
228
+ v2: 'lmdMiddlewareV2'
229
+ }
230
+ },
231
+ awsSesEmail: {
232
+ accessKeyId: 'AKIAUQEOPWEJPXIVER74',
233
+ secretAccessKey: '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',
234
+ email: 'support@hatio.asia'
203
235
  },
204
236
  reportApiUrl:
205
- 'http://k8s-default-operator-8eeba2e246-3e3a5ee7979bcd57.elb.ap-southeast-1.amazonaws.com/rest/report/show_html'
237
+ 'http://k8s-default-operator-2fd6178d98-66c66a0f76c09575.elb.ap-southeast-1.amazonaws.com/rest/report/show_html'
206
238
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-wms",
3
- "version": "4.3.734",
3
+ "version": "4.3.737",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -91,7 +91,7 @@
91
91
  "@things-factory/print-ui": "^4.3.734",
92
92
  "@things-factory/product-base": "^4.3.734",
93
93
  "@things-factory/resource-ui": "^4.3.734",
94
- "@things-factory/sales-ui": "^4.3.734",
94
+ "@things-factory/sales-ui": "^4.3.736",
95
95
  "@things-factory/scene-data-transform": "^4.3.734",
96
96
  "@things-factory/scene-excel": "^4.3.734",
97
97
  "@things-factory/scene-firebase": "^4.3.734",
@@ -108,7 +108,7 @@
108
108
  "@things-factory/transport-base": "^4.3.734",
109
109
  "@things-factory/tutorial-ui": "^4.3.734",
110
110
  "@things-factory/warehouse-base": "^4.3.734",
111
- "@things-factory/worksheet-base": "^4.3.734"
111
+ "@things-factory/worksheet-base": "^4.3.736"
112
112
  },
113
113
  "devDependencies": {
114
114
  "@things-factory/builder": "^4.3.734",
@@ -117,5 +117,5 @@
117
117
  "cypress-localstorage-commands": "^1.6.1",
118
118
  "eslint-plugin-cypress": "^2.12.1"
119
119
  },
120
- "gitHead": "c85c5a1e8ed4f0c4e7c438b6067539216d96caa9"
120
+ "gitHead": "e6f8a64149623c60ac264af2d2060bbe823e1d36"
121
121
  }