Dev #89
@@ -85,6 +85,8 @@ builder.Services.AddScoped<IDashboardReportRepository, DashboardReportRepository
|
||||
builder.Services.AddScoped<DashboardReportService>();
|
||||
builder.Services.AddScoped<Distribution.Features.PaymentReport.IPaymentReportRepository, Distribution.Features.PaymentReport.PaymentReportRepository>();
|
||||
builder.Services.AddScoped<Distribution.Features.PaymentReport.PaymentReportService>();
|
||||
builder.Services.AddScoped<Distribution.Features.DayEndReport.IDayEndReportRepository, Distribution.Features.DayEndReport.DayEndReportRepository>();
|
||||
builder.Services.AddScoped<Distribution.Features.DayEndReport.DayEndReportService>();
|
||||
builder.Services.AddScoped<IStockReportRepository, StockReportRepository>();
|
||||
builder.Services.AddScoped<StockReportService>();
|
||||
builder.Services.AddScoped<IDriverProfileRepository, DriverProfileRepository>();
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# Day-End Sales Report — Plan (Distribution ERP)
|
||||
|
||||
A per-day view of sales, collections by method, returns, expenses and the resulting income, with a
|
||||
day-wise chart and a PDF export. Read-only: it adds no tables and changes no existing models.
|
||||
|
||||
> Modelled on the Day-End report in the other HexDrive ERP, but adapted to this project's data.
|
||||
> The big difference: **there is no cash/card split here.** `PaymentMethod` is `Cash | Cheque | Credit`,
|
||||
> so the report splits collections by those three.
|
||||
|
||||
---
|
||||
|
||||
## 1. What the report shows (one selected day)
|
||||
|
||||
| Group | Figures |
|
||||
|---|---|
|
||||
| Sales | Invoiced total (finalized invoices that day), Collected, Due |
|
||||
| Collections by method | Cash, Cheque, Credit (credit = extended to the store, not money received) |
|
||||
| Counts | Invoices count, payments count, count by method |
|
||||
| Returns | Total credit amount of sale returns that day (`SaleReturn.TotalCreditAmount`) |
|
||||
| Expenses | Total + list of that day's expenses |
|
||||
| Result | **Income of the day** |
|
||||
| Secondary | Cash in hand movement: cash collected − cash expenses paid |
|
||||
|
||||
Plus:
|
||||
- Day-wise income **chart** over a date range (Sales / Expenses / Income).
|
||||
- Day-wise table with a totals row.
|
||||
- **PDF export** (single day, and day-wise range).
|
||||
|
||||
---
|
||||
|
||||
## 2. What already exists (reused, nothing new in the DB)
|
||||
|
||||
| Need | Source |
|
||||
|---|---|
|
||||
| Sales | `Invoice` — `Status = Finalized`, `FinalizedAt`, `TotalAmount`, `IsActive`, excluding `ShopPO.Status = Cancelled` |
|
||||
| Collections | `Payment` — `Amount`, `Method`, `CollectedAt`, `FK_BankAccountId` |
|
||||
| Returns | `SaleReturn` — `TotalCreditAmount` (ItemExchange is 0), `CreatedAt` |
|
||||
| Expenses | `Expense` — `Amount`, `BillDate`, `PaidAt`, `Status` (`Draft/Posted/Paid/Void`), `Method` |
|
||||
| Region scope | `Invoice → ShopPO → Store → Route.FK_RegionId` (same filter `PaymentReport` uses) |
|
||||
| Backend pattern | `Features/PaymentReport/*` (controller + service + repository + DTOs) |
|
||||
| Frontend | `lib/api/reports.ts`, `config/nav.ts`, `recharts`, `jspdf` + `jspdf-autotable` (all already installed) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Backend — new `Features/DayEndReport/`
|
||||
|
||||
Same shape as `PaymentReport`:
|
||||
|
||||
- `DayEndReportController.cs`
|
||||
- `DayEndReportService.cs`
|
||||
- `IDayEndReportRepository.cs` / `DayEndReportRepository.cs`
|
||||
- `DayEndReportDTOs.cs`
|
||||
- Register repo + service in `Program.cs` next to the `PaymentReport` lines.
|
||||
|
||||
### 3.1 `GET /api/reports/day-end?date=YYYY-MM-DD®ionId=`
|
||||
|
||||
Response (one day):
|
||||
|
||||
| Section | Fields |
|
||||
|---|---|
|
||||
| Sales | `TotalSales`, `Collected`, `Due` |
|
||||
| By method | `Cash`, `Cheque`, `Credit` (amount + count each) |
|
||||
| Counts | `InvoiceCount`, `PaymentCount` |
|
||||
| Returns | `SalesReturns` |
|
||||
| Expenses | `ExpenseTotal`, `Expenses[]` (doc no, category, title, payee, method, amount) |
|
||||
| Income | `Income = TotalSales − SalesReturns − ExpenseTotal` |
|
||||
| Cash in hand | `CashCollected`, `CashExpensesPaid`, `NetCash` |
|
||||
|
||||
### 3.2 `GET /api/reports/day-end/daily?from=&to=®ionId=`
|
||||
|
||||
One row per day: `Date, TotalSales, Collected, Due, Cash, Cheque, Credit, Returns, Expenses, Income`
|
||||
plus a totals row. Feeds the chart, the table and the PDF.
|
||||
|
||||
- Days with no activity are returned as zeros.
|
||||
- Range capped at 92 days (matches `PaymentReport`'s daily granularity; error message in the same style).
|
||||
|
||||
### 3.3 Rules (need confirming — see §6)
|
||||
|
||||
- **Sales** = finalized invoices by `FinalizedAt`, active, order not cancelled.
|
||||
- **Collected** = payments by `CollectedAt` (includes instalments against older invoices).
|
||||
- **Due** = that day's invoiced total − payments received **on the same invoices** that day? or running balance? → decision #2.
|
||||
- **Expenses** = `Posted` and `Paid` expenses, `Void` and `Draft` excluded. Dated by `BillDate`.
|
||||
- **Region filter** optional; unset = all regions.
|
||||
- **Day boundaries**: use the same local-date handling `PaymentReport` uses (`DateTime.Now.Date`, `[day, day+1)`), so numbers agree with the Payment Analytics page.
|
||||
- Permission: a `reports.day-end` view permission, seeded like the other permissions (to confirm the existing seeding pattern when implementing).
|
||||
|
||||
---
|
||||
|
||||
## 4. Frontend — `/reports/day-end`
|
||||
|
||||
- API: add `dayEnd` calls + types to `lib/api/reports.ts`.
|
||||
- Page `app/(dashboard)/reports/day-end/page.tsx`:
|
||||
- Toolbar: date picker (default today), region select, **Download PDF**.
|
||||
- Summary cards: Total Sales · Collected · Due · Cash · Cheque · Credit · Returns · Expenses · **Income** (green/red by sign).
|
||||
- Expenses table for the selected day.
|
||||
- Chart: from/to (default last 30 days), Sales / Expenses / Income lines (`recharts`), daily table below.
|
||||
- Nav: add "Day-End Sales" entry in `config/nav.ts` (Reports group), gated by the permission.
|
||||
|
||||
## 5. PDF export
|
||||
|
||||
- `lib/pdf/day-end-report-pdf.ts` using `jspdf` + `jspdf-autotable`.
|
||||
- Page 1: header (company, region, range, generated at), period totals, chart image.
|
||||
- Following pages: day-wise table with totals row.
|
||||
- Single-day variant: summary figures + expense list.
|
||||
|
||||
---
|
||||
|
||||
## 6. Decisions I need from you
|
||||
|
||||
| # | Question | My default |
|
||||
|---|---|---|
|
||||
| 1 | **Income basis.** Accrual (sales − returns − expenses dated that day) or cash basis (money collected − expenses paid that day)? | Accrual; cash shown as secondary `NetCash`. |
|
||||
| 2 | **"Due" meaning.** Unpaid part of that day's invoices, or the running outstanding balance? | Unpaid part of that day's invoices. |
|
||||
| 3 | **Credit method.** Count `Credit` payments as collected? | No — shown separately, not in "Collected" (same as Payment Analytics). |
|
||||
| 4 | **Card.** You asked for cash vs card in the other project; here only Cash/Cheque/Credit exist. Add a Card method (schema change + UI) or just report what exists? | Report what exists; no schema change. |
|
||||
| 5 | **Expense date.** `BillDate` or `PaidAt`? | `BillDate`. |
|
||||
|
||||
## 7. Verification
|
||||
|
||||
- Backend tests (in `Distribution.Tests`): mixed methods, partial payments, cancelled order excluded, void/draft expense excluded, instalment on an older invoice, day-boundary case, empty days.
|
||||
- Cross-check: the "Collected" total for a range equals Payment Analytics' collected for the same range.
|
||||
- Frontend: cards match the daily table; PDF paginates over a 92-day range.
|
||||
|
||||
---
|
||||
|
||||
## 8. Implemented (2026-10-23) — differences from the plan
|
||||
|
||||
Built with all five recommended defaults.
|
||||
|
||||
- **No region filter and no new permission.** Expenses are attributed to a warehouse, not a region, so a region filter would make income inconsistent. The endpoints follow `PaymentReport` (any authenticated user); the nav entry reuses `warehouses.view` like the other reports.
|
||||
- **Endpoints:** `GET /api/reports/day-end?date=` and `GET /api/reports/day-end/daily?from=&to=`.
|
||||
- **PDF:** reuses `exportPdf` from `lib/export.ts` (day-wise table with totals row). No chart image in the PDF.
|
||||
- **Tests:** `Distribution.Tests/Services/DayEndReportServiceTests.cs` (12 passing). The older test files in that project (`OrderServiceTests`, `StoreServiceTests`, `AuthServiceTests`, `ItemServiceTests`, `RouteServiceTests`, `RegionServiceTests`) no longer compile, so the project can't build until they are fixed. Not touched here.
|
||||
Reference in New Issue
Block a user