Add tagged catalog import

This commit is contained in:
Ruslan Bakiev
2026-04-09 14:14:10 +07:00
parent b321075293
commit 40b4515305
6 changed files with 2475 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,8 @@
"prisma:migrate": "prisma migrate deploy",
"prisma:push": "prisma db push",
"seed": "node scripts/seed.js",
"seed:demo": "node scripts/seed-demo.js"
"seed:demo": "node scripts/seed-demo.js",
"import:catalog": "node scripts/import-catalog.js"
},
"keywords": [],
"author": "",

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Product" ADD COLUMN "tags" TEXT[] DEFAULT ARRAY[]::TEXT[];

View File

@@ -179,6 +179,7 @@ model Product {
thicknessMicron Int?
sleeveBrand String?
quantityPerBox String?
tags String[] @default([])
description String?
isCustomizable Boolean @default(false)
isActive Boolean @default(true)

105
scripts/import-catalog.js Normal file
View File

@@ -0,0 +1,105 @@
import 'dotenv/config';
import { readFileSync } from 'node:fs';
import { prisma } from '../src/prisma-client.js';
const IMPORT_DESCRIPTION_PREFIX = 'Импорт каталога 2026-04-08: ';
const dataset = JSON.parse(
readFileSync(new URL('../data/catalog-import-2026-04-08.json', import.meta.url), 'utf8'),
);
const warehouses = [
{ code: 'MSK-01', name: 'Склад Москва' },
{ code: 'SPB-01', name: 'Склад СПб' },
];
function formatQuantity(value) {
return Number(value ?? 0).toFixed(3);
}
for (const warehouse of warehouses) {
await prisma.warehouse.upsert({
where: { code: warehouse.code },
update: { name: warehouse.name },
create: warehouse,
});
}
const warehouseIds = Object.fromEntries(
await Promise.all(
warehouses.map(async (warehouse) => {
const persistedWarehouse = await prisma.warehouse.findUniqueOrThrow({
where: { code: warehouse.code },
select: { id: true },
});
return [warehouse.code, persistedWarehouse.id];
}),
),
);
await prisma.product.updateMany({
data: {
isActive: false,
},
});
let importedCount = 0;
for (const item of dataset) {
const product = await prisma.product.upsert({
where: { sku: item.sku },
update: {
name: item.name,
productType: item.productType,
widthMm: item.widthMm,
lengthM: item.lengthM,
thicknessMicron: item.thicknessMicron,
sleeveBrand: item.sleeveBrand,
quantityPerBox: item.quantityPerBox,
tags: item.tags,
description: `${IMPORT_DESCRIPTION_PREFIX}${item.rawName}`,
isCustomizable: false,
isActive: true,
},
create: {
sku: item.sku,
name: item.name,
productType: item.productType,
widthMm: item.widthMm,
lengthM: item.lengthM,
thicknessMicron: item.thicknessMicron,
sleeveBrand: item.sleeveBrand,
quantityPerBox: item.quantityPerBox,
tags: item.tags,
description: `${IMPORT_DESCRIPTION_PREFIX}${item.rawName}`,
isCustomizable: false,
isActive: true,
},
});
for (const warehouse of warehouses) {
await prisma.productStock.upsert({
where: {
productId_warehouseId: {
productId: product.id,
warehouseId: warehouseIds[warehouse.code],
},
},
update: {
availableQty: formatQuantity(item.balances[warehouse.code]),
},
create: {
productId: product.id,
warehouseId: warehouseIds[warehouse.code],
availableQty: formatQuantity(item.balances[warehouse.code]),
},
});
}
importedCount += 1;
}
console.log(`Imported ${importedCount} catalog products from 2026-04-08 stock reports.`);
await prisma.$disconnect();

View File

@@ -242,6 +242,7 @@ type Product {
thicknessMicron: Int
sleeveBrand: String
quantityPerBox: String
tags: [String!]!
isCustomizable: Boolean!
isActive: Boolean!
availableInWarehouses: [ProductWarehouseBalance!]!