Skip to content

Commit 4c2120a

Browse files
committed
Inventory tab: inline multi-warehouse table
Overhaul inventory UI and data flow: add TableHeaderOption model and table-values, introduce reserved_quantity to UpdateProductInventoryPayload and mapResponseToPayload, and replace the old inventory form with a full-featured inline multi-warehouse table. The ProductInventoryTab component now uses signals/computeds/local state, provides add/change/remove/toggles, computes totals and stock badges, and emits inventoriesChange. ProductWorkspace passes inventories and handles onInventoriesChange. Minor UX / template improvements and safer payload mapping included.
1 parent 892780b commit 4c2120a

7 files changed

Lines changed: 763 additions & 152 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface TableHeaderOption {
2+
key: string;
3+
label: string;
4+
align?: 'left' | 'center' | 'right';
5+
minWidth?: string;
6+
width?: string;
7+
showInReadOnly?: boolean;
8+
}

src/app/core/models/products/product-request.model.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export interface UpdateProductInventoryPayload {
128128
maximum_quantity?: number | null;
129129
allow_backorder?: boolean | null;
130130
active?: boolean | null;
131+
reserved_quantity?: number;
131132
}
132133

133134
/**
@@ -174,14 +175,13 @@ export function mapResponseToPayload(prod: {
174175
id?: string;
175176
warehouse: { id: string };
176177
quantity: number;
178+
reserved_quantity?: number;
177179
minimum_quantity?: number | null;
178180
maximum_quantity?: number | null;
179181
allow_backorder?: boolean;
180182
active?: boolean;
181183
}[];
182184
}): UpdateProductPayload {
183-
const firstInventory = prod.inventories?.[0];
184-
185185
return {
186186
// Referências (IDs de entidades relacionadas)
187187
category_id: prod.category?.id,
@@ -218,17 +218,17 @@ export function mapResponseToPayload(prod: {
218218
: undefined,
219219

220220
// Inventário: incluído apenas se o produto já tiver estoque cadastrado
221-
inventories: firstInventory
222-
? [
223-
{
224-
warehouse_id: firstInventory.warehouse.id,
225-
quantity: firstInventory.quantity,
226-
minimum_quantity: firstInventory.minimum_quantity ?? null,
227-
maximum_quantity: firstInventory.maximum_quantity ?? null,
228-
allow_backorder: firstInventory.allow_backorder ?? false,
229-
active: firstInventory.active ?? true,
230-
},
231-
]
221+
inventories: prod.inventories
222+
? prod.inventories.map((inv) => ({
223+
id: inv.id,
224+
warehouse_id: inv.warehouse.id,
225+
quantity: inv.quantity,
226+
reserved_quantity: inv.reserved_quantity || 0,
227+
minimum_quantity: inv.minimum_quantity ?? null,
228+
maximum_quantity: inv.maximum_quantity ?? null,
229+
allow_backorder: inv.allow_backorder ?? false,
230+
active: inv.active ?? true,
231+
}))
232232
: undefined,
233233

234234
// Relacionamentos: undefined (não enviados) até o usuário editar a aba correspondente.

0 commit comments

Comments
 (0)