fix(wizard): store material name cleanly instead of brand+category+specs

Adding a new item wrote the material name as 'brand + category + specs'
(e.g. 'پارس لوله لوله PE100 سایز ۱۶'), while specs were also stored
correctly in EAV attributes. The wizard then tried to recover the base
name by stripping brand and specs out of that string, but never stripped
the injected category — so the spec stayed baked into the cached material
name and the مشخصه appeared as part of the material name on later visits.

- api.ts / WizardPage / EditModal: build name from the material itself
  only (brand goes to brand_ids, specs to attributes)
- materialBaseName: strip category too, never strip a part that would
  empty the name, and reject a spec-only result; legacy rows whose name
  cannot be disentangled fall back to the stored name rather than a guess
- WizardPage: match existing materials on category+brand so legacy rows
  are still reused instead of duplicated
This commit is contained in:
MMD
2026-09-16 20:24:45 +03:30
parent b65938ef06
commit ae977e5e66
4 changed files with 38 additions and 20 deletions
+4 -2
View File
@@ -1041,8 +1041,10 @@ export const api = {
const unitId = await unitIdByNameOrCreate(lookup, unitName);
// برند — اگر تعریف نشده، در جدول brands ساخته و به متریال متصل می‌شود
const brandId = await brandIdByNameOrCreate(lookup, m.brand);
// تایپ جلوی برنامه name ندارد — از متریال/برند/مشخصه ساخته می‌شود
const name = [m.brand, m.category, ...(m.specs || [])].filter(Boolean).join(" ") || "کالای جدید";
// name فقط نامِ خودِ متریال است؛ برند در brand_ids و مشخصه‌ها در
// attributes (EAV) ذخیره می‌شوند. اگر برند/مشخصه داخل name ریخته شود،
// در ویزارد به‌عنوان «نامِ متریال» کش می‌شود و مشخصه‌ها در نام ظاهر می‌شوند.
const name = (m.category || m.brand || (m.specs || []).join(" ") || "").trim() || "کالای جدید";
// مشخصه‌ها به‌صورت attribute (EAV) ذخیره می‌شوند تا بعد از رفرش دیده شوند
const attrs: { attribute_definition_id: string; value: string }[] = [];
const seen = new Set<string>();