8.7 KiB
Krishna Sales Mobile App
This is a Progressive Web App (Pwa) built for the Krishna Sales team.
Version
1.0.2
Sitemap
Public Routes
/login- User Authentication
Authenticated Routes (Console)
These routes require the user to be logged in. Roles determine access.
Daily Logs
/daily- My Daily Logs (Sales Officer, Manager, Admin)/daily/:instanceId- View specific daily log/all-daily- All Daily Logs (Manager, Admin)/all-daily/:instanceId- View specific daily log from all
Orders
/orders- View Orders (Sales Officer, Manager, Admin)/orders/:instanceId- View specific order
Calls
/calls- View Calls (Sales Officer, Manager, Admin)/calls/:instanceId- View specific call
Stores
/stores- View Stores (Sales Officer, Manager, Admin)/stores/:instanceId- View specific store
Reports & Analytics
/analytics- Analytics Dashboard (Sales Officer, Manager, Admin)/sales-report- Daily Sales Report (Manager, Admin)
Admin
/admin/users- Manage Users (Manager, Admin)/admin/datasets- Manage Datasets (Admin Only)/admin/datasets/:id- Manage Dataset Items (Admin Only)
Architecture & Workflows (How Things Work)
This app interfaces with a generic backend platform via ZinoClient (see src/api/client.ts). The business logic is driven by configuring Workflows, Activities, and Views.
1. Workflows
The app is divided into three primary Workflows, mapped out in src/api/config.ts:
- ORDER_BOOKING: Manages everything from logging a visit, taking an order, to closing an order.
- STORE: Manages the creation and editing of stores/retailers.
- DAILY_REPORTS: Manages the Sales Officer's daily punch-in (Day Plan) and punch-out (End of Day report).
Each workflow has a unique workflowUuid and versionUuid.
2. How to Add or Start a New Instance
When a user submits a form to create something new (e.g., adding a new Store or starting a new Daily Log), the app "starts an instance" of that specific workflow.
- Instantiate the Client: A
ZinoClientis created for the specific workflow.const client = new ZinoClient(BASE_URL, STORE.workflowUuid); - Start the Instance: The app calls the API to begin the first activity (e.g.,
INITactivity) with the form payload.const res = await client.startInstance( STORE.activities.INIT.uid, payload, { version_uuid: STORE.versionUuid } ); - Progressing the Instance: If the workflow has multiple steps (like Order Booking, which progresses from
LOG_VISITtoPLACE_ORDERtoCLOSE_ORDER), subsequent updates useprogressInstancewith the existinginstance_id.const res = await client.progressInstance( instanceId, ORDER_BOOKING.activities.PLACE_ORDER.uid, payload );
3. Views (Listing Data)
To display lists of data (like the tables on the /orders or /stores pages), the app queries "Record Views" configured on the backend.
const data = await client.listInstances(STORE.recordViews.STORE, filters);
These views return tabular data containing the latest state of all instances in that workflow.
4. Workflows Deep Dive & Activity Chains
4.1 Order Booking Workflow
Manages the end-to-end process of visiting a store and taking an order.
Activity Chain:
LOG_VISIT ➔ PLACE_ORDER ➔ EDIT_ORDER ➔ PRODUCTIVITY_OF_VISIT ➔ POTENTIAL_MINING ➔ CLOSE_ORDER
- LOG_VISIT (Init)
- Fields:
select_store(wf_lookup),date_of_visit(date),time_of_visit(time),upload_image(image)
- Fields:
- PLACE_ORDER
- Fields:
date_of_order(date),order_details(grid),total_bags(number),total_kgs(number)
- Fields:
- EDIT_ORDER
- Fields: Same as Place Order, allowing modifications before closure.
- PRODUCTIVITY_OF_VISIT
- Fields:
is_productive_call(radio),store_status(select),order_received_channel(select),remarks(longtext),action(radio)
- Fields:
- POTENTIAL_MINING
- Fields:
potential(grid - tracks actual potential vs ordered)
- Fields:
- CLOSE_ORDER
- Fields:
remarks_2(longtext)
- Fields:
4.2 Store Workflow
Manages onboarding and updating retailers in the system.
Activity Chain:
INIT ➔ EDIT_STORE
- INIT (Store Creation)
- Fields:
business_name_2(text),area_2(text),complete_address_2(longtext),pin_code_2(number),owner_name_2(text),phone_number_2(phone),email_2(email),store_location_2(geolocation),store_image_2(image),route_name_2(select),route_code_2(select),sub_route_2(select),distributor_name_2(select),distributor_owner_name_2(text),distributor_email_2(email),distributor_phone_number_2(phone),notes_2(longtext),potential_2(grid)
- Fields:
- EDIT_STORE
- Fields: Matches the INIT fields (uses
_3suffix) to allow updates to store metadata.
- Fields: Matches the INIT fields (uses
4.3 Daily Reports Workflow
Tracks Sales Officer attendance, daily planning, and end-of-day reports.
Activity Chain:
INIT (Day Plan) ➔ PUNCH_OUT (EOD)
- INIT (Punch In)
- Fields:
sales_officer_name(app_user),date(date),time(time),route_code(select),sub_route(select),store_image(image),day_plan_notes(longtext)
- Fields:
- PUNCH_OUT (Punch Out)
- Fields:
total_productive_calls(number),total_non_productive_calls(number),eod_notes_remarks(longtext)
- Fields:
4.4 User Management Workflow
Manages Sales Officers and their credentials.
Activity Chain:
ADD_USER ➔ EDIT_USER
- ADD_USER
- Fields:
name(text),email(email),password(password)
- Fields:
- EDIT_USER
- Fields:
name_3(text),email_3(email)
- Fields:
5. Custom Pipelines
The app uses backend pipelines (custom API endpoints) to fetch aggregated data that standard Record Views cannot provide. These are defined in src/api/config.ts:
/api/p/krishna-group/v1/nearest-stores: Fetches stores near the user's geolocation for logging visits. (Used in:NearestStoresMap.tsx)/api/p/krishna-group/v1/daily-sales-report: Aggregates the daily sales report for managers. (Used in:DailySalesReportPage.tsxviaclient.ts)/api/p/krishna-group/v1/productive-call-summary: Summarizes productive vs non-productive calls. (Used in:DynamicForm.tsxduring order workflows)/api/p/krishna-group/v1/sales-officers: Retrieves a list of Sales Officers for filtering. (Used in:DailySalesReportPage.tsx)/api/p/krishna-group/v1/auto-close-orders: Batch process to close pending orders. (Defined in config, executed via backend CRON or specific admin actions)/api/p/krishna-group/v1/edit-orders: Pipeline to handle order modifications. (Configured for future implementation)/api/p/krishna-group/v1/orders: Fetches order summaries. (Configured for future implementation)/api/p/krishna-group/v1/potential-mining: Retrieves potential data for stores to pre-fill the smart grid. (Used in:DynamicForm.tsx,CallDetail.tsx,OrdersPage.tsx,CallsPage.tsx)
6. Admin Pages
The application includes two dedicated administrative panels restricted to users with the Admin role (and sometimes Manager).
-
Manage Datasets (
/admin/datasets): Connects to Zino's dataset API viaclient.getDatasets(). It dynamically renders a dual-pane UI where admins can select a dataset (either aListor aTableof objects) from the left sidebar and manage its items on the right viaDatasetItemsPage.tsx. This allows admins to update core master data (like product lists, route configurations) without deploying new code. -
Manage Users (
/admin/users): Operates on theUSERworkflow (ADD_USER,EDIT_USERactivities) to onboard new Sales Officers and edit their profiles or access roles, using standard workflow instances.
7. Daily Sales Report (DSR)
The Daily Sales Report (/sales-report) page provides managers and administrators with a consolidated view of all orders booked on a specific day.
How it works:
- Filtering: The user selects a specific Date, Route, Distributor, and Sales Officer.
- Pipeline Aggregation: Instead of relying on raw workflow lists, it queries a custom pipeline (
/api/p/krishna-group/v1/daily-sales-report) that heavily aggregates order data from the backend, matching the selected filters. - PDF Generation: It uses
jspdfandjspdf-autotableto generate a dynamic, printable PDF in landscape mode. - SKU Chunking: Because a store might order many different SKUs across multiple brands, the PDF logic dynamically splits columns (SKUs) into printable chunks (
PDF_MAX_SKUS_PER_CHUNKdefined in config) so that tables never overflow the page horizontally. It generates subsequent pages for overflowed SKUs automatically.