fix
This commit is contained in:
@@ -42,6 +42,7 @@ func NormalizeGTIN(ean string) string {
|
||||
}
|
||||
|
||||
// BuildMappedDataFromV1Item mirrors legacy buildMappedDataFromItem + image field storage.
|
||||
// Empty optional fields are omitted (not null) so jsonb || merges cannot wipe catalog titles.
|
||||
func BuildMappedDataFromV1Item(item V1ProcessItem) map[string]any {
|
||||
mapped := map[string]any{
|
||||
"ean": item.EAN,
|
||||
@@ -49,23 +50,15 @@ func BuildMappedDataFromV1Item(item V1ProcessItem) map[string]any {
|
||||
if item.Title != "" {
|
||||
mapped["title"] = item.Title
|
||||
mapped["name"] = item.Title
|
||||
} else {
|
||||
mapped["title"] = nil
|
||||
}
|
||||
if item.Description != "" {
|
||||
mapped["description"] = item.Description
|
||||
} else {
|
||||
mapped["description"] = nil
|
||||
}
|
||||
if len(item.Specifications) > 0 {
|
||||
mapped["specifications"] = item.Specifications
|
||||
} else {
|
||||
mapped["specifications"] = []any{}
|
||||
}
|
||||
if item.Search != "" {
|
||||
mapped["search"] = item.Search
|
||||
} else {
|
||||
mapped["search"] = nil
|
||||
}
|
||||
if item.CategoryUniqueID != "" {
|
||||
mapped["category"] = item.CategoryUniqueID
|
||||
@@ -77,6 +70,21 @@ func BuildMappedDataFromV1Item(item V1ProcessItem) map[string]any {
|
||||
return mapped
|
||||
}
|
||||
|
||||
// v1ItemHasContent reports whether the request carries feed/product fields beyond EAN.
|
||||
// EAN-only requests must resolve an existing catalog row (e.g. after admin clone).
|
||||
func v1ItemHasContent(item V1ProcessItem) bool {
|
||||
if strings.TrimSpace(item.Title) != "" || strings.TrimSpace(item.Description) != "" {
|
||||
return true
|
||||
}
|
||||
if strings.TrimSpace(item.CategoryUniqueID) != "" || strings.TrimSpace(item.Search) != "" {
|
||||
return true
|
||||
}
|
||||
if len(item.Specifications) > 0 {
|
||||
return true
|
||||
}
|
||||
return len(mappedImageFieldsFromV1Item(item)) > 0
|
||||
}
|
||||
|
||||
func mappedImageFieldsFromV1Item(item V1ProcessItem) map[string]any {
|
||||
source := map[string]any{}
|
||||
putIf := func(k, v string) {
|
||||
@@ -279,6 +287,10 @@ type EnsureRawResult struct {
|
||||
|
||||
// EnsureRawProductsFromV1Items finds or creates/updates raw_products by EAN for the company.
|
||||
// Returns successfully resolved IDs and per-item error messages (non-fatal for partial batches).
|
||||
//
|
||||
// EAN-only items reuse existing catalog mapped_data (e.g. after admin clone-from-company).
|
||||
// Creating a brand-new row requires at least one content field; otherwise callers get empty
|
||||
// "Product {ean}" stubs with no feed data.
|
||||
func (s *Service) EnsureRawProductsFromV1Items(ctx context.Context, companyID uuid.UUID, items []V1ProcessItem) (ids []uuid.UUID, results []EnsureRawResult, errs []string, err error) {
|
||||
if s == nil || s.Pool == nil {
|
||||
return nil, nil, nil, fmt.Errorf("catalog not configured")
|
||||
@@ -309,24 +321,23 @@ func (s *Service) EnsureRawProductsFromV1Items(ctx context.Context, companyID uu
|
||||
if qErr == nil {
|
||||
merged := map[string]any{}
|
||||
_ = json.Unmarshal(existingMapped, &merged)
|
||||
img := mappedImageFieldsFromV1Item(item)
|
||||
if len(img) > 0 {
|
||||
for k, v := range img {
|
||||
merged[k] = v
|
||||
changed := false
|
||||
for k, v := range mapped {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if item.CategoryUniqueID != "" {
|
||||
merged["category"] = item.CategoryUniqueID
|
||||
merged["category_unique_id"] = item.CategoryUniqueID
|
||||
if s, ok := v.(string); ok && strings.TrimSpace(s) == "" {
|
||||
continue
|
||||
}
|
||||
mergedJSON, _ := json.Marshal(merged)
|
||||
_, _ = s.Pool.Exec(ctx, `
|
||||
UPDATE raw_products
|
||||
SET mapped_data = $3::jsonb, updated_at = now()
|
||||
WHERE id = $1 AND company_id = $2`, existingID, companyID, string(mergedJSON))
|
||||
} else if item.CategoryUniqueID != "" {
|
||||
_ = json.Unmarshal(existingMapped, &merged)
|
||||
merged[k] = v
|
||||
changed = true
|
||||
}
|
||||
if item.CategoryUniqueID != "" {
|
||||
merged["category"] = item.CategoryUniqueID
|
||||
merged["category_unique_id"] = item.CategoryUniqueID
|
||||
changed = true
|
||||
}
|
||||
if changed {
|
||||
mergedJSON, _ := json.Marshal(merged)
|
||||
_, _ = s.Pool.Exec(ctx, `
|
||||
UPDATE raw_products
|
||||
@@ -342,6 +353,14 @@ func (s *Service) EnsureRawProductsFromV1Items(ctx context.Context, companyID uu
|
||||
continue
|
||||
}
|
||||
|
||||
if !v1ItemHasContent(item) {
|
||||
errs = append(errs, fmt.Sprintf(
|
||||
"No catalog product for EAN %s. Use a GTIN from the cloned/synced feed, or include title/description/images in the request.",
|
||||
item.EAN,
|
||||
))
|
||||
continue
|
||||
}
|
||||
|
||||
var newID uuid.UUID
|
||||
insErr := s.Pool.QueryRow(ctx, `
|
||||
INSERT INTO raw_products (company_id, gtin, raw_data, mapped_data, processing_status, is_processed)
|
||||
|
||||
Reference in New Issue
Block a user