fix(wizard): allow global materials without a canonical category
Quote creation was blocked for any new material whose typed name is not one of the 8 canonical category names: api.materials.create threw «دسته ... در سامانه تعریف نشده است» and the failed create cascaded a bogus temp material_id into the quote payload (invalid-payload error). v2.5+ model: materials are global (name UNIQUE) and the category attaches via the supplier (first-link-wins). The backend already accepts category_id=null (MaterialCreate schema + material_service). This removes the frontend-only hard block: unknown category names now create the material with category_id null, and the category is derived automatically from the first linked supplier on quote save. The 8 canonical categories are still never auto-created (no rogue-category regression). Verified end-to-end through the real API: create «سیم» (category null) → supplier → quote via material_id → 201/201/201 with material.category_id derived from the supplier; lint + build green.
This commit is contained in:
+6
-11
@@ -959,17 +959,12 @@ export const api = {
|
|||||||
},
|
},
|
||||||
create: async (m: Material): Promise<Material> => {
|
create: async (m: Material): Promise<Material> => {
|
||||||
const lookup = await fetchLookup();
|
const lookup = await fetchLookup();
|
||||||
|
// v2.5: category_id اختیاری است — اگر نامِ تایپشده یکی از ۸ دستهی ثابت
|
||||||
|
// نباشد، متریال بهصورت سراسری (بدون دسته) ساخته میشود و دستهاش بعداً
|
||||||
|
// از اولین تأمینکنندهی مرتبط استنتاج میشود (first-link-wins).
|
||||||
|
// دستهی rogue دیگر هرگز ساخته نمیشود — فقط تطبیق با ۸ دستهی موجود؛
|
||||||
|
// در صورت نبود تطبیق، خطا نمیدهیم و category_id را null میفرستیم.
|
||||||
const categoryId = m.category ? lookup.categoryNameToId.get(norm(m.category)) : undefined;
|
const categoryId = m.category ? lookup.categoryNameToId.get(norm(m.category)) : undefined;
|
||||||
// دستهها همان ۸ دستهی ثابت سیستماند و هرگز بهصورت خودکار ساخته
|
|
||||||
// نمیشوند — قبلاً اینجا برای هر نامِ ناشناخته یک رکورد material_categories
|
|
||||||
// میساخت و باگ «پریز» (دستهی rogue) را به وجود آورد.
|
|
||||||
if (!categoryId) {
|
|
||||||
throw new Error(
|
|
||||||
m.category
|
|
||||||
? `دسته «${m.category}» در سامانه تعریف نشده است — یکی از ۸ دستهی موجود را انتخاب کنید`
|
|
||||||
: "دستهی متریال مشخص نیست — یکی از ۸ دستهی موجود را انتخاب کنید",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// واحد مرجع — اگر تعریف نشده، بساز (بکاند canonical_unit_id الزامی دارد)
|
// واحد مرجع — اگر تعریف نشده، بساز (بکاند canonical_unit_id الزامی دارد)
|
||||||
const unitName = m.base_unit || "عدد";
|
const unitName = m.base_unit || "عدد";
|
||||||
const unitId = await unitIdByNameOrCreate(lookup, unitName);
|
const unitId = await unitIdByNameOrCreate(lookup, unitName);
|
||||||
@@ -988,7 +983,7 @@ export const api = {
|
|||||||
if (defId) attrs.push({ attribute_definition_id: defId, value: spec });
|
if (defId) attrs.push({ attribute_definition_id: defId, value: spec });
|
||||||
}
|
}
|
||||||
const raw = await postData<RawMaterial>("/materials", {
|
const raw = await postData<RawMaterial>("/materials", {
|
||||||
category_id: categoryId,
|
category_id: categoryId ?? null,
|
||||||
name,
|
name,
|
||||||
topic: m.topic || null,
|
topic: m.topic || null,
|
||||||
canonical_unit_id: unitId,
|
canonical_unit_id: unitId,
|
||||||
|
|||||||
Reference in New Issue
Block a user