E2E SCENARIOS — CATALOGUE & UNITS
VietGara — Releases 6.0 and 7.3 · Version 1.1 — October 20, 2026
Covers FR-CAT-01 to FR-CAT-04, FR-CAT-05, FR-CAT-07, FR-CAT-08 (the job catalogue, Release 7.3), FR-CAT-09, the unit side of FR-INV-01 and FR-INV-02, and the Excel exports of FR-DOC-02. The part, its units, packaging, categories, price and images belong to the Catalogue module; the stock belongs to Inventory (HLD Section 3.1), and the scenarios check both through the screens. Records are in 00_Test_Data.md §3.4: gara1-1 has the units litre, piece, can and case, three categories and the parts OIL-5W30, FLT-OIL-01, WPR-24 and, from vietgara-testdata v0.3.0, BEER-330 (base unit can, selling price 9,000, case = 24 cans priced 200,000). Business view: Business Procedures P10 to P13.
| ID | Title | Priority | Automation |
|---|---|---|---|
| E2E-CAT-001 | Create a unit and a part with base unit, price, category and brand | P1 | Automated |
| E2E-CAT-002 | Receive by the case, issue by the can | P1 | Automated |
| E2E-CAT-003 | A new quote line prefills from the selling price; a later price change leaves the quote unchanged | P1 | Automated |
| E2E-CAT-004 | Packaging units: derived and overridden prices, and invalid tables | P2 | Automated |
| E2E-CAT-005 | Category tree (three levels) and filtering by category and brand | P2 | Automated |
| E2E-CAT-006 | Part images: up to three, thumbnail in the lists | P2 | Automated |
| E2E-CAT-007 | Delete or deactivate a unit, a category and a part that are in use | P2 | Automated |
| E2E-CAT-008 | Excel exports: revenue and stock movements | P2 | Automated |
| E2E-CAT-009 | Permissions: catalogue read-only, and full access | P1 | Automated |
| E2E-CAT-010 | Create and edit a job with suggested parts; its rules and validation | P1 | Automated |
| E2E-CAT-011 | Delete or deactivate a job; an inactive job leaves the picker and can be reactivated | P1 | Automated |
| E2E-CAT-012 | A part or packaging unit that a job suggests is protected | P2 | Automated (API) |
| E2E-CAT-013 | Job permissions follow the quote permissions; jobs are per garage | P1 | Automated (API) |
E2E-CAT-001 · Create a unit and a part with base unit, price, category and brand
Priority: P1 · Covers: FR-CAT-01, FR-CAT-03, FR-CAT-09 · Automation: Automated
Preconditions: baseline. MANAGER_A1, A1 active.
Test data: unit Bottle (btl); part QA-WATER-500, “Mineral water 500 ml”, base unit Bottle, selling price 6000, category Filters (any), brand Aquafina.
Steps
- Units → New unit with the unit’s data. Save. Try a second unit named
bottle(other letter case). - Parts → New part with the part’s data. Save.
- Open the part.
Expected results
- Step 1: Bottle is created; the second is refused as a duplicate name.
- Step 2: the part is saved; the form refuses to save without a base unit (“Please check the highlighted information.”).
- Step 3: the detail shows the base unit Bottle (btl), price 6,000, the category and the brand. On hand
0 btlin the stock list. - Clean-up: delete the part and the unit (nothing uses them, so they are deleted).
E2E-CAT-002 · Receive by the case, issue by the can
Priority: P1 · Covers: FR-CAT-02, FR-INV-01, FR-INV-02 · Automation: Automated
Preconditions: baseline plus BEER-330 (base unit can, case = 24). MANAGER_A1 and ADVISOR_A1, A1 active.
Steps
- Inventory → on
BEER-330Receive stock: unit case, quantity10, unit cost150000. Save. - Open Stock movements and read the new row.
- As ADVISOR_A1 create a repair order with a part line for
BEER-330, quantity30in cans. Complete the line and close the order. Wait a couple of seconds. - Look at the stock list again.
Expected results
- Step 1: On hand
240 can, shown next to 10 case. - Step 2: the movement is In with quantity
240 can, entered10 case; the recorded cost is per can (6,250). - Step 4: On hand
210 can, also shown as 8.75 case. - A free-text part line on the same order deducts nothing.
E2E-CAT-003 · A new quote line prefills from the selling price; a later price change leaves the quote unchanged
Priority: P1 · Covers: FR-CAT-09 · Automation: Automated
Preconditions: baseline plus OIL-5W30 with selling price 120000. ADVISOR_A1 and MANAGER_A1, A1 active.
Steps
- As ADVISOR_A1 create a quote for An Nguyen and add a part line picking
OIL-5W30, quantity1. Look at the unit price, then save the quote. - As MANAGER_A1 change the selling price of
OIL-5W30to150000. - Reopen the saved quote. Then create another quote and add the same part.
Expected results
- Step 1: the unit price is prefilled with 120,000; the saved line keeps it.
- Step 3: the first quote still shows 120,000; the new line is prefilled with 150,000.
- Clean-up: set the price back to
120000and delete the quotes.
E2E-CAT-004 · Packaging units: derived and overridden prices, and invalid tables
Priority: P2 · Covers: FR-CAT-02, FR-CAT-09 · Automation: Automated
Preconditions: baseline plus BEER-330 (price 9,000 per can; case = 24 with an override of 200,000). MANAGER_A1, A1 active.
Steps
- Open
BEER-330and read the packaging table. - Remove the override of the case price. Save.
- Try to save a table in which: the base unit (can) is a packaging unit; a unit appears twice; the factor is
0.
Expected results
- Step 1: the case price is 200,000 (override).
- Step 2: the case price becomes 216,000 (9,000 × 24). Clean-up: put the override back.
- Step 3: every invalid table is refused with a message naming the problem; the saved table does not change.
E2E-CAT-005 · Category tree (three levels) and filtering by category and brand
Priority: P2 · Covers: FR-CAT-03 · Automation: Automated
Preconditions: baseline (categories Engine oil > Synthetic, Filters, Wipers). MANAGER_A1, A1 active. OIL-5W30 in Synthetic with brand Castrol.
Steps
- Categories → add 5W-30 under Synthetic. Try to add a fourth level under it.
- In the stock list filter by category Engine oil, then by Filters, then clear the filter.
- Filter by brand
Castrol, then bynobrand.
Expected results
- Step 1: the third level is created; the fourth is refused.
- Step 2: Engine oil also lists the parts of its sub-categories; Filters lists only filter parts; clearing restores the list.
- Step 3: the first lists
OIL-5W30only; the second shows the empty state. - Clean-up: delete 5W-30 (no part uses it).
E2E-CAT-006 · Part images: up to three, thumbnail in the lists
Priority: P2 · Covers: FR-CAT-04 · Automation: Automated
Preconditions: baseline. MANAGER_A1, A1 active. Four small PNG files.
Steps
- Open
WPR-24and add one image, then two more. - Try to add a fourth. Try a
.txtfile. - Remove the first image.
Expected results
- Step 1: up to three images show on the part; the first one is the thumbnail in the stock list and in the part picker.
- Step 2: the fourth and the
.txtare refused with a message. - Step 3: the next image becomes the thumbnail.
E2E-CAT-007 · Delete or deactivate a unit, a category and a part that are in use
Priority: P2 · Covers: FR-CAT-07 · Automation: Automated
Preconditions: baseline plus BEER-330 received once (E2E-CAT-002). MANAGER_A1, A1 active.
Steps
- Delete the unit case, the category Wipers (after moving
WPR-24out of it, then back), and the partBEER-330; read each confirmation first. - Open the part picker of a new quote.
- Reactivate what was deactivated.
Expected results
- Step 1: each confirmation says deactivate (they are in use) and the item stays on existing documents with a “deactivated” marker. A unit, category and part used nowhere (created for this scenario) say delete and disappear.
- Step 2: deactivated parts, units and categories are not offered.
- Step 3: they are offered again.
E2E-CAT-008 · Excel exports: revenue and stock movements
Priority: P2 · Covers: FR-DOC-02 · Automation: Automated
Preconditions: baseline plus the movement of E2E-CAT-002 and at least one settlement this month. MANAGER_A1, A1 active.
Steps
- Dashboard → Export revenue Excel for the current month.
- Stock movements → Export Excel.
- Open both files.
Expected results
- The revenue file’s total equals the dashboard’s monthly revenue.
- The movements file lists the beer receipt with both the base amount (
240) and the entered amount (10 case).
E2E-CAT-009 · Permissions: catalogue read-only, and full access
Priority: P1 · Covers: FR-CAT-01, FR-CAT-03, FR-IAM-03 · Automation: Automated
Preconditions: baseline. OWNER_A, A1 active. A role QA Catalogue Reader with only Catalogue → View, and a role QA Catalogue Editor with Catalogue → Add & edit (View comes with it).
Steps
- Assign the Reader role to a member and sign in as them. Open Parts, Units and Categories.
- Sign in as TECH_A1A2 (default Technician, which can view the catalogue) and ADVISOR_A1. Open Parts.
- Assign the Editor role to the member and repeat step 1.
Expected results
- Step 1: the lists load with prices, but there is no New, edit, delete or image control; the stock list needs Inventory → View and is not shown to this member.
- Step 2: both see the parts and prices without editing controls.
- Step 3: the member can create and edit a part, a unit and a category. Clean-up: delete the roles.
E2E-CAT-010 · Create and edit a job with suggested parts; its rules and validation
Priority: P1 · Covers: FR-CAT-05, FR-CAT-08 · Automation: Automated
Blackbox: TestJobsCreateAndValidate (the job answers each suggestion described with SKU, name, unit and current price; the name is unique without regard to case; negative price and duration, the same part twice, an unknown or inactive part, a unit the part does not have, a bad quantity and 31 parts are each refused; a partial update keeps the parts, sending parts replaces them, sending none clears them; the list filters by name and category and pages).
Preconditions: baseline. ADVISOR_A1, A1 active. Parts OIL-5W30 (base unit litre, selling price 90,000, packaging unit Jug = 5 L) and FLT-OIL-01.
Test data: job Oil change, category Maintenance, labor price 200,000, duration 45 minutes; suggested parts OIL-5W30 × 4 (litres) and FLT-OIL-01 × 1 marked Do not bill the customer.
Steps
- Catalogue → Jobs → New job with the test data. Save.
- Open the job: change the quantity of
OIL-5W30to1in the unit Jug; save. - Try a second job named
OIL CHANGE; a job with a negative labor price; a job suggestingOIL-5W30twice; a job with a quantity of0or1.0005. - Search the list for
oil; filter it by the category Maintenance and by a category with no jobs.
Expected results
- Step 1: the job is saved; its suggested parts list the SKU, the name, the unit and the current price (
90,000per litre), and the filter is marked “Not billed”. - Step 2: the line reads
1 Jugat450,000. - Step 3: each is refused with a field message (“A job with this name already exists.” for the duplicate name; “A part can be suggested only once in a job.”; “Quantity must be above zero.”).
- Step 4: the search and the filter narrow the list; an unknown category shows an empty list.
- Clean-up: delete the job (E2E-CAT-011).
E2E-CAT-011 · Delete or deactivate a job; an inactive job leaves the picker and can be reactivated
Priority: P1 · Covers: FR-CAT-05, FR-CAT-06, FR-CAT-07 · Automation: Automated
Blackbox: TestJobsDeleteOrDeactivate (a job nothing used is deleted and its name is free again; a job on a quote line, or an order line, is only deactivated; dryRun says which; the inactive job is hidden from the list unless asked for and from the quote; the old quote keeps its lines; reactivating brings it back).
Preconditions: baseline. ADVISOR_A1, A1 active. Two jobs: QA Used job (already picked on a quote) and QA Unused job.
Steps
- Delete QA Unused job; the dialog says it will be deleted. Create a job with the same name.
- Delete QA Used job; the dialog says it will be deactivated. Confirm.
- Open the job picker on a new quote and search for it.
- Open the old quote that used it.
- Jobs → show inactive → Reactivate the job.
Expected results
- Step 1: the job is removed, and the same name can be used again.
- Step 2: the job stays in the list under “Inactive”.
- Step 3: it is not offered; trying to add it through the API is refused (
JOB_INACTIVE). - Step 4: the quote still shows the lines the job made.
- Step 5: the job is active and offered again.
E2E-CAT-012 · A part or packaging unit that a job suggests is protected
Priority: P2 · Covers: FR-CAT-05, FR-CAT-07, FR-CAT-02 · Automation: Automated (API)
Blackbox: TestJobsProtectTheirPartsAndUnits (deleting the part deactivates it and its base unit is locked; removing the packaging unit is refused with PACKAGING_UNIT_USED_BY_JOB while changing its factor works; deleting the job releases both; a deactivated part is skipped when the job is added to a quote).
Preconditions: baseline. MANAGER_A1, A1 active. A job suggesting OIL-5W30 in the unit Jug.
Steps
- Delete the part
OIL-5W30; open the part. - Change the part’s base unit.
- Remove Jug from the part’s packaging units; then change its factor from
5to4. - Delete the job; remove Jug again.
- Re-create the job, deactivate the part, and add the job to a quote.
Expected results
- Step 1: the dialog says the part will be deactivated; it is inactive afterwards.
- Step 2: refused (“The base unit cannot change once the part has stock, packaging or documents.”).
- Step 3: removing is refused (“A packaging unit that a job uses cannot be removed.”); the new factor is saved.
- Step 4: the job is deleted and the unit is removed.
- Step 5: the quote gets the labor line and no line for the inactive part.
E2E-CAT-013 · Job permissions follow the quote permissions; jobs are per garage
Priority: P1 · Covers: FR-CAT-05, FR-IAM-03 · Automation: Automated (API)
Blackbox: TestJobsPermissions (a member with quote.read lists and reads; quote.write creates, edits, deletes and adds to a quote; a member with neither is refused; another garage’s job is not found; no token is 401).
Preconditions: baseline. OWNER_A with garages A1 and A2 (as the plan allows), one job in A1. A role QA Quote Reader with only Quote → View.
Steps
- Sign in as a member with the Reader role. Open Jobs, then try to create one and to add a job to a quote.
- Sign in as ADVISOR_A1 and repeat.
- Sign in as TECH_A1A2 (no quote access). Open Jobs.
- As ADVISOR_A1 ask for the A1 job through garage A2’s address.
Expected results
- Step 1: the job list and detail load; creating and adding are refused (403), and the screens offer no such control.
- Step 2: everything works.
- Step 3: refused (403); the menu entry is not shown.
- Step 4: not found; a job is never visible across garages.
- Clean-up: delete the role.