@tewtawanc/loops-utils 1.0.0
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/dist/index.d.mts +140 -0
- package/dist/index.d.ts +140 -0
- package/dist/index.js +124 -0
- package/dist/index.mjs +90 -0
- package/package.json +33 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tewtawanc/loops-utils
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for Loops warehouse management system.
|
|
5
|
+
*
|
|
6
|
+
* SKU Generation:
|
|
7
|
+
* - Inventory SKU: Product specifications (grade, lot, material, weight, package)
|
|
8
|
+
* - Stock SKU: Physical units with location tracking
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { generateInventorySku, generateStockSku } from '@tewtawanc/loops-utils';
|
|
12
|
+
*
|
|
13
|
+
* const sku = generateInventorySku({
|
|
14
|
+
* grade: 'HD6600B',
|
|
15
|
+
* lotNumber: 'H5490205B',
|
|
16
|
+
* materialCode: 'C/P',
|
|
17
|
+
* netWeight: 25,
|
|
18
|
+
* packageType: 'PALLET'
|
|
19
|
+
* });
|
|
20
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
21
|
+
*/
|
|
22
|
+
interface InventorySkuParams {
|
|
23
|
+
materialCode: string;
|
|
24
|
+
grade: string;
|
|
25
|
+
lotNumber: string;
|
|
26
|
+
netWeight: number;
|
|
27
|
+
packageType: string;
|
|
28
|
+
}
|
|
29
|
+
interface StockSkuParams extends InventorySkuParams {
|
|
30
|
+
stockNumber: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Normalize SKU component to ensure valid SKU string:
|
|
34
|
+
* - Trims whitespace from both ends
|
|
35
|
+
* - Converts to uppercase for consistency
|
|
36
|
+
* - Replaces spaces with underscores
|
|
37
|
+
* - Removes special characters except / (for codes like C/P) and _ (word separator)
|
|
38
|
+
* - Removes consecutive underscores
|
|
39
|
+
* - Removes leading/trailing underscores
|
|
40
|
+
*/
|
|
41
|
+
declare function normalizeSkuComponent(component: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Format weight with appropriate precision
|
|
44
|
+
* - Integer weights: "25"
|
|
45
|
+
* - Decimal weights: "25.5"
|
|
46
|
+
*/
|
|
47
|
+
declare function formatWeight(weight: number): string;
|
|
48
|
+
/**
|
|
49
|
+
* Generate SKU for logical Inventory
|
|
50
|
+
* Format: {grade}-{lotNumber}-{materialCode}-{netWeight}KG-{packageType}
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* generateInventorySku({
|
|
54
|
+
* materialCode: 'C/P',
|
|
55
|
+
* grade: 'HD6600B',
|
|
56
|
+
* lotNumber: 'H5490205B',
|
|
57
|
+
* netWeight: 25.0,
|
|
58
|
+
* packageType: 'PALLET'
|
|
59
|
+
* })
|
|
60
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
61
|
+
*/
|
|
62
|
+
declare function generateInventorySku(params: InventorySkuParams): string;
|
|
63
|
+
/**
|
|
64
|
+
* Generate SKU for physical Stock
|
|
65
|
+
* Format: {inventorySKU}-{stockNumber}
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* generateStockSku({
|
|
69
|
+
* materialCode: 'C/P',
|
|
70
|
+
* grade: 'HD6600B',
|
|
71
|
+
* lotNumber: 'H5490205B',
|
|
72
|
+
* netWeight: 25.0,
|
|
73
|
+
* packageType: 'PALLET',
|
|
74
|
+
* stockNumber: 'P001234'
|
|
75
|
+
* })
|
|
76
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET-P001234"
|
|
77
|
+
*/
|
|
78
|
+
declare function generateStockSku(params: StockSkuParams): string;
|
|
79
|
+
/**
|
|
80
|
+
* Parse an Inventory SKU into its components
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* parseInventorySku('HD6600B-H5490205B-C/P-25KG-PALLET')
|
|
84
|
+
* // Returns: {
|
|
85
|
+
* // materialCode: 'C/P',
|
|
86
|
+
* // grade: 'HD6600B',
|
|
87
|
+
* // lotNumber: 'H5490205B',
|
|
88
|
+
* // netWeight: 25.0,
|
|
89
|
+
* // packageType: 'PALLET'
|
|
90
|
+
* // }
|
|
91
|
+
*/
|
|
92
|
+
declare function parseInventorySku(sku: string): InventorySkuParams | null;
|
|
93
|
+
/**
|
|
94
|
+
* Parse a Stock SKU into its components
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* parseStockSku('HD6600B-H5490205B-C/P-25KG-PALLET-P001234')
|
|
98
|
+
* // Returns: {
|
|
99
|
+
* // materialCode: 'C/P',
|
|
100
|
+
* // grade: 'HD6600B',
|
|
101
|
+
* // lotNumber: 'H5490205B',
|
|
102
|
+
* // netWeight: 25.0,
|
|
103
|
+
* // packageType: 'PALLET',
|
|
104
|
+
* // stockNumber: 'P001234'
|
|
105
|
+
* // }
|
|
106
|
+
*/
|
|
107
|
+
declare function parseStockSku(sku: string): StockSkuParams | null;
|
|
108
|
+
/**
|
|
109
|
+
* Extract inventory SKU from stock SKU
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* extractInventorySku('HD6600B-H5490205B-C/P-25KG-PALLET-P001234')
|
|
113
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
114
|
+
*/
|
|
115
|
+
declare function extractInventorySku(stockSku: string): string | null;
|
|
116
|
+
/**
|
|
117
|
+
* Validate if a string is a valid Inventory SKU format
|
|
118
|
+
*/
|
|
119
|
+
declare function isValidInventorySku(sku: string): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Validate if a string is a valid Stock SKU format
|
|
122
|
+
*/
|
|
123
|
+
declare function isValidStockSku(sku: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Generate a human-readable name from SKU components
|
|
126
|
+
* Format: {grade} {lotNumber} {materialCode} {netWeight}kg {packageType}
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* generateInventoryName({
|
|
130
|
+
* materialCode: 'C/P',
|
|
131
|
+
* grade: 'HD6600B',
|
|
132
|
+
* lotNumber: 'H5490205B',
|
|
133
|
+
* netWeight: 25.0,
|
|
134
|
+
* packageType: 'PALLET'
|
|
135
|
+
* })
|
|
136
|
+
* // Returns: "HD6600B H5490205B C/P 25kg Pallet"
|
|
137
|
+
*/
|
|
138
|
+
declare function generateInventoryName(params: InventorySkuParams): string;
|
|
139
|
+
|
|
140
|
+
export { type InventorySkuParams, type StockSkuParams, extractInventorySku, formatWeight, generateInventoryName, generateInventorySku, generateStockSku, isValidInventorySku, isValidStockSku, normalizeSkuComponent, parseInventorySku, parseStockSku };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tewtawanc/loops-utils
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for Loops warehouse management system.
|
|
5
|
+
*
|
|
6
|
+
* SKU Generation:
|
|
7
|
+
* - Inventory SKU: Product specifications (grade, lot, material, weight, package)
|
|
8
|
+
* - Stock SKU: Physical units with location tracking
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { generateInventorySku, generateStockSku } from '@tewtawanc/loops-utils';
|
|
12
|
+
*
|
|
13
|
+
* const sku = generateInventorySku({
|
|
14
|
+
* grade: 'HD6600B',
|
|
15
|
+
* lotNumber: 'H5490205B',
|
|
16
|
+
* materialCode: 'C/P',
|
|
17
|
+
* netWeight: 25,
|
|
18
|
+
* packageType: 'PALLET'
|
|
19
|
+
* });
|
|
20
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
21
|
+
*/
|
|
22
|
+
interface InventorySkuParams {
|
|
23
|
+
materialCode: string;
|
|
24
|
+
grade: string;
|
|
25
|
+
lotNumber: string;
|
|
26
|
+
netWeight: number;
|
|
27
|
+
packageType: string;
|
|
28
|
+
}
|
|
29
|
+
interface StockSkuParams extends InventorySkuParams {
|
|
30
|
+
stockNumber: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Normalize SKU component to ensure valid SKU string:
|
|
34
|
+
* - Trims whitespace from both ends
|
|
35
|
+
* - Converts to uppercase for consistency
|
|
36
|
+
* - Replaces spaces with underscores
|
|
37
|
+
* - Removes special characters except / (for codes like C/P) and _ (word separator)
|
|
38
|
+
* - Removes consecutive underscores
|
|
39
|
+
* - Removes leading/trailing underscores
|
|
40
|
+
*/
|
|
41
|
+
declare function normalizeSkuComponent(component: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Format weight with appropriate precision
|
|
44
|
+
* - Integer weights: "25"
|
|
45
|
+
* - Decimal weights: "25.5"
|
|
46
|
+
*/
|
|
47
|
+
declare function formatWeight(weight: number): string;
|
|
48
|
+
/**
|
|
49
|
+
* Generate SKU for logical Inventory
|
|
50
|
+
* Format: {grade}-{lotNumber}-{materialCode}-{netWeight}KG-{packageType}
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* generateInventorySku({
|
|
54
|
+
* materialCode: 'C/P',
|
|
55
|
+
* grade: 'HD6600B',
|
|
56
|
+
* lotNumber: 'H5490205B',
|
|
57
|
+
* netWeight: 25.0,
|
|
58
|
+
* packageType: 'PALLET'
|
|
59
|
+
* })
|
|
60
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
61
|
+
*/
|
|
62
|
+
declare function generateInventorySku(params: InventorySkuParams): string;
|
|
63
|
+
/**
|
|
64
|
+
* Generate SKU for physical Stock
|
|
65
|
+
* Format: {inventorySKU}-{stockNumber}
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* generateStockSku({
|
|
69
|
+
* materialCode: 'C/P',
|
|
70
|
+
* grade: 'HD6600B',
|
|
71
|
+
* lotNumber: 'H5490205B',
|
|
72
|
+
* netWeight: 25.0,
|
|
73
|
+
* packageType: 'PALLET',
|
|
74
|
+
* stockNumber: 'P001234'
|
|
75
|
+
* })
|
|
76
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET-P001234"
|
|
77
|
+
*/
|
|
78
|
+
declare function generateStockSku(params: StockSkuParams): string;
|
|
79
|
+
/**
|
|
80
|
+
* Parse an Inventory SKU into its components
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* parseInventorySku('HD6600B-H5490205B-C/P-25KG-PALLET')
|
|
84
|
+
* // Returns: {
|
|
85
|
+
* // materialCode: 'C/P',
|
|
86
|
+
* // grade: 'HD6600B',
|
|
87
|
+
* // lotNumber: 'H5490205B',
|
|
88
|
+
* // netWeight: 25.0,
|
|
89
|
+
* // packageType: 'PALLET'
|
|
90
|
+
* // }
|
|
91
|
+
*/
|
|
92
|
+
declare function parseInventorySku(sku: string): InventorySkuParams | null;
|
|
93
|
+
/**
|
|
94
|
+
* Parse a Stock SKU into its components
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* parseStockSku('HD6600B-H5490205B-C/P-25KG-PALLET-P001234')
|
|
98
|
+
* // Returns: {
|
|
99
|
+
* // materialCode: 'C/P',
|
|
100
|
+
* // grade: 'HD6600B',
|
|
101
|
+
* // lotNumber: 'H5490205B',
|
|
102
|
+
* // netWeight: 25.0,
|
|
103
|
+
* // packageType: 'PALLET',
|
|
104
|
+
* // stockNumber: 'P001234'
|
|
105
|
+
* // }
|
|
106
|
+
*/
|
|
107
|
+
declare function parseStockSku(sku: string): StockSkuParams | null;
|
|
108
|
+
/**
|
|
109
|
+
* Extract inventory SKU from stock SKU
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* extractInventorySku('HD6600B-H5490205B-C/P-25KG-PALLET-P001234')
|
|
113
|
+
* // Returns: "HD6600B-H5490205B-C/P-25KG-PALLET"
|
|
114
|
+
*/
|
|
115
|
+
declare function extractInventorySku(stockSku: string): string | null;
|
|
116
|
+
/**
|
|
117
|
+
* Validate if a string is a valid Inventory SKU format
|
|
118
|
+
*/
|
|
119
|
+
declare function isValidInventorySku(sku: string): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Validate if a string is a valid Stock SKU format
|
|
122
|
+
*/
|
|
123
|
+
declare function isValidStockSku(sku: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Generate a human-readable name from SKU components
|
|
126
|
+
* Format: {grade} {lotNumber} {materialCode} {netWeight}kg {packageType}
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* generateInventoryName({
|
|
130
|
+
* materialCode: 'C/P',
|
|
131
|
+
* grade: 'HD6600B',
|
|
132
|
+
* lotNumber: 'H5490205B',
|
|
133
|
+
* netWeight: 25.0,
|
|
134
|
+
* packageType: 'PALLET'
|
|
135
|
+
* })
|
|
136
|
+
* // Returns: "HD6600B H5490205B C/P 25kg Pallet"
|
|
137
|
+
*/
|
|
138
|
+
declare function generateInventoryName(params: InventorySkuParams): string;
|
|
139
|
+
|
|
140
|
+
export { type InventorySkuParams, type StockSkuParams, extractInventorySku, formatWeight, generateInventoryName, generateInventorySku, generateStockSku, isValidInventorySku, isValidStockSku, normalizeSkuComponent, parseInventorySku, parseStockSku };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
extractInventorySku: () => extractInventorySku,
|
|
24
|
+
formatWeight: () => formatWeight,
|
|
25
|
+
generateInventoryName: () => generateInventoryName,
|
|
26
|
+
generateInventorySku: () => generateInventorySku,
|
|
27
|
+
generateStockSku: () => generateStockSku,
|
|
28
|
+
isValidInventorySku: () => isValidInventorySku,
|
|
29
|
+
isValidStockSku: () => isValidStockSku,
|
|
30
|
+
normalizeSkuComponent: () => normalizeSkuComponent,
|
|
31
|
+
parseInventorySku: () => parseInventorySku,
|
|
32
|
+
parseStockSku: () => parseStockSku
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
35
|
+
function normalizeSkuComponent(component) {
|
|
36
|
+
return component.trim().toUpperCase().replace(/\s+/g, "_").replace(/[^A-Z0-9/_]/g, "").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
37
|
+
}
|
|
38
|
+
function formatWeight(weight) {
|
|
39
|
+
if (Number.isInteger(weight)) {
|
|
40
|
+
return weight.toString();
|
|
41
|
+
}
|
|
42
|
+
return weight.toFixed(2).replace(/\.?0+$/, "");
|
|
43
|
+
}
|
|
44
|
+
function generateInventorySku(params) {
|
|
45
|
+
const { materialCode, grade, lotNumber, netWeight, packageType } = params;
|
|
46
|
+
const normalizedMaterialCode = normalizeSkuComponent(materialCode);
|
|
47
|
+
const normalizedGrade = normalizeSkuComponent(grade);
|
|
48
|
+
const normalizedLotNumber = normalizeSkuComponent(lotNumber);
|
|
49
|
+
const normalizedPackageType = normalizeSkuComponent(packageType);
|
|
50
|
+
const weightStr = formatWeight(netWeight);
|
|
51
|
+
return `${normalizedGrade}-${normalizedLotNumber}-${normalizedMaterialCode}-${weightStr}KG-${normalizedPackageType}`;
|
|
52
|
+
}
|
|
53
|
+
function generateStockSku(params) {
|
|
54
|
+
const inventorySku = generateInventorySku(params);
|
|
55
|
+
const normalizedStockNumber = normalizeSkuComponent(params.stockNumber);
|
|
56
|
+
return `${inventorySku}-${normalizedStockNumber}`;
|
|
57
|
+
}
|
|
58
|
+
function parseInventorySku(sku) {
|
|
59
|
+
const parts = sku.split("-");
|
|
60
|
+
if (parts.length < 5) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const grade = parts[0];
|
|
64
|
+
const lotNumber = parts[1];
|
|
65
|
+
const materialCode = parts[2];
|
|
66
|
+
const weightPart = parts[3];
|
|
67
|
+
if (!weightPart.endsWith("KG")) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const netWeight = parseFloat(weightPart.replace("KG", ""));
|
|
71
|
+
const packageType = parts[4];
|
|
72
|
+
return {
|
|
73
|
+
materialCode,
|
|
74
|
+
grade,
|
|
75
|
+
lotNumber,
|
|
76
|
+
netWeight,
|
|
77
|
+
packageType
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function parseStockSku(sku) {
|
|
81
|
+
const parts = sku.split("-");
|
|
82
|
+
if (parts.length < 6) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const inventoryParams = parseInventorySku(parts.slice(0, 5).join("-"));
|
|
86
|
+
if (!inventoryParams) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
...inventoryParams,
|
|
91
|
+
stockNumber: parts[5]
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function extractInventorySku(stockSku) {
|
|
95
|
+
const parsed = parseStockSku(stockSku);
|
|
96
|
+
if (!parsed) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return generateInventorySku(parsed);
|
|
100
|
+
}
|
|
101
|
+
function isValidInventorySku(sku) {
|
|
102
|
+
return parseInventorySku(sku) !== null;
|
|
103
|
+
}
|
|
104
|
+
function isValidStockSku(sku) {
|
|
105
|
+
return parseStockSku(sku) !== null;
|
|
106
|
+
}
|
|
107
|
+
function generateInventoryName(params) {
|
|
108
|
+
const { materialCode, grade, lotNumber, netWeight, packageType } = params;
|
|
109
|
+
const capitalizedPackageType = packageType.toLowerCase().split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
110
|
+
return `${grade} ${lotNumber} ${materialCode} ${netWeight}kg ${capitalizedPackageType}`;
|
|
111
|
+
}
|
|
112
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
113
|
+
0 && (module.exports = {
|
|
114
|
+
extractInventorySku,
|
|
115
|
+
formatWeight,
|
|
116
|
+
generateInventoryName,
|
|
117
|
+
generateInventorySku,
|
|
118
|
+
generateStockSku,
|
|
119
|
+
isValidInventorySku,
|
|
120
|
+
isValidStockSku,
|
|
121
|
+
normalizeSkuComponent,
|
|
122
|
+
parseInventorySku,
|
|
123
|
+
parseStockSku
|
|
124
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function normalizeSkuComponent(component) {
|
|
3
|
+
return component.trim().toUpperCase().replace(/\s+/g, "_").replace(/[^A-Z0-9/_]/g, "").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
4
|
+
}
|
|
5
|
+
function formatWeight(weight) {
|
|
6
|
+
if (Number.isInteger(weight)) {
|
|
7
|
+
return weight.toString();
|
|
8
|
+
}
|
|
9
|
+
return weight.toFixed(2).replace(/\.?0+$/, "");
|
|
10
|
+
}
|
|
11
|
+
function generateInventorySku(params) {
|
|
12
|
+
const { materialCode, grade, lotNumber, netWeight, packageType } = params;
|
|
13
|
+
const normalizedMaterialCode = normalizeSkuComponent(materialCode);
|
|
14
|
+
const normalizedGrade = normalizeSkuComponent(grade);
|
|
15
|
+
const normalizedLotNumber = normalizeSkuComponent(lotNumber);
|
|
16
|
+
const normalizedPackageType = normalizeSkuComponent(packageType);
|
|
17
|
+
const weightStr = formatWeight(netWeight);
|
|
18
|
+
return `${normalizedGrade}-${normalizedLotNumber}-${normalizedMaterialCode}-${weightStr}KG-${normalizedPackageType}`;
|
|
19
|
+
}
|
|
20
|
+
function generateStockSku(params) {
|
|
21
|
+
const inventorySku = generateInventorySku(params);
|
|
22
|
+
const normalizedStockNumber = normalizeSkuComponent(params.stockNumber);
|
|
23
|
+
return `${inventorySku}-${normalizedStockNumber}`;
|
|
24
|
+
}
|
|
25
|
+
function parseInventorySku(sku) {
|
|
26
|
+
const parts = sku.split("-");
|
|
27
|
+
if (parts.length < 5) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const grade = parts[0];
|
|
31
|
+
const lotNumber = parts[1];
|
|
32
|
+
const materialCode = parts[2];
|
|
33
|
+
const weightPart = parts[3];
|
|
34
|
+
if (!weightPart.endsWith("KG")) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const netWeight = parseFloat(weightPart.replace("KG", ""));
|
|
38
|
+
const packageType = parts[4];
|
|
39
|
+
return {
|
|
40
|
+
materialCode,
|
|
41
|
+
grade,
|
|
42
|
+
lotNumber,
|
|
43
|
+
netWeight,
|
|
44
|
+
packageType
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function parseStockSku(sku) {
|
|
48
|
+
const parts = sku.split("-");
|
|
49
|
+
if (parts.length < 6) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const inventoryParams = parseInventorySku(parts.slice(0, 5).join("-"));
|
|
53
|
+
if (!inventoryParams) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
...inventoryParams,
|
|
58
|
+
stockNumber: parts[5]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function extractInventorySku(stockSku) {
|
|
62
|
+
const parsed = parseStockSku(stockSku);
|
|
63
|
+
if (!parsed) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return generateInventorySku(parsed);
|
|
67
|
+
}
|
|
68
|
+
function isValidInventorySku(sku) {
|
|
69
|
+
return parseInventorySku(sku) !== null;
|
|
70
|
+
}
|
|
71
|
+
function isValidStockSku(sku) {
|
|
72
|
+
return parseStockSku(sku) !== null;
|
|
73
|
+
}
|
|
74
|
+
function generateInventoryName(params) {
|
|
75
|
+
const { materialCode, grade, lotNumber, netWeight, packageType } = params;
|
|
76
|
+
const capitalizedPackageType = packageType.toLowerCase().split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
77
|
+
return `${grade} ${lotNumber} ${materialCode} ${netWeight}kg ${capitalizedPackageType}`;
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
extractInventorySku,
|
|
81
|
+
formatWeight,
|
|
82
|
+
generateInventoryName,
|
|
83
|
+
generateInventorySku,
|
|
84
|
+
generateStockSku,
|
|
85
|
+
isValidInventorySku,
|
|
86
|
+
isValidStockSku,
|
|
87
|
+
normalizeSkuComponent,
|
|
88
|
+
parseInventorySku,
|
|
89
|
+
parseStockSku
|
|
90
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tewtawanc/loops-utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared utilities for Loops warehouse management system",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"sku",
|
|
24
|
+
"inventory",
|
|
25
|
+
"warehouse"
|
|
26
|
+
],
|
|
27
|
+
"author": "tewtawanc",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"tsup": "^8.0.0",
|
|
31
|
+
"typescript": "^5.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|