203 lines
8.1 KiB
JavaScript
203 lines
8.1 KiB
JavaScript
import 'dotenv/config';
|
|
|
|
import { prisma } from '../src/prisma-client.js';
|
|
|
|
const managerEmail = 'manager@fregat.local';
|
|
const clientEmail = 'client@fregat.local';
|
|
|
|
const PRODUCT_TYPES = {
|
|
STANDARD: 'стандартная лента',
|
|
PAINTING: 'малярный скотч',
|
|
};
|
|
|
|
const PRODUCT_ROWS = [
|
|
{ sku: '480200', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 40, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '72' },
|
|
{ sku: '481200', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 55, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '72/36' },
|
|
{ sku: '482200', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 66, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '483200', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 120, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '751200', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 55, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '48' },
|
|
{ sku: '752200', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 66, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '753200', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 120, thicknessMicron: 38, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '481400', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 55, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '72/36' },
|
|
{ sku: '482400', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 66, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '483400', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 120, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '751400', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 55, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '48' },
|
|
{ sku: '752400', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 66, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '753400', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 120, thicknessMicron: 43, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '481500', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 55, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '72/36' },
|
|
{ sku: '482500', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 66, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '483500', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 120, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '487500', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 150, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '751500', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 55, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '48' },
|
|
{ sku: '752500', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 66, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '743500', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 120, thicknessMicron: 45, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '482600', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 66, thicknessMicron: 47, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '483600', productType: PRODUCT_TYPES.STANDARD, widthMm: 48, lengthM: 120, thicknessMicron: 47, sleeveBrand: 'фрегат', quantityPerBox: '36' },
|
|
{ sku: '752600', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 66, thicknessMicron: 47, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
{ sku: '753600', productType: PRODUCT_TYPES.STANDARD, widthMm: 75, lengthM: 120, thicknessMicron: 47, sleeveBrand: 'фрегат', quantityPerBox: '24' },
|
|
];
|
|
|
|
function assertUniqueProductRows(rows) {
|
|
const seen = new Map();
|
|
|
|
for (const row of rows) {
|
|
const signature = [
|
|
row.productType,
|
|
row.widthMm,
|
|
row.lengthM,
|
|
row.thicknessMicron,
|
|
row.sleeveBrand,
|
|
].join('|');
|
|
|
|
const duplicate = seen.get(signature);
|
|
if (duplicate) {
|
|
throw new Error(
|
|
`Duplicate product signature detected for ${row.sku} and ${duplicate.sku}: ${signature}`,
|
|
);
|
|
}
|
|
|
|
seen.set(signature, row);
|
|
}
|
|
}
|
|
|
|
function sentenceCase(value) {
|
|
if (!value) {
|
|
return value;
|
|
}
|
|
return value[0].toUpperCase() + value.slice(1);
|
|
}
|
|
|
|
function buildName(product) {
|
|
return [
|
|
sentenceCase(product.productType),
|
|
`${product.widthMm}x${product.lengthM} м`,
|
|
`${product.thicknessMicron} мкм`,
|
|
`втулка ${sentenceCase(product.sleeveBrand)}`,
|
|
`короб ${product.quantityPerBox}`,
|
|
].join(', ');
|
|
}
|
|
|
|
function baseQuantity(quantityPerBox) {
|
|
const firstValue = quantityPerBox.split('/')[0];
|
|
const parsed = Number.parseInt(firstValue, 10);
|
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 24;
|
|
}
|
|
|
|
const company = await prisma.company.upsert({
|
|
where: { inn: '7701000000' },
|
|
update: {},
|
|
create: {
|
|
name: 'Fregat Client LLC',
|
|
inn: '7701000000',
|
|
},
|
|
});
|
|
|
|
const manager = await prisma.user.upsert({
|
|
where: { email: managerEmail },
|
|
update: { fullName: 'Default Manager' },
|
|
create: {
|
|
email: managerEmail,
|
|
fullName: 'Default Manager',
|
|
role: 'MANAGER',
|
|
},
|
|
});
|
|
|
|
await prisma.user.upsert({
|
|
where: { email: clientEmail },
|
|
update: { fullName: 'Demo Client', companyId: company.id },
|
|
create: {
|
|
email: clientEmail,
|
|
fullName: 'Demo Client',
|
|
role: 'CLIENT',
|
|
companyId: company.id,
|
|
},
|
|
});
|
|
|
|
const warehouseMain = await prisma.warehouse.upsert({
|
|
where: { code: 'MSK-01' },
|
|
update: { name: 'Main warehouse' },
|
|
create: { code: 'MSK-01', name: 'Main warehouse' },
|
|
});
|
|
|
|
const warehouseReserve = await prisma.warehouse.upsert({
|
|
where: { code: 'SPB-01' },
|
|
update: { name: 'Reserve warehouse' },
|
|
create: { code: 'SPB-01', name: 'Reserve warehouse' },
|
|
});
|
|
|
|
const activeSkus = PRODUCT_ROWS.map((item) => item.sku);
|
|
assertUniqueProductRows(PRODUCT_ROWS);
|
|
|
|
await prisma.product.updateMany({
|
|
where: { sku: { notIn: activeSkus } },
|
|
data: { isActive: false },
|
|
});
|
|
|
|
for (const product of PRODUCT_ROWS) {
|
|
const qtyBase = baseQuantity(product.quantityPerBox);
|
|
const qtyMain = qtyBase * 10;
|
|
const qtyReserve = qtyBase * 5;
|
|
|
|
const dbProduct = await prisma.product.upsert({
|
|
where: { sku: product.sku },
|
|
update: {
|
|
name: buildName(product),
|
|
description: `Артикул: ${product.sku}`,
|
|
productType: product.productType,
|
|
widthMm: product.widthMm,
|
|
lengthM: product.lengthM,
|
|
thicknessMicron: product.thicknessMicron,
|
|
sleeveBrand: product.sleeveBrand,
|
|
quantityPerBox: product.quantityPerBox,
|
|
isCustomizable: false,
|
|
isActive: true,
|
|
},
|
|
create: {
|
|
sku: product.sku,
|
|
name: buildName(product),
|
|
description: `Артикул: ${product.sku}`,
|
|
productType: product.productType,
|
|
widthMm: product.widthMm,
|
|
lengthM: product.lengthM,
|
|
thicknessMicron: product.thicknessMicron,
|
|
sleeveBrand: product.sleeveBrand,
|
|
quantityPerBox: product.quantityPerBox,
|
|
isCustomizable: false,
|
|
isActive: true,
|
|
},
|
|
});
|
|
|
|
await prisma.productStock.upsert({
|
|
where: {
|
|
productId_warehouseId: {
|
|
productId: dbProduct.id,
|
|
warehouseId: warehouseMain.id,
|
|
},
|
|
},
|
|
update: { availableQty: qtyMain },
|
|
create: {
|
|
productId: dbProduct.id,
|
|
warehouseId: warehouseMain.id,
|
|
availableQty: qtyMain,
|
|
},
|
|
});
|
|
|
|
await prisma.productStock.upsert({
|
|
where: {
|
|
productId_warehouseId: {
|
|
productId: dbProduct.id,
|
|
warehouseId: warehouseReserve.id,
|
|
},
|
|
},
|
|
update: { availableQty: qtyReserve },
|
|
create: {
|
|
productId: dbProduct.id,
|
|
warehouseId: warehouseReserve.id,
|
|
availableQty: qtyReserve,
|
|
},
|
|
});
|
|
}
|
|
|
|
console.log(`Seed complete with ${PRODUCT_ROWS.length} products. Use manager header x-user-id: ${manager.id}`);
|
|
await prisma.$disconnect();
|