- Add WarehouseItem model with bilingual names (FA/EN) and bilingual counting units - Add WarehouseItemTransaction model for IN/OUT movements with reason and actor - Add WarehouseItemStock model for denormalized per-(item×warehouse) running balance - Add warehouseItemService with full CRUD, atomic stock updates via $inc, negative stock guard, and aggregation queries for per-item/per-warehouse/total stock - Add warehouseItemController and REST routes at /api/warehouse-items - Add warehouseService, warehouseController, warehouseRoutes for warehouse location CRUD at /api/warehouses - Register both route groups in routerEndpoints.js
63 lines
2.0 KiB
JavaScript
63 lines
2.0 KiB
JavaScript
const Warehouse = require('./warehouseModel')
|
|
const AppError = require('../../globalErrorHandler/AppError')
|
|
|
|
const createWarehouse = async (data) => {
|
|
const warehouse = await Warehouse.create({
|
|
name: data.name,
|
|
code: data.code || undefined,
|
|
location: data.location,
|
|
manager: data.manager,
|
|
description: data.description,
|
|
})
|
|
return warehouse
|
|
}
|
|
|
|
const listWarehouses = async (query = {}) => {
|
|
const filter = {}
|
|
if (query.isActive !== undefined) filter.isActive = query.isActive === 'true'
|
|
if (query.search) {
|
|
filter.$or = [
|
|
{ name: { $regex: query.search, $options: 'i' } },
|
|
{ code: { $regex: query.search, $options: 'i' } },
|
|
]
|
|
}
|
|
|
|
const warehouses = await Warehouse.find(filter)
|
|
.populate('manager', 'name email')
|
|
.sort({ createdAt: -1 })
|
|
|
|
return warehouses
|
|
}
|
|
|
|
const getWarehouse = async (warehouseId) => {
|
|
const warehouse = await Warehouse.findById(warehouseId).populate('manager', 'name email')
|
|
if (!warehouse) throw new AppError('انبار یافت نشد', 404, {})
|
|
return warehouse
|
|
}
|
|
|
|
const updateWarehouse = async (warehouseId, data) => {
|
|
const allowed = ['name', 'code', 'location', 'manager', 'description', 'isActive']
|
|
const update = {}
|
|
allowed.forEach((field) => {
|
|
if (data[field] !== undefined) update[field] = data[field]
|
|
})
|
|
|
|
const warehouse = await Warehouse.findByIdAndUpdate(warehouseId, update, { new: true, runValidators: true })
|
|
if (!warehouse) throw new AppError('انبار یافت نشد', 404, {})
|
|
return warehouse
|
|
}
|
|
|
|
const deleteWarehouse = async (warehouseId) => {
|
|
const warehouse = await Warehouse.findByIdAndUpdate(warehouseId, { isActive: false }, { new: true })
|
|
if (!warehouse) throw new AppError('انبار یافت نشد', 404, {})
|
|
return warehouse
|
|
}
|
|
|
|
module.exports = {
|
|
createWarehouse,
|
|
listWarehouses,
|
|
getWarehouse,
|
|
updateWarehouse,
|
|
deleteWarehouse,
|
|
}
|