import { Injectable } from '@nestjs/common';
import {
DatabaseService,
type DatabaseQueryClient,
} from '../../../infrastructure/database/database.service';
import { DomainConflictError } from '../../../common/errors/domain-conflict.error';
@Injectable()
export class InventoryUnitConversionService {
constructor(private readonly database:DatabaseService) {}
async convert(input:{
quantity:string;
fromUnitCode:string;
toUnitCode:string;
},client?:DatabaseQueryClient):Promise<string> {
const db=client??this.database;
const rows=await db.query<{result:string}>(
`select
(($1::numeric*f.factor_to_base::numeric)
/nullif(t.factor_to_base::numeric,0))::numeric(24,8)::text as result
from units f
join units t on t.dimension=f.dimension
where f.code=$2 and t.code=$3
and f.factor_to_base is not null
and t.factor_to_base is not null`,
[input.quantity,input.fromUnitCode,input.toUnitCode],
);
if(!rows[0]) {
throw new DomainConflictError('inventory.unit_incompatible',{
fromUnitCode:input.fromUnitCode,toUnitCode:input.toUnitCode,
});
}
return rows[0].result;
}
async multiplyDivide(input:{
value:string;
multiplier:string;
divisor:string;
},client?:DatabaseQueryClient):Promise<string> {
const db=client??this.database;
const rows=await db.query<{result:string}>(
`select (($1::numeric*$2::numeric)/nullif($3::numeric,0))::numeric(24,8)::text as result`,
[input.value,input.multiplier,input.divisor],
);
if(!rows[0]) throw new DomainConflictError('inventory.decimal_calculation_failed');
return rows[0].result;
}
}
