@things-factory/worksheet-base 5.0.0-alpha.8 → 5.0.0-alpha.9

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 (63) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +235 -0
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/loading-worksheet-controller.js +10 -0
  4. package/dist-server/controllers/outbound/loading-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/packing-worksheet-controller.js +7 -0
  6. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/outbound/picking-worksheet-controller.js +327 -11
  8. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  9. package/dist-server/controllers/outbound/returning-worksheet-controller.js +4 -0
  10. package/dist-server/controllers/outbound/returning-worksheet-controller.js.map +1 -1
  11. package/dist-server/controllers/render-invoices.js +103 -65
  12. package/dist-server/controllers/render-invoices.js.map +1 -1
  13. package/dist-server/controllers/worksheet-controller.js +14 -0
  14. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +16 -2
  16. package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +2 -1
  18. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
  19. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +0 -17
  20. package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
  21. package/dist-server/graphql/resolvers/worksheet/picking/index.js +2 -1
  22. package/dist-server/graphql/resolvers/worksheet/picking/index.js.map +1 -1
  23. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js +15 -0
  24. package/dist-server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.js.map +1 -0
  25. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js +3 -2
  26. package/dist-server/graphql/resolvers/worksheet/unloaded-inventories.js.map +1 -1
  27. package/dist-server/graphql/resolvers/worksheet/unloading/index.js +3 -1
  28. package/dist-server/graphql/resolvers/worksheet/unloading/index.js.map +1 -1
  29. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js +15 -0
  30. package/dist-server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.js.map +1 -0
  31. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js +15 -0
  32. package/dist-server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.js.map +1 -0
  33. package/dist-server/graphql/resolvers/worksheet/unloading/unload.js.map +1 -1
  34. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js +3 -1
  35. package/dist-server/graphql/resolvers/worksheet/unloading-worksheet.js.map +1 -1
  36. package/dist-server/graphql/types/worksheet/index.js +16 -0
  37. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  38. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +1 -0
  39. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
  40. package/dist-server/graphql/types/worksheet/worksheet-info.js +1 -0
  41. package/dist-server/graphql/types/worksheet/worksheet-info.js.map +1 -1
  42. package/package.json +17 -17
  43. package/server/controllers/inbound/unloading-worksheet-controller.ts +277 -1
  44. package/server/controllers/outbound/loading-worksheet-controller.ts +13 -0
  45. package/server/controllers/outbound/packing-worksheet-controller.ts +9 -0
  46. package/server/controllers/outbound/picking-worksheet-controller.ts +434 -17
  47. package/server/controllers/outbound/returning-worksheet-controller.ts +5 -0
  48. package/server/controllers/render-invoices.ts +119 -72
  49. package/server/controllers/worksheet-controller.ts +17 -2
  50. package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +25 -6
  51. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +3 -3
  52. package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +0 -18
  53. package/server/graphql/resolvers/worksheet/picking/index.ts +3 -1
  54. package/server/graphql/resolvers/worksheet/picking/undo-serial-number-picking.ts +24 -0
  55. package/server/graphql/resolvers/worksheet/unloaded-inventories.ts +6 -2
  56. package/server/graphql/resolvers/worksheet/unloading/index.ts +4 -0
  57. package/server/graphql/resolvers/worksheet/unloading/scan-serial-number-unload.ts +26 -0
  58. package/server/graphql/resolvers/worksheet/unloading/undo-serial-number-unload.ts +24 -0
  59. package/server/graphql/resolvers/worksheet/unloading/unload.ts +3 -1
  60. package/server/graphql/resolvers/worksheet/unloading-worksheet.ts +3 -1
  61. package/server/graphql/types/worksheet/index.ts +16 -0
  62. package/server/graphql/types/worksheet/worksheet-detail-info.ts +1 -0
  63. package/server/graphql/types/worksheet/worksheet-info.ts +1 -0
@@ -1,11 +1,11 @@
1
1
  import FormData from 'form-data'
2
2
  import fetch from 'node-fetch'
3
- import { getRepository } from 'typeorm'
3
+ import { getRepository, SelectQueryBuilder } from 'typeorm'
4
4
 
5
5
  import { Attachment, STORAGE } from '@things-factory/attachment-base'
6
6
  import { Bizplace } from '@things-factory/biz-base'
7
7
  import { config } from '@things-factory/env'
