Merge: Products/Catalog module (agente eden-commercial)

This commit is contained in:
2026-09-03 09:40:44 -03:00
7 changed files with 430 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
import { query } from "../pool.js";
export interface Product {
id: string;
created_at: Date;
updated_at: Date;
created_by: string | null;
product_code: number;
name: string;
description: string | null;
product_type: string;
product_group: string | null;
product_subgroup: string | null;
brand: string | null;
unit: string;
active: boolean;
discontinued: boolean;
tracks_stock: boolean;
tracks_serial: boolean;
tracks_asset_tag: boolean;
tracks_mac: boolean;
price_0: string | null;
price_12: string | null;
price_24: string | null;
price_36: string | null;
price_48: string | null;
impl_unit_price: string;
}
export async function listProducts(includeInactive = false): Promise<Product[]> {
const { rows } = await query<Product>(
includeInactive
? "SELECT * FROM products ORDER BY created_at ASC"
: "SELECT * FROM products WHERE active = true ORDER BY created_at ASC",
);
return rows;
}
export async function getProductById(id: string): Promise<Product | null> {
const { rows } = await query<Product>("SELECT * FROM products WHERE id = $1", [id]);
return rows[0] ?? null;
}
export interface CreateProductInput {
name: string;
description?: string | null;
productType: string;
productGroup?: string | null;
productSubgroup?: string | null;
brand?: string | null;
unit?: string;
active?: boolean;
discontinued?: boolean;
tracksStock?: boolean;
tracksSerial?: boolean;
tracksAssetTag?: boolean;
tracksMac?: boolean;
price0?: number | null;
price12?: number | null;
price24?: number | null;
price36?: number | null;
price48?: number | null;
implUnitPrice?: number;
createdBy?: string | null;
}
export async function createProduct(input: CreateProductInput): Promise<Product> {
const { rows } = await query<Product>(
`INSERT INTO products (
name, description, product_type, product_group, product_subgroup, brand, unit,
active, discontinued, tracks_stock, tracks_serial, tracks_asset_tag, tracks_mac,
price_0, price_12, price_24, price_36, price_48, impl_unit_price, created_by
) VALUES (
$1,$2,$3,$4,$5,$6,COALESCE($7,'unidade'),
COALESCE($8,true),COALESCE($9,false),COALESCE($10,false),COALESCE($11,false),COALESCE($12,false),COALESCE($13,false),
$14,$15,$16,$17,$18,COALESCE($19,0),$20
)
RETURNING *`,
[
input.name,
input.description ?? null,
input.productType,
input.productGroup ?? null,
input.productSubgroup ?? null,
input.brand ?? null,
input.unit ?? null,
input.active ?? null,
input.discontinued ?? null,
input.tracksStock ?? null,
input.tracksSerial ?? null,
input.tracksAssetTag ?? null,
input.tracksMac ?? null,
input.price0 ?? null,
input.price12 ?? null,
input.price24 ?? null,
input.price36 ?? null,
input.price48 ?? null,
input.implUnitPrice ?? null,
input.createdBy ?? null,
],
);
const product = rows[0];
if (!product) throw new Error("failed to create product");
return product;
}
export type UpdateProductInput = Partial<Omit<CreateProductInput, "createdBy">>;
export async function updateProduct(id: string, input: UpdateProductInput): Promise<Product | null> {
const { rows } = await query<Product>(
`UPDATE products SET
name = COALESCE($2, name),
description = COALESCE($3, description),
product_type = COALESCE($4, product_type),
product_group = COALESCE($5, product_group),
product_subgroup = COALESCE($6, product_subgroup),
brand = COALESCE($7, brand),
unit = COALESCE($8, unit),
active = COALESCE($9, active),
discontinued = COALESCE($10, discontinued),
tracks_stock = COALESCE($11, tracks_stock),
tracks_serial = COALESCE($12, tracks_serial),
tracks_asset_tag = COALESCE($13, tracks_asset_tag),
tracks_mac = COALESCE($14, tracks_mac),
price_0 = COALESCE($15, price_0),
price_12 = COALESCE($16, price_12),
price_24 = COALESCE($17, price_24),
price_36 = COALESCE($18, price_36),
price_48 = COALESCE($19, price_48),
impl_unit_price = COALESCE($20, impl_unit_price)
WHERE id = $1
RETURNING *`,
[
id,
input.name ?? null,
input.description ?? null,
input.productType ?? null,
input.productGroup ?? null,
input.productSubgroup ?? null,
input.brand ?? null,
input.unit ?? null,
input.active ?? null,
input.discontinued ?? null,
input.tracksStock ?? null,
input.tracksSerial ?? null,
input.tracksAssetTag ?? null,
input.tracksMac ?? null,
input.price0 ?? null,
input.price12 ?? null,
input.price24 ?? null,
input.price36 ?? null,
input.price48 ?? null,
input.implUnitPrice ?? null,
],
);
return rows[0] ?? null;
}