xforge · tài liệu FE

FE: module product — sản phẩm, biến thể, thuộc tính #

Phần chung (khởi tạo client, lỗi, danh sách, ngôn ngữ) ở tài liệu FE của Core: docs/fe/common.md (bản đọc: xforge-documentation, ADR-0102 của xforge-core). Sửa file này CÙNG PR khi đổi hành vi FE thấy được của module.

Mô hình #

sản phẩm (code, status, brand, category, đơn vị gốc, ảnh, bản dịch, version)
  ├─ đơn vị bán thêm  uoms[]: { uomId, factor }      (vd thùng = 24 lon)
  └─ biến thể         variants[] (≥ 1): sku, barcode, price, compareAtPrice, currency,
                        options[] (một giá trị mỗi thuộc tính: Màu = Đỏ, Size = M),
                        unitPrices[] (giá theo MỌI đơn vị bán, đơn vị gốc trước)
thuộc tính  attributes (Màu, Size…) + values (Đỏ, Xanh… có thể có màu swatch #RRGGBB)

CMS / admin (XforgeClient) #

Menu: key product.products (quyền product.read).

ViệcMethodQuyền
Danh sáchlistProducts({ query }) — không kèm biến thể: variantCount, minPrice / maxPriceproduct.read
Picker sản phẩmlistProductOptions({ query })product.read
Picker biến thể (SKU)listProductVariantOptions({ query }) — cho form nhập kho, đơn…product.read
Chi tiếtgetProduct({ params: { id } }) — kèm ảnh, đơn vị, MỌI biến thểproduct.read
Tạo (kèm biến thể)createProduct({ body })product.create
Sửa sản phẩmupdateProduct({ params: { id }, body: { version, … } })product.update
Thêm / sửa / xoá biến thểaddProductVariant / updateProductVariant / deleteProductVariant (query: { version })product.update
Xoá (thùng rác) / khôi phụcdeleteProduct / listProductTrash / restoreProductproduct.delete / product.restore
Xoá vĩnh viễndeleteProduct({ params: { id }, query: { force: "true" } })+ product.hard_delete
Thuộc tính + giá trịlistProductAttributes, createProductAttribute, …AttributeValueproduct.read / product.manage_attributes

Xuất / nhập file (dataset product.products) #

Màn hình chung của Core (docs/fe/cms.md §7, listDatasets, exportDataset, importDataset…). Xuất cần product.read. Nhập cần product.update; dòng tạo SẢN PHẨM mới cần thêm product.create (không có → forbidden ở đúng dòng).

Mỗi dòng = một biến thể, khoá là SKU; các dòng cùng productCode là một sản phẩm. Nhập lại cùng file không nhân đôi: dòng không đổi tính skipped, sản phẩm không tăng version.

CộtMứcGhi chú
productCode, sku, pricebiến thểbắt buộc. Không chuyển SKU sang sản phẩm khác
barcode, compareAtPrice, weightGrams, sortOrder, activebiến thể
currencybiến thểvắng = tiền của store. Biến thể đã có: không đổi qua file
optionsbiến thểtheo MÃ: color=red\|size=m; thuộc tính + giá trị phải có sẵn
name, shortDescription, slug, metaTitle, metaDescriptionsản phẩmbản dịch của lang
langsản phẩmvắng = ngôn ngữ mặc định của store; phải là ngôn ngữ store hỗ trợ
brandCode, categoryCode, baseUomCodesản phẩmtheo MÃ, trong store
status, featured, productSortOrdersản phẩmfeatured: true / false; status áp ở dòng cuối của sản phẩm

Lỗi nhập nằm trong errors[] (HTTP vẫn 200, applied: false): line, code, message. Hiện message: câu đã dịch, đã có sẵn mã / cột cụ thể (item không có details).

codeNghĩa
product_import_missing_fieldssản phẩm mới còn thiếu cột
product_import_row_conflicthai dòng của cùng sản phẩm ghi khác nhau ở một cột
product_import_sku_duplicateSKU lặp trong file
product_import_sku_other_productSKU đang thuộc sản phẩm khác
product_import_currency_changeđổi tiền tệ của biến thể: làm ở form
product_import_price_formatsố tiền lẻ hơn đơn vị của loại tiền / dấu ngăn nghìn
product_brand_invalid / product_category_invalidmã không có trong store
product_uom_invalid / product_variant_options_invalidmã không có trong store
unsupported_languagelang không thuộc ngôn ngữ của store
forbiddenthiếu product.create cho dòng tạo sản phẩm mới
luật khác của form (product_not_publishable, product_slug_exists…)như bảng lỗi bên dưới

Storefront (StorefrontClient) #

Không cần đăng nhập. Chỉ sản phẩm active, có bản dịch và ít nhất một biến thể đang bật; trả kèm các biến thể đang bật.

Lỗi cần xử lý #

codeStatusFE nên
product_not_found404trang 404 (storefront: không còn bán / slug đổi)
version_conflict409người khác vừa lưu: tải lại, so, lưu lại
product_code_exists / product_sku_exists / product_barcode_exists409báo ở đúng ô (mã / SKU / mã vạch của biến thể)
product_slug_exists409báo ở ô slug của đúng ngôn ngữ
product_not_publishable409cần bản dịch + biến thể đang bật trước khi đặt active
product_variant_options_invalid400mỗi thuộc tính chọn đúng một giá trị
product_variant_attributes_mismatch409biến thể phải dùng cùng bộ thuộc tính với các biến thể khác
product_variant_combination_exists409tổ hợp lựa chọn đã có
product_last_variant409không xoá được biến thể duy nhất
product_variant_price_uom_invalid400giá đặt tay chỉ cho đơn vị bán thêm của sản phẩm
product_brand_invalid / product_category_invalid / product_uom_invalid400tham chiếu không thuộc store → tải lại picker
product_extra_uoms_invalid400đơn vị bán thêm phải khác đơn vị gốc
product_image_not_found404ảnh không còn → ảnh giữ chỗ
product_attribute_code_exists / product_attribute_value_code_exists409báo ở ô mã
resource_in_use409thuộc tính / giá trị còn được biến thể dùng
file_not_attachable400ảnh không phải file của store này
Nguồn: xforge-modules: modules/catalog/product/FE.md