Intranet · SAFT-E / IntelliSales import
Lets a store upload its SAFT-E fiscal file for a month so sales are derived from the official accounting export instead of being typed in, with anonymisation and a history of uploaded files and their processing status.
| Area | Intranet |
| Routes | intranet.safte · intranet.safte.import · intranet.safte.import.index |
| Centre modules | intranet · intranet-sovos |
| Staff levels | root · admin · manager · storeManager |
| Models | anonymazed-saft · closed-month · commerce · sovos-file |
| UI label | title.header.safte / menu.navbar.intranet.saft |
| Coverage | 3 use cases · 1 happy · 7 failure |
Known issues (1)
Missing translations
These keys are used on this screen but do not exist in
translations.json, so users see the raw key:
error.month.requiredsovosFile
How it works
A wizard with three steps and no per-step attribute validation (validateAttrs: null throughout); the real check is anonymazedSaft.validate() requiring a file, a commerce and a month. The month picker is filtered by notValidatedMonths, computed as the store’s closed months minus those already validated — so a store cannot upload against a settled month. The upload posts directly and converts a non-OK response into a rejection (response.json().then((error) => Promise.reject(error))), which is a cleaner pattern than most fetches here. The index tab lists history with amount, commerce, month, name and status, and the sales screen branches on hasIntelliSalesEnabled to hide manual editing when this is the source of truth.
Use cases
Why someone opens this (3)
- A Portuguese/Spanish tenant submitting its SAFT-E file so the centre derives turnover from certified accounting data.
- Avoiding manual sales entry entirely for IntelliSales-enabled stores.
- Checking whether last month’s file was processed successfully.
Path map
flowchart LR F(["SAFT-E / IntelliSales import"]):::feat F --> H1["SAFT file uploaded and processed"]:::ok F -.-> X1["File missing"]:::bad F -.-> X2["Store missing"]:::bad F -.-> X3["Month missing"]:::bad F -.-> X4["Month already validated"]:::bad F -.-> X5["Upload rejected by the API"]:::bad F -.-> X6["Sovos list unavailable"]:::bad F -.-> X7["Raw translation key on screen"]:::bad classDef feat fill:#26688f,stroke:#26688f,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
SAFT file uploaded and processed
- Store user opens IntelliSales → import and selects the store.
- Picks a month from the not-yet-validated list.
- Attaches the SAFT-E file and chooses the anonymisation option.
anonymazedSaft.validate()passes and the file is uploaded.- The history tab shows it with its processing status and the derived amount.
Failure paths
File missing
Cause — No SAFT file attached.
What happens —
required+error.file.required(‘SAFT file’).
Store missing
Cause — No commerce selected.
What happens —
required+error.commerce.required(‘Field required’).
Month missing
Cause — No month selected.
What happens —
required+error.month.required.
Month already validated
Cause — The chosen month has been settled.
What happens — It is excluded from
notValidatedMonths, so it cannot be chosen at all.
Upload rejected by the API
Cause — Malformed or non-conforming SAFT file.
What happens — The non-OK response is parsed and rejected, then handled in
.catch((error) => …); the detail comes from the API.
Sovos list unavailable
Cause — The Sovos backend errors while loading the history.
What happens —
intranet.sovos.error-title+intranet.sovos.error(‘An error has occurred and we were unable to load your information at this time. You can try again or reload the page.‘) — one of the better-written error states.
Raw translation key on screen
Cause — The code references
error.month.required,sovosFilebut the key does not exist in translations.json.What happens — ember-intl renders the missing key (or its missing-message placeholder) instead of text — visible to every user of this screen until the key is added.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ SAFT file uploaded and processed
- ⛔ File missing
- ⛔ Store missing
- ⛔ Month missing
- ⛔ Month already validated
- ⛔ Upload rejected by the API
- ⛔ Sovos list unavailable
- ⛔ Raw translation key on screen
Implementation
app/controllers/intranet/safte/import.jsapp/controllers/intranet/safte/import/index.jsapp/routes/intranet/safte/*.jsapp/models/anonymazed-saft.jsapp/models/sovos-file.jsapp/models/module-intranet-sovos.jsapp/abilities/intranet-safte.jsapp/enums/sovos-file-status.jsapp/enums/intranet-saft-index-filters.js
Translation keys (11)
Key English title.header.safteSAFT-E menu.navbar.intranet.saftIntelliSales intranet.safte.upload-safte-dataUpload anonymize file intranet.safte.anonymize-safte-dataAnonymize SAFT file intranet.safte.sended-fileFile sent. The result of its processing will be notified by means of a communication on the intranet once it has been completed. intranet.safte.uploaded-files-historyuploaded files status error.file.requiredSAFT file error.commerce.requiredField required error.month.required⚠️ missing intranet.sovos.errorAn error has occurred and we were unable to load your information at this time. You can try again or reload the page. intranet.sovos.error-titleWe were unable to load the list
Related
- Same area — Store sales declaration & month closing · Sales status overview & Yardi export · Sales & audit-log CSV download · Annual sales statement · Intranet communications (threads, confirmations, authorisations) · Communication subtypes · Files management · Footfall (flows) & Yardi upload · Utility consumptions
- Shares data with — Customer receipts tab & ticket-stamp generation · Customer loyalty — coupon exchanges · Receipt verification queue · Store list, filters & exports · Store create & edit · Store CSV import · Activity editor (loyalty mechanics, rules & targeting) · Proposal editor (content, coupon, push, AI images)
- Behind the same module — Store create & edit · Store sales declaration & month closing
Generated from doc/feature-inventory.json · id intranet-safte · commit 276788ca6