Files
mbmanager-api/components/warehouse/warehouseSeeder.js
T
2026-08-30 09:29:21 +03:30

177 lines
6.7 KiB
JavaScript

const Warehouse = require('./warehouseModel')
const WarehouseItem = require('../warehouseItem/warehouseItemModel')
const WarehouseItemTransaction = require('../warehouseItem/warehouseItemTransactionModel')
const WarehouseItemStock = require('../warehouseItem/warehouseItemStockModel')
const User = require('../user/userModel')
const chalk = require('chalk')
const runSeeder = async () => {
// 1. Find or create admin user for actor
const adminUser = await User.findOne({ email: 'superadmin@mbmanager.ir' }) || await User.findOne()
// 2. Warehouses
const sampleWarehouses = [
{
name: 'انبار مرکزی تهران',
code: 'WH-TEH-01',
location: 'تهران، جاده مخصوص کرج، کیلومتر ۱۱',
description: 'انبار اصلی مصالح ساختمانی و تجهیزات مکانیکی',
isActive: true,
},
{
name: 'انبار پروژه نیاوران',
code: 'WH-NYA-02',
location: 'تهران، نیاوران، خیابان باهنر',
description: 'انبار پای کار پروژه برج یاس',
isActive: true,
},
{
name: 'انبار مصالح اصفهان',
code: 'WH-ISF-01',
location: 'اصفهان، شهرک صنعتی جی',
description: 'انبار پشتیبانی پروژه‌های مرکزی',
isActive: true,
},
]
const createdWarehouses = []
for (const wh of sampleWarehouses) {
let doc = await Warehouse.findOne({ name: wh.name })
if (!doc) {
doc = await Warehouse.create(wh)
}
createdWarehouses.push(doc)
}
// 3. Warehouse Items
const sampleItems = [
{
nameFa: 'سیمان تیپ ۲ (کیسه ۵۰ کیلویی)',
nameEn: 'Cement Type 2 (50kg)',
code: 'CEM-T2-50',
unitFa: 'کیسه',
unitEn: 'Bag',
category: 'مصالح پایه',
description: 'سیمان پرتلند تیپ ۲ استاندارد',
},
{
nameFa: 'میلگرد آجدار سایز ۱۶ (A3)',
nameEn: 'Rebar A3 Size 16',
code: 'REB-16-A3',
unitFa: 'شاخه',
unitEn: 'Piece',
category: 'آهن آلات',
description: 'میلگرد شاخه ۱۲ متری فولاد مبارکه',
},
{
nameFa: 'سرامیک پرسلان ۶۰*۱۲۰',
nameEn: 'Porcelain Tile 60x120',
code: 'TIL-60120-P',
unitFa: 'مترمربع',
unitEn: 'Sqm',
category: 'نازک‌کاری',
description: 'سرامیک درجه یک کالیبره مات',
},
{
nameFa: 'لوله پلی‌اتیلن سایز ۶۳',
nameEn: 'PE Pipe Size 63',
code: 'PIP-PE-63',
unitFa: 'متر',
unitEn: 'Meter',
category: 'تأسیسات مکانیکی',
description: 'لوله آبرسانی ۱۰ بار استاندارد',
},
{
nameFa: 'رنگ اکریلیک پایه آب (حلب ۲۰ لیتری)',
nameEn: 'Acrylic Paint 20L',
code: 'PNT-ACR-20L',
unitFa: 'حلب',
unitEn: 'Can',
category: 'رنگ و نقاشی',
description: 'رنگ مات قابل شستشو درجه یک',
},
]
const createdItems = []
for (const it of sampleItems) {
let doc = await WarehouseItem.findOne({ code: it.code })
if (!doc) {
doc = await WarehouseItem.create(it)
}
createdItems.push(doc)
}
// 4. Sample Transactions
const txCount = await WarehouseItemTransaction.countDocuments()
if (txCount === 0 && adminUser && createdWarehouses.length > 0 && createdItems.length > 0) {
const sampleTransactions = [
{
item: createdItems[0]._id,
warehouse: createdWarehouses[0]._id,
type: 'IN',
quantity: 500,
unit: createdItems[0].unitFa,
reason: 'خرید مستقیم از کارخانه سیمان تهران',
actor: adminUser._id,
actorName: adminUser.name || 'مدیر سیستم',
note: 'بارگیری از کارخانه با فاکتور شماره ۱۲۸۹',
},
{
item: createdItems[1]._id,
warehouse: createdWarehouses[0]._id,
type: 'IN',
quantity: 120,
unit: createdItems[1].unitFa,
reason: 'تأمین آهن‌آلات اسکلت سازه',
actor: adminUser._id,
actorName: adminUser.name || 'مدیر سیستم',
},
{
item: createdItems[0]._id,
warehouse: createdWarehouses[1]._id,
type: 'OUT',
quantity: 80,
unit: createdItems[0].unitFa,
reason: 'مصرف در بتن‌ریزی سقف طبقه پنجم',
actor: adminUser._id,
actorName: adminUser.name || 'مدیر سیستم',
},
{
item: createdItems[2]._id,
warehouse: createdWarehouses[0]._id,
type: 'IN',
quantity: 350,
unit: createdItems[2].unitFa,
reason: 'خرید مصالح نازک‌کاری',
actor: adminUser._id,
actorName: adminUser.name || 'مدیر سیستم',
},
{
item: createdItems[3]._id,
warehouse: createdWarehouses[1]._id,
type: 'IN',
quantity: 200,
unit: createdItems[3].unitFa,
reason: 'تجهیز تأسیسات لوله‌کشی آب',
actor: adminUser._id,
actorName: adminUser.name || 'مدیر سیستم',
},
]
for (const tx of sampleTransactions) {
await WarehouseItemTransaction.create(tx)
// Update or create stock
const delta = tx.type === 'IN' ? tx.quantity : -tx.quantity
await WarehouseItemStock.findOneAndUpdate(
{ item: tx.item, warehouse: tx.warehouse },
{ $inc: { quantity: delta } },
{ upsert: true, new: true }
)
}
console.log(chalk.green.bold(`WAREHOUSE: Created ${sampleTransactions.length} sample inventory transactions`))
}
}
module.exports = { runSeeder }