Skip to main content

noon-listing

Noon listing operations — create SKU (3-step wizard) and edit listings (Offer / Content / Sizes / Groups tabs). Load when creating, editing, pricing, restocking, or updating content on a noon SKU.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
zpoint/vibe-seller
آخر نشاط في المصدر
٢٠ سبتمبر ٢٠٢٦ في ٠٦:٤٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٨٣
التفرعات
١٩

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
noon-listing
description
Noon listing operations — create SKU (3-step wizard) and edit listings (Offer / Content / Sizes / Groups tabs). Load when creating, editing, pricing, restocking, or updating content on a noon SKU.
requires
["noon-shared"]
review
{"criteria":"- The SKU is ACTUALLY created and live on noon, not just \"submitted\":\n the create flow reached the success redirect to\n /catalog/{noon_sku}/p, and the Offer tab shows the base price /\n sale price / stock / barcode as entered (committed on the live\n page). Content/Sizes match the request.\n- For a NIS import: the import's **Report File** is non-empty and\n every row carries a `catalog_sku`. `Status: Complete` and\n `Total Processed Rows: N` are NOT evidence of creation — an import\n that created nothing shows both, with a 4-byte Report File.\n- Every bilingual field the request supplied in English also has its\n Arabic half on the live Content tab (title, long description, each\n feature bullet) — not a stub a fraction of the English length.\n- An edit is done only when the live page reflects it (green success\n + updated values), not on a toast alone.\n","verify_by":"Open the created SKU's catalog page and its Offer tab; confirm price\n/ stock / barcode match what was entered. For an edit, reload the tab\nand confirm the new values persisted. A feed/toast without the live\npage reflecting it is a gap. For a NIS import, additionally download\nthe import's Report File and confirm one row per SKU with a\n`catalog_sku`, and open the Content tab to confirm the Arabic half of\nevery filled English field. Import-row counters are not evidence.\n"}
# Noon — Listing Operations > **PREREQUISITE:** Read `../noon-shared/SKILL.md` for login, page > structure, modals, and button-click patterns. Covers SKU creation and the post-creation edit flow (price, stock, barcode, content, visibility status). > **Two create paths — PREFER file-based, FALL BACK to click.** > File-based (§1, NIS spreadsheet import) sets every hard field through a > spreadsheet, so it never touches the Ant-Design dropdowns (Warranty, > Department, Gender, Size, Content selects) that the click wizard needs > a *trusted mouse* to open — those dropdowns are the recurring wall on > the click path. Use file-based whenever creating one or more SKUs of a > known category. Use the click wizard (§2) only for a one-off where you > can drive a real trusted click, or to *edit* a SKU after creation. ## 1. Create Listing — File-based (PREFERRED, NIS import) Noon's **NIS** (noon Item Sheet) importer creates SKUs in bulk from a spreadsheet. Everything the click wizard sets via a dropdown is a plain cell here, so it sidesteps the anti-automation selects entirely. **Flow:** `Imports` → **Add Import** → **Type = Content**, **Subtype = NIS Create/Update** → pick the category → **Download** the template → fill it → **Next** → upload → SKUs go to async Quality Check (QC). URL: `https://noon-catalog.noon.partners/en/imports/create?project=PRJ{project_id}` The Type / Subtype selects are Ant-Design dropdowns — open each with a trusted `click_at_xy` on the field, then option-click the item in `.ant-select-dropdown .ant-select-item` (type-to-filter does NOT work; see `../noon-shared`). ### 1.1 Which import for which field Imports are keyed by **Type → Subtype**. The relevant ones: | Type | Subtype | Creates / sets | |------|---------|----------------| | Content | **NIS Create/Update** | **Creates new SKUs** — identity, sizes, attributes, images, in bulk. This is the create step. | | Content | Product Import | *Updates* content (title/description/attributes) of **existing** SKUs only. | | Pricing | **Price Update** | Base price + sale price/window for existing SKUs (see §1.3). | | Pricing | Price Range Update | Long-dated sale windows (the discount pattern, §1.3). | | Stock | (stock subtype) | On-hand quantity for existing SKUs. **Match the store's warehouse type**: an FBP Stock Update fails ("no FBP warehouse") if the store has none; FBN stock requires an ASN shipment flow, not a stock import. Check the SKU's Offer→Stock section for which warehouse the store actually has before choosing the stock import. | | Warranty | (warranty subtype) | Warranty type for existing SKUs (file equivalent of the click "No Warranty"). | So a full file-based create is: **NIS Create/Update** (identity + images) → then **Price Update** (price) and **Stock** as follow-up imports keyed on the `seller_sku`/`partner_sku` you assigned. Each import's own "ABOUT THIS UPLOAD" panel lists its exact Required/Optional columns — read it in-page before filling; do not assume. ### 1.2 The NIS template (Content → NIS Create/Update) - **Category**: "Download templates for" → **Specific category** → drill the tree (e.g. **Apparel** → product-types incl. *Socks & Tights*) and select it, **plus** the target store/marketplace, to enable the per-category **Download English** / **Download English + Arabic** buttons (AE stores need the +Arabic template for the local title). "All categories" downloads a generic shell without the category attribute columns — only use it to see the structure. - **`With Instructions`** checkbox adds a column-guidance row — leave it on the first time. - **Core required columns** (from the template's `valid values` sheet): `family`, `product_type`, `product_subtype`, `seller_sku`, `item_condition` (`New`), `parent_child_variation` (`Parent`/`Child` for sized products), and per-marketplace `vat_rate_ae` / `vat_rate_sa` / `vat_rate_eg` (`Std`). Category attribute columns + image-URL columns follow — fill per the in-sheet guidance and the linked "How to fill out the NIS sheet" article. - Each row needs a **unique `seller_sku`**. Partial failures are per-row: good rows still create; fix the error file and re-upload the rest. - **A parent needs a child — a lone parent creates NOTHING.** Verified live: a single row with `parent_child_variation=parent` imports "successfully" but the SKU never appears, and the error file's `creation_error` column reads **`child is missing`**. Every product needs **two rows sharing one `parent_group_key`**: a `parent` row (identity) **and** at least one `child` row (the sellable variant, with its own distinct `seller_sku` and a `size_variation`/`size_map`, e.g. `One Size`). The **child** is what carries the offer — follow-up Pricing/Stock imports key on the **child** `seller_sku`. - **Multiple sizes = one parent row + one child row PER SIZE** (all sharing the parent's `parent_group_key`). Verified live: a parent + three children (`size_variation`/`size_map` = `S`, `M`, `L`, distinct `seller_sku`s) created one parent noon-SKU with children `-1/-2/-3`, one per size — the same shape a real sized product uses (e.g. an S/M/L/XL/XXL family is a parent + five child rows). `size_map` is the **noon** size and may differ from your label (e.g. `XXL` → noon `2XL`); check the template's `valid values` / the live **Sizes tab** for the noon size names. This is noon's **new** variation style — always use it for new listings. ⚠️ **NIS has no Arabic-size column — only `size_variation` (Seller Size EN) and `size_map` (noon Size).** So after a NIS create the sized product's **Seller Size (AR)** — a `*`-mandatory field on the Sizes tab — is not authored by you: noon back-fills it with the *English* `size_variation` string, so the field looks satisfied while showing English text in the Arabic column. (An earlier revision of this skill said it shows `--`; re-verified, it is the copied English value.) Either way the family is bound but not content-complete. Fill the Arabic seller size per row on the live **Sizes tab** (edit each size) after import. Verified live: a parent + S/M/L children imported correctly (one parent hash, children `-1/-2/-3`, all shown bound on the Sizes tab) but with **Seller Size (AR) holding the English `size_variation` string** until replaced by hand. - **Leave a field BLANK unless the task specified it.** This is the default, not a preference. A NIS sheet has ~150 columns and almost all of them are optional; filling one "because it is there" invents data the seller never agreed to. Every invented value in the one audited run was wrong: `hs_code` was a guessed 4-digit customs code (rejected for length), a select attribute carried a value nobody claimed (rejected as out-of-enum), and one answer of "100 AED" was fanned out to `msrp_ae`, `msrp_sa` **and** `msrp_eg` — pricing two marketplaces the user never priced, one of which the seller does not sell in. > ⚠️ **On noon an invented value is effectively permanent.** A blank > cell in a NIS *update* means "no change", NOT "clear" — verified: an > update whose `msrp_*` cells were emptied imported with 0 errors and > left the live values untouched. Clearing them on the Content tab did > not persist either. So the only reliable moment to not have a wrong > value is **before the first upload**. If a field seems needed but the task did not give it, ASK — do not infer it from the English copy, the other marketplaces, or the Amazon listing. - **Pre-flight the sheet BEFORE uploading — always:** ```bash # Your CWD is the task workspace, not the skill dir — address the # script through the synced skill path. S=.claude/skills/noon-listing/scripts # --markets is the marketplaces the TASK covers, not the ones the # store has. "Only list on the UAE site" means --markets AE. python3 $S/validate_nis.py FILLED.xlsx --markets AE ``` It fails the file on the traps that have each burned a live import: a leftover template sample row, a select value that is not in the template's `valid values` sheet, an out-of-range `hs_code`, an English field whose Arabic half is empty, and a per-marketplace field (`msrp_*`, `vat_rate_*`) set outside the task's scope. A live import costs minutes and its error reporting is unreliable (below); this costs nothing. - **DELETE the template's sample row(s) before uploading.** The downloaded template ships a row carrying only `family` / `product_type` / `product_subtype` and no `seller_sku`. Leave it in and noon's Error File reports **only** that row's `seller_sku is missing` and silently drops every real row's `content_error`, while the counters read `1 error / N processed` — which reads as success. Verified: the same import's Error File still showed only the sample row 6.5 h later, and its Report File was empty. - **Upload flow (filled NIS sheet):** Imports → Add Import → Type=Content, Subtype=NIS Create/Update → **Next** → drag/drop or pick the `.xlsx` (the hidden `input[type=file]` accepts `.csv,.xlsx`) → **Submit**. The import runs async (a `IMP…` code); it shows Completed even on row failures, so verify the SKUs actually appear in My Catalog. - **`Total Processed Rows` is NOT "created" — the Report File is.** The counter counts rows that passed *partner-level* validation; rows that then fail content validation still count toward it. The only trustworthy signal is the import's **Report File**: one row per SKU with a filled `catalog_sku` (and `sku_parent` for a variation family). A failed import's Report File is **4 bytes** — a UTF-8 BOM and a newline. Download it every time; do not report success without it. - **Reading the error file is the debug loop.** An import that shows Completed but creates nothing failed row validation; open the import's Result/error CSV — its trailing `partner_error` / `content_error` / `creation_error` columns name the exact problem. Fix those cells (use the exact valid-value strings) and re-upload. If the error file names only a row you did not write, you still have a sample row in the file (above) — remove it and re-upload to see the real errors. - **Fill BOTH halves of every bilingual pair.** The `English + Arabic` template pairs each localised field (`product_title_*`, `long_description_*`, `feature_bullet_N_*`, `colour_name_*`). Filling only `_en` imports clean — no error, no warning — and ships a half-translated listing; shipped once with all four Arabic feature bullets empty and Arabic title/description stubs a third the length of their English source. `validate_nis.py` fails the file on a missing `_ar`, and warns when one is suspiciously short. ### 1.3 Pricing import — optional high-base + long sale (a seller pattern) Some sellers list a **high base price** and a **long-dated half-price sale** so the page shows a large discount on day one, while the true selling price is the sale price every day. This is a **guideline, not a requirement** — only apply it when the seller asks for it. To do it file-based, after the SKU exists run **Pricing → Price Update** (columns: required `country_code`, `id_partner`, `partner_sku`; optional `price`, `sale_price`, `sale_start`, `sale_end`, `is_active`): - `price` = the high base (e.g. `100`) - `sale_price` = the real everyday price (e.g. `50`) - `sale_start` = today, `sale_end` = a far-future date (e.g. +5 years) For a rolling window use **Pricing → Price Range Update**. If the seller did not ask for the discount pattern, just set `price` to the real price and leave the sale columns blank. ## 2. Create Listing — Click wizard (FALLBACK) **URL**: `https://noon-catalog.noon.partners/en/catalog/create?project=PRJ{project_id}` > Use this only when file-based isn't practical (a true one-off you can > drive with a real trusted click). It needs trusted `click_at_xy` for > every Ant-Design select; a programmatic `.click()` / nativeSetter does > NOT register. If a required dropdown won't open, fall back to §1. 3-step wizard: **Category → Brand → Identity**. > **MINIMAL PATH to a valid listing — do exactly these, in order, and > STOP:** > 1. Wizard create (Category → Brand → Identity), `fill_input` the SKU. > 2. **Offer tab** → `fill_input` **Base Price**, then **set Warranty** > (MANDATORY — see below), then **Save Changes** (green modal; price > persists across reload). > 3. **Content** on `/d?code=…&tab=content` → Product **Title** (EN via > `fill_input`, Arabic via `Input.insertText` — see §2.7) + set > **Gender** (MANDATORY; Department + Arabic gender auto-derive — §2.7) > → **Save Changes** → Submit → "sent for review" (async QC — done; > do NOT re-fill). > 4. **Image** (mandatory ≥1): upload the seller's **real product photo** > (§2.7) — a placeholder fails noon's async image validation and the > listing never goes live. > 5. **Seller Status → ON**. > > **Warranty is MANDATORY — but trivial: select "No Warranty".** The > Offer save FAILS with `Save failed — Warranty / No Offer Created` > unless the Warranty **type** is set. Do NOT try to configure a real > warranty (service center + 1–60mo duration — that path IS an > anti-automation rathole). Just open the Warranty **type** select and > pick **"No Warranty"** (options: No Warranty / Seller Warranty / > Manufacturer Warranty) — no service center or duration needed, and the > offer saves. Open it with a trusted `click_at_xy` on the select's > centre (it's below the fold — grow the viewport via > `Emulation.setDeviceMetricsOverride` first), then click the > **"No Warranty"** option in the `.ant-select-dropdown`. Verified live: > price + No-Warranty → Save → offer created, persists across reload. > > **Gender IS MANDATORY (verified live) — Department derives from it.** > Content Check flags `Missing Department` until Gender is set; you do > NOT set Department directly (there is no Department field). Set the > **English `Gender *`** select (e.g. `Men`) and noon **auto-fills the > Arabic gender (`رجال`) and clears the Department requirement**. The > Gender select is the same anti-automation ant-select as Warranty — open > it with the virtual-list technique in §2.7 (grow viewport → scroll the > dropdown's `.rc-virtual-list-holder` → in-panel trusted `click_at_xy`). > An earlier note calling Gender "optional, skip it" was WRONG — a listing > without Gender never clears mandatory content and never goes live. > > **These ARE optional — skip unless the seller asked:** Size Unit, > Feature Bullets, Long Description, Material, Colour, and the other > detailed-content attributes. The listing saves and goes live without > them. If a seller explicitly wants one and its dropdown won't open with > §2.7, note it as a manual follow-up rather than looping. **Runnable Offer-tab snippet (price + No Warranty) — copy verbatim.** The below-fold Warranty select can't be found by an un-scrolled DOM query; this grows the viewport, trusted-clicks the Warranty card's select, and picks "No Warranty". It also clears the price field first (`fill_input` *appends* if a value is already present → `59.59.9`). Verified live: ```bash browser-use <<'PY' import time, json # 1) price — clear first (fill_input appends to an existing value), then fill js("var i=document.querySelector('input[name=new_price]'); if(i){i.value='';}") fill_input('input[name="new_price"]', '59.90') # 2) Warranty = No Warranty (MANDATORY). Grow viewport (it's below fold), # trusted-click the Warranty card's ant-select, option-click No Warranty. cdp("Emulation.setDeviceMetricsOverride", width=1500, height=2200, deviceScaleFactor=1, mobile=False) time.sleep(2) info = js("""(function(){
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub