diff --git a/src/features/products/products/product.service.js b/src/features/products/products/product.service.js index e30a7de..ec6e7a7 100644 --- a/src/features/products/products/product.service.js +++ b/src/features/products/products/product.service.js @@ -291,6 +291,32 @@ export class ProductService { return formatProductResponse(json); } + async generateSku(family, finalCode, transaction) { + let familyPrefix = 'PRD'; + if (family) { + familyPrefix = (family.name || family.code || 'PRD') + .toUpperCase() + .replace(/[^A-Z0-9]/g, '') + .substring(0, 4); + if (!familyPrefix || familyPrefix.length < 2) familyPrefix = 'PRD'; + } + + let runningSeq = '00001'; + if (family) { + const familyProductCount = await models.Product.count({ + where: { family_id: family.id }, + transaction + }); + runningSeq = String(familyProductCount + 1).padStart(5, '0'); + } else { + const totalProductCount = await models.Product.count({ + transaction + }); + runningSeq = String(totalProductCount + 1).padStart(5, '0'); + } + return `${familyPrefix}-${finalCode}-${runningSeq}`; + } + async create(data, context = {}) { const transaction = await sequelize.transaction(); try { @@ -384,31 +410,6 @@ export class ProductService { } data.code = finalCode; - // 4b. Autogenerate Master SKU (FAMILY_PREFIX-PRODUCT_CODE-SEQUENCE) - let familyPrefix = 'PRD'; - if (family) { - familyPrefix = (family.name || family.code || 'PRD') - .toUpperCase() - .replace(/[^A-Z0-9]/g, '') - .substring(0, 4); - if (!familyPrefix || familyPrefix.length < 2) familyPrefix = 'PRD'; - } - - let runningSeq = '00001'; - if (family) { - const familyProductCount = await models.Product.count({ - where: { family_id: family.id }, - transaction - }); - runningSeq = String(familyProductCount + 1).padStart(5, '0'); - } else { - const totalProductCount = await models.Product.count({ - transaction - }); - runningSeq = String(totalProductCount + 1).padStart(5, '0'); - } - const generatedSku = `${familyPrefix}-${finalCode}-${runningSeq}`; - // Setup default inherited channels and workflows const metadata = data.metadata || {}; if (!metadata.channels) { @@ -438,7 +439,12 @@ export class ProductService { metadata.currentStage = currentStage; // Pack general form fields into metadata since they aren't core columns - metadata.sku = generatedSku; + const initialStatus = data.status || 'draft'; + if (initialStatus === 'pending') { + metadata.sku = await this.generateSku(family, finalCode, transaction); + } else { + metadata.sku = null; + } metadata.price = data.price || ''; metadata.stock = data.stock !== undefined ? data.stock : 0; metadata.barcode = data.barcode || ''; @@ -478,7 +484,7 @@ export class ProductService { } } } - if (Array.isArray(family.attributes)) { + if (family && Array.isArray(family.attributes)) { for (const a of family.attributes) { if (a && a.id) familyAttributesMap.set(a.id, a); } @@ -486,12 +492,14 @@ export class ProductService { const attrKeys = typeof bodyAttributes === 'object' && bodyAttributes !== null ? Object.keys(bodyAttributes) : []; if (familyAttributesMap.size === 0 && attrKeys.length > 0) { + const uuidKeys = attrKeys.filter(k => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(k)); + const orConditions = [{ code: attrKeys }]; + if (uuidKeys.length > 0) { + orConditions.push({ id: uuidKeys }); + } const dbAttrs = await models.Attribute.findAll({ where: { - [Op.or]: [ - { code: attrKeys }, - { id: attrKeys } - ] + [Op.or]: orConditions }, transaction }); @@ -644,6 +652,13 @@ export class ProductService { metadata.currentStage = record.metadata?.currentStage || 'draft'; } + const oldStatus = record.status || record.metadata?.currentStage || 'draft'; + const newStatus = data.status || metadata.currentStage || oldStatus; + + if (!metadata.sku && oldStatus === 'draft' && newStatus === 'pending') { + metadata.sku = await this.generateSku(family, record.code, transaction); + } + // Keep general fields inside metadata up to date if (data.hasOwnProperty('sku')) metadata.sku = data.sku; if (data.hasOwnProperty('price')) metadata.price = data.price; @@ -697,12 +712,14 @@ export class ProductService { const attrKeys = typeof bodyAttributes === 'object' && bodyAttributes !== null ? Object.keys(bodyAttributes) : []; if (familyAttributesMap.size === 0 && attrKeys.length > 0) { + const uuidKeys = attrKeys.filter(k => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(k)); + const orConditions = [{ code: attrKeys }]; + if (uuidKeys.length > 0) { + orConditions.push({ id: uuidKeys }); + } const dbAttrs = await models.Attribute.findAll({ where: { - [Op.or]: [ - { code: attrKeys }, - { id: attrKeys } - ] + [Op.or]: orConditions }, transaction });