Analytics
Location: dg_smart_pos_api/modules/Analytics. Owns store-facing reporting: the daily summary dashboard, month/year cash flow, the day-closing (till reconciliation) workflow, and per-user sales/invoice performance drill-downs. It owns no tables of its own; it reads and aggregates other modules’ data (sales, expenses, debt_histories, supplier_histories, deposits, invoice_payments, credit_notes, repair_payments, job_payments, installment_payments, and the daily_summaries/transactions reporting tables) plus App\Models\DayClosing, which is a core app/ model, not one of its own.
Data model
Section titled “Data model”None under modules/Analytics/Models/ (confirmed empty, matching the stub’s note). This module is a read/aggregation layer, not a data owner. By this project’s own convention, daily_summaries is the reporting source of truth per (store, date); AnalyticsService and CashFlowService read it directly via DB::table() rather than through an Eloquent model, and AnalyticsService::refresh_daily_summary() is what (re)computes it from source transactions. CashFlowController’s “all shops” scope (scope=all, admin-only) also queries transactions directly, which per that same convention is a derived table, not a second source of truth.
Daily analytics
Section titled “Daily analytics”DailyAnalytics::getDailyAnalytics returns today’s cash/M-Pesa/debt/expense breakdown for a store (or, for admins with scope=all, an aggregate across every store). refreshDailySummary recalculates a given date’s daily_summaries row from source tables (sales, expenses, debt, supplier payments, deposits, invoice payments) and returns before/after snapshots. getAllDailySummaries lists summaries filtered by year/month.
Day closing (till reconciliation)
Section titled “Day closing (till reconciliation)”DayClosingController wraps DayClosingService/DayClosingExpectedBuilder/DayClosingDeclaredBreakdown: current shows the day’s expected vs. declared cash/M-Pesa position, validateClosing/saveDraft snapshot a cashier’s declared breakdown without closing, close finalizes the day (optionally with a close_reason when it doesn’t reconcile), and report fetches a previously closed day’s reconciliation report. Whether a user may enter the M-Pesa “at hand” figure is decided by canEnterMpesa(): the cashier role or any of enter close day mpesa/close business day/make sale/view pos permissions.
Cash flow and payments ledger
Section titled “Cash flow and payments ledger”CashFlowController serves month/year cash flow (get_month_cashflow, get_yearly_analytics), a general filtered view (get_analytics_by_filter, filters like this_year/custom year), available reporting dates, a get_cashflow_summary convenience wrapper, and get_payments, a filterable receivable/payable ledger read straight from the transactions table. Every one of these accepts ?scope=all for a cross-store admin rollup, gated by an inline isAdminUser() role check (admin/super admin/super-admin/superadmin) rather than a route permission middleware.
User sales/invoice performance
Section titled “User sales/invoice performance”UserSalesController::getUserPerformance/getUserSaleItems/getUserInvoices delegate to App\Services\SaleService for the actual query (get_users_and_their_sales, get_user_sale_items_by_id, get_user_invoice_items_by_id) and support the same year/month or named-filter (today/this_week/this_month/this_year/all) parameters, plus the same admin-only scope=all aggregation pattern as the cash flow endpoints.
Route surface
Section titled “Route surface”Registered via modules/Analytics/Routes/analytics_routes.php, required directly from routes/tenant.php. All under auth:sanctum.
| Method | Path | Controller method |
|---|---|---|
| GET | v1_analytics/store/{store}/get_new_daily_summary |
DailyAnalytics::getDailyAnalytics |
| GET | v1_analytics/store/{store}/all_summaries/year/{year?}/month/{month?} |
DailyAnalytics::getAllDailySummaries |
| POST | v1_analytics/store/{store}/daily_summary/refresh |
DailyAnalytics::refreshDailySummary |
| GET | v1_analytics/store/{store}/day-closing/current |
DayClosingController::current |
| POST | v1_analytics/store/{store}/day-closing/validate |
DayClosingController::validateClosing |
| POST | v1_analytics/store/{store}/day-closing/save-draft |
DayClosingController::saveDraft |
| POST | v1_analytics/store/{store}/day-closing/close |
DayClosingController::close |
| GET | v1_analytics/store/{store}/day-closing/pending-status |
DayClosingController::pendingStatus |
| GET | v1_analytics/store/{store}/day-closing/report |
DayClosingController::report |
| GET | v1_analytics/store/{store}/analytics |
CashFlowController::get_analytics_by_filter |
| GET | v1_analytics/store/{store}/year/{year}/yearly_analytics |
CashFlowController::get_yearly_analytics |
| GET | v1_new_sales/store/{store}/get_user_performance |
UserSalesController::getUserPerformance |
| GET | v1_new_sales/store/{store}/get_user_sales/{user_id} |
UserSalesController::getUserSaleItems |
| GET | v1_new_sales/store/{store}/get_user_invoices/{user_id} |
UserSalesController::getUserInvoices |
| GET | v1_cashflow/store/{store}/get_cashflow/year/{year}/month/{month} |
CashFlowController::get_month_cashflow |
| GET | v1_cashflow/store/{store}/available-dates |
CashFlowController::get_available_dates |
| GET | v1_cashflow/store/{store}/summary |
CashFlowController::get_cashflow_summary |
| GET | v1_cashflow/store/{store}/payments |
CashFlowController::get_payments |
Related
Section titled “Related”- Sales: primary source of the sales figures Analytics aggregates; see the caution above about the
v1_new_salesuser-performance endpoints - CreditNotes:
credit_notestable feeds into daily summary aggregation - Accounting: a double-entry ledger exists but nothing posts to it yet, so Analytics remains the derived-from-raw-transactions source of truth for reporting
- HR: commission/salary records referenced by
AnalyticsService