diff --git a/picking/docs/implementationplan/picking-pwa-app-implementation_plan.md b/picking/docs/implementationplan/picking-pwa-app-implementation_plan.md new file mode 100644 index 000000000..fd4bebd81 --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-app-implementation_plan.md @@ -0,0 +1,79 @@ +# PWA Picking Application for OFBiz + +The goal is to provide a modern, mobile-first Progressive Web App (PWA) for warehouse operators to manage the picking process efficiently. This includes creating picklists from approved orders, performing the physical picking, and completing the picklists. + +## User Review Required + +> [!IMPORTANT] +> The PWA will be built as a **standalone Vite + React project** located in `/Users/arun/personal/arun/ofbiz_dev/picking-app`. It will not be hosted as an OFBiz webapp. + +> [!NOTE] +> We will leverage the existing `rest-api` plugin in OFBiz to provide the backend services. We may need to configure CORS in OFBiz to allow requests from the standalone frontend. + +## Proposed Changes + +### [Backend] Picking Component + +We will create a new component `plugins/picking` to house all picking-related logic and the PWA itself. + +#### [NEW] [ofbiz-component.xml](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/ofbiz-component.xml) +Defines the component and its services. No `webapp` will be defined here for the picking app. + +#### [NEW] [services.xml](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/servicedef/services.xml) +Definition of business services for the picking process: +- `picking.getOrdersToPick`: Returns a list of orders ready for picking. +- `picking.createPicklist`: Groups selected orders into a new Picklist. +- `picking.getPicklistForPicking`: Returns detailed picklist data (items, locations, quantities) optimized for the PWA. +- `picking.recordPick`: Updates the status and quantity of a picklist item. +- `picking.completePicklist`: Finalizes the picklist. + +#### [NEW] [PickingServices.groovy](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/src/main/groovy/org/apache/ofbiz/picking/PickingServices.groovy) +Implementation of the above services using standard OFBiz entity and service patterns. + +--- + +### [Frontend] Standalone PWA Application + +A modern React-based PWA located in `/Users/arun/personal/arun/ofbiz_dev/picking-app`. + +#### [NEW] [Project Structure] +- **Vite**: Build tool for the standalone project. +- **PWA Features**: Service worker for offline capability and manifest for "Add to Home Screen". +- **Design System**: Premium "Industrial Dark" theme using Vanilla CSS and glassmorphism. + +#### [NEW] [UI Screens] +1. **Facility Selection**: Choose target warehouse. +2. **Order Picking Queue**: List and select orders to create a picklist. +3. **Active Picklist**: Sorted list of items by location. +4. **Picking Interface**: Advanced scanning support: + - **Camera Scan**: Integrated via `html5-qrcode` or similar for mobile camera use. + - **Hardware Scan**: Global listener for keyboard emulation (Bluetooth/USB scanners) with automated input focus. + - Manual quantity entry and confirmation. +5. **Success Summary**: Confirmation and picklist completion. + +### [Design Mockup] + +![PWA Picking App Mockup](/Users/arun/.gemini/antigravity/brain/dbf793e9-6761-453f-81b1-33ebf9205a7a/pwa_picking_app_mockup_1775804263452.png) + +--- + +### [Integration] API & Security + +- **CORS**: Configure the `rest-api` or global OFBiz settings to allow origin `http://localhost:5173` (default Vite port) for development. +- **Auth**: Use `generateAuthToken` for JWT-based session management. +- **Permissions**: Standard OFBiz permissions (`FACILITY_VIEW`, `FACILITY_CREATE`) will be required. + +## Open Questions + +> [!NOTE] +> All design and technical requirements have been addressed. Ready for execution. + +## Verification Plan + +### Automated Tests +- OFBiz Service Unit Tests for picking logic. +- Mocked API tests for frontend components. + +### Manual Verification +- end-to-end flow: Find Orders -> Create Picklist -> Pick All Items -> Complete. +- Verify inventory updates (if applicable) and picklist status changes in the backend. diff --git a/picking/docs/implementationplan/picking-pwa-phase1-backend.md b/picking/docs/implementationplan/picking-pwa-phase1-backend.md new file mode 100644 index 000000000..4964cce58 --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase1-backend.md @@ -0,0 +1,37 @@ +# Picking PWA - Phase 1: Backend Foundation + +This phase focuses on setting up the `picking` component and implementing the core business services required for the picking process. + +## Proposed Changes + +### [Backend] Picking Component Setup +We will initialize the component structure and define the necessary services. + +#### [NEW] [ofbiz-component.xml](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/ofbiz-component.xml) +Defines the component metadata and resource paths for services. + +#### [NEW] [services.xml](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/servicedef/services.xml) +Definition of business services: +- **`getOrdersToPick`**: Wraps `findOrdersToPickMove`. `action="GET"`, `export="true"`. +- **`createPicklist`**: Wraps `createPicklistFromOrders`. `action="POST"`, `export="true"`. +- **`getPicklistDetails`**: Wraps `getPickAndPackReportInfo`. `action="GET"`, `export="true"`. +- **`recordPick`**: Wraps `setPicklistItemToComplete`. `action="POST"`, `export="true"`. + +> [!IMPORTANT] +> **Status Transitions**: We are not creating a custom `completePicklist` service. The transition of the `Picklist` to `PICKLIST_PICKED` status will be handled by the **existing SECA** (`checkPicklistBinItemStatuses`) which triggers automatically when all items in a bin are marked completed. + +#### [NEW] [PickingServices.groovy](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/picking/src/main/groovy/org/apache/ofbiz/picking/PickingServices.groovy) +Implementation of the logic using Groovy DSL: +- **Logic Consistency**: Every custom service MUST call the corresponding `runService("existingService", ...)` to ensure transactions, reservations, and business rules remain unchanged. +- **Data Transformation**: The main responsibility of these Groovy services is to "flatten" the complex Map structures returned by standard OFBiz into simple, flat JSON-serializable Lists and Maps for the PWA. +- **Business Validation**: Ensuring orders aren't already on a picklist and validating picked quantities against available reservations. + +## Verification Plan + +### Automated Tests +- Integration tests using the OFBiz Service Engine (`test-run` command). +- Validate that `createPicklist` correctly associates all items from selected orders. +- Confirm `recordPick` correctly updates items and that the overall Picklist transitions to `PICKLIST_PICKED` (via SECA). + +### Manual Verification +- Use the OFBiz Web Tools (Service Engine) to manually trigger the services with mock data and verify the entity state in the database. diff --git a/picking/docs/implementationplan/picking-pwa-phase2-api.md b/picking/docs/implementationplan/picking-pwa-phase2-api.md new file mode 100644 index 000000000..5eb094665 --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase2-api.md @@ -0,0 +1,36 @@ +# Picking PWA - Phase 2: API Gateway & Security + +This phase focuses on making the backend services accessible to the frontend PWA securely. + +## Proposed Changes + +### [Backend] API Exposure +We will map the services defined in Phase 1 to REST endpoints. + +#### [MODIFY] [rest-api config](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/plugins/rest-api/...) +(Exact file depends on the `rest-api` plugin implementation, usually a mapping XML or Java configuration). +- Map `picking.getOrdersToPick` -> `GET /api/picking/orders` +- Map `picking.createPicklist` -> `POST /api/picking/picklist/create` +- Map `picking.getPicklistForPicking` -> `GET /api/picking/picklist/{picklistId}` +- Map `picking.recordPick` -> `POST /api/picking/picklist/bin/item/pick` +- Map `picking.completePicklist` -> `POST /api/picking/picklist/{picklistId}/complete` + +### [Backend] Security & CORS +#### [MODIFY] [url.properties](file:///Users/arun/personal/arun/ofbiz_dev/ofbiz-framework/framework/webapp/config/url.properties) (or equivalent component config) +- Configure `allowed-origins`: `http://localhost:5173` (Vite Default). +- Set `Access-Control-Allow-Methods` and `Access-Control-Allow-Headers` required for JWT and JSON payloads. + +#### [Auth] JWT Integration +- Ensure the `rest-api` uses `generateAuthToken` for session management. +- Validate that the PWA can exchange user credentials for a token. + +## Verification Plan + +### Automated Tests +- Postman or `curl` test collection verifying that: + - Root API is accessible. + - Protected endpoints return `401 Unauthorized` without a token. + - Valid JWT allows service execution. + +### Manual Verification +- Verify CORS "Pre-flight" OPTIONS request from a browser console (simulating the PWA origin). diff --git a/picking/docs/implementationplan/picking-pwa-phase3-frontend.md b/picking/docs/implementationplan/picking-pwa-phase3-frontend.md new file mode 100644 index 000000000..792c5fe0d --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase3-frontend.md @@ -0,0 +1,37 @@ +# Picking PWA - Phase 3: Frontend Core & Design System + +This phase bootstraps the PWA and establishes the premium design system. + +## Proposed Changes + +### [Frontend] Project Initialization +Located in `/Users/arun/personal/arun/ofbiz_dev/picking-app`. + +#### [NEW] [Vite + React Setup] +- Initialize project: `npx -y create-vite@latest ./ --template react-swc`. +- Install dependencies: `react-router-dom`, `lucide-react` (icons), `jwt-decode`. + +### [Frontend] Design System +#### [NEW] [index.css](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/index.css) +- Implement **Industrial Dark** theme using CSS variables: + ```css + :root { + --bg-primary: #0a0a0c; + --bg-secondary: #161618; + --accent: #f59e0b; /* Amber for industrial feel */ + --glass-bg: rgba(255, 255, 255, 0.05); + --glass-border: rgba(255, 255, 255, 0.1); + } + ``` +- Utility classes for glassmorphism effects and transitions. + +#### [NEW] [App.jsx](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/App.jsx) +- Set up routing and layout wrappers. +- Global state for authentication and facility selection. + +## Verification Plan + +### Manual Verification +- Verify the dev server starts (`npm run dev`). +- Check responsiveness on various screen sizes via Chrome DevTools. +- Verify fonts and color tokens render correctly according to the mockup. diff --git a/picking/docs/implementationplan/picking-pwa-phase4-ui.md b/picking/docs/implementationplan/picking-pwa-phase4-ui.md new file mode 100644 index 000000000..1e41f9990 --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase4-ui.md @@ -0,0 +1,30 @@ +# Picking PWA - Phase 4: Workflow UI + +This phase implements the screens for browsing orders and managing the active picklist. + +## Proposed Changes + +### [Frontend] Workflow Screens +Implementation of core components in `picking-app/src/screens/`. + +#### [NEW] [OrderQueue.jsx](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/screens/OrderQueue.jsx) +- Display a list of orders ready for picking (using `GET /api/picking/orders`). +- Multi-select functionality to group orders. +- "Create Picklist" button triggering `POST /api/picking/picklist/create`. + +#### [NEW] [ActivePicklist.jsx](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/screens/ActivePicklist.jsx) +- Displays the items of a specific picklist (using `GET /api/picking/picklist/{picklistId}`). +- Grouping by Warehouse Aisle/Location for optimal picking. +- Visual status indicators (To Pick, In Progress, Completed). +- "Complete Run" button (appears when all items picked) navigating to Phase 6 flow. + +### [Frontend] Integration Hooks +#### [NEW] [usePickingApi.js](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/hooks/usePickingApi.js) +- Custom hook to handle API calls with the JWT token. +- Centralized error handling for the picking workflow. + +## Verification Plan + +### Manual Verification +- Verify that clicking "Create Picklist" navigates the user to the Active Picklist for that specific ID. +- Check that the sorting logic (by location) is visible in the UI. diff --git a/picking/docs/implementationplan/picking-pwa-phase5-scanning.md b/picking/docs/implementationplan/picking-pwa-phase5-scanning.md new file mode 100644 index 000000000..3d61bb747 --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase5-scanning.md @@ -0,0 +1,27 @@ +# Picking PWA - Phase 5: Scanning & Recording + +This phase implements the high-performance picking interface with scanning support. + +## Proposed Changes + +### [Frontend] Picking Interface +#### [NEW] [PickingDetail.jsx](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/screens/PickingDetail.jsx) +- Interactive view for the current target item. +- Visual display of: Location, Product Name, SKU, and Quantity to pick. + +### [Frontend] Scanning Integration +#### [NEW] [ScannerManager.js](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/utils/ScannerManager.js) +- **Camera Scan**: Wrapper for `html5-qrcode` to enable camera-based scanning. +- **Hardware Scan**: Global `keydown` listener to capture input from Bluetooth/HID scanners. +- Automatic focus management to ensure scanning works without manual tap. + +### [Integration] Pick Recording +Implement the link to the `POST /api/picking/picklist/bin/item/pick` API to update the backend as items are scanned or manually confirmed. +- Handle optimistic UI updates for a "fast feel". + +## Verification Plan + +### Manual Verification +- Test camera scanning with a mock QR code/Barcode on a smartphone. +- Simulate hardware scanning by typing a SKU into the browser while the listener is active. +- Verify status changes in the UI after a successful scan. diff --git a/picking/docs/implementationplan/picking-pwa-phase6-finalization.md b/picking/docs/implementationplan/picking-pwa-phase6-finalization.md new file mode 100644 index 000000000..b281d57fa --- /dev/null +++ b/picking/docs/implementationplan/picking-pwa-phase6-finalization.md @@ -0,0 +1,30 @@ +# Picking PWA - Phase 6: PWA Finalization + +This final phase prepares the application for production use and mobile installation. + +## Proposed Changes + +### [Frontend] PWA Features +#### [NEW] [manifest.json](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/public/manifest.json) +- Define application name, icons, and theme colors. +- Set `display: standalone` for an app-like experience. + +#### [NEW] [sw.js](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/public/sw.js) +- Implement basic caching strategies for offline app shell loading. +- Ensure the app stays functional in areas with poor warehouse Wi-Fi. + +### [Frontend] Success & Polish +#### [NEW] [SuccessSummary.jsx](file:///Users/arun/personal/arun/ofbiz_dev/picking-app/src/screens/SuccessSummary.jsx) +- Summary of the picklist completion. +- Confetti effect or success animation for "WOW" factor. +- "Next Picklist" shortcut. + +### [Integration] Finalization +Invoke `POST /api/picking/picklist/{picklistId}/complete` in the backend to update inventory and status once the run is done. + +## Verification Plan + +### Manual Verification +- Install the app on a mobile device via Chrome's "Add to Home Screen". +- Verify offline loading by turning off Wi-Fi after initial load. +- Full End-to-End run verification. diff --git a/picking/ofbiz-component.xml b/picking/ofbiz-component.xml new file mode 100644 index 000000000..6ab31b716 --- /dev/null +++ b/picking/ofbiz-component.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/picking/servicedef/services.xml b/picking/servicedef/services.xml new file mode 100644 index 000000000..b992cb9a1 --- /dev/null +++ b/picking/servicedef/services.xml @@ -0,0 +1,42 @@ + + + Picking PWA Services + + + + Wrapper for findOrdersToPickMove to retrieve pickable orders. + + + + + + + Wrapper for createPicklistFromOrders to group orders into a picklist. + + + + + + + + Wrapper for getPickAndPackReportInfo to retrieve details for a specific picklist. + + + + + + + Wrapper for setPicklistItemToComplete to record a pick and transition status via existing SECA. + + + + + + + + diff --git a/picking/src/main/groovy/org/apache/ofbiz/picking/PickingServices.groovy b/picking/src/main/groovy/org/apache/ofbiz/picking/PickingServices.groovy new file mode 100644 index 000000000..b7bf66194 --- /dev/null +++ b/picking/src/main/groovy/org/apache/ofbiz/picking/PickingServices.groovy @@ -0,0 +1,117 @@ +package org.apache.ofbiz.picking + +import org.apache.ofbiz.base.util.UtilMisc +import org.apache.ofbiz.service.ServiceUtil + +/** + * Retrieves a list of orders available to be picked for a given facility. + * Wraps existing findOrdersToPickMove service. + */ +def getOrdersToPick() { + Map result = ServiceUtil.returnSuccess() + + Map findResult = runService("findOrdersToPickMove", [facilityId: context.facilityId, userLogin: context.userLogin]) + if (ServiceUtil.isError(findResult)) { + return findResult + } + + // Transform orderHeaders to a simpler list for the PWA + List orderList = [] + if (findResult.orderHeaders) { + findResult.orderHeaders.each { orderHeader -> + orderList << [ + orderId: orderHeader.orderId, + orderDate: orderHeader.orderDate, + statusId: orderHeader.statusId, + grandTotal: orderHeader.grandTotal + ] + } + } + + result.orderList = orderList + return result +} + +/** + * Creates a picklist from a list of orderIds. + * Wraps existing createPicklistFromOrders service. + */ +def createPicklist() { + Map serviceResult = runService("createPicklistFromOrders", [ + orderIds: context.orderIds, + facilityId: context.facilityId, + userLogin: context.userLogin + ]) + + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + return ServiceUtil.returnSuccess(null, [picklistId: serviceResult.picklistId]) +} + +/** + * Retrieves details of a specific picklist, including items sorted by location. + * Wraps existing getPickAndPackReportInfo service. + */ +def getPicklistDetails() { + Map result = ServiceUtil.returnSuccess() + + Map reportResult = runService("getPickAndPackReportInfo", [ + picklistId: context.picklistId, + userLogin: context.userLogin + ]) + + if (ServiceUtil.isError(reportResult)) { + return reportResult + } + + // The reportResult contains a complex structure of picklistBins and their items. + // We will extract and flatten this for the PWA. + Map picklistDetails = [:] + picklistDetails.picklistId = context.picklistId + + List items = [] + if (reportResult.picklistBinInfoList) { + reportResult.picklistBinInfoList.each { binInfo -> + if (binInfo.picklistBinItemInfoList) { + binInfo.picklistBinItemInfoList.each { itemInfo -> + items << [ + picklistBinId: binInfo.picklistBin.picklistBinId, + orderId: itemInfo.orderHeader.orderId, + orderItemSeqId: itemInfo.orderItem.orderItemSeqId, + productId: itemInfo.product.productId, + productName: itemInfo.product.internalName, + quantity: itemInfo.picklistItem.quantity, + locationSeqId: itemInfo.inventoryItem?.locationSeqId, + area: itemInfo.facilityLocation?.areaId, + aisle: itemInfo.facilityLocation?.aisleId, + section: itemInfo.facilityLocation?.sectionId, + level: itemInfo.facilityLocation?.levelId + ] + } + } + } + } + + result.picklistDetails = picklistDetails + result.picklistDetails.items = items + return result +} + +/** + * Records a pick for a specific picklist item. + * Wraps setPicklistItemToComplete which internally calls updatePicklistItem. + */ +def recordPick() { + Map serviceCtx = context.subMap(["picklistBinId", "orderItemSeqId", "orderId", "inventoryItemId", "quantity"]) + serviceCtx.userLogin = context.userLogin + + Map serviceResult = runService("setPicklistItemToComplete", serviceCtx) + + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + return ServiceUtil.returnSuccess() +}