8
- import { Invoice, ReleaseGood } from '@things-factory/sales-base'
8
+ import { InvoiceProduct, ReleaseGood } from '@things-factory/sales-base'
9
9
  import { Domain } from '@things-factory/shell'
10
10
 
11
11
  import { TEMPLATE_TYPE } from '../constants'
@@ -22,20 +22,34 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
22
22
  let result = await Promise.all(
23
23
  req.roIds.map(async roId => {
24
24
  try {
25
- const foundReleaseGoods: ReleaseGood = await getRepository(ReleaseGood).findOne({
26
- where: { domain, id: roId },
27
- relations: ['domain', 'bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
28
- })
29
-
30
- if (foundReleaseGoods) {
31
- const foundInvoice: Invoice = await getRepository(Invoice).findOne({
32
- where: { releaseGood: foundReleaseGoods },
33
- relations: ['invoiceProducts', 'invoiceProducts.product', 'domain', 'creator', 'updater']
34
- })
35
-
36
- const partnerBiz: Bizplace = foundReleaseGoods.bizplace
25
+ const qb: SelectQueryBuilder<ReleaseGood> = await getRepository(ReleaseGood)
26
+ .createQueryBuilder('rg')
27
+ .innerJoinAndSelect('rg.domain', 'domain')
28
+ .innerJoinAndSelect('rg.bizplace', 'bizplace')
29
+ .innerJoinAndSelect('bizplace.domain', 'bizplace_domain')
30
+ .innerJoinAndSelect('bizplace.company', 'company')
31
+ .innerJoinAndSelect('company.domain', 'company_domain')
32
+ .innerJoinAndSelect('invoices', 'iv', 'rg.ref_no = iv.ref_no_1')
33
+ .leftJoinAndSelect('marketplace_orders', 'mo', 'rg.id = mo.release_order_id::uuid')
34
+ .leftJoinAndSelect('marketplace_order_shippings', 'mos', 'rg.id = mos.release_order_id::uuid')
35
+ .leftJoinAndSelect('mo.fulfillmentCenter', 'fc')
36
+ .where('rg.id = :roId')
37
+ .andWhere('rg.domain = :domainId')
38
+ .setParameters({ roId, domainId: domain.id })
39
+
40
+ let record: any = await qb.getRawOne()
41
+
42
+ if (record) {
43
+ const partnerBiz: Partial<Bizplace> = {
44
+ id: record.bizplace_id,
45
+ name: record.bizplace_name,
46
+ address: record.bizplace_address
47
+ }
37
48
 
38
- const partnerCompanyDomain: Domain = foundReleaseGoods.bizplace.company.domain
49
+ const partnerCompanyDomain: Partial<Domain> = {
50
+ id: record.company_domain_id,
51
+ name: record.company_domain_name
52
+ }
39
53
 
40
54
  const foundTemplate: Attachment = await getRepository(Attachment).findOne({
41
55
  where: { domain: partnerCompanyDomain, category: TEMPLATE_TYPE.INVOICE_TEMPLATE }
@@ -44,43 +58,74 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
44
58
  const template = await STORAGE.readFile(foundTemplate.path, 'utf-8')
45
59
 
46
60
  let fullBillingAddress = [
47
- foundInvoice.billingAddress1,
48
- foundInvoice.billingAddress2,
49
- foundInvoice.billingAddress3,
50
- foundInvoice.billingAddress4,
51
- foundInvoice.billingAddress5
61
+ record.iv_billing_address_1,
62
+ record.iv_billing_address_2,
63
+ record.iv_billing_address_3,
64
+ record.iv_billing_address_4,
65
+ record.iv_billing_address_5
52
66
  ]
53
67
 
54
68
  let fullDeliveryAddress = [
55
- foundInvoice.deliveryAddress1,
56
- foundInvoice.deliveryAddress2,
57
- foundInvoice.deliveryAddress3,
58
- foundInvoice.deliveryAddress4,
59
- foundInvoice.deliveryAddress5
69
+ record.iv_delivery_address_1,
70
+ record.iv_delivery_address_2,
71
+ record.iv_delivery_address_3,
72
+ record.iv_delivery_address_4,
73
+ record.iv_delivery_address_5
60
74
  ]
61
75
 
62
- let date = DateTimeConverter.date(
63
- new Date((foundInvoice.issuedOn || foundInvoice.createdAt) - timezoneOffSet)
76
+ const qb: SelectQueryBuilder<InvoiceProduct> = await getRepository(InvoiceProduct)
77
+ .createQueryBuilder('ip')
78
+ .innerJoin('invoices', 'iv', 'iv.id = ip.invoice_id')
79
+ .leftJoin('release_goods', 'rg', 'rg.ref_no = iv.ref_no_1')
80
+ .where('rg.id = :roId')
81
+ .andWhere('rg.domain = :domainId')
82
+ .setParameters({ roId, domainId: domain.id })
83
+
84
+ let items: any[] = await qb.getRawMany()
85
+
86
+ const product_list = items.map((item, idx) => {
87
+ return {
88
+ list_no: idx + 1,
89
+ product_sku: item.ip_sku,
90
+ product_name: item.ip_name,
91
+ product_desc: item.ip_description,
92
+ product_qty: item.ip_qty,
93
+ product_other_charges: item.ip_other_charges,
94
+ product_paid_price: getRoundedValue(item.ip_paid_price || item.ip_unit_price),
95
+ product_unit_price: getRoundedValue(item.ip_unit_price),
96
+ product_total_paid_price: getRoundedValue(
97
+ (item.ip_paid_price || item.ip_unit_price) * parseInt(item.ip_qty || 0)
98
+ ),
99
+ product_total_unit_price: getRoundedValue(item.ip_unit_price * parseInt(item.ip_qty || 0)),
100
+ original_price: getRoundedValue(parseFloat(item.ip_unit_price || 0)),
101
+ product_discount: getRoundedValue(parseFloat(item.ip_discount || 0)),
102
+ shipping_fee_paid_by_customer: getRoundedValue(parseFloat(item.ip_shipping_fee_paid_by_customer || 0))
103
+ }
104
+ })
105
+
106
+ const sumProductTotalPaidPrice: number = product_list.reduce(
107
+ (total, item) => total + item.product_total_paid_price,
108
+ 0
64
109
  )
110
+
111
+ let date = DateTimeConverter.date(new Date((record.iv_issued_on || record.iv_created_at) - timezoneOffSet))
65
112
  const data = {
66
- order_no: foundReleaseGoods.name,
67
- ref_no: foundReleaseGoods.refNo,
68
- deliver_to: foundInvoice.deliverTo,
69
- deliver_to_phone: foundInvoice.deliverToPhone || '',
70
- bill_to: foundInvoice.billTo,
71
- bill_to_phone: foundInvoice.billToPhone || '',
113
+ order_no: record.rg_name,
114
+ ref_no: record.rg_ref_no,
115
+ from: record.iv_from,
72
116
  customer_address: partnerBiz.address,
73
- delivery_date: date,
74
- store_name: foundInvoice.from,
75
- billing_address_1: foundInvoice.billingAddress1,
76
- billing_address_2: foundInvoice.billingAddress2,
77
- billing_address_3: foundInvoice.billingAddress3,
78
- billing_address_4: foundInvoice.billingAddress4,
79
- billing_address_5: foundInvoice.billingAddress5,
80
- billing_postcode: foundInvoice.billingPostcode,
81
- billing_city: foundInvoice.billingCity,
82
- billing_state: foundInvoice.billingState,
83
- billing_country: foundInvoice.billingCountry,
117
+ store_name: record.iv_from,
118
+ bill_to: record.iv_bill_to,
119
+ bill_to_phone: record.iv_bill_to_phone,
120
+ billing_address_1: record.iv_billing_address_1,
121
+ billing_address_2: record.iv_billing_address_2,
122
+ billing_address_3: record.iv_billing_address_3,
123
+ billing_address_4: record.iv_billing_address_4,
124
+ billing_address_5: record.iv_billing_address_5,
125
+ billing_postcode: record.iv_billing_postcode,
126
+ billing_city: record.iv_billing_city,
127
+ billing_state: record.iv_billing_state,
128
+ billing_country: record.iv_billing_country,
84
129
  full_billing_address: fullBillingAddress
85
130
  .reduce((acc, itm) => {
86
131
  if (itm && itm.trim() != '') {
@@ -90,15 +135,18 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
90
135
  return acc
91
136
  }, [])
92
137
  .join(' '),
93
- delivery_address_1: foundInvoice.deliveryAddress1,
94
- delivery_address_2: foundInvoice.deliveryAddress2,
95
- delivery_address_3: foundInvoice.deliveryAddress3,
96
- delivery_address_4: foundInvoice.deliveryAddress4,
97
- delivery_address_5: foundInvoice.deliveryAddress5,
98
- delivery_postcode: foundInvoice.deliveryPostcode,
99
- delivery_city: foundInvoice.deliveryCity,
100
- delivery_state: foundInvoice.deliveryState,
101
- delivery_country: foundInvoice.deliveryCountry,
138
+ delivery_date: date,
139
+ deliver_to: record.iv_deliver_to,
140
+ deliver_to_phone: record.iv_deliver_to_phone,
141
+ delivery_address_1: record.iv_delivery_address_1,
142
+ delivery_address_2: record.iv_delivery_address_2,
143
+ delivery_address_3: record.iv_delivery_address_3,
144
+ delivery_address_4: record.iv_delivery_address_4,
145
+ delivery_address_5: record.iv_delivery_address_5,
146
+ delivery_postcode: record.iv_delivery_postcode,
147
+ delivery_city: record.iv_delivery_city,
148
+ delivery_state: record.iv_delivery_state,
149
+ delivery_country: record.iv_delivery_country,
102
150
  full_delivery_address: fullDeliveryAddress
103
151
  .reduce((acc, itm) => {
104
152
  if (itm && itm.trim() != '') {
@@ -108,22 +156,16 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
108
156
  return acc
109
157
  }, [])
110
158
  .join(' '),
111
- product_list: foundInvoice.invoiceProducts.map((item, idx) => {
112
- return {
113
- list_no: idx + 1,
114
- product_sku: item.sku,
115
- product_name: item.name,
116
- product_desc: item.description,
117
- product_qty: item.qty,
118
- product_other_charges: item.otherCharges,
119
- product_paid_price: parseFloat(item.paidPrice || item.unitPrice).toFixed(2),
120
- product_unit_price: parseFloat(item.unitPrice).toFixed(2),
121
- product_total_paid_price: (
122
- parseFloat(item.paidPrice || item.unitPrice) * parseFloat(item.qty)
123
- ).toFixed(2),
124
- product_total_unit_price: (parseFloat(item.unitPrice) * parseFloat(item.qty)).toFixed(2)
125
- }
126
- })
159
+ fulfillment_center: record.fc_name,
160
+ voucher_amount: getRoundedValue(parseFloat(record.mo_voucher_amount || 0)),
161
+ actual_shipping_fee: getRoundedValue(parseFloat(record.mos_actual_shipping_fee || 0)),
162
+ sub_total: sumProductTotalPaidPrice,
163
+ grand_total: getRoundedValue(
164
+ sumProductTotalPaidPrice -
165
+ parseFloat(record.mo_voucher_amount || 0) +
166
+ parseFloat(record.mos_actual_shipping_fee || 0)
167
+ ),
168
+ product_list
127
169
  }
128
170
 
129
171
  const formData = new FormData()
@@ -137,18 +179,23 @@ export async function renderInvoices({ req, timezoneOffSet }, context: any) {
137
179
 
138
180
  return await response.text()
139
181
  }
140
- return ''
182
+ return null
141
183
  } catch (ex) {
142
- return ''
184
+ return null
143
185
  }
144
186
  })
145
187
  )
146
188
 
147
- if (result.length <= 0) {
189
+ if (result.filter(x => x != null).length <= 0) {
148
190
  throw Error('No invoice found!')
149
191
  }
192
+
150
193
  return result.join()
151
194
  } catch (ex) {
152
195
  throw ex
153
196
  }
154
197
  }
198
+
199
+ function getRoundedValue(value = 0) {
200
+ return Math.round((value + Number.EPSILON) * 100) / 100
201
+ }
@@ -3,7 +3,7 @@ import { EntityManager, EntitySchema, Equal, FindOneOptions, In, Not } from 'typ
3
3
  import { Role, User } from '@things-factory/auth-base'
4
4
  import { Bizplace, getDomainUsers } from '@things-factory/biz-base'
5
5
  import { sendNotification } from '@things-factory/notification'
6
- import { ProductDetail } from '@things-factory/product-base'
6
+ import { Product, ProductDetail } from '@things-factory/product-base'
7
7
  import {
8
8
  ArrivalNotice,
9
9
  DeliveryOrder,
@@ -19,7 +19,7 @@ import {
19
19
  VasOrder
20
20
  } from '@things-factory/sales-base'
21
21
  import { Domain } from '@things-factory/shell'
22
- import { Inventory, INVENTORY_STATUS, Pallet } from '@things-factory/warehouse-base'
22
+ import { Inventory, INVENTORY_STATUS, InventoryItem, Pallet } from '@things-factory/warehouse-base'
23
23
 
24
24
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../constants'
25
25
  import { Worksheet, WorksheetDetail } from '../entities'
@@ -941,6 +941,21 @@ export class WorksheetController {
941
941
  if (duplicatedCartonCnt) throw new Error(this.ERROR_MSG.VALIDITY.DUPLICATED('Carton ID', cartonId))
942
942
  }
943
943
 
944
+ /**
945
+ * @summary Check whether passed serial number is existing already
946
+ * @description It will try to count inventories which has same domain and same serial number and and not terminated one
947
+ * If there's positive result it will throw an error cause serial number is duplicated
948
+ */
949
+ async checkSerialNumberDuplication(serialNumber: string, product: Product): Promise<void> {
950
+ const duplicatedSerialNumberCnt: number = await this.trxMgr.getRepository(InventoryItem).count({
951
+ domain: this.domain,
952
+ product,
953
+ serialNumber
954
+ })
955
+
956
+ if (duplicatedSerialNumberCnt) throw new Error(this.ERROR_MSG.VALIDITY.DUPLICATED('Serial Number', serialNumber))
957
+ }
958
+
944
959
  /**
945
960
  * @summary Check for product child qty at any scanned level
946
961
  * @description It will check every level of product detail by comparing scanned level and GAN registered level.
@@ -5,6 +5,7 @@ import { EntityManager } from 'typeorm'
5
5
  import { WORKSHEET_TYPE } from '../../../../constants'
6
6
  import { LoadingWorksheetController, ReturningWorksheetController } from '../../../../controllers'
7
7
  import { Worksheet, WorksheetDetail } from '../../../../entities'
8
+ import { Sftp, SftpAPI } from '@things-factory/integration-sftp'
8
9
 
9
10
  export const completeLoadingResolver = {
10
11
  async completeLoading(_: any, { releaseGoodNo }, context: any) {
@@ -20,14 +21,19 @@ export async function completeLoading(
20
21
  releaseGoodNo: string
21
22
  ): Promise<void> {
22
23
  const worksheetController: LoadingWorksheetController = new LoadingWorksheetController(tx, domain, user)
23
- const releaseGood: ReleaseGood = await worksheetController.findRefOrder(ReleaseGood, {
24
- domain,
25
- name: releaseGoodNo,
26
- status: ORDER_STATUS.LOADING
27
- })
24
+ const releaseGood: ReleaseGood = await worksheetController.findRefOrder(
25
+ ReleaseGood,
26
+ {
27
+ domain,
28
+ name: releaseGoodNo,
29
+ status: ORDER_STATUS.LOADING
30
+ },
31
+ ['bizplace', 'bizplace.domain']
32
+ )
28
33
  const worksheet: Worksheet = await worksheetController.findWorksheetByRefOrder(releaseGood, WORKSHEET_TYPE.LOADING, [
29
34
  'worksheetDetails',
30
- 'worksheetDetails.targetInventory'
35
+ 'worksheetDetails.targetInventory',
36
+ 'worksheetDetails.targetInventory.product'
31
37
  ])
32
38
  const worksheetDetails: WorksheetDetail[] = worksheet.worksheetDetails
33
39
  const targetInventories: OrderInventory[] = worksheetDetails.map((wsd: WorksheetDetail) => wsd.targetInventory)
@@ -35,6 +41,19 @@ export async function completeLoading(
35
41
  (targetInventory: OrderInventory) => targetInventory.status === ORDER_INVENTORY_STATUS.LOADING
36
42
  )
37
43
 
44
+ const customerDomain: Domain = releaseGood.bizplace.domain
45
+ let customerAvailableSftp: Sftp = await tx.getRepository(Sftp).findOne({
46
+ where: { domain: customerDomain }
47
+ })
48
+ if (customerAvailableSftp) {
49
+ let result: Sftp = await SftpAPI.createShipment(customerAvailableSftp, {
50
+ releaseGood,
51
+ orderInventories: targetInventories,
52
+ sftp: customerAvailableSftp
53
+ })
54
+ customerAvailableSftp = await tx.getRepository(Sftp).save(result)
55
+ }
56
+
38
57
  await worksheetController.completeLoading(releaseGoodNo)
39
58
 
40
59
  if (remainInventories.length) {
@@ -11,6 +11,7 @@ import {
11
11
  import { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
12
12
  import { Domain } from '@things-factory/shell'
13
13
  import { Inventory, Location } from '@things-factory/warehouse-base'
14
+ import { ProductDetail } from '@things-factory/product-base'
14
15
 
15
16
  import { WORKSHEET_TYPE } from '../../../constants'
16
17
  import { SellercraftController } from '../../../controllers'
@@ -70,6 +71,7 @@ export const packingWorksheetResolver = {
70
71
  'worksheetDetails.targetInventory.inventory',
71
72
  'worksheetDetails.targetInventory.inventory.location',
72
73
  'worksheetDetails.targetInventory.inventory.product',
74
+ 'worksheetDetails.targetInventory.inventory.product.productDetails',
73
75
  'worksheetDetails.toLocation'
74
76
  ],
75
77
  WORKSHEET_TYPE.PACKING,
@@ -97,9 +99,7 @@ export const packingWorksheetResolver = {
97
99
  trackingNo = releaseGood?.trackingNo
98
100
  shippingProvider = releaseGood?.transporter
99
101
  marketplaceStatus = releaseGood?.marketplaceOrderStatus
100
- }
101
-
102
- if (!sellercraft) {
102
+ } else {
103
103
  marketplaceOrder = await tx.getRepository(MarketplaceOrder).findOne({
104
104
  where: { orderNo: releaseGood.refNo },
105
105
  relations: [
@@ -5,7 +5,6 @@ import { Bizplace, ContactPoint, getMyBizplace } from '@things-factory/biz-base'
5
5
  import { LastMileAPI, LastMileDelivery } from '@things-factory/integration-lmd'
6
6
  import { MarketplaceStore, MarketplaceTransporter } from '@things-factory/integration-marketplace'
7
7
  import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
8
- import { Sftp, SftpAPI } from '@things-factory/integration-sftp'
9
8
  import {
10
9
  MarketplaceOrder,
11
10
  MarketplaceOrderItem,
@@ -213,23 +212,6 @@ export async function completePicking(
213
212
  }
214
213
  }
215
214
 
216
- const customerDomain: Domain = releaseGood.bizplace.domain
217
- let customerAvailableSftp: Sftp = await tx.getRepository(Sftp).findOne({
218
- where: { domain: customerDomain }
219
- })
220
- if (customerAvailableSftp) {
221
- const orderInventories: OrderInventory[] = await tx.getRepository(OrderInventory).find({
222
- where: { releaseGood },
223
- relations: ['product']
224
- })
225
- let result: Sftp = await SftpAPI.createShipment(customerAvailableSftp, {
226
- releaseGood,
227
- orderInventories,
228
- sftp: customerAvailableSftp
229
- })
230
- customerAvailableSftp = await tx.getRepository(Sftp).save(result)
231
- }
232
-
233
215
  if (releaseGood.packingOption) {
234
216
  const packingWSCtrl: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
235
217
 
@@ -10,6 +10,7 @@ import { pickingResolver } from './picking'
10
10
  import { scanProductPickingResolver } from './scan-product-picking'
11
11
  import { scanProductBatchPickingResolver } from './scan-product-batch-picking'
12
12
  import { undoPickingAssigmentResolver } from './undo-picking-assignment'
13
+ import { undoSerialNumberPickingResolver } from './undo-serial-number-picking'
13
14
 
14
15
  export const Mutations = {
15
16
  ...assignPickingInventoriesResolver,
@@ -23,5 +24,6 @@ export const Mutations = {
23
24
  ...completePickingResolver,
24
25
  ...completeBatchPickingResolver,
25
26
  ...assignPickingWorkerResolver,
26
- ...fetchAndAssignPickingTaskResolver
27
+ ...fetchAndAssignPickingTaskResolver,
28
+ ...undoSerialNumberPickingResolver
27
29
  }
@@ -0,0 +1,24 @@
1
+ import { EntityManager } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Domain } from '@things-factory/shell'
5
+
6
+ import { PickingWorksheetController } from '../../../../controllers'
7
+
8
+ export const undoSerialNumberPickingResolver = {
9
+ async undoSerialNumberPicking(_: any, { worksheetDetailName, inventoryItemId }, context: any) {
10
+ const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
11
+ await undoSerialNumberPicking(tx, domain, user, worksheetDetailName, inventoryItemId)
12
+ }
13
+ }
14
+
15
+ async function undoSerialNumberPicking(
16
+ tx: EntityManager,
17
+ domain: Domain,
18
+ user: User,
19
+ worksheetDetailName: string,
20
+ inventoryItemId: string
21
+ ): Promise<void> {
22
+ const worksheetController: PickingWorksheetController = new PickingWorksheetController(tx, domain, user)
23
+ await worksheetController.undoSerialNumberPicking(worksheetDetailName, inventoryItemId)
24
+ }
@@ -1,7 +1,9 @@
1
+ import { getRepository, In } from 'typeorm'
2
+
1
3
  import { ArrivalNotice, Bizplace, ReturnOrder } from '@things-factory/sales-base'
2
4
  import { Domain } from '@things-factory/shell'
3
5
  import { Inventory, INVENTORY_STATUS } from '@things-factory/warehouse-base'
4
- import { getRepository, In } from 'typeorm'
6
+
5
7
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
6
8
  import { WorksheetDetail } from '../../../entities'
7
9
 
@@ -46,9 +48,11 @@ export const unloadedInventories = {
46
48
  })
47
49
  const items = foundInv.map((inv: Inventory) => {
48
50
  const expirationDate: Date = inv.expirationDate ? new Date(inv.expirationDate) : null
51
+ const manufactureDate: Date = inv.manufactureDate ? new Date(inv.manufactureDate) : null
49
52
  return {
50
53
  ...inv,
51
- expirationDate: expirationDate
54
+ expirationDate: expirationDate,
55
+ manufactureDate: manufactureDate
52
56
  }
53
57
  })
54
58
 
@@ -3,14 +3,18 @@ import { completeProductScanUnloadResolver } from './complete-product-scan-unloa
3
3
  import { completeUnloadingResolver } from './complete-unloading'
4
4
  import { completeUnloadingPartiallyResolver } from './complete-unloading-partially'
5
5
  import { scanProductUnloadResolver } from './scan-product-unload'
6
+ import { scanSerialNumberUnloadResolver } from './scan-serial-number-unload'
7
+ import { undoSerialNumberUnloadResolver } from './undo-serial-number-unload'
6
8
  import { undoUnloadingResolver } from './undo-unloading'
7
9
  import { unloadResolver } from './unload'
8
10
 
9
11
  export const Mutations = {
10
12
  ...activateUnloadingResolver,
11
13
  ...scanProductUnloadResolver,
14
+ ...scanSerialNumberUnloadResolver,
12
15
  ...unloadResolver,
13
16
  ...undoUnloadingResolver,
17
+ ...undoSerialNumberUnloadResolver,
14
18
  ...completeProductScanUnloadResolver,
15
19
  ...completeUnloadingResolver,
16
20
  ...completeUnloadingPartiallyResolver
@@ -0,0 +1,26 @@
1
+ import { EntityManager } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Domain } from '@things-factory/shell'
5
+ import { Inventory } from '@things-factory/warehouse-base'
6
+
7
+ import { UnloadingWorksheetController } from '../../../../controllers'
8
+
9
+ export const scanSerialNumberUnloadResolver = {
10
+ async scanSerialNumberUnload(_: any, { worksheetDetailName, serialNumber, inventory }, context: any) {
11
+ const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
12
+ await scanSerialNumberUnload(tx, domain, user, worksheetDetailName, serialNumber, inventory)
13
+ }
14
+ }
15
+
16
+ async function scanSerialNumberUnload(
17
+ tx: EntityManager,
18
+ domain: Domain,
19
+ user: User,
20
+ worksheetDetailName: string,
21
+ serialNumber: string,
22
+ inventory: Partial<Inventory>
23
+ ): Promise<void> {
24
+ const worksheetController: UnloadingWorksheetController = new UnloadingWorksheetController(tx, domain, user)
25
+ await worksheetController.scanSerialNumberUnload(worksheetDetailName, serialNumber, inventory)
26
+ }
@@ -0,0 +1,24 @@
1
+ import { EntityManager } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Domain } from '@things-factory/shell'
5
+
6
+ import { UnloadingWorksheetController } from '../../../../controllers'
7
+
8
+ export const undoSerialNumberUnloadResolver = {
9
+ async undoSerialNumberUnload(_: any, { worksheetDetailName, inventoryItemId }, context: any) {
10
+ const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
11
+ await undoSerialNumberUnload(tx, domain, user, worksheetDetailName, inventoryItemId)
12
+ }
13
+ }
14
+
15
+ async function undoSerialNumberUnload(
16
+ tx: EntityManager,
17
+ domain: Domain,
18
+ user: User,
19
+ worksheetDetailName: string,
20
+ inventoryItemId: string
21
+ ): Promise<void> {
22
+ const worksheetController: UnloadingWorksheetController = new UnloadingWorksheetController(tx, domain, user)
23
+ await worksheetController.undoSerialNumberUnload(worksheetDetailName, inventoryItemId)
24
+ }
@@ -1,7 +1,9 @@
1
+ import { EntityManager } from 'typeorm'
2
+
1
3
  import { User } from '@things-factory/auth-base'
2
4
  import { Domain } from '@things-factory/shell'
3
5
  import { Inventory } from '@things-factory/warehouse-base'
4
- import { EntityManager } from 'typeorm'
6
+
5
7
  import { UnloadingWorksheetController } from '../../../../controllers'
6
8
 
7
9
  export const unloadResolver = {
@@ -59,6 +59,7 @@ export const unloadingWorksheetResolver = {
59
59
 
60
60
  return {
61
61
  worksheetInfo: {
62
+ arrivalNotice,
62
63
  bizplaceName: customerBizplace.name,
63
64
  partnerDomainId: customerBizplace?.domain.id,
64
65
  customerCompanyDomainId: customerCompanyDomain.id,
@@ -90,7 +91,8 @@ export const unloadingWorksheetResolver = {
90
91
  actualPackQty: targetProduct.actualPackQty,
91
92
  remark: targetProduct.remark,
92
93
  issue: productWSD.issue,
93
- status: productWSD.status
94
+ status: productWSD.status,
95
+ manufactureDate: targetProduct.manufactureDate ? new Date(targetProduct.manufactureDate) : null
94
96
  }
95
97
  })
96
98
  }
@@ -168,6 +168,11 @@ export const Mutation = /* GraphQL */ `
168
168
  worksheetNo: String!
169
169
  ): Worksheet @privilege(category: "worksheet_control", privilege: "mutation") @transaction
170
170
 
171
+ undoSerialNumberPicking (
172
+ worksheetDetailName: String!
173
+ inventoryItemId: String!
174
+ ): Boolean @privilege(category: "worksheet_execute", privilege: "mutation") @transaction
175
+
171
176
  unload (
172
177
  worksheetDetailName: String!
173
178
  inventory: InventoryPatch!
@@ -185,6 +190,12 @@ export const Mutation = /* GraphQL */ `
185
190
  inventory: InventoryPatch!
186
191
  ): Boolean @privilege(category: "worksheet_execute", privilege: "mutation") @transaction
187
192
 
193
+ scanSerialNumberUnload (
194
+ worksheetDetailName: String!
195
+ serialNumber: String!
196
+ inventory: InventoryPatch!
197
+ ): Boolean @privilege(category: "worksheet_execute", privilege: "mutation") @transaction
198
+
188
199
  cycleCountAdjustment (
189
200
  cycleCountNo: String!
190
201
  ): Boolean @transaction
@@ -195,6 +206,11 @@ export const Mutation = /* GraphQL */ `
195
206
  inventoryIds: [String]!
196
207
  ): Boolean @privilege(category: "worksheet_execute", privilege: "mutation") @transaction
197
208
 
209
+ undoSerialNumberUnload (
210
+ worksheetDetailName: String!
211
+ inventoryItemId: String!
212
+ ): Boolean @privilege(category: "worksheet_execute", privilege: "mutation") @transaction
213
+
198
214
  completeUnloadingPartially (
199
215
  arrivalNoticeNo: String!
200
216
  worksheetDetail: [WorksheetDetailPatch!]
@@ -59,5 +59,6 @@ export const WorksheetDetailInfo = gql`
59
59
  releaseGood: ReleaseGood
60
60
  actualQty: Int
61
61
  actualUomValue: Float
62
+ manufactureDate: String
62
63
  }
63
64
  `
@@ -2,6 +2,7 @@ import { gql } from 'apollo-server-koa'
2
2
 
3
3
  export const WorksheetInfo = gql`
4
4
  type WorksheetInfo {
5
+ arrivalNotice: ArrivalNotice
5
6
  releaseGood: ReleaseGood
6
7
  returnOrder: ReturnOrder
7
8
  bizplaceName: String