Skip to main content

Force Transfer Receive - (Developer Guide)

Web-based tool for locating Transfer Deliveries without a Transfer Receipt and force-creating the TRs in bulk.


Overview

Force Transfer Receive is a guided, three-step tool that lets the Audit team find Transfer Deliveries (TDs) that still have no corresponding Transfer Receipt (TR) for a given store and date range, review the exact items on each TD, and then create the TRs in one action using a chosen document date. The flow moves through three stages — Filter (pick date range, area, and store), Review (select which TDs to receive, expandable to line items), and Done (confirmation listing each generated TD → TR pair). TR creation is handled server-side by a stored procedure inside a transaction, so either all selected TRs are created or none are.


Target Users


• Audit Team — reconciles delivered TDs that were never receipted by force-creating the missing TRs.


Problem Solved


• Some TDs are delivered but never get a TR created by the promo, leaving them stuck and unreconciled.
• There was no quick way to list exactly which TDs for a store and period are missing their TR.
• Creating those TRs one by one was slow and error-prone, with no single confirmation of what was generated.
• This tool surfaces the missing-TR TDs, lets the user select and review them down to line items, and force creates the TRs in one transactional call — returning the TD → TR mapping

 

Main Features
Category Features
Filtering Pick a From/To date range with a timezone-safe date picker.

Cascading Area → Store selection; store list loads only after an area is chosen.

Find TD(s) is enabled only when date range and store are all set.
Review & Select TDs grouped by month, with per-month select-all (indeterminate state supported).

Expand any TD to see its line items (item code, description, color, size, UM, qty).

Running count of how many TDs are selected.
TR Creation Confirm a document date in a dialog before creating.

All selected TRs created in one transactional stored-procedure call.

Done screen lists each generated TD → TR pair.

 

System Architecture


Frontend: React + TypeScript (Vite)
Backend: Node.js + NestJS (TypeScript)
Server State / Data Fetching: TanStack Query (react-query) mutations + queries
Client State: Redux (auth slice for the access token / username)
UI: shadcn/ui + Tailwind CSS, react-toastify for notifications
Database: Microsoft SQL Server (mssql driver), spanning the ERP and McjimDB databases
TR creation: McjimDB.dbo.CreateTransferReceive stored procedure via a table-valued parameter
Authentication: JWT-based (AuthGuard); note the controller guard is currently commented out — see Notes

 
Installation & Setup

Requirements
• Node.js v18+
• Visual Studio Code
• MSSQL Database (ERP + McjimDB), including the CreateTransferReceive procedure and TdList table type

 

Install Dependencies
Frontend and backend are installed separately.

npm install

Environment Variables
Frontend

VITE_FRONTEND_URL=https://localhost:5173
VITE_ENV=development
VITE_API_BASE_URL=http://localhost:3000/api

Backend

PORT=3000
NODE_ENV=development
 
Mssql_DB_SERVER=your_server
Mssql_DB_USER=your_username
Mssql_DB_PASSWORD=your_pass
Mssql_DB_DATABASE=
Mssql_DB_PORT=1433
 
JWT_ACCESS_SECRET=your_access_secret
JWT_REFRESH_SECRET=your_refresh_secret
FRONTEND_URL_DEV=http://localhost:5173

Run Locally

Frontend

npm run dev

Backend

npm run start:dev

Project Structure

Frontend

force_transfer_receive/
  ForceTransferReceive.tsx   page shell
  FetchTdTransfer.tsx        stage switch: filter -> review -> done
  useForceTr.ts              wizard state + fetch/create mutations
  FilterStage.tsx            date range + area + store selection
  ReviewStage.tsx            month-grouped TD selection
  TransferDialog.tsx         document-date confirm dialog
  DoneStage.tsx              success screen (TD -> TR pairs)
  TdMonthGroup.tsx  TdRow.tsx   memoized list pieces
  TdDatePicker.tsx  utils.ts    date picker + grouping helpers

 

Backend

force-transfer-receive/
  force-transfer-receive.controller.ts
  force-transfer-receive.service.ts     groups rows into TD records
  force-transfer-receive.repository.ts  SQL + CreateTransferReceive proc
  force-transfer-receive.module.ts
  dto/         find_tds.dto, create_tr.dto
  interface/   all_area, td_list

 

API Documentation


All routes are prefixed with /api/force-transfer-receive.


•  Get All Areas

Endpoint:

GET /api/force-transfer-receive/get-all-area

Description: Returns the list of territory/area codes used to populate the Area dropdown.

[ { "value": "AREA 1", "text": "AREA 1" }, ... ]

 

•  Get Stores By Area

Endpoint:

GET /api/force-transfer-receive/get-store

Description: Returns the stores that belong to the selected area, for the Store dropdown.

Request:

area (required)   // e.g. AREA 1

Response:

[ { "value": "SNE", "text": "SNE" }, ... ]

 

•  Get TDs to TR

Endpoint:

POST /api/force-transfer-receive/get-tds-to-tr

Description: Returns the TDs (with line items) for a store and date range that do not yet have a TR. The backend groups 
the flat rows into one record per TD with item_count and total_qty.

Request:

{
  "from_date": "2026-06-01",   // YYYY-MM-DD
  "to_date":   "2026-06-30",
  "store_code": "SNE"
}

Response:

[
  {
    "td_num": "TD46260159", "td_date": "2026-06-10", "store_code": "SNE",
    "item_count": 2, "total_qty": 14,
    "items": [
      { "item_code": "...", "qty": 7, "stock_num": "...",
        "color": "...", "size": "...", "um_code": "..." }, ...
    ]
  }, ...
]

 

•  Create TR

Endpoint:

POST /api/force-transfer-receive/create-tr

Description: Force-creates TRs for the selected TDs using the given document date. Runs the CreateTransferReceive stored procedure inside a transaction (all-or-nothing). A business-rule violation surfaces as a 409 Conflict (SQL error 50001).

Request:

{
  "td_nums": ["TD46260158", "TD46260159"],
  "date_received": "2026-06-30",
  "store_code": "SNE",
  "username": "MMALINAO"
}

Response:

[ { "td_num": "TD46260158", "tr_num": "..." },
  { "td_num": "TD46260159", "tr_num": "..." } ]