/** * POST /api/materials/warehouse-layouts — create a floor. * Body { warehouseId, name, floorNo, gridWidth, gridHeight, layout?, isDefault?, description? } */ import { withIdempiere } from '../../../utils/withIdempiere' import { LAYOUT_MODEL, LAYOUT_TABLE, bustCapabilities, errMessage, errStatus, isMissingTableError, mapLayoutRow, userNameFromCookie, warehouseOrg } from '../../../utils/warehouseLayout' import { createLayout, parseLayout } from '../../../../app/utils/warehouseLayout/schema' import fetchHelper from '../../../utils/fetchHelper' export default withIdempiere(async (event, token) => { const body = await readBody(event) const warehouseId = Number(body?.warehouseId) if (!warehouseId) return { status: 400, message: 'warehouseId required' } const parsed = body?.layout ? parseLayout(body.layout) : { layout: createLayout() } if (!parsed.layout) return { status: 400, message: 'invalid layout: ' + parsed.error } const layout = parsed.layout const gridWidth = Number(body?.gridWidth) || layout.grid.width const gridHeight = Number(body?.gridHeight) || layout.grid.height layout.grid = { width: gridWidth, height: gridHeight } layout.meta = { ...layout.meta, version: 1, savedAt: new Date().toISOString(), savedBy: userNameFromCookie(event) } const json = JSON.stringify(layout) if (json.length > 2 * 1024 * 1024) return { status: 413, message: 'layout too large' } const wh = await warehouseOrg(event, token, warehouseId) const orgId = wh.orgId ?? Number(getCookie(event, 'logship_organization_id')) try { const res: any = await fetchHelper(event, LAYOUT_MODEL, 'POST', token, { AD_Org_ID: { id: orgId, tableName: 'AD_Org' }, M_Warehouse_ID: { id: warehouseId, tableName: 'M_Warehouse' }, name: String(body?.name || wh.name || 'Layout').slice(0, 60), floorNo: Number(body?.floorNo) || 0, isDefault: body?.isDefault !== false, gridWidth, gridHeight, layoutJSON: json, layoutVersion: 1, appliedVersion: 0, description: String(body?.description || '').slice(0, 255), isActive: true, tableName: LAYOUT_TABLE }) bustCapabilities() return { status: 200, record: mapLayoutRow(res, true) } } catch (err: any) { const st = errStatus(err) if (st === 401 || st === 403) throw err if (isMissingTableError(err)) return { status: 424, layoutTableMissing: true, message: errMessage(err) } return { status: st || 500, message: errMessage(err) } } })