@things-factory/operato-wms 3.7.2 → 3.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/pages/components/select-product-popup.js +5 -1
- package/client/pages/constants/order.js +10 -0
- package/client/pages/inbound/putaway-product.js +162 -139
- package/client/pages/inventory-check/inspecting-product.js +146 -80
- package/client/pages/manifest/create-loading-manifest.js +314 -0
- package/client/pages/manifest/dispatcher-verification-popup.js +86 -0
- package/client/pages/manifest/loading-manifest-detail.js +345 -0
- package/client/pages/manifest/loading-manifest-list.js +305 -0
- package/client/pages/order/arrival-notice/create-arrival-notice.js +8 -1
- package/client/pages/order/goods-received-note/received-note-list.js +138 -6
- package/client/pages/order/release-order/b2b/b2b-order-list.js +45 -5
- package/client/pages/order/release-order/b2b/b2b-order-requests.js +45 -5
- package/client/pages/order/release-order/b2c/b2c-order-requests.js +181 -21
- package/client/pages/order/release-order/bulk-print-packing-list.js +23 -0
- package/client/pages/order/release-order/create-release-order.js +25 -4
- package/client/pages/order/release-order/receive-release-order-request.js +27 -24
- package/client/pages/order/release-order/release-extra-product-popup.js +189 -56
- package/client/pages/order/release-order/release-order-detail.js +292 -71
- package/client/pages/order/reverse-kitting-order/reverse-kitting-order-detail.js +115 -50
- package/client/pages/order/reverse-kitting-order/reverse-kitting-order-list.js +1 -6
- package/client/pages/order/reverse-kitting-order/reverse-kitting-pallet-label-popup.js +239 -0
- package/client/pages/order/transport-order/delivery-order-list.js +99 -59
- package/client/pages/outbound/loading-product.js +4 -1
- package/client/pages/outbound/merged-outbound-worksheet.js +39 -1
- package/client/pages/outbound/packing-product.js +4 -1
- package/client/pages/outbound/packing-worksheet-list.js +39 -1
- package/client/pages/outbound/picking-product.js +622 -290
- package/client/pages/outbound/serial-number-popup.js +280 -0
- package/client/pages/outbound/worksheet-picking.js +28 -2
- package/client/pages/report/product-label-report.js +401 -0
- package/client/pages/support/inventory-comparison.js +296 -0
- package/client/pages/vas/print-product-label.js +298 -132
- package/client/pages/vas/reverse-kitting/execute-reverse-kitting.js +30 -12
- package/client/pages/vas/reverse-kitting/popup-combination-sets.js +75 -5
- package/client/pages/vas/reverse-kitting/popup-reverse-kitting-template.js +113 -18
- package/client/route.js +23 -0
- package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +64 -54
- package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js.map +1 -1
- package/dist-server/graphql/resolvers/extra/add-release-good-products.js +34 -9
- package/dist-server/graphql/resolvers/extra/add-release-good-products.js.map +1 -1
- package/dist-server/graphql/resolvers/index.js +3 -1
- package/dist-server/graphql/resolvers/index.js.map +1 -1
- package/dist-server/graphql/resolvers/inventory-comparison/index.js +6 -0
- package/dist-server/graphql/resolvers/inventory-comparison/index.js.map +1 -0
- package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js +78 -0
- package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js.map +1 -0
- package/dist-server/graphql/resolvers/reports/index.js +2 -1
- package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/product-label-report.js +56 -0
- package/dist-server/graphql/resolvers/reports/product-label-report.js.map +1 -0
- package/dist-server/graphql/types/index.js +5 -2
- package/dist-server/graphql/types/index.js.map +1 -1
- package/dist-server/graphql/types/inventory-comparison/index.js +13 -0
- package/dist-server/graphql/types/inventory-comparison/index.js.map +1 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js +14 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js.map +1 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js +18 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js.map +1 -0
- package/dist-server/graphql/types/reports/index.js +6 -1
- package/dist-server/graphql/types/reports/index.js.map +1 -1
- package/dist-server/graphql/types/reports/product-label-report-list.js +14 -0
- package/dist-server/graphql/types/reports/product-label-report-list.js.map +1 -0
- package/dist-server/graphql/types/reports/product-label-report.js +16 -0
- package/dist-server/graphql/types/reports/product-label-report.js.map +1 -0
- package/package.json +65 -65
- package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +75 -65
- package/server/graphql/resolvers/extra/add-release-good-products.ts +57 -15
- package/server/graphql/resolvers/index.ts +3 -1
- package/server/graphql/resolvers/inventory-comparison/index.ts +5 -0
- package/server/graphql/resolvers/inventory-comparison/inventory-comparison-list.ts +99 -0
- package/server/graphql/resolvers/reports/index.ts +3 -1
- package/server/graphql/resolvers/reports/product-label-report.ts +56 -0
- package/server/graphql/types/index.ts +5 -2
- package/server/graphql/types/inventory-comparison/index.ts +11 -0
- package/server/graphql/types/inventory-comparison/inventory-comparison-list.ts +8 -0
- package/server/graphql/types/inventory-comparison/inventory-comparison.ts +12 -0
- package/server/graphql/types/reports/index.ts +6 -1
- package/server/graphql/types/reports/product-label-report-list.ts +8 -0
- package/server/graphql/types/reports/product-label-report.ts +10 -0
- package/things-factory.config.js +24 -0
- package/translations/en.json +64 -12
- package/translations/ko.json +50 -1
- package/translations/ms.json +51 -1
- package/translations/zh.json +50 -1
|
@@ -11,7 +11,7 @@ import { i18next, localize } from '@things-factory/i18n-base'
|
|
|
11
11
|
import { openPopup } from '@things-factory/layout-base'
|
|
12
12
|
import { client, CustomAlert, PageView, store, UPDATE_CONTEXT } from '@things-factory/shell'
|
|
13
13
|
import { CommonButtonStyles } from '@things-factory/styles'
|
|
14
|
-
import {
|
|
14
|
+
import { isMobileDevice } from '@things-factory/utils'
|
|
15
15
|
|
|
16
16
|
import { fetchLocationSortingRule } from '../../fetch-location-sorting-rule'
|
|
17
17
|
import { fetchSettingRule } from '../../fetch-setting-value'
|
|
@@ -233,12 +233,7 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
233
233
|
: html` <barcode-scanable-input name="palletId" custom-input></barcode-scanable-input>`}
|
|
234
234
|
|
|
235
235
|
<label>${i18next.t('label.inspected_batch_no')}</label>
|
|
236
|
-
<input
|
|
237
|
-
name="inspectedBatchNo"
|
|
238
|
-
.value="${this._hideCCColumnSetting
|
|
239
|
-
? this.selectedInventory?.inspectedBatchNo || ''
|
|
240
|
-
: this.selectedInventory?.inspectedBatchNo || this.selectedInventory?.batchId || ''}"
|
|
241
|
-
/>
|
|
236
|
+
<input name="inspectedBatchNo" .value="${this.selectedInventory?.batchId || ''}" />
|
|
242
237
|
|
|
243
238
|
<label>${i18next.t('label.inspected_qty')}</label>
|
|
244
239
|
<input
|
|
@@ -434,6 +429,7 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
434
429
|
{ type: 'gutter', gutterName: 'sequence' },
|
|
435
430
|
{ type: 'boolean', name: 'completed', header: i18next.t('button.completed'), width: 80 },
|
|
436
431
|
{ type: 'string', name: 'palletId', header: i18next.t('label.lot_id'), width: 160 },
|
|
432
|
+
{ type: 'string', name: 'batchId', header: i18next.t('label.batch_id'), width: 120 },
|
|
437
433
|
{
|
|
438
434
|
type: 'string',
|
|
439
435
|
name: 'orderInventoryStatus',
|
|
@@ -900,19 +896,34 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
900
896
|
inspectedQty = Number(inspectedQty)
|
|
901
897
|
inspectedUomValue = Number(inspectedUomValue)
|
|
902
898
|
|
|
903
|
-
const response = await client.
|
|
904
|
-
|
|
905
|
-
mutation
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
899
|
+
const response = await client.mutate({
|
|
900
|
+
mutation: gql`
|
|
901
|
+
mutation addExtraPallet(
|
|
902
|
+
$cycleCountNo: String!
|
|
903
|
+
$palletId: String!
|
|
904
|
+
$inspectedBatchNo: String!
|
|
905
|
+
$inspectedQty: Int!
|
|
906
|
+
$inspectedUomValue: Float!
|
|
907
|
+
$locationName: String!
|
|
908
|
+
) {
|
|
909
|
+
addExtraPallet(
|
|
910
|
+
cycleCountNo: $cycleCountNo
|
|
911
|
+
palletId: $palletId
|
|
912
|
+
inspectedBatchNo: $inspectedBatchNo
|
|
913
|
+
inspectedQty: $inspectedQty
|
|
914
|
+
inspectedUomValue: $inspectedUomValue
|
|
915
|
+
locationName: $locationName
|
|
916
|
+
)
|
|
914
917
|
}
|
|
915
|
-
|
|
918
|
+
`,
|
|
919
|
+
variables: {
|
|
920
|
+
cycleCountNo: this.cycleCountNo,
|
|
921
|
+
palletId,
|
|
922
|
+
inspectedBatchNo,
|
|
923
|
+
inspectedQty,
|
|
924
|
+
inspectedUomValue,
|
|
925
|
+
locationName
|
|
926
|
+
}
|
|
916
927
|
})
|
|
917
928
|
|
|
918
929
|
if (!response.errors) {
|
|
@@ -1003,10 +1014,8 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1003
1014
|
|
|
1004
1015
|
const response = await client.query({
|
|
1005
1016
|
query: gql`
|
|
1006
|
-
query {
|
|
1007
|
-
orderInventories(${
|
|
1008
|
-
filters
|
|
1009
|
-
})}) {
|
|
1017
|
+
query orderInventories($filters: [Filter]) {
|
|
1018
|
+
orderInventories(filters: $filters) {
|
|
1010
1019
|
items {
|
|
1011
1020
|
id
|
|
1012
1021
|
name
|
|
@@ -1014,7 +1023,8 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1014
1023
|
total
|
|
1015
1024
|
}
|
|
1016
1025
|
}
|
|
1017
|
-
|
|
1026
|
+
`,
|
|
1027
|
+
variables: { filters }
|
|
1018
1028
|
})
|
|
1019
1029
|
|
|
1020
1030
|
if (!response.errors) {
|
|
@@ -1044,14 +1054,13 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1044
1054
|
return
|
|
1045
1055
|
}
|
|
1046
1056
|
|
|
1047
|
-
const response = await client.
|
|
1048
|
-
|
|
1049
|
-
mutation {
|
|
1050
|
-
checkMissingPallet($
|
|
1051
|
-
worksheetDetailName: this.selectedInventory.worksheetDetailName
|
|
1052
|
-
})})
|
|
1057
|
+
const response = await client.mutate({
|
|
1058
|
+
mutation: gql`
|
|
1059
|
+
mutation checkMissingPallet($worksheetDetailName: String!) {
|
|
1060
|
+
checkMissingPallet(worksheetDetailName: $worksheetDetailName)
|
|
1053
1061
|
}
|
|
1054
|
-
|
|
1062
|
+
`,
|
|
1063
|
+
variables: { worksheetDetailName: this.selectedInventory.worksheetDetailName }
|
|
1055
1064
|
})
|
|
1056
1065
|
|
|
1057
1066
|
if (!response.errors) {
|
|
@@ -1065,7 +1074,7 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1065
1074
|
|
|
1066
1075
|
async relocatePallet() {
|
|
1067
1076
|
try {
|
|
1068
|
-
this.checkInputFormValidity()
|
|
1077
|
+
await this.checkInputFormValidity()
|
|
1069
1078
|
|
|
1070
1079
|
const result = await CustomAlert({
|
|
1071
1080
|
title: i18next.t('title.are_you_sure'),
|
|
@@ -1078,25 +1087,35 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1078
1087
|
return
|
|
1079
1088
|
}
|
|
1080
1089
|
|
|
1081
|
-
|
|
1090
|
+
const { inspectedBatchNo, inspectedQty, inspectedUomValue } = Object.fromEntries(
|
|
1082
1091
|
new FormData(this.inputForm).entries()
|
|
1083
1092
|
)
|
|
1084
|
-
inspectedQty = Number(inspectedQty)
|
|
1085
|
-
inspectedUomValue = Number(inspectedUomValue)
|
|
1086
|
-
var locationName = this.locationInput.value
|
|
1087
1093
|
|
|
1088
|
-
const response = await client.
|
|
1089
|
-
|
|
1090
|
-
mutation
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1094
|
+
const response = await client.mutate({
|
|
1095
|
+
mutation: gql`
|
|
1096
|
+
mutation relocatePallet(
|
|
1097
|
+
$worksheetDetailName: String!
|
|
1098
|
+
$inspectedBatchNo: String!
|
|
1099
|
+
$inspectedQty: Int!
|
|
1100
|
+
$inspectedUomValue: Float!
|
|
1101
|
+
$inspectedLocationName: String!
|
|
1102
|
+
) {
|
|
1103
|
+
relocatePallet(
|
|
1104
|
+
worksheetDetailName: $worksheetDetailName
|
|
1105
|
+
inspectedBatchNo: $inspectedBatchNo
|
|
1106
|
+
inspectedQty: $inspectedQty
|
|
1107
|
+
inspectedUomValue: $inspectedUomValue
|
|
1108
|
+
inspectedLocationName: $inspectedLocationName
|
|
1109
|
+
)
|
|
1098
1110
|
}
|
|
1099
|
-
|
|
1111
|
+
`,
|
|
1112
|
+
variables: {
|
|
1113
|
+
worksheetDetailName: this.selectedInventory.worksheetDetailName,
|
|
1114
|
+
inspectedBatchNo,
|
|
1115
|
+
inspectedQty: Number(inspectedQty),
|
|
1116
|
+
inspectedUomValue: Number(inspectedUomValue),
|
|
1117
|
+
inspectedLocationName: this.locationInput.value
|
|
1118
|
+
}
|
|
1100
1119
|
})
|
|
1101
1120
|
|
|
1102
1121
|
if (!response.errors) {
|
|
@@ -1119,24 +1138,34 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1119
1138
|
inspectedQty = Number(inspectedQty)
|
|
1120
1139
|
inspectedUomValue = Number(inspectedUomValue)
|
|
1121
1140
|
|
|
1122
|
-
const response = await client.
|
|
1123
|
-
|
|
1124
|
-
mutation
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1141
|
+
const response = await client.mutate({
|
|
1142
|
+
mutation: gql`
|
|
1143
|
+
mutation inspecting(
|
|
1144
|
+
$worksheetDetailName: String!
|
|
1145
|
+
$inspectedBatchNo: String!
|
|
1146
|
+
$inspectedQty: Int!
|
|
1147
|
+
$inspectedUomValue: Float!
|
|
1148
|
+
) {
|
|
1149
|
+
inspecting(
|
|
1150
|
+
worksheetDetailName: $worksheetDetailName
|
|
1151
|
+
inspectedBatchNo: $inspectedBatchNo
|
|
1152
|
+
inspectedQty: $inspectedQty
|
|
1153
|
+
inspectedUomValue: $inspectedUomValue
|
|
1154
|
+
)
|
|
1131
1155
|
}
|
|
1132
|
-
|
|
1156
|
+
`,
|
|
1157
|
+
variables: {
|
|
1158
|
+
worksheetDetailName: this.selectedInventory.worksheetDetailName,
|
|
1159
|
+
inspectedBatchNo,
|
|
1160
|
+
inspectedQty,
|
|
1161
|
+
inspectedUomValue
|
|
1162
|
+
}
|
|
1133
1163
|
})
|
|
1134
1164
|
|
|
1135
1165
|
if (!response.errors) {
|
|
1136
1166
|
await this.fetchCycleCountWorksheet()
|
|
1137
1167
|
this.renewInventoryGrist()
|
|
1138
|
-
this.
|
|
1139
|
-
this.locationInput.value = ''
|
|
1168
|
+
this.resetInput()
|
|
1140
1169
|
}
|
|
1141
1170
|
} catch (e) {
|
|
1142
1171
|
this.showToast(e)
|
|
@@ -1145,14 +1174,13 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1145
1174
|
|
|
1146
1175
|
async undoInventoryCheck() {
|
|
1147
1176
|
try {
|
|
1148
|
-
const response = await client.
|
|
1149
|
-
|
|
1150
|
-
mutation {
|
|
1151
|
-
undoInspection($
|
|
1152
|
-
worksheetDetailName: this.selectedInventory.worksheetDetailName
|
|
1153
|
-
})})
|
|
1177
|
+
const response = await client.mutate({
|
|
1178
|
+
mutation: gql`
|
|
1179
|
+
mutation undoInspection($worksheetDetailName: String!) {
|
|
1180
|
+
undoInspection(worksheetDetailName: $worksheetDetailName)
|
|
1154
1181
|
}
|
|
1155
|
-
|
|
1182
|
+
`,
|
|
1183
|
+
variables: { worksheetDetailName: this.selectedInventory.worksheetDetailName }
|
|
1156
1184
|
})
|
|
1157
1185
|
|
|
1158
1186
|
if (!response.errors) {
|
|
@@ -1182,14 +1210,13 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1182
1210
|
})
|
|
1183
1211
|
|
|
1184
1212
|
try {
|
|
1185
|
-
const response = await client.
|
|
1186
|
-
|
|
1187
|
-
mutation {
|
|
1188
|
-
completeInspection($
|
|
1189
|
-
inventoryCheckNo: this.cycleCountNo
|
|
1190
|
-
})})
|
|
1213
|
+
const response = await client.mutate({
|
|
1214
|
+
mutation: gql`
|
|
1215
|
+
mutation completeInspection($inventoryCheckNo: String!) {
|
|
1216
|
+
completeInspection(inventoryCheckNo: $inventoryCheckNo)
|
|
1191
1217
|
}
|
|
1192
|
-
|
|
1218
|
+
`,
|
|
1219
|
+
variables: { inventoryCheckNo: this.cycleCountNo }
|
|
1193
1220
|
})
|
|
1194
1221
|
|
|
1195
1222
|
if (!response.errors) {
|
|
@@ -1213,6 +1240,12 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1213
1240
|
}
|
|
1214
1241
|
}
|
|
1215
1242
|
|
|
1243
|
+
resetInput() {
|
|
1244
|
+
this.inspectedQtyInput.value = ''
|
|
1245
|
+
this.locationInput.value = ''
|
|
1246
|
+
this.inspectedUomValueInput.value = ''
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1216
1249
|
renewInventoryGrist() {
|
|
1217
1250
|
this.selectedLocation = this.selectedLocation?.id
|
|
1218
1251
|
? this.formattedLocations.find(loc => loc.id === this.selectedLocation.id)
|
|
@@ -1226,13 +1259,11 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1226
1259
|
try {
|
|
1227
1260
|
const response = await client.query({
|
|
1228
1261
|
query: gql`
|
|
1229
|
-
query {
|
|
1230
|
-
checkInventoryOwner($
|
|
1231
|
-
palletId,
|
|
1232
|
-
bizplaceName
|
|
1233
|
-
})})
|
|
1262
|
+
query checkInventoryOwner($palletId: String!, $bizplaceName: String!) {
|
|
1263
|
+
checkInventoryOwner(palletId: $palletId, bizplaceName: $bizplaceName)
|
|
1234
1264
|
}
|
|
1235
|
-
|
|
1265
|
+
`,
|
|
1266
|
+
variables: { palletId, bizplaceName }
|
|
1236
1267
|
})
|
|
1237
1268
|
|
|
1238
1269
|
if (!response.errors) {
|
|
@@ -1243,7 +1274,37 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1243
1274
|
}
|
|
1244
1275
|
}
|
|
1245
1276
|
|
|
1246
|
-
|
|
1277
|
+
async validateLocation(scannedLocation) {
|
|
1278
|
+
try {
|
|
1279
|
+
const response = await client.query({
|
|
1280
|
+
query: gql`
|
|
1281
|
+
query locations($filters: [Filter]) {
|
|
1282
|
+
locations(filters: $filters) {
|
|
1283
|
+
items {
|
|
1284
|
+
id
|
|
1285
|
+
name
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
`,
|
|
1290
|
+
variables: { filters: [{ name: 'name', operator: 'eq', value: scannedLocation }] }
|
|
1291
|
+
})
|
|
1292
|
+
|
|
1293
|
+
if (!response.errors) {
|
|
1294
|
+
const locations = response.data.locations.items || []
|
|
1295
|
+
|
|
1296
|
+
if (!locations?.length) {
|
|
1297
|
+
return false
|
|
1298
|
+
} else {
|
|
1299
|
+
return true
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
} catch (e) {
|
|
1303
|
+
this.showToast(e)
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
async checkInputFormValidity() {
|
|
1247
1308
|
let { inspectedBatchNo, inspectedQty, inspectedUomValue, location } = Object.fromEntries(
|
|
1248
1309
|
new FormData(this.inputForm).entries()
|
|
1249
1310
|
)
|
|
@@ -1285,6 +1346,11 @@ class InspectingProduct extends connect(store)(localize(i18next)(PageView)) {
|
|
|
1285
1346
|
if (!locationName) {
|
|
1286
1347
|
this.selectOnInput(this.locationInput)
|
|
1287
1348
|
throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.location') } }))
|
|
1349
|
+
} else {
|
|
1350
|
+
const locationExist = await this.validateLocation(locationName)
|
|
1351
|
+
if (!locationExist) {
|
|
1352
|
+
throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.location') } }))
|
|
1353
|
+
}
|
|
1288
1354
|
}
|
|
1289
1355
|
}
|
|
1290
1356
|
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import '@things-factory/grist-ui'
|
|
2
|
+
import '@things-factory/barcode-ui'
|
|
3
|
+
|
|
4
|
+
import gql from 'graphql-tag'
|
|
5
|
+
import { css, html } from 'lit-element'
|
|
6
|
+
|
|
7
|
+
import { MultiColumnFormStyles } from '@things-factory/form-ui'
|
|
8
|
+
import { i18next, localize } from '@things-factory/i18n-base'
|
|
9
|
+
import { client, navigate, PageView } from '@things-factory/shell'
|
|
10
|
+
import { CommonButtonStyles } from '@things-factory/styles'
|
|
11
|
+
import { isMobileDevice } from '@things-factory/utils'
|
|
12
|
+
|
|
13
|
+
class CreateLoadingManifest extends localize(i18next)(PageView) {
|
|
14
|
+
static get styles() {
|
|
15
|
+
return [
|
|
16
|
+
MultiColumnFormStyles,
|
|
17
|
+
css`
|
|
18
|
+
:host {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
overflow-x: auto;
|
|
22
|
+
}
|
|
23
|
+
.container {
|
|
24
|
+
flex: 1;
|
|
25
|
+
display: flex;
|
|
26
|
+
overflow-y: auto;
|
|
27
|
+
min-height: 50vh;
|
|
28
|
+
}
|
|
29
|
+
.grist {
|
|
30
|
+
background-color: var(--main-section-background-color);
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
flex: 1;
|
|
34
|
+
overflow-y: auto;
|
|
35
|
+
}
|
|
36
|
+
data-grist {
|
|
37
|
+
overflow-y: hidden;
|
|
38
|
+
flex: 1;
|
|
39
|
+
}
|
|
40
|
+
h2 {
|
|
41
|
+
padding: var(--subtitle-padding);
|
|
42
|
+
font: var(--subtitle-font);
|
|
43
|
+
color: var(--subtitle-text-color);
|
|
44
|
+
border-bottom: var(--subtitle-border-bottom);
|
|
45
|
+
}
|
|
46
|
+
.grist h2 {
|
|
47
|
+
margin: var(--grist-title-margin);
|
|
48
|
+
border: var(--grist-title-border);
|
|
49
|
+
font: var(--grist-title-font);
|
|
50
|
+
color: var(--secondary-color);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.grist h2 mwc-icon {
|
|
54
|
+
vertical-align: middle;
|
|
55
|
+
margin: var(--grist-title-icon-margin);
|
|
56
|
+
font-size: var(--grist-title-icon-size);
|
|
57
|
+
color: var(--grist-title-icon-color);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
h2 + data-grist {
|
|
61
|
+
padding-top: var(--grist-title-with-grid-padding);
|
|
62
|
+
}
|
|
63
|
+
`
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static get properties() {
|
|
68
|
+
return {
|
|
69
|
+
shippingData: Object,
|
|
70
|
+
shippingGristConfig: Object
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get context() {
|
|
75
|
+
return {
|
|
76
|
+
title: i18next.t('title.manifest'),
|
|
77
|
+
actions: [
|
|
78
|
+
{
|
|
79
|
+
title: i18next.t('button.submit'),
|
|
80
|
+
action: this._generateLoadingManifest.bind(this),
|
|
81
|
+
...CommonButtonStyles.submit
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
render() {
|
|
88
|
+
return html`
|
|
89
|
+
<form name="manifest" class="multi-column-form" autocomplete="off">
|
|
90
|
+
<fieldset>
|
|
91
|
+
<legend>${i18next.t('title.create_loading_manifest')}</legend>
|
|
92
|
+
<label>${i18next.t('label.scan_tracking_no')}</label>
|
|
93
|
+
<barcode-scanable-input
|
|
94
|
+
name="trackingNo"
|
|
95
|
+
custom-input
|
|
96
|
+
@keypress="${e => {
|
|
97
|
+
if (e.keyCode === 13) {
|
|
98
|
+
e.preventDefault()
|
|
99
|
+
if (this.trackingNoInput.value) {
|
|
100
|
+
this._fetchManifestItems(this.trackingNoInput.value)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}}"
|
|
104
|
+
></barcode-scanable-input>
|
|
105
|
+
</fieldset>
|
|
106
|
+
</form>
|
|
107
|
+
|
|
108
|
+
<div class="container">
|
|
109
|
+
<div class="grist">
|
|
110
|
+
<h2><mwc-icon>list_alt</mwc-icon>${i18next.t('title.manifest_items')}</h2>
|
|
111
|
+
|
|
112
|
+
<data-grist
|
|
113
|
+
.mode=${isMobileDevice() ? 'LIST' : 'GRID'}
|
|
114
|
+
.config=${this.shippingGristConfig}
|
|
115
|
+
.data=${this.shippingData}
|
|
116
|
+
></data-grist>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
constructor() {
|
|
123
|
+
super()
|
|
124
|
+
this.shippingData = { records: [] }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get shippingGrist() {
|
|
128
|
+
return this.shadowRoot.querySelector('data-grist')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
get manifestForm() {
|
|
132
|
+
return this.shadowRoot.querySelector('form[name=manifest]')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
get trackingNoInput() {
|
|
136
|
+
return this.shadowRoot.querySelector('barcode-scanable-input[name=trackingNo]')?.shadowRoot.querySelector('input')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
pageUpdated(changes, lifecycle, before) {
|
|
140
|
+
if (this.active) {
|
|
141
|
+
this._focusOnTrackingNoInput()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
pageInitialized() {
|
|
146
|
+
this.shippingGristConfig = {
|
|
147
|
+
list: { fields: ['refNo', 'trackingNo', 'transporter'] },
|
|
148
|
+
pagination: { infinite: true },
|
|
149
|
+
columns: [
|
|
150
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
151
|
+
{
|
|
152
|
+
type: 'gutter',
|
|
153
|
+
gutterName: 'button',
|
|
154
|
+
icon: 'close',
|
|
155
|
+
handlers: {
|
|
156
|
+
click: (columns, data, column, record, rowIndex) => {
|
|
157
|
+
const newData = data.records.filter((_, idx) => idx !== rowIndex)
|
|
158
|
+
this.shippingData = { ...this.shippingData, records: newData }
|
|
159
|
+
this.shippingGrist.dirtyData.records = newData
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: 'string',
|
|
165
|
+
name: 'refNo',
|
|
166
|
+
label: true,
|
|
167
|
+
header: i18next.t('field.order_no'),
|
|
168
|
+
width: 200
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'string',
|
|
172
|
+
name: 'trackingNo',
|
|
173
|
+
label: true,
|
|
174
|
+
header: i18next.t('field.tracking_no'),
|
|
175
|
+
width: 200
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: 'string',
|
|
179
|
+
name: 'transporter',
|
|
180
|
+
label: true,
|
|
181
|
+
header: i18next.t('field.shipping_provider'),
|
|
182
|
+
width: 200
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async _fetchManifestItems() {
|
|
189
|
+
try {
|
|
190
|
+
this._validateTrackingNo()
|
|
191
|
+
|
|
192
|
+
const filters = [
|
|
193
|
+
{ name: 'trackingNo', operator: 'eq', value: this.trackingNoInput.value.trim() },
|
|
194
|
+
{ name: 'manifest_id', operator: 'is_null', value: '' },
|
|
195
|
+
{ name: 'status', operator: 'in', value: ['PACKING', 'DONE'] }
|
|
196
|
+
]
|
|
197
|
+
const response = await client.query({
|
|
198
|
+
query: gql`
|
|
199
|
+
query releaseGoods($filters: [Filter], $sortings: [Sorting]) {
|
|
200
|
+
releaseGoods(filters: $filters, sortings: $sortings) {
|
|
201
|
+
items {
|
|
202
|
+
id
|
|
203
|
+
name
|
|
204
|
+
trackingNo
|
|
205
|
+
refNo
|
|
206
|
+
transporter
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
`,
|
|
211
|
+
variables: { filters, sortings: [] }
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
if (!response.errors) {
|
|
215
|
+
const releaseGood = (response.data.releaseGoods.items || []).map(record => {
|
|
216
|
+
return {
|
|
217
|
+
...record,
|
|
218
|
+
orderNo: record?.refNo
|
|
219
|
+
}
|
|
220
|
+
})[0]
|
|
221
|
+
|
|
222
|
+
if (releaseGood && !this.shippingData.records.map(record => record.refNo).includes(releaseGood.refNo)) {
|
|
223
|
+
let manifestItems = this.shippingData.records || []
|
|
224
|
+
manifestItems.push({ ...releaseGood })
|
|
225
|
+
this.shippingData = { records: manifestItems }
|
|
226
|
+
} else {
|
|
227
|
+
this._showToast({ message: i18next.t('text.tracking_no_already_exist_in_manifest_list') })
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
this._clearTrackingNoInput()
|
|
231
|
+
}
|
|
232
|
+
} catch (e) {
|
|
233
|
+
this._showToast(e)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async _generateLoadingManifest() {
|
|
238
|
+
try {
|
|
239
|
+
this._validateManifestSubmission()
|
|
240
|
+
|
|
241
|
+
let manifest = {}
|
|
242
|
+
manifest.manifestItems = await this._getManifestItems()
|
|
243
|
+
|
|
244
|
+
const response = await client.mutate({
|
|
245
|
+
mutation: gql`
|
|
246
|
+
mutation generateManifest($manifest: NewManifest!) {
|
|
247
|
+
generateManifest(manifest: $manifest)
|
|
248
|
+
}
|
|
249
|
+
`,
|
|
250
|
+
variables: { manifest }
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
if (!response.errors) {
|
|
254
|
+
this._showToast({ message: i18next.t('text.manifest_has_been_generated') })
|
|
255
|
+
this._clearPage()
|
|
256
|
+
navigate('loading_manifest_list')
|
|
257
|
+
}
|
|
258
|
+
} catch (e) {
|
|
259
|
+
this._showToast(e)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
_focusOnTrackingNoInput() {
|
|
264
|
+
setTimeout(() => this.trackingNoInput.focus(), 50)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
_getManifestItems() {
|
|
268
|
+
return this.shippingGrist.data.records.map(record => {
|
|
269
|
+
return {
|
|
270
|
+
refNo: record.refNo,
|
|
271
|
+
trackingNo: record.trackingNo,
|
|
272
|
+
transporter: record.transporter
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
_validateManifestSubmission() {
|
|
278
|
+
if (!this.shippingGrist.data.records?.length) {
|
|
279
|
+
this._focusOnTrackingNoInput()
|
|
280
|
+
throw new Error(i18next.t('text.manifest_items_is_empty'))
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
_validateTrackingNo() {
|
|
285
|
+
if (!this.trackingNoInput?.value) {
|
|
286
|
+
this._focusOnTrackingNoInput()
|
|
287
|
+
throw new Error(i18next.t('text.tracking_no_is_empty'))
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
_clearTrackingNoInput() {
|
|
292
|
+
this.trackingNoInput.value = ''
|
|
293
|
+
this._focusOnTrackingNoInput()
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
_clearPage() {
|
|
297
|
+
this._clearTrackingNoInput()
|
|
298
|
+
this.shippingData = { ...this.shippingData, records: [] }
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
_showToast({ type, message }) {
|
|
302
|
+
document.dispatchEvent(
|
|
303
|
+
new CustomEvent('notify', {
|
|
304
|
+
detail: {
|
|
305
|
+
type,
|
|
306
|
+
message,
|
|
307
|
+
option: { timer: 1000 }
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
customElements.define('create-loading-manifest', CreateLoadingManifest)
|