@things-factory/worksheet-base 8.0.94 → 8.0.97

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.
@@ -33,18 +33,23 @@ async function generateInventoryHistory(inventory, refOrder, transactionType, qt
33
33
  }
34
34
  const domain = inventory.domain;
35
35
  const location = inventory.location;
36
- const seq = await invHistoryRepo.countBy({
37
- domain: { id: inventory.domain.id },
38
- palletId: inventory.palletId
36
+ // 동시성 제어 - 트랜잭션 내에서 해당 재고 행을 FOR UPDATE로 잠가, 동시 실행이 같은 seq 읽어 중복 기록하는 것을 막는다.
37
+ if (trxMgr) {
38
+ await invRepo.findOne({ where: { id: inventory.id }, lock: { mode: 'pessimistic_write' } });
39
+ }
40
+ // 최신 재고이력을 seq 내림차순으로 조회
41
+ const lastInvHistory = await invHistoryRepo.findOne({
42
+ where: {
43
+ domain: { id: inventory.domain.id },
44
+ palletId: inventory.palletId
45
+ },
46
+ order: { seq: 'DESC' }
39
47
  });
48
+ // 다음 seq는 마지막 seq + 1 (이력이 없으면 0)
49
+ const seq = lastInvHistory ? lastInvHistory.seq + 1 : 0;
40
50
  let openingQty = 0;
41
51
  let openingUomValue = 0;
42
- if (seq) {
43
- const lastInvHistory = await invHistoryRepo.findOneBy({
44
- domain: { id: inventory.domain.id },
45
- palletId: inventory.palletId,
46
- seq: seq - 1
47
- });
52
+ if (lastInvHistory) {
48
53
  openingQty = lastInvHistory.openingQty + lastInvHistory.qty;
49
54
  openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue;
50
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inventory-util.js","sourceRoot":"","sources":["../../server/utils/inventory-util.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, Repository } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Bizplace } from '@things-factory/biz-base'\nimport { Product } from '@things-factory/product-base'\nimport { Domain, getRepository } from '@things-factory/shell'\nimport {\n Inventory,\n INVENTORY_STATUS,\n InventoryHistory,\n InventoryNoGenerator,\n Location,\n LOCATION_STATUS,\n LOCATION_TYPE\n} from '@things-factory/warehouse-base'\n\n/**\n * @description It will insert new record into inventory histories table.\n * seq will be calculated based on number of records for one specific pallet id (provided by inventory object)\n */\nexport async function generateInventoryHistory(\n inventory: Inventory,\n refOrder: any,\n transactionType: string,\n qty: number = 0,\n uomValue: number = 0,\n user: User,\n trxMgr?: EntityManager,\n targetInventory: Inventory = {} as any\n): Promise<InventoryHistory> {\n const invHistoryRepo: Repository<InventoryHistory> =\n trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (!inventory?.id) throw new Error(`Can't find out ID of inventory.`)\n if (!refOrder?.id || !refOrder.name) throw new Error(`Can't find out ID or Name of Reference Order`)\n if (\n !inventory?.domain ||\n !inventory?.bizplace ||\n !inventory?.product?.id ||\n !inventory?.warehouse?.id ||\n !inventory?.location?.id\n ) {\n inventory = await invRepo.findOne({\n where: { id: inventory.id },\n relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']\n })\n }\n\n const domain: Domain = inventory.domain\n const location: Location = inventory.location\n\n const seq: number = await invHistoryRepo.countBy({\n domain: { id: inventory.domain.id },\n palletId: inventory.palletId\n })\n let openingQty: number = 0\n let openingUomValue: number = 0\n\n if (seq) {\n const lastInvHistory: InventoryHistory = await invHistoryRepo.findOneBy({\n domain: { id: inventory.domain.id },\n palletId: inventory.palletId,\n seq: seq - 1\n })\n\n openingQty = lastInvHistory.openingQty + lastInvHistory.qty\n openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue\n }\n\n if (transactionType == 'PICKING' || transactionType == 'UNLOADING') {\n // @ts-ignore\n const [findSameOrderHistory, total]: InventoryHistory = await invHistoryRepo.findAndCountBy({\n domain: { id: inventory.domain.id },\n palletId: inventory.palletId,\n refOrderId: refOrder.id\n })\n\n if (findSameOrderHistory) {\n let prevTotalQty = 0\n let prevTotalUomValue = 0\n for (let oh of findSameOrderHistory) {\n prevTotalQty += oh.qty\n prevTotalUomValue += oh.uomValue\n }\n qty -= prevTotalQty\n uomValue -= prevTotalUomValue\n }\n }\n\n let inventoryHistory: InventoryHistory = new InventoryHistory()\n inventoryHistory.name = InventoryNoGenerator.inventoryHistoryName()\n inventoryHistory.description = inventory.description\n inventoryHistory.seq = seq\n inventoryHistory.palletId = inventory.palletId\n inventoryHistory.cartonId = inventory.cartonId\n inventoryHistory.batchId = inventory.batchId\n inventoryHistory.batchIdRef = inventory.batchIdRef\n inventoryHistory.status = inventory.status\n inventoryHistory.transactionType = transactionType\n inventoryHistory.refOrderId = refOrder?.id || null\n inventoryHistory.orderNo = refOrder?.name || null\n inventoryHistory.orderRefNo = refOrder?.refNo || null\n inventoryHistory.inventory = inventory\n ;(inventoryHistory as any).targetInventory = targetInventory as any\n inventoryHistory.product = inventory.product\n inventoryHistory.reusablePallet = inventory.reusablePallet\n inventoryHistory.zone = inventory.zone\n inventoryHistory.warehouse = inventory.warehouse\n inventoryHistory.location = inventory.location\n inventoryHistory.expirationDate = inventory.expirationDate\n inventoryHistory.packingType = inventory.packingType\n inventoryHistory.packingSize = inventory.packingSize\n inventoryHistory.uom = inventory.uom\n inventoryHistory.qty = qty\n inventoryHistory.openingQty = openingQty\n inventoryHistory.uomValue = uomValue\n inventoryHistory.openingUomValue = openingUomValue\n inventoryHistory.unitCost = inventory.unitCost\n inventoryHistory.domain = inventory.domain\n inventoryHistory.bizplace = inventory.bizplace\n inventoryHistory.creator = user\n inventoryHistory.updater = user\n inventoryHistory.auxInfo3 = inventory.auxInfo3\n\n inventoryHistory = await invHistoryRepo.save(inventoryHistory)\n\n if (inventory.lastSeq !== seq) {\n await invRepo.save({\n id: inventory.id,\n lastSeq: inventoryHistory.seq,\n updater: user\n })\n }\n\n await switchLocationStatus(domain, location, user, trxMgr)\n return inventoryHistory\n}\n\n/**\n * @description: Check location emptiness and update status of location\n * @param domain\n * @param location\n * @param updater\n * @param trxMgr\n */\nexport async function switchLocationStatus(\n domain: Domain,\n location: Location,\n updater: User,\n trxMgr?: EntityManager\n): Promise<Location> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const locationRepo: Repository<Location> = trxMgr?.getRepository(Location) || getRepository(Location)\n const allocatedItemsCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n status: INVENTORY_STATUS.STORED,\n location: { id: location.id }\n })\n\n if (!allocatedItemsCnt && location.status !== LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.EMPTY,\n updater\n })\n } else if (allocatedItemsCnt && location.status === LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.OCCUPIED,\n updater\n })\n }\n\n return location\n}\n\nexport async function checkPalletDuplication(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n trxMgr?: EntityManager\n): Promise<boolean> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const duplicatedPalletCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n bizplace,\n palletId\n })\n\n return Boolean(duplicatedPalletCnt)\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Bizplace} bizplace\n * @param {String} palletId\n * @param {String} batchId\n * @param {String | Product} product\n * @param {String} packingType\n * @param {EntityManager} trxMgr\n */\nexport async function checkPalletIdenticallity(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n batchId: string,\n product: string | Product,\n packingType: string,\n trxMgr?: EntityManager\n): Promise<{ identicallity: boolean; errorMessage?: string }> {\n const productRepo: Repository<Product> = trxMgr?.getRepository(Product) || getRepository(Product)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (typeof product === 'string') {\n const foundProduct: Product = await productRepo.findOneBy({ id: product })\n if (!foundProduct) throw new Error(`Failed to find product with ${product}`)\n product = foundProduct\n }\n\n const inv: Inventory = await invRepo.findOne({\n where: { domain: { id: domain.id }, bizplace: { id: bizplace.id }, palletId },\n relations: ['product']\n })\n\n if (batchId !== inv.batchId) return { identicallity: false, errorMessage: `Batch ID is not matched with ${batchId}` }\n\n if (product?.id !== inv?.product?.id)\n return { identicallity: false, errorMessage: `Product is not matched with ${product.name}` }\n\n if (packingType !== inv.packingType)\n return { identicallity: false, errorMessage: `Packing Type is not matched with ${packingType}` }\n\n return { identicallity: true }\n}\n\n/**\n * @description: Get inventory based on picking strategy and sorting rule\n * @param { worksheetId, batchId, bizplaceId, productId, packingType, pickingStrategy, locationSortingRules }\n * @param trxMgr\n */\nexport async function inventoriesByStrategy(\n { worksheetId, batchId, bizplaceId, productId, packingType, packingSize, uom, pickingStrategy, locationSortingRules },\n domain: Domain,\n trxMgr: EntityManager\n) {\n const qb = await trxMgr.getRepository(Inventory).createQueryBuilder('INV')\n qb.innerJoinAndSelect('INV.product', 'PROD')\n .innerJoinAndSelect('INV.location', 'LOC')\n .addSelect(subQuery =>\n subQuery\n .select('COALESCE(SUM(release_qty), 0)', 'releaseQty')\n .from('order_inventories', 'OI')\n .where('\"OI\".\"inventory_id\" = \"INV\".\"id\"')\n .andWhere(\"\\\"OI\\\".\\\"status\\\" IN ('PENDING', 'PENDING_RECEIVE', 'PENDING_WORKSHEET', 'PENDING_SPLIT')\")\n .andWhere('\"OI\".\"ref_worksheet_id\" <> :worksheetId', { worksheetId: worksheetId })\n )\n .addSelect(subQuery =>\n subQuery\n .select('COALESCE(SUM(release_uom_value), 0)', 'releaseUomValue')\n .from('order_inventories', 'OI')\n .where('\"OI\".\"inventory_id\" = \"INV\".\"id\"')\n .andWhere(\"\\\"OI\\\".\\\"status\\\" IN ('PENDING', 'PENDING_RECEIVE', 'PENDING_WORKSHEET', 'PENDING_SPLIT')\")\n .andWhere('\"OI\".\"ref_worksheet_id\" <> :worksheetId', { worksheetId: worksheetId })\n )\n .andWhere('\"INV\".\"domain_id\" = :domainId')\n .andWhere('\"PROD\".\"id\" = :productId')\n .andWhere('\"INV\".\"packing_type\" = :packingType')\n .andWhere('\"INV\".\"packing_size\" = :packingSize')\n .andWhere('\"INV\".\"uom\" = :uom')\n .andWhere('\"INV\".\"status\" = :status', { status: 'STORED' })\n .andWhere('\"LOC\".\"type\" NOT IN (:...locationTypes)', {\n locationTypes: [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]\n })\n .setParameters({\n domainId: domain.id,\n productId,\n packingType,\n packingSize,\n uom\n })\n\n if (batchId !== '') {\n qb.andWhere('\"INV\".\"batch_id\" = :batchId', { batchId })\n }\n\n if (bizplaceId) {\n qb.andWhere('\"INV\".\"bizplace_id\" = :bizplaceId', { bizplaceId: bizplaceId })\n }\n\n let locIdx = 0\n\n switch (pickingStrategy.toUpperCase()) {\n case 'FIFO':\n qb.orderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'LIFO':\n qb.orderBy('\"INV\".\"created_at\"', 'DESC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'FEFO':\n qb.orderBy('\"INV\".\"expiration_date\"', 'ASC')\n qb.addOrderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'FMFO':\n qb.orderBy('\"INV\".\"manufacture_date\"', 'ASC')\n qb.addOrderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'LOCATION':\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n if (locIdx === 0) {\n qb.orderBy(`LOC.${key}`, locationSortingRules[key])\n } else {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n ++locIdx\n }\n } else qb.orderBy('\"LOC\".\"name\"', 'DESC')\n break\n }\n\n const { entities, raw } = await qb.getRawAndEntities()\n const items = entities\n .map((inv: Inventory, idx: number) => {\n const qty: number = inv?.qty > 0 ? inv.qty : 0\n const uomValue: number = inv?.uomValue > 0 ? inv.uomValue : 0\n const lockedQty: number = inv.lockedQty || 0\n const lockedUomValue: number = inv.lockedUomValue || 0\n const releaseQty: number = parseInt(raw[idx].releaseQty) || 0\n const releaseUomValue: number = parseFloat(raw[idx].releaseUomValue) || 0\n\n return {\n ...inv,\n qty: qty - lockedQty - releaseQty,\n uomValue: uomValue - lockedUomValue - releaseUomValue\n }\n })\n .filter((inv: Inventory) => inv.qty > 0)\n\n const total: number = await qb.getCount()\n return { items, total }\n}\n\nexport async function isInventoryExpiring(inventory: Inventory): Promise<boolean> {\n if (!inventory.id) throw new Error('No inventory id provided')\n let product: Product | undefined = inventory.product\n if (!product) {\n inventory = await getRepository(Inventory).findOne({\n where: { id: inventory.id },\n relations: ['product']\n })\n product = inventory.product\n }\n\n const { expirationDate } = inventory\n const { isRequiredCheckExpiry, expirationPeriod } = product\n\n if (!isRequiredCheckExpiry || !expirationPeriod || Number(expirationDate) <= 0) return false\n\n let date: Date = new Date()\n const acceptBefore: Date = new Date(date.setDate(date.getDate() + expirationPeriod))\n const expiryDate: Date = new Date(expirationDate)\n\n return expiryDate < acceptBefore\n}\n"]}
1
+ {"version":3,"file":"inventory-util.js","sourceRoot":"","sources":["../../server/utils/inventory-util.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, Repository } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Bizplace } from '@things-factory/biz-base'\nimport { Product } from '@things-factory/product-base'\nimport { Domain, getRepository } from '@things-factory/shell'\nimport {\n Inventory,\n INVENTORY_STATUS,\n InventoryHistory,\n InventoryNoGenerator,\n Location,\n LOCATION_STATUS,\n LOCATION_TYPE\n} from '@things-factory/warehouse-base'\n\n/**\n * @description It will insert new record into inventory histories table.\n * seq will be calculated based on number of records for one specific pallet id (provided by inventory object)\n */\nexport async function generateInventoryHistory(\n inventory: Inventory,\n refOrder: any,\n transactionType: string,\n qty: number = 0,\n uomValue: number = 0,\n user: User,\n trxMgr?: EntityManager,\n targetInventory: Inventory = {} as any\n): Promise<InventoryHistory> {\n const invHistoryRepo: Repository<InventoryHistory> =\n trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (!inventory?.id) throw new Error(`Can't find out ID of inventory.`)\n if (!refOrder?.id || !refOrder.name) throw new Error(`Can't find out ID or Name of Reference Order`)\n if (\n !inventory?.domain ||\n !inventory?.bizplace ||\n !inventory?.product?.id ||\n !inventory?.warehouse?.id ||\n !inventory?.location?.id\n ) {\n inventory = await invRepo.findOne({\n where: { id: inventory.id },\n relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']\n })\n }\n\n const domain: Domain = inventory.domain\n const location: Location = inventory.location\n\n // 동시성 제어 - 트랜잭션 내에서 해당 재고 행을 FOR UPDATE로 잠가, 동시 실행이 같은 seq를 읽어 중복 기록하는 것을 막는다.\n if (trxMgr) {\n await invRepo.findOne({ where: { id: inventory.id }, lock: { mode: 'pessimistic_write' } })\n }\n\n // 최신 재고이력을 seq 내림차순으로 조회\n const lastInvHistory: InventoryHistory = await invHistoryRepo.findOne({\n where: {\n domain: { id: inventory.domain.id },\n palletId: inventory.palletId\n },\n order: { seq: 'DESC' }\n })\n\n // 다음 seq는 마지막 seq + 1 (이력이 없으면 0)\n const seq: number = lastInvHistory ? lastInvHistory.seq + 1 : 0\n let openingQty: number = 0\n let openingUomValue: number = 0\n\n if (lastInvHistory) {\n openingQty = lastInvHistory.openingQty + lastInvHistory.qty\n openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue\n }\n\n if (transactionType == 'PICKING' || transactionType == 'UNLOADING') {\n // @ts-ignore\n const [findSameOrderHistory, total]: InventoryHistory = await invHistoryRepo.findAndCountBy({\n domain: { id: inventory.domain.id },\n palletId: inventory.palletId,\n refOrderId: refOrder.id\n })\n\n if (findSameOrderHistory) {\n let prevTotalQty = 0\n let prevTotalUomValue = 0\n for (let oh of findSameOrderHistory) {\n prevTotalQty += oh.qty\n prevTotalUomValue += oh.uomValue\n }\n qty -= prevTotalQty\n uomValue -= prevTotalUomValue\n }\n }\n\n let inventoryHistory: InventoryHistory = new InventoryHistory()\n inventoryHistory.name = InventoryNoGenerator.inventoryHistoryName()\n inventoryHistory.description = inventory.description\n inventoryHistory.seq = seq\n inventoryHistory.palletId = inventory.palletId\n inventoryHistory.cartonId = inventory.cartonId\n inventoryHistory.batchId = inventory.batchId\n inventoryHistory.batchIdRef = inventory.batchIdRef\n inventoryHistory.status = inventory.status\n inventoryHistory.transactionType = transactionType\n inventoryHistory.refOrderId = refOrder?.id || null\n inventoryHistory.orderNo = refOrder?.name || null\n inventoryHistory.orderRefNo = refOrder?.refNo || null\n inventoryHistory.inventory = inventory\n ;(inventoryHistory as any).targetInventory = targetInventory as any\n inventoryHistory.product = inventory.product\n inventoryHistory.reusablePallet = inventory.reusablePallet\n inventoryHistory.zone = inventory.zone\n inventoryHistory.warehouse = inventory.warehouse\n inventoryHistory.location = inventory.location\n inventoryHistory.expirationDate = inventory.expirationDate\n inventoryHistory.packingType = inventory.packingType\n inventoryHistory.packingSize = inventory.packingSize\n inventoryHistory.uom = inventory.uom\n inventoryHistory.qty = qty\n inventoryHistory.openingQty = openingQty\n inventoryHistory.uomValue = uomValue\n inventoryHistory.openingUomValue = openingUomValue\n inventoryHistory.unitCost = inventory.unitCost\n inventoryHistory.domain = inventory.domain\n inventoryHistory.bizplace = inventory.bizplace\n inventoryHistory.creator = user\n inventoryHistory.updater = user\n inventoryHistory.auxInfo3 = inventory.auxInfo3\n\n inventoryHistory = await invHistoryRepo.save(inventoryHistory)\n\n if (inventory.lastSeq !== seq) {\n await invRepo.save({\n id: inventory.id,\n lastSeq: inventoryHistory.seq,\n updater: user\n })\n }\n\n await switchLocationStatus(domain, location, user, trxMgr)\n return inventoryHistory\n}\n\n/**\n * @description: Check location emptiness and update status of location\n * @param domain\n * @param location\n * @param updater\n * @param trxMgr\n */\nexport async function switchLocationStatus(\n domain: Domain,\n location: Location,\n updater: User,\n trxMgr?: EntityManager\n): Promise<Location> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const locationRepo: Repository<Location> = trxMgr?.getRepository(Location) || getRepository(Location)\n const allocatedItemsCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n status: INVENTORY_STATUS.STORED,\n location: { id: location.id }\n })\n\n if (!allocatedItemsCnt && location.status !== LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.EMPTY,\n updater\n })\n } else if (allocatedItemsCnt && location.status === LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.OCCUPIED,\n updater\n })\n }\n\n return location\n}\n\nexport async function checkPalletDuplication(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n trxMgr?: EntityManager\n): Promise<boolean> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const duplicatedPalletCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n bizplace,\n palletId\n })\n\n return Boolean(duplicatedPalletCnt)\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Bizplace} bizplace\n * @param {String} palletId\n * @param {String} batchId\n * @param {String | Product} product\n * @param {String} packingType\n * @param {EntityManager} trxMgr\n */\nexport async function checkPalletIdenticallity(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n batchId: string,\n product: string | Product,\n packingType: string,\n trxMgr?: EntityManager\n): Promise<{ identicallity: boolean; errorMessage?: string }> {\n const productRepo: Repository<Product> = trxMgr?.getRepository(Product) || getRepository(Product)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (typeof product === 'string') {\n const foundProduct: Product = await productRepo.findOneBy({ id: product })\n if (!foundProduct) throw new Error(`Failed to find product with ${product}`)\n product = foundProduct\n }\n\n const inv: Inventory = await invRepo.findOne({\n where: { domain: { id: domain.id }, bizplace: { id: bizplace.id }, palletId },\n relations: ['product']\n })\n\n if (batchId !== inv.batchId) return { identicallity: false, errorMessage: `Batch ID is not matched with ${batchId}` }\n\n if (product?.id !== inv?.product?.id)\n return { identicallity: false, errorMessage: `Product is not matched with ${product.name}` }\n\n if (packingType !== inv.packingType)\n return { identicallity: false, errorMessage: `Packing Type is not matched with ${packingType}` }\n\n return { identicallity: true }\n}\n\n/**\n * @description: Get inventory based on picking strategy and sorting rule\n * @param { worksheetId, batchId, bizplaceId, productId, packingType, pickingStrategy, locationSortingRules }\n * @param trxMgr\n */\nexport async function inventoriesByStrategy(\n { worksheetId, batchId, bizplaceId, productId, packingType, packingSize, uom, pickingStrategy, locationSortingRules },\n domain: Domain,\n trxMgr: EntityManager\n) {\n const qb = await trxMgr.getRepository(Inventory).createQueryBuilder('INV')\n qb.innerJoinAndSelect('INV.product', 'PROD')\n .innerJoinAndSelect('INV.location', 'LOC')\n .addSelect(subQuery =>\n subQuery\n .select('COALESCE(SUM(release_qty), 0)', 'releaseQty')\n .from('order_inventories', 'OI')\n .where('\"OI\".\"inventory_id\" = \"INV\".\"id\"')\n .andWhere(\"\\\"OI\\\".\\\"status\\\" IN ('PENDING', 'PENDING_RECEIVE', 'PENDING_WORKSHEET', 'PENDING_SPLIT')\")\n .andWhere('\"OI\".\"ref_worksheet_id\" <> :worksheetId', { worksheetId: worksheetId })\n )\n .addSelect(subQuery =>\n subQuery\n .select('COALESCE(SUM(release_uom_value), 0)', 'releaseUomValue')\n .from('order_inventories', 'OI')\n .where('\"OI\".\"inventory_id\" = \"INV\".\"id\"')\n .andWhere(\"\\\"OI\\\".\\\"status\\\" IN ('PENDING', 'PENDING_RECEIVE', 'PENDING_WORKSHEET', 'PENDING_SPLIT')\")\n .andWhere('\"OI\".\"ref_worksheet_id\" <> :worksheetId', { worksheetId: worksheetId })\n )\n .andWhere('\"INV\".\"domain_id\" = :domainId')\n .andWhere('\"PROD\".\"id\" = :productId')\n .andWhere('\"INV\".\"packing_type\" = :packingType')\n .andWhere('\"INV\".\"packing_size\" = :packingSize')\n .andWhere('\"INV\".\"uom\" = :uom')\n .andWhere('\"INV\".\"status\" = :status', { status: 'STORED' })\n .andWhere('\"LOC\".\"type\" NOT IN (:...locationTypes)', {\n locationTypes: [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]\n })\n .setParameters({\n domainId: domain.id,\n productId,\n packingType,\n packingSize,\n uom\n })\n\n if (batchId !== '') {\n qb.andWhere('\"INV\".\"batch_id\" = :batchId', { batchId })\n }\n\n if (bizplaceId) {\n qb.andWhere('\"INV\".\"bizplace_id\" = :bizplaceId', { bizplaceId: bizplaceId })\n }\n\n let locIdx = 0\n\n switch (pickingStrategy.toUpperCase()) {\n case 'FIFO':\n qb.orderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'LIFO':\n qb.orderBy('\"INV\".\"created_at\"', 'DESC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'FEFO':\n qb.orderBy('\"INV\".\"expiration_date\"', 'ASC')\n qb.addOrderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'FMFO':\n qb.orderBy('\"INV\".\"manufacture_date\"', 'ASC')\n qb.addOrderBy('\"INV\".\"created_at\"', 'ASC')\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n }\n break\n\n case 'LOCATION':\n if (locationSortingRules) {\n for (const key in locationSortingRules) {\n if (locIdx === 0) {\n qb.orderBy(`LOC.${key}`, locationSortingRules[key])\n } else {\n qb.addOrderBy(`LOC.${key}`, locationSortingRules[key])\n }\n ++locIdx\n }\n } else qb.orderBy('\"LOC\".\"name\"', 'DESC')\n break\n }\n\n const { entities, raw } = await qb.getRawAndEntities()\n const items = entities\n .map((inv: Inventory, idx: number) => {\n const qty: number = inv?.qty > 0 ? inv.qty : 0\n const uomValue: number = inv?.uomValue > 0 ? inv.uomValue : 0\n const lockedQty: number = inv.lockedQty || 0\n const lockedUomValue: number = inv.lockedUomValue || 0\n const releaseQty: number = parseInt(raw[idx].releaseQty) || 0\n const releaseUomValue: number = parseFloat(raw[idx].releaseUomValue) || 0\n\n return {\n ...inv,\n qty: qty - lockedQty - releaseQty,\n uomValue: uomValue - lockedUomValue - releaseUomValue\n }\n })\n .filter((inv: Inventory) => inv.qty > 0)\n\n const total: number = await qb.getCount()\n return { items, total }\n}\n\nexport async function isInventoryExpiring(inventory: Inventory): Promise<boolean> {\n if (!inventory.id) throw new Error('No inventory id provided')\n let product: Product | undefined = inventory.product\n if (!product) {\n inventory = await getRepository(Inventory).findOne({\n where: { id: inventory.id },\n relations: ['product']\n })\n product = inventory.product\n }\n\n const { expirationDate } = inventory\n const { isRequiredCheckExpiry, expirationPeriod } = product\n\n if (!isRequiredCheckExpiry || !expirationPeriod || Number(expirationDate) <= 0) return false\n\n let date: Date = new Date()\n const acceptBefore: Date = new Date(date.setDate(date.getDate() + expirationPeriod))\n const expiryDate: Date = new Date(expirationDate)\n\n return expiryDate < acceptBefore\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/worksheet-base",
3
- "version": "8.0.94",
3
+ "version": "8.0.97",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,21 +24,21 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create ./server/migrations/migration"
25
25
  },
26
26
  "dependencies": {
27
- "@things-factory/auth-base": "^8.0.94",
28
- "@things-factory/biz-base": "^8.0.94",
29
- "@things-factory/document-template-base": "^8.0.94",
30
- "@things-factory/id-rule-base": "^8.0.94",
31
- "@things-factory/integration-lmd": "^8.0.94",
32
- "@things-factory/integration-marketplace": "^8.0.94",
33
- "@things-factory/integration-sellercraft": "^8.0.94",
34
- "@things-factory/integration-sftp": "^8.0.94",
35
- "@things-factory/marketplace-base": "^8.0.94",
36
- "@things-factory/notification": "^8.0.94",
37
- "@things-factory/sales-base": "^8.0.94",
38
- "@things-factory/setting-base": "^8.0.94",
39
- "@things-factory/shell": "^8.0.94",
40
- "@things-factory/transport-base": "^8.0.94",
41
- "@things-factory/warehouse-base": "^8.0.94"
27
+ "@things-factory/auth-base": "^8.0.97",
28
+ "@things-factory/biz-base": "^8.0.97",
29
+ "@things-factory/document-template-base": "^8.0.97",
30
+ "@things-factory/id-rule-base": "^8.0.97",
31
+ "@things-factory/integration-lmd": "^8.0.97",
32
+ "@things-factory/integration-marketplace": "^8.0.97",
33
+ "@things-factory/integration-sellercraft": "^8.0.97",
34
+ "@things-factory/integration-sftp": "^8.0.97",
35
+ "@things-factory/marketplace-base": "^8.0.97",
36
+ "@things-factory/notification": "^8.0.97",
37
+ "@things-factory/sales-base": "^8.0.97",
38
+ "@things-factory/setting-base": "^8.0.97",
39
+ "@things-factory/shell": "^8.0.97",
40
+ "@things-factory/transport-base": "^8.0.97",
41
+ "@things-factory/warehouse-base": "^8.0.97"
42
42
  },
43
- "gitHead": "8624fb1b8c9d979f1b5edf747c5ee1d08cf79a6f"
43
+ "gitHead": "5d03c18493fb5e9d58e56bf893b51a9d682b8823"
44
44
  }
@@ -50,20 +50,26 @@ export async function generateInventoryHistory(
50
50
  const domain: Domain = inventory.domain
51
51
  const location: Location = inventory.location
52
52
 
53
- const seq: number = await invHistoryRepo.countBy({
54
- domain: { id: inventory.domain.id },
55
- palletId: inventory.palletId
53
+ // 동시성 제어 - 트랜잭션 내에서 해당 재고 행을 FOR UPDATE로 잠가, 동시 실행이 같은 seq 읽어 중복 기록하는 것을 막는다.
54
+ if (trxMgr) {
55
+ await invRepo.findOne({ where: { id: inventory.id }, lock: { mode: 'pessimistic_write' } })
56
+ }
57
+
58
+ // 최신 재고이력을 seq 내림차순으로 조회
59
+ const lastInvHistory: InventoryHistory = await invHistoryRepo.findOne({
60
+ where: {
61
+ domain: { id: inventory.domain.id },
62
+ palletId: inventory.palletId
63
+ },
64
+ order: { seq: 'DESC' }
56
65
  })
66
+
67
+ // 다음 seq는 마지막 seq + 1 (이력이 없으면 0)
68
+ const seq: number = lastInvHistory ? lastInvHistory.seq + 1 : 0
57
69
  let openingQty: number = 0
58
70
  let openingUomValue: number = 0
59
71
 
60
- if (seq) {
61
- const lastInvHistory: InventoryHistory = await invHistoryRepo.findOneBy({
62
- domain: { id: inventory.domain.id },
63
- palletId: inventory.palletId,
64
- seq: seq - 1
65
- })
66
-
72
+ if (lastInvHistory) {
67
73
  openingQty = lastInvHistory.openingQty + lastInvHistory.qty
68
74
  openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue
69
75
  }