SAP CAP application for managing budget expenditure requests with a multi-level approval workflow. Built with Node.js, CDS, SQLite and Fiori Elements.
- Draft-based editing — requests are created and edited as drafts before submission
- Multi-level approval — L1 Approver → L2 Approver → Finance Controller (threshold-based routing)
- Role-driven UI — action buttons (Submit, Approve, Reject, Withdraw, Request Info) are enabled or disabled based on the authenticated user's role and the request's current status
- Approval history — every decision is recorded with approver name, timestamp and comments
- S/4HANA mock — Cost Center and G/L Account master data served via a mocked external OData service
| User | Role | Access |
|---|---|---|
requester1, requester2 |
Requester | Create, edit, submit and withdraw own requests |
l1approver1, l1approver2 |
L1Approver | Approve/reject requests from their cost center |
l2approver1 |
L2Approver | Approve/reject high-value requests (all cost centers) |
finctrl1 |
FinanceController | Full access — final approval level |
All mock users have empty password.
Draft → [Submit] → PendingL1 → [Approve] → PendingL2 → [Approve] → PendingFC → [Approve] → Approved
↘ [Reject] → Rejected
↘ [Request Info] → Draft (resubmit)
[Withdraw] available at any non-final status
Routing thresholds are defined in srv/lib/approval-routing.js.
npm install
npm run watch # starts cds watch on http://localhost:4004Open http://localhost:4004 — a launcher page lets you choose your role and open the app. The browser will prompt for credentials (username from the table above, empty password).
npm test25 tests covering: draft lifecycle, Submit/Approve/Reject/Withdraw/RequestMoreInfo actions, auth guards, virtual field flags, and $metadata structure.
db/
schema.cds — domain model (ExpenditureRequest, ExpenditureItem, ApprovalStep)
data/ — seed data for code lists
srv/
ber-service.cds — service definition, projections, auth restrictions
ber-service.js — action handlers and virtual field population
lib/
approval-routing.js — threshold config and level routing logic
external/ — mocked API_COSTCENTER_SRV (S/4 Cost Centers and G/L Accounts)
app/
ber-requests.cds — Fiori Elements annotations for the Requester view
ber-approvals.cds — Fiori Elements annotations for the Approver view
index.html — launcher page
server.js — custom entry point: Basic Auth gate before $fiori-preview redirect
test/
ber.test.js — integration tests (@cap-js/cds-test)
@sap/cds9.x@cap-js/sqlite— in-memory database for dev/testcds-plugin-ui50.17 — UI5 tooling integration- Fiori Elements via
/$fiori-preview(FLP sandbox, SAPUI5 1.145)