Files
tehran_taj/apps/api/release/seed.js
T

403 lines
18 KiB
JavaScript

"use strict";
// prisma/seed.ts
var import_client = require("@prisma/client");
var prisma = new import_client.PrismaClient();
var PLACEHOLDER_PASSWORD_HASH = "placeholder-hash-not-for-production";
var PLACEHOLDER_PRODUCT_IMAGE = "/img/no-items.png";
async function main() {
const [tehran, mashhad, isfahan, tabriz] = await Promise.all([
prisma.city.upsert({ where: { id: "city-tehran" }, update: {}, create: { id: "city-tehran", name: "\u062A\u0647\u0631\u0627\u0646", province: "\u062A\u0647\u0631\u0627\u0646" } }),
prisma.city.upsert({ where: { id: "city-mashhad" }, update: {}, create: { id: "city-mashhad", name: "\u0645\u0634\u0647\u062F", province: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0631\u0636\u0648\u06CC" } }),
prisma.city.upsert({ where: { id: "city-isfahan" }, update: {}, create: { id: "city-isfahan", name: "\u0627\u0635\u0641\u0647\u0627\u0646", province: "\u0627\u0635\u0641\u0647\u0627\u0646" } }),
prisma.city.upsert({ where: { id: "city-tabriz" }, update: {}, create: { id: "city-tabriz", name: "\u062A\u0628\u0631\u06CC\u0632", province: "\u0622\u0630\u0631\u0628\u0627\u06CC\u062C\u0627\u0646 \u0634\u0631\u0642\u06CC" } })
]);
const branchTehran = await prisma.branch.upsert({
where: { id: "branch-tehran-bazaar" },
update: {},
create: { id: "branch-tehran-bazaar", name: "\u0634\u0639\u0628\u0647 \u0628\u0627\u0632\u0627\u0631 \u0628\u0632\u0631\u06AF \u062A\u0647\u0631\u0627\u0646", cityId: tehran.id }
});
const branchMashhad = await prisma.branch.upsert({
where: { id: "branch-mashhad-main" },
update: {},
create: { id: "branch-mashhad-main", name: "\u0634\u0639\u0628\u0647 \u0645\u0631\u06A9\u0632\u06CC \u0645\u0634\u0647\u062F", cityId: mashhad.id }
});
await prisma.workshop.upsert({
where: { id: "workshop-central" },
update: {},
create: { id: "workshop-central", name: "\u06A9\u0627\u0631\u06AF\u0627\u0647 \u0645\u0631\u06A9\u0632\u06CC \u0633\u0627\u062E\u062A \u0637\u0644\u0627" }
});
await prisma.adminUser.upsert({
where: { mobile: "09120000001" },
update: {},
create: {
mobile: "09120000001",
fullName: "\u0645\u062F\u06CC\u0631 \u0627\u0631\u0634\u062F \u0633\u06CC\u0633\u062A\u0645",
passwordHash: PLACEHOLDER_PASSWORD_HASH,
role: import_client.AdminRole.SUPER_ADMIN,
branchId: branchTehran.id
}
});
const agentReza = await prisma.adminUser.upsert({
where: { mobile: "09121234567" },
update: {},
create: {
mobile: "09121234567",
fullName: "\u0631\u0636\u0627 \u0627\u062D\u0645\u062F\u06CC",
passwordHash: PLACEHOLDER_PASSWORD_HASH,
role: import_client.AdminRole.SALES_EXPERT,
branchId: branchTehran.id,
wagePercent: 1.5
}
});
const agentSara = await prisma.adminUser.upsert({
where: { mobile: "09129876543" },
update: {},
create: {
mobile: "09129876543",
fullName: "\u0633\u0627\u0631\u0627 \u06A9\u0631\u06CC\u0645\u06CC",
passwordHash: PLACEHOLDER_PASSWORD_HASH,
role: import_client.AdminRole.SALES_EXPERT,
branchId: branchMashhad.id,
wagePercent: 1.2
}
});
await prisma.adminUser.upsert({
where: { mobile: "09123334444" },
update: {},
create: {
mobile: "09123334444",
fullName: "\u0647\u0648\u0645\u0646 \u06CC\u0632\u062F\u0627\u0646\u06CC",
passwordHash: PLACEHOLDER_PASSWORD_HASH,
role: import_client.AdminRole.WORKSHOP_SUPERVISOR
}
});
await prisma.adminUser.upsert({
where: { mobile: "09125556666" },
update: {},
create: {
mobile: "09125556666",
fullName: "\u0641\u0631\u0632\u0627\u0646\u0647 \u0645\u062D\u0645\u0648\u062F\u06CC",
passwordHash: PLACEHOLDER_PASSWORD_HASH,
role: import_client.AdminRole.ACCOUNTANT,
branchId: branchTehran.id
}
});
const customerData = [
{
id: "customer-1",
fullName: "\u0639\u0644\u06CC \u0645\u062D\u0645\u062F\u06CC",
mobile: "09151112233",
nationalCode: "0012345678",
cityId: tehran.id,
referredByAgentId: agentReza.id,
goldCreditLimitGrams: "200",
verificationStep: import_client.VerificationStep.VERIFIED
},
{
id: "customer-2",
fullName: "\u0645\u0631\u06CC\u0645 \u062D\u0633\u06CC\u0646\u06CC",
mobile: "09151112234",
nationalCode: "0012345679",
cityId: tehran.id,
referredByAgentId: agentReza.id,
goldCreditLimitGrams: "100",
verificationStep: import_client.VerificationStep.VERIFIED
},
{
id: "customer-3",
fullName: "\u062C\u0648\u0627\u062F \u0646\u0648\u0631\u0648\u0632\u06CC",
mobile: "09151112235",
nationalCode: "0012345680",
cityId: mashhad.id,
referredByAgentId: agentSara.id,
goldCreditLimitGrams: "50",
verificationStep: import_client.VerificationStep.STEP_TWO_SUBMITTED
},
{
id: "customer-4",
fullName: "\u0646\u0631\u06AF\u0633 \u0627\u0628\u0631\u0627\u0647\u06CC\u0645\u06CC",
mobile: "09151112236",
nationalCode: "0012345681",
cityId: isfahan.id,
referredByAgentId: null,
goldCreditLimitGrams: "30",
verificationStep: import_client.VerificationStep.UNVERIFIED
},
{
id: "customer-5",
fullName: "\u06A9\u0627\u0645\u0631\u0627\u0646 \u0635\u0627\u062F\u0642\u06CC",
mobile: "09151112237",
nationalCode: "0012345682",
cityId: tehran.id,
referredByAgentId: agentReza.id,
goldCreditLimitGrams: "500",
verificationStep: import_client.VerificationStep.VERIFIED
},
{
id: "customer-6",
fullName: "\u0632\u0647\u0631\u0627 \u0642\u0627\u0633\u0645\u06CC",
mobile: "09151112238",
nationalCode: "0012345683",
cityId: tabriz.id,
referredByAgentId: agentSara.id,
goldCreditLimitGrams: "80",
verificationStep: import_client.VerificationStep.STEP_ONE_SUBMITTED
}
];
const customers = [];
for (const c of customerData) {
customers.push(
await prisma.customer.upsert({
where: { id: c.id },
update: {},
create: {
id: c.id,
fullName: c.fullName,
mobile: c.mobile,
nationalCode: c.nationalCode,
passwordHash: PLACEHOLDER_PASSWORD_HASH,
cityId: c.cityId,
referredByAgentId: c.referredByAgentId,
goldCreditLimitGrams: c.goldCreditLimitGrams,
verificationStep: c.verificationStep
}
})
);
}
const [customer1, customer2, , , customer5] = customers;
const [ringsCategory, braceletsCategory, necklacesCategory, earringsCategory, coinsCategory] = await Promise.all([
prisma.category.upsert({ where: { id: "cat-rings" }, update: {}, create: { id: "cat-rings", title: "\u0627\u0646\u06AF\u0634\u062A\u0631" } }),
prisma.category.upsert({ where: { id: "cat-bracelets" }, update: {}, create: { id: "cat-bracelets", title: "\u062F\u0633\u062A\u0628\u0646\u062F" } }),
prisma.category.upsert({ where: { id: "cat-necklaces" }, update: {}, create: { id: "cat-necklaces", title: "\u06AF\u0631\u062F\u0646\u0628\u0646\u062F" } }),
prisma.category.upsert({ where: { id: "cat-earrings" }, update: {}, create: { id: "cat-earrings", title: "\u06AF\u0648\u0634\u0648\u0627\u0631\u0647" } }),
prisma.category.upsert({ where: { id: "cat-coins" }, update: {}, create: { id: "cat-coins", title: "\u0633\u06A9\u0647 \u0648 \u0634\u0645\u0634" } })
]);
const brandHenza = await prisma.brand.upsert({
where: { id: "brand-henza" },
update: {},
create: { id: "brand-henza", title: "\u0647\u0646\u0632\u0627 \u0637\u0644\u0627" }
});
const brandArtisan = await prisma.brand.upsert({
where: { id: "brand-artisan" },
update: {},
create: { id: "brand-artisan", title: "\u0645\u062C\u0645\u0648\u0639\u0647 \u0635\u0646\u0639\u062A\u06AF\u0631" }
});
const productDefs = [
{
id: "product-classic-ring",
title: "\u0627\u0646\u06AF\u0634\u062A\u0631 \u062A\u06A9 \u0646\u06AF\u06CC\u0646 \u06A9\u0644\u0627\u0633\u06CC\u06A9",
description: "\u0627\u0646\u06AF\u0634\u062A\u0631 \u0637\u0644\u0627\u06CC \u06F1\u06F8 \u0639\u06CC\u0627\u0631 \u0628\u0627 \u0637\u0631\u0627\u062D\u06CC \u0633\u0627\u062F\u0647 \u0648 \u0645\u06CC\u0646\u06CC\u0645\u0627\u0644.",
categoryId: ringsCategory.id,
brandId: brandHenza.id,
variants: [
{ id: "variant-ring-size-6", title: "\u0633\u0627\u06CC\u0632 \u06F6", sku: "RING-CLASSIC-6", rashWeightGrams: "2.850", defaultWagePercent: "9.0" },
{ id: "variant-ring-size-7", title: "\u0633\u0627\u06CC\u0632 \u06F7", sku: "RING-CLASSIC-7", rashWeightGrams: "3.100", defaultWagePercent: "9.0" }
]
},
{
id: "product-woven-bracelet",
title: "\u062F\u0633\u062A\u0628\u0646\u062F \u0628\u0627\u0641\u062A \u0632\u0646\u062C\u06CC\u0631\u06CC",
description: "\u062F\u0633\u062A\u0628\u0646\u062F \u0628\u0627\u0641\u062A\u200C\u062F\u0627\u0631 \u062F\u0633\u062A\u200C\u0633\u0627\u0632 \u0627\u0632 \u0637\u0644\u0627\u06CC \u06F1\u06F8 \u0639\u06CC\u0627\u0631.",
categoryId: braceletsCategory.id,
brandId: brandArtisan.id,
variants: [
{ id: "variant-bracelet-standard", title: "\u0627\u0633\u062A\u0627\u0646\u062F\u0627\u0631\u062F \u06F1\u06F8 \u0633\u0627\u0646\u062A\u06CC", sku: "BRC-WOVEN-18", rashWeightGrams: "14.200", defaultWagePercent: "11.5" }
]
},
{
id: "product-pendant-necklace",
title: "\u06AF\u0631\u062F\u0646\u0628\u0646\u062F \u0622\u0648\u06CC\u0632 \u0627\u0634\u06A9\u06CC",
description: "\u06AF\u0631\u062F\u0646\u0628\u0646\u062F \u0638\u0631\u06CC\u0641 \u0628\u0627 \u0622\u0648\u06CC\u0632 \u0627\u0634\u06A9\u06CC \u0648 \u0632\u0646\u062C\u06CC\u0631 \u0646\u0627\u0632\u06A9.",
categoryId: necklacesCategory.id,
brandId: brandHenza.id,
variants: [
{ id: "variant-necklace-40cm", title: "\u0632\u0646\u062C\u06CC\u0631 \u06F4\u06F0 \u0633\u0627\u0646\u062A\u06CC", sku: "NCK-TEARDROP-40", rashWeightGrams: "5.600", defaultWagePercent: "10.0" },
{ id: "variant-necklace-45cm", title: "\u0632\u0646\u062C\u06CC\u0631 \u06F4\u06F5 \u0633\u0627\u0646\u062A\u06CC", sku: "NCK-TEARDROP-45", rashWeightGrams: "6.100", defaultWagePercent: "10.0" }
]
},
{
id: "product-hoop-earrings",
title: "\u06AF\u0648\u0634\u0648\u0627\u0631\u0647 \u062D\u0644\u0642\u0647\u200C\u0627\u06CC \u06A9\u0644\u0627\u0633\u06CC\u06A9",
description: "\u06AF\u0648\u0634\u0648\u0627\u0631\u0647 \u062D\u0644\u0642\u0647\u200C\u0627\u06CC \u0637\u0644\u0627\u06CC \u06F1\u06F8 \u0639\u06CC\u0627\u0631 \u0645\u0646\u0627\u0633\u0628 \u0627\u0633\u062A\u0641\u0627\u062F\u0647 \u0631\u0648\u0632\u0645\u0631\u0647.",
categoryId: earringsCategory.id,
brandId: brandArtisan.id,
variants: [
{ id: "variant-hoop-small", title: "\u06A9\u0648\u0686\u06A9", sku: "ERG-HOOP-S", rashWeightGrams: "1.900", defaultWagePercent: "8.5" },
{ id: "variant-hoop-large", title: "\u0628\u0632\u0631\u06AF", sku: "ERG-HOOP-L", rashWeightGrams: "3.400", defaultWagePercent: "8.5" }
]
},
{
id: "product-full-coin",
title: "\u0633\u06A9\u0647 \u062A\u0645\u0627\u0645 \u0628\u0647\u0627\u0631 \u0622\u0632\u0627\u062F\u06CC",
description: "\u0633\u06A9\u0647 \u0637\u0644\u0627\u06CC \u062A\u0645\u0627\u0645 \u0628\u0647\u0627\u0631 \u0622\u0632\u0627\u062F\u06CC\u060C \u0639\u06CC\u0627\u0631 \u0627\u0633\u062A\u0627\u0646\u062F\u0627\u0631\u062F.",
categoryId: coinsCategory.id,
brandId: brandHenza.id,
variants: [
{ id: "variant-coin-full", title: "\u062A\u0645\u0627\u0645 \u0633\u06A9\u0647", sku: "COIN-FULL", rashWeightGrams: "8.133", defaultWagePercent: "2.0" },
{ id: "variant-coin-half", title: "\u0646\u06CC\u0645 \u0633\u06A9\u0647", sku: "COIN-HALF", rashWeightGrams: "4.066", defaultWagePercent: "2.5" }
]
}
];
const createdVariantIds = {};
let imageCount = 0;
for (const p of productDefs) {
const product = await prisma.product.upsert({
where: { id: p.id },
update: {},
create: {
id: p.id,
title: p.title,
description: p.description,
categoryId: p.categoryId,
brandId: p.brandId
}
});
for (const v of p.variants) {
await prisma.productVariant.upsert({
where: { id: v.id },
update: {},
create: {
id: v.id,
productId: product.id,
title: v.title,
sku: v.sku,
rashWeightGrams: v.rashWeightGrams,
defaultWagePercent: v.defaultWagePercent
}
});
createdVariantIds[v.id] = v.id;
}
await prisma.productImage.upsert({
where: { id: `${p.id}-img-1` },
update: { url: PLACEHOLDER_PRODUCT_IMAGE },
create: {
id: `${p.id}-img-1`,
productId: product.id,
url: PLACEHOLDER_PRODUCT_IMAGE,
sortOrder: 0
}
});
imageCount += 1;
}
const featured = await prisma.collection.upsert({
where: { id: "collection-featured" },
update: {},
create: { id: "collection-featured", title: "\u067E\u0631\u0641\u0631\u0648\u0634\u200C\u0647\u0627\u06CC \u0627\u06CC\u0646 \u0647\u0641\u062A\u0647", description: "\u0645\u0646\u062A\u062E\u0628\u06CC \u0627\u0632 \u0645\u062D\u0628\u0648\u0628\u200C\u062A\u0631\u06CC\u0646 \u0645\u062D\u0635\u0648\u0644\u0627\u062A \u0641\u0631\u0648\u0634\u06AF\u0627\u0647." }
});
await prisma.collectionProduct.upsert({
where: { collectionId_productId: { collectionId: featured.id, productId: "product-classic-ring" } },
update: {},
create: { collectionId: featured.id, productId: "product-classic-ring" }
});
await prisma.collectionProduct.upsert({
where: { collectionId_productId: { collectionId: featured.id, productId: "product-pendant-necklace" } },
update: {},
create: { collectionId: featured.id, productId: "product-pendant-necklace" }
});
await prisma.collectionProduct.upsert({
where: { collectionId_productId: { collectionId: featured.id, productId: "product-full-coin" } },
update: {},
create: { collectionId: featured.id, productId: "product-full-coin" }
});
await prisma.goldPriceQuote.create({
data: { karatPerMille: 750, pricePerGramRial: "61500000", source: "seed-illustrative" }
});
const existingDemoOrder = await prisma.order.findUnique({ where: { orderNumber: "ORD-SEED-0001" } });
if (!existingDemoOrder) {
const rashWeight = "3.100";
const wagePercent = 9;
const discountPercent = 0;
const computedWeight = (parseFloat(rashWeight) * (1 + (wagePercent - discountPercent) / 100)).toFixed(4);
const quantity = 1;
const flatRialChargePerUnit = "500000";
const order = await prisma.order.create({
data: {
orderNumber: "ORD-SEED-0001",
customerId: customer1.id,
branchId: branchTehran.id,
status: "DELIVERED_TO_CUSTOMER",
totalGoldWeightGrams: computedWeight,
wageWeightGrams: (parseFloat(computedWeight) - parseFloat(rashWeight)).toFixed(4),
flatRialCharge: flatRialChargePerUnit,
deliveredAt: /* @__PURE__ */ new Date(),
items: {
create: [
{
productVariantId: "variant-ring-size-7",
quantity,
rashWeightGramsSnapshot: rashWeight,
wagePercentSnapshot: wagePercent.toString(),
discountPercentSnapshot: discountPercent.toString(),
computedWeightGrams: computedWeight,
flatRialCharge: flatRialChargePerUnit
}
]
},
statusEvents: {
create: [{ toStatus: "PLACED" }, { toStatus: "ADMIN_APPROVED" }, { toStatus: "DELIVERED_TO_CUSTOMER" }]
}
}
});
await prisma.ledgerEntry.create({
data: {
customerId: customer1.id,
currency: "GOLD_GRAM",
direction: "DEBIT",
sourceType: "ORDER_STOCK",
amount: computedWeight,
orderId: order.id,
confirmed: true,
confirmedAt: /* @__PURE__ */ new Date(),
note: "\u0628\u062F\u0647\u06CC \u0648\u0632\u0646\u06CC \u0637\u0644\u0627 \u0647\u0646\u06AF\u0627\u0645 \u062A\u062D\u0648\u06CC\u0644 (\u062F\u0627\u062F\u0647 \u0622\u0632\u0645\u0627\u06CC\u0634\u06CC)"
}
});
await prisma.ledgerEntry.create({
data: {
customerId: customer1.id,
currency: "RIAL",
direction: "DEBIT",
sourceType: "ORDER_STOCK",
amount: flatRialChargePerUnit,
orderId: order.id,
confirmed: true,
confirmedAt: /* @__PURE__ */ new Date(),
note: "\u0647\u0632\u06CC\u0646\u0647 \u062B\u0627\u0628\u062A \u0631\u06CC\u0627\u0644\u06CC \u0647\u0646\u06AF\u0627\u0645 \u062A\u062D\u0648\u06CC\u0644 (\u062F\u0627\u062F\u0647 \u0622\u0632\u0645\u0627\u06CC\u0634\u06CC)"
}
});
await prisma.customer.update({
where: { id: customer1.id },
data: { goldDebtGrams: { increment: computedWeight }, fiatDebtRial: { increment: flatRialChargePerUnit } }
});
await prisma.ledgerEntry.create({
data: {
customerId: customer1.id,
currency: "GOLD_GRAM",
direction: "CREDIT",
sourceType: "REPAYMENT_MELTED_GOLD",
amount: "1.5000",
karatPerMille: 750,
confirmed: false,
note: "\u062A\u0633\u0648\u06CC\u0647 \u0628\u0627 \u0637\u0644\u0627\u06CC \u0622\u0628\u200C\u0634\u062F\u0647\u060C \u062F\u0631 \u0627\u0646\u062A\u0638\u0627\u0631 \u062A\u0627\u06CC\u06CC\u062F (\u062F\u0627\u062F\u0647 \u0622\u0632\u0645\u0627\u06CC\u0634\u06CC)"
}
});
}
await prisma.customer.update({ where: { id: customer2.id }, data: { goldDebtGrams: "8.2500", fiatDebtRial: "2000000" } });
await prisma.customer.update({ where: { id: customer5.id }, data: { goldDebtGrams: "0", fiatDebtRial: "0" } });
console.log("Seed complete:", {
cities: 4,
branches: 2,
adminUsers: 5,
customers: customers.length,
products: productDefs.length,
variants: Object.keys(createdVariantIds).length,
productImages: imageCount
});
}
main().catch((e) => {
console.error(e);
process.exit(1);
}).finally(async () => {
await prisma.$disconnect();
});