import { Types } from "mongoose"; import { ProductModel } from "@/models/product"; import { ProductTypeModel } from "@/models/product-type"; import { StoreModel } from "@/models/store"; import type { MealCardProvider } from "@/shared/accounts"; import { autoConvertible } from "@/shared/products"; import { foldTr } from "@/shared/search"; import type { StoreKind } from "@/shared/stores"; /** * Örnek mağazalar ve ürünler (Faz 12). Çakır Ailesi (Kadıköy) için marketler, pazar ve online * platform; stok ürün tiplerine bağlı marka/paketler. Elle dönüşüm gereken örnekler: deterjan * (kg → yıkama), tablet paketi (paket → tablet), diş macunu/şampuan (ml → adet). Görsel yok. * Idempotent (`seedRef`). Miktarlar binde bir, tutarlar kuruş. */ type SeedStore = { ref: string; name: string; kind: StoreKind; branch?: string; distanceM?: number; carry: number; deliveryFee?: number; freeDeliveryMin?: number; mealCards?: MealCardProvider[]; note?: string; }; export const STORES: SeedStore[] = [ { ref: "migros", name: "Migros", kind: "market", branch: "Bahariye", distanceM: 1_200, carry: 2, mealCards: ["pluxee", "multinet", "edenred", "setcard"], }, { ref: "a101", name: "A101", kind: "market", branch: "Moda", distanceM: 400, carry: 1 }, { ref: "bim", name: "BİM", kind: "market", branch: "Yeldeğirmeni", distanceM: 650, carry: 2 }, { ref: "sok", name: "Şok", kind: "market", branch: "Rasimpaşa", distanceM: 300, carry: 1, mealCards: ["multinet", "pluxee"], }, { ref: "carrefoursa", name: "CarrefourSA", kind: "market", branch: "Acıbadem", distanceM: 3_800, carry: 4, mealCards: ["pluxee", "multinet", "edenred", "setcard", "metropol"], note: "Hafta sonu arabayla; büyük alışveriş.", }, { ref: "sali-pazari", name: "Salı Pazarı", kind: "bazaar", branch: "Kadıköy", distanceM: 1_900, carry: 4, note: "Salı ve cuma; sebze-meyve.", }, { ref: "getir-buyuk", name: "Getir Büyük", kind: "online", carry: 1, deliveryFee: 39_90, freeDeliveryMin: 750_00, mealCards: ["multinet"], }, { ref: "metro", name: "Metro Toptancı", kind: "market", branch: "Kozyatağı", distanceM: 9_500, carry: 5, }, ]; type SeedProduct = { ref: string; /** Stok seed'indeki ürün tipi `seedRef`'i. */ type: string; brand: string; name?: string; barcode?: string; qty: number; unit: string; /** Elle dönüşüm (bir paket = bu kadar ürün tipi birimi). */ typeQty?: number; }; const K = 1000; export const PRODUCTS: SeedProduct[] = [ { ref: "ariel-5kg", type: "toz-deterjan", brand: "Ariel", name: "Matik Dağ Esintisi", qty: 5 * K, unit: "kg", typeQty: 33 * K, barcode: "8690000100015", }, { ref: "omo-6kg", type: "toz-deterjan", brand: "Omo", name: "Matik Active Fresh", qty: 6 * K, unit: "kg", typeQty: 40 * K, }, { ref: "bingo-4kg", type: "toz-deterjan", brand: "Bingo", name: "Matik", qty: 4 * K, unit: "kg", typeQty: 26 * K, }, { ref: "fairy-50", type: "tablet-deterjan", brand: "Fairy", name: "Platinum Plus", qty: 1 * K, unit: "paket", typeQty: 50 * K, barcode: "8690000100022", }, { ref: "finish-40", type: "tablet-deterjan", brand: "Finish", name: "Quantum", qty: 40 * K, unit: "tablet", }, { ref: "yayla-mercimek", type: "kirmizi-mercimek", brand: "Yayla", name: "Kırmızı Mercimek", qty: 1 * K, unit: "kg", }, { ref: "reis-mercimek", type: "kirmizi-mercimek", brand: "Reis", name: "Kırmızı Mercimek", qty: 1 * K, unit: "kg", }, { ref: "duru-mercimek", type: "kirmizi-mercimek", brand: "Duru", name: "Kırmızı Mercimek", qty: 2_500, unit: "kg", }, { ref: "yayla-baldo", type: "pirinc", brand: "Yayla", name: "Baldo", qty: 2_500, unit: "kg" }, { ref: "reis-baldo", type: "pirinc", brand: "Reis", name: "Baldo", qty: 1 * K, unit: "kg" }, { ref: "pinar-sut", type: "sut", brand: "Pınar", name: "Tam Yağlı Süt", qty: 1 * K, unit: "lt", barcode: "8690000100039", }, { ref: "sutas-sut", type: "sut", brand: "Sütaş", name: "Tam Yağlı Süt", qty: 1 * K, unit: "lt" }, { ref: "icim-sut-500", type: "sut", brand: "İçim", name: "Yarım Yağlı Süt", qty: 500 * K, unit: "ml", }, { ref: "keskinoglu-30", type: "yumurta", brand: "Keskinoğlu", name: "L Boy 30'lu", qty: 30 * K, unit: "adet", }, { ref: "koy-yumurta-15", type: "yumurta", brand: "Köy Yumurtası", name: "15'li", qty: 15 * K, unit: "adet", }, { ref: "pinar-peynir", type: "beyaz-peynir", brand: "Pınar", name: "Beyaz Peynir", qty: 500 * K, unit: "g", }, { ref: "yumos-1440", type: "yumusatici", brand: "Yumoş", name: "Extra Lilyum", qty: 1_440 * K, unit: "ml", }, { ref: "selpak-32", type: "tuvalet-kagidi", brand: "Selpak", name: "32'li", qty: 32 * K, unit: "rulo", }, { ref: "solo-24", type: "tuvalet-kagidi", brand: "Solo", name: "24'lü", qty: 24 * K, unit: "rulo", }, { ref: "colgate-75", type: "dis-macunu", brand: "Colgate", name: "Total 75 ml", qty: 75 * K, unit: "ml", typeQty: 1 * K, }, { ref: "sensodyne-75", type: "dis-macunu", brand: "Sensodyne", name: "Repair 75 ml", qty: 75 * K, unit: "ml", typeQty: 1 * K, }, { ref: "elidor-500", type: "sampuan", brand: "Elidor", name: "500 ml", qty: 500 * K, unit: "ml", typeQty: 1 * K, }, ]; export async function seedShopping( householdIds: Map, users: Map, ): Promise<{ stores: number; products: number }> { const actor = new Types.ObjectId(users.get("ayse")!); const householdId = householdIds.get("Çakır Ailesi")!; let stores = 0; for (const s of STORES) { if (await StoreModel.exists({ householdId, seedRef: s.ref })) continue; await StoreModel.create({ householdId, name: s.name, nameKey: foldTr(s.name), kind: s.kind, branch: s.branch ?? "", distanceM: s.kind === "online" ? null : (s.distanceM ?? null), carryDifficulty: s.carry, deliveryFeeMinor: s.kind === "online" ? (s.deliveryFee ?? null) : null, freeDeliveryMinMinor: s.kind === "online" ? (s.freeDeliveryMin ?? null) : null, mealCardAccepted: Boolean(s.mealCards?.length), mealCardProviders: s.mealCards ?? [], note: s.note ?? "", seedRef: s.ref, createdBy: actor, updatedBy: actor, }); stores++; } const types = await ProductTypeModel.find({ householdId, seedRef: { $type: "string" } }) .select({ seedRef: 1, unit: 1 }) .lean<{ _id: Types.ObjectId; seedRef: string; unit: string }[]>(); const typeByRef = new Map(types.map((x) => [x.seedRef, x])); let products = 0; for (const p of PRODUCTS) { const type = typeByRef.get(p.type); if (!type || (await ProductModel.exists({ householdId, seedRef: p.ref }))) continue; if (!autoConvertible(p.unit, type.unit) && !p.typeQty) throw new Error(`Seed ürünü ${p.ref}: ${p.unit} → ${type.unit} dönüşümü eksik`); await ProductModel.create({ householdId, productTypeId: type._id, brand: p.brand, name: p.name ?? "", searchKey: foldTr(`${p.brand} ${p.name ?? ""}`), barcode: p.barcode ?? null, packageQuantity: p.qty, packageUnit: p.unit, typeQuantity: autoConvertible(p.unit, type.unit) ? null : p.typeQty, seedRef: p.ref, createdBy: actor, updatedBy: actor, }); products++; } return { stores, products }; }