CRM · Store create & edit
Multi-step store editor covering general data, physical-store attributes, the store QR code and centre-defined extra attributes, including social links, opening data, categories, zone, gift-card administrators and integration codes.
| Area | CRM |
| Routes | crm.commerces.new · crm.commerces.edit |
| Centre modules | crm · fideliza · intranet-sovos · intranet-yardi |
| Staff levels | root · admin · manager · scmanager · weboperator |
| Models | campaign · commerce · commerce-extra · commerce-type · extra · language · zone |
| UI label | crm.commerce.general-data |
| Coverage | 4 use cases · 2 happy · 8 failure |
Known issues (1)
How it works
Steps and tabs are computed, and several are module-conditional: hasYardi adds the tenant-code field (with a centre-specific label via yardiCodeLabel), hasFideliza brings in gift-card administrators, and canSeeIntelISales exposes IntelliSales. Extra attributes are handled separately from the model: requiredExtras is assembled per label and isValidCommerceExtra sets a bespoke extraError of the form `${label} is required` — note this message is built in code, not translated. saveCommerce validates the commerce, then saves extras, and special-cases HTTP 422 from the adapter. A loyalty-QR flow (downloadQr, searchCampaign, loadSelectedCampaign) ties a store QR to a campaign. Category selection supports select-all.
Use cases
Why someone opens this (4)
- Onboarding a new tenant: address, categories, contact, social links and images.
- Setting the Yardi tenant code so the store’s sales can be exported.
- Nominating gift-card administrators for a Fideliza-enabled centre.
- Printing a store’s loyalty QR code tied to a specific campaign.
Path map
flowchart LR F(["Store create and edit"]):::feat F --> H1["Store created with extras"]:::ok F --> H2["Loyalty QR downloaded"]:::ok F -.-> X1["Mandatory store fields missing"]:::bad F -.-> X2["Yardi code missing"]:::bad F -.-> X3["Malformed URL"]:::bad F -.-> X4["WhatsApp number without country code"]:::bad F -.-> X5["Invalid gift-card administrator emails"]:::bad F -.-> X6["Required extra attribute empty"]:::bad F -.-> X7["Unprocessable entity from the API"]:::bad F -.-> X8["Extras image/HTML with embedded images"]:::bad classDef feat fill:#157068,stroke:#157068,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Store created with extras
- User fills general data: name, categories, zone, address, locality, province, image.
- Yardi centres also require the tenant code.
- Extra attributes required by the centre are completed.
saveCommercevalidates the model, saves it, then persists the commerce-extras.- The store appears in the directory and in the app.
Loyalty QR downloaded
- User searches and selects a campaign for the store QR.
downloadQrrenders and downloads the QR image with the store name as alt text.
Failure paths
Mandatory store fields missing
Cause — Name, categories, zone, image, address, direction, locality or province blank.
What happens —
error.commerce.name.required,error.commerce.categories.required,error.commerce.zone.required,error.commerce.imageUrl.required,error.commerce.address.required,error.commerce.direction.required,error.commerce.locality.required,error.commerce.province.required.
Yardi code missing
Cause — Centre has Yardi but
tenantCodeis blank.What happens —
error.commerce.tenantCode.required(‘Yardi code is required’).
Malformed URL
Cause —
webUrlorbookTableUrldoes not match the http(s) regex.What happens —
error.commerce.web.format(‘The text must be a url’).
WhatsApp number without country code
Cause — Phone not in
+346xxxxxxxxshape.What happens —
error.commerce.whatsapp-phone.formatspells out the expected format; a WhatsApp message is also required (error.commerce.whatsapp-message.required).
Invalid gift-card administrator emails
Cause — One or more addresses malformed, or the field left empty when required.
What happens —
error.commerce.gift-card-admins.invalid-email/error.commerce.gift-card-admins.required.
Required extra attribute empty
Cause — A centre-defined required extra has no value.
What happens —
extraErroris set to an untranslated"<label> is required"string — inconsistent with the rest of the form’s localised errors.
Unprocessable entity from the API
Cause — Adapter returns 422 (e.g. duplicate name or code).
What happens — Explicitly branched on
'422' === adapterError.errors[0].status; other statuses fall through to the generic catch.
Extras image/HTML with embedded images
Cause — HTML extra contains an
<img>.What happens —
error.configuration.center.extra.image-not-suported(and the proposal/campaign equivalents) reject embedded images in rich-text fields.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Store created with extras
- ✅ Loyalty QR downloaded
- ⛔ Mandatory store fields missing
- ⛔ Yardi code missing
- ⛔ Malformed URL
- ⛔ WhatsApp number without country code
- ⛔ Invalid gift-card administrator emails
- ⛔ Required extra attribute empty
- ⛔ Unprocessable entity from the API
- ⛔ Extras image/HTML with embedded images
Implementation
app/controllers/crm/commerces/new.jsapp/routes/crm/commerces/new.jsapp/models/commerce.jsapp/models/commerce-extra.js
Translation keys (19)
Key English crm.commerce.general-dataGeneral Data crm.commerce.physical-storePhysical Store crm.commerce.qr-codeQR code of the store {name} crm.commerce.extra-attributesExtra attributes yardi-codeYardi code error.commerce.name.requiredName is required error.commerce.categories.requiredA category is required error.commerce.zone.requiredZone is required error.commerce.imageUrl.requiredImage url is required error.commerce.tenantCode.requiredYardi code is required error.commerce.web.formatThe text must be a url error.commerce.whatsapp-phone.formatWhatsApp phone doesn’t have a code area. It should follow the format +346xxxxxxxx. error.commerce.whatsapp-message.requiredA WhatsApp Message is required error.commerce.gift-card-admins.invalid-emailOne or more emails entered are not valid error.commerce.gift-card-admins.requiredField required error.commerce.address.requiredField required error.commerce.direction.requiredDirection required error.commerce.locality.requiredLocality required error.commerce.province.requiredProvince required
Related
- Same area — Customer list & filtering · Customer create & edit · Customer deletion with unsubscribe notice · Customer CSV export with column picker · Customer CSV import · Children CSV import · AI natural-language customer filter · Save current filters as a segment · Segment list, refresh & export · Segment builder with automatic tag actions · Segment categories · User tags (user types) · Customer receipts tab & ticket-stamp generation · Customer loyalty — raffle tickets · Customer loyalty — cards & stamps · Customer loyalty — rewards · Customer loyalty — coupon exchanges · Customer children (dependants) · Receipt verification queue · Store list, filters & exports · Store CSV import · Store labels (store types) · Customer action log (dormant)
- Shares data with — Proposal editor (content, coupon, push, AI images) · Activity editor (loyalty mechanics, rules & targeting) · Extra attributes · Activity campaigns (programme grouping) · App button manager (MOFs) · Multicentre proposals · Centre editor (modules, app config, integrations) · Activity list & duplication
- Behind the same module — Footfall (flows) & Yardi upload · SAFT-E - IntelliSales import · Store sales declaration & month closing · Sales status overview & Yardi export · Annual sales statement · Activity editor (loyalty mechanics, rules & targeting) · Present cards (Fideliza gift cards)
Generated from doc/feature-inventory.json · id crm-commerce-form · commit 276788ca6