import { Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import { DatabaseService } from '../../../infrastructure/database/database.service';
import {
assertLocationConfigurationInput,
assertReorderRuleInput,
assertStockItemCreateInput,
assertStorageLocationCreateInput,
} from './inventory-input-validation';
@Injectable()
export class InventorySetupService {
constructor(private readonly database: DatabaseService) {}
async createStorageLocation(input: {
organizationId: string;
locationId: string;
name: string;
storageType: string;
sortOrder?: number;
}) {
assertStorageLocationCreateInput(input);
const id = randomUUID();
await this.database.query(
`insert into storage_locations(
id,organization_id,location_id,name,storage_type,sort_order
) values($1,$2,$3,$4,$5,$6)`,
[
id,
input.organizationId,
input.locationId,
input.name,
input.storageType,
input.sortOrder ?? 0,
],
);
return { id };
}
async createStockItem(input: {
organizationId: string;
ingredientId?: string;
name: string;
baseUnitCode: string;
}) {
assertStockItemCreateInput(input);
const id = randomUUID();
await this.database.query(
`insert into stock_items(
id,organization_id,ingredient_id,name,base_unit_code
) values($1,$2,$3,$4,$5)`,
[
id,
input.organizationId,
input.ingredientId ?? null,
input.name,
input.baseUnitCode,
],
);
return { id };
}
async configureLocation(input: {
stockItemId: string;
locationId: string;
defaultStorageLocationId: string;
isTracked?: boolean;
}) {
assertLocationConfigurationInput(input);
await this.database.query(
`insert into stock_item_locations(
stock_item_id,location_id,default_storage_location_id,is_tracked
) values($1,$2,$3,$4)
on conflict(stock_item_id,location_id)
do update set
default_storage_location_id=excluded.default_storage_location_id,
is_tracked=excluded.is_tracked,
updated_at=now()`,
[
input.stockItemId,
input.locationId,
input.defaultStorageLocationId,
input.isTracked ?? true,
],
);
return { configured: true };
}
async setReorderRule(input: {
organizationId: string;
locationId: string;
stockItemId: string;
reorderPoint: string;
targetStock?: string;
unitCode: string;
}) {
assertReorderRuleInput(input);
const id = randomUUID();
await this.database.query(
`insert into reorder_rules(
id,organization_id,location_id,stock_item_id,
reorder_point,target_stock,unit_code
) values($1,$2,$3,$4,$5,$6,$7)
on conflict(location_id,stock_item_id)
do update set
reorder_point=excluded.reorder_point,
target_stock=excluded.target_stock,
unit_code=excluded.unit_code,
is_active=true,
updated_at=now(),
version=reorder_rules.version+1`,
[
id,
input.organizationId,
input.locationId,
input.stockItemId,
input.reorderPoint,
input.targetStock ?? null,
input.unitCode,
],
);
return { id };
}
}
