IntelliFlowERP System Docs
Login
## Version 8.87.0 **Release Date:** 2026-12-05 ### Module: Purchase #### Bug Fixes - **Purchase index stuck on "Processing..."** The purchase listing showed the DataTables loading spinner indefinitely with no visible error in the UI and no entry in `laravel.log`. The AJAX request actually completed quickly on the server side (≈ 160 ms, 2 queries), but the response payload could not be rendered because of an unhandled JavaScript exception in the table's footer callback. - Root cause: the recently added `shipping_charges` column outputs HTML (``) but was missing from the `$raw_columns` array passed to `rawColumns()`. Yajra DataTables therefore HTML-escaped the markup to `<span class="shipping-charges…`, and the client-side `footerCallback` then called `$(data[r].shipping_charges).data('orig-value')` on that escaped string. jQuery's Sizzle engine treated the value as a selector and threw `Syntax error, unrecognized expression: <span class="shipping-charges…`, which aborted DataTables before the `Processing` overlay could be removed. - `shipping_charges` is now declared as a raw column, so the HTML reaches the browser intact, the footer total parses correctly, and the listing renders normally. #### Technical Updates - `app/Http/Controllers/PurchaseController.php` (`index`): added `'shipping_charges'` to the `$raw_columns` array used by `Datatables::rawColumns()`. --- ## Version 8.86.7 **Release Date:** 2026-09-05 ### Module: POS — Recent Transactions #### Bug Fixes - **Recent Transactions modal total now matches Cash Register Net Sales.** The *Final* tab was filtering by `payment_status = 'paid'`, which excluded credit and partial-payment sales from both the list and the *Recent Transaction Total*. As a result, the modal could show a smaller figure (e.g. `38,435`) than the Cash Register details *Net Sales* (e.g. `45,400`) for the same day/session. The Final tab now lists every sale with `status = final` (paid, partial and due), so the running total reconciles with the register's *Net Sales*. - The dedicated *Credit Sale* tab is unchanged and continues to show only unpaid / partially-paid sales. #### Technical Updates - `SellPosController@getRecentTransactions`: removed the `payment_status = 'paid'` constraint from the `final` branch; credit-sale filtering remains scoped to the `credit_sale` branch. ### Module: Cash Register #### Bug Fixes - **Register open/close time in the modal title is now displayed in the business timezone.** Previously the *Current Register* and *Register Details* modal titles formatted `cash_registers.created_at` (and `closed_at`) verbatim using `Carbon::createFromFormat`, which assumed the value was already in the business timezone. When the register row was written by a code path that did not pass through the `Timezone` middleware (e.g. queued jobs, console commands, certain API requests), `created_at` was stored in the application's storage timezone (typically UTC). As a result, a register opened at, for example, **2:09 PM** in the cashier's local timezone could appear as **9:09 AM** in the modal title. - Both modal titles now interpret the stored datetime in the application's storage timezone (`APP_TIMEZONE`, default `UTC`) and convert it to the active business timezone before formatting, so the displayed open/close times always match the cashier's wall clock. - **Net Sales / Paid Sales no longer inflated by split-payment invoices.** When an invoice was paid using more than one payment row (e.g. cash + card on the same sale), the cash-register details modal computed `total_sales` (which feeds *Paid Sales* and *Net Sales*) by joining `transactions` to `cash_register_transactions` and then summing `final_total`. Each extra payment row multiplied the invoice's `final_total` in the SUM, so the modal could show e.g. **Net Sales `Rs 45,400`** while the *Sales by Date / Time* report showed only **`Rs 32,675`** for the exact same period. The brand-wise sell-line totals were affected the same way. - The cash-register session filter is now applied via `whereExists` against `cash_register_transactions`, so each linked sale is counted exactly once. *Net Sales*, *Paid Sales*, *Sales Invoices Paid*, *Sales Return*, *Total Tax*, *Total Discount*, *Total Shipping Charges* and the *brand-wise quantity / amount* breakdown now reconcile with the *Sales by Date / Time* report. #### Technical Updates - New helper `to_business_timezone($date)` in `app/Http/helpers.php`. Parses a stored `Y-m-d H:i:s` value as `env('APP_TIMEZONE', 'UTC')` and returns a Carbon instance shifted to `session('business.time_zone')` (falling back to `config('app.timezone')`). - `resources/views/cash_register/close_register_modal.blade.php`: open time and "now" reference both rendered through the business timezone. - `resources/views/cash_register/register_details.blade.php`: open time and close time both rendered through the business timezone. - `CashRegisterUtil@getRegisterTransactionDetails`: replaced the `JOIN cash_register_transactions` row-multiplying constraint on the `$transaction_details` and `$product_details_by_brand` queries with a `whereExists` subquery. Aggregates (`total_sales`, `total_sales_direct`, `total_sales_return`, `total_tax`, `total_discount`, `total_shipping_charges`, brand `total_quantity` / `total_amount`) are now computed once per transaction regardless of how many payment rows the invoice has. --- ## Version 8.87.2 **Release Date:** 2026-05-05 ### Module: Business Location Settings #### New Features - **New "Map & Location" tab** added to *Business Location → Settings* (`/business-location/{id}/settings`). Allows administrators to: - Search for an address with **Google Places autocomplete**. - **Click anywhere on the map** to drop a draggable pin and capture exact coordinates. - Use **"Use My Current Location"** to auto-fill from the browser's geolocation. - Set a custom **map zoom** level used by the live delivery map. - Persist `latitude`, `longitude`, and `map_zoom` against the business location row. ### Module: Delivery Management #### Improvements - **Live Map now centres on the configured business location** instead of an arbitrary world point. Each active business location with saved coordinates appears as a navy-blue store pin (“🏪 Ride start point”) on the live tracking map. - Browser geolocation fallback is only used when no business location has been pinned. #### Technical Updates - **Migration:** `2026_05_05_130000_add_latlng_to_business_locations.php` adds `latitude` (decimal 10,7), `longitude` (decimal 10,7) and `map_zoom` (tinyint) columns to `business_locations`. Idempotent via `Schema::hasColumn` guards. - **`LocationSettingsController::updateSettings`** whitelist now includes `latitude`, `longitude`, `map_zoom` and normalises empty strings to `null`. - **`DeliveryManagementController::dashboard`** returns a new `$location_pins` collection (id, name, lat, lng, zoom) consumed by the dashboard view. - **New translation keys:** `lang_v1.map`, `business_location_map`, `business_location_map_help`, `business_location_map_delivery_note`, `search_address`, `search_address_help`, `start_typing_address`, `latitude`, `longitude`, `map_zoom`, `use_my_current_location`, `clear_pinned_location`. --- ### Module: HRM — Attendance (ADMS / BioSecurity Push) #### New Features - **Direct device-to-server attendance push** is now supported for newer ZKTeco face / multi-bio terminals (SenseFace 2A, 4A, 7C, ProFace X, SpeedFace M5, G4 and any ZKTeco device that supports the *ADMS / Cloud Server* mode). Devices push attendance records straight to the application in real time — no Python connector and no scheduled sync required. - **New "ADMS / SenseFace Devices" management page** added under *HRM → Attendance → Import Attendance*. Administrators can register devices by serial number, generate / rotate a per-device push secret, monitor the *Last Seen* timestamp + IP, and enable / disable a device without un-cabling it. - **Built-in `/iclock/*` ADMS endpoints** (`cdata`, `getrequest`, `devicecmd`, `fdata`, `ping`) that speak the standard ZKTeco push protocol; ATTLOG records are mapped to the existing `essentials_attendances` table using the user's `essentials_attendence_uid` (PIN). - **Per-device push secret** validated on every request (`?token=…` or `X-Push-Token` header). Devices with no secret can be supported for legacy units that don't allow custom URL parameters. - Compatibility list on the *Import Attendance* page now shows a dedicated **ADMS / BioSecurity** badge group with **SenseFace 2A** (officially tested) plus the rest of the ADMS-capable family. #### Improvements - *Import Attendance* page now exposes a quick-access **ADMS / SenseFace Devices** button alongside the existing *Download Template* and *Download ZKTeco API* actions. - Step-by-step *Live Push Setup* guide is rendered inline on the *Import Attendance* page with the application's own host / port pre-filled, so admins can configure the device's *Cloud Server* settings without leaving the screen. #### Technical Updates - **New tables (migration `2026_05_05_000001_create_essentials_adms_devices_table.php`):** - `essentials_adms_devices` — registered terminals (business_id, location_id, serial_number, name, model, push_secret, firmware_version, last_ip, last_seen_at, is_active, options json, timestamps). - `essentials_adms_push_logs` — raw payload audit log per push (device_id, table_type, payload, records_received / imported / skipped, error, created_at). Safe to truncate periodically. - **New models:** `Modules\Essentials\Entities\EssentialsAdmsDevice`, `EssentialsAdmsPushLog`. - **New controllers:** `Modules\Essentials\Http\Controllers\Api\AdmsController` (push endpoints, plain-text responses), `Modules\Essentials\Http\Controllers\AdmsDeviceController` (admin CRUD). - **New service:** `Modules\Essentials\Services\AdmsAttendanceProcessor` parses ATTLOG batches, maps PIN → user, treats status `0/3/4` as check-in and `1/2/5` as check-out, deduplicates by user + minute, and pairs check-outs with the latest open check-in. - **Routes:** `/iclock/cdata`, `/iclock/getrequest`, `/iclock/devicecmd`, `/iclock/fdata`, `/iclock/ping` registered at the public root in `Modules/Essentials/Routes/web.php` (no auth, no session). Admin UI at `/hrm/attendance/adms-devices` lives inside the standard auth group and requires the `essentials.crud_attendance` permission. - **CSRF exception:** `/iclock/*` added to `App\Http\Middleware\VerifyCsrfToken::$except` — devices submit plain text without session cookies. - **Documentation:** *How to Set Up a Biometric Attendance Terminal* in `cp-docs/en/GYM_GUIDE.md` extended with a *Live Push Setup* sub-section covering SenseFace 2A. #### UI / UX Changes - Compatibility notice on *Import Attendance* re-grouped into four protocol families (Fingerprint/RFID, Multi-bio, iClock/SpeedFace, ADMS push) with a clear "officially tested vs. protocol-compatible" footnote. - ADMS Devices table shows status badges, push-secret indicator, *Last Seen* relative time, and one-click *Disable / Enable* and *Rotate Secret* actions. --- ## Version 8.87.1 **Release Date:** 2026-05-05 ### Module: Business Settings — Modules #### New Features - **Delivery Management module toggle:** Added a new checkbox **"Delivery Management (Riders & Live Map)"** under *Settings → Business Settings → Modules tab*. Default: **unticked**. The Delivery sidebar menu and all `/delivery/*` routes are now hidden/blocked unless this module is enabled. The mobile rider-ping API endpoint remains accessible so rider devices can still post location updates while administrators are configuring the feature. #### Technical Updates - **`App\Utils\ModuleUtil::availableModules()`** now lists `delivery` with a tooltip. - **Sidebar gate:** `AdminSidebarMenu` checks `in_array('delivery', $enabled_modules)` before showing the *Delivery* dropdown. - **Controller gate:** `DeliveryManagementController` constructor middleware aborts with HTTP 403 (or JSON error for AJAX) when the `delivery` module is disabled, except for `apiRiderPing` to allow rider device pings during setup. - **New translation keys:** `lang_v1.delivery_management`, `lang_v1.delivery_management_tooltip` (English). --- ## Version 8.87.0 **Release Date:** 2026-05-05 ### Module: Delivery Management (NEW) #### New Features - **Delivery Riders Management module:** A complete delivery operations suite has been introduced under a new top-level *Delivery* menu (visible to users with `delivery.view` permission). Riders are sourced from existing **Sales Commission Agents**, and customers from the standard contact list — no duplication of master data. - **Live Map Dashboard (`/delivery/dashboard`):** Real-time Google Maps view showing every active rider's current position with colour-coded status pins (Available / On Delivery / On Break / Offline). Clicking a rider reveals an info window with name, phone, vehicle, current speed, last-ping time, and the active delivery (customer, address). When a rider has an active delivery, a dotted route line is drawn from the rider to the drop-off point. The map auto-refreshes every 10 seconds. - **Stat cards on dashboard:** Total Riders, Available, On Delivery, Today's Orders, Active Assignments, Delivered Today. - **Riders directory (`/delivery/riders`):** DataTable list with status, availability and *Last Seen* columns. Add / edit modals capture vehicle type (bike, motorbike, scooter, car, van, truck, cycle, on foot), plate, colour, driving licence number and expiry, emergency contact, max load (kg), base delivery fee, per-km rate, photo upload, base location and operational status. - **Per-rider Track screen (`/delivery/riders/{id}/track`):** 24-hour breadcrumb trail of GPS pings drawn as a polyline with Start / End markers. - **Assignments (`/delivery/assignments`):** Create deliveries linked to a sale invoice (auto-fills customer + drop-off from contact's stored Google Maps `position`) or as a stand-alone delivery. Filters by status, rider and date range. - **Distance & fee auto-calculation:** Drop-off distance from pickup is computed via Haversine; default fee = `base_fee + (distance × per_km_rate)` (overridable per assignment). ETA is estimated at an average 30 km/h. - **Delivery lifecycle:** Pending → Accepted → Picked Up → On The Way → Delivered (with optional Failed / Cancelled). Each transition timestamp is recorded; the rider's *availability* automatically flips between `available` and `on_delivery`. - **Performance Report (`/delivery/reports/performance`):** Per-rider KPIs over a date range — total assignments, delivered, cancelled, success %, total km, total fees and average delivery time. - **Mobile rider ping API (`POST /delivery/api/rider-ping`):** Accepts `latitude`, `longitude`, `heading`, `speed`, `accuracy_m` from a rider's mobile/PWA app; updates last-known position and appends to the breadcrumb trail (rate-limited to one row per 5 seconds). - **Auto-fill from Contact Google Maps position:** When an existing customer is selected for an assignment, the drop-off latitude/longitude/address are pre-populated from the contact's stored `position` field (set on the Contact create/edit page via Google Places autocomplete). #### Technical Updates - **New tables:** `delivery_riders`, `delivery_assignments`, `delivery_rider_locations`. - **New permissions:** `delivery.view`, `delivery.create`, `delivery.update`, `delivery.delete`, `delivery.assign`, `delivery.track` — auto-granted to all existing `Admin#` roles via migration. - **New routes:** Grouped under `/delivery/*` in `routes/web.php`. - **New controller:** `App\Http\Controllers\DeliveryManagementController`. - **New models:** `App\DeliveryRider`, `App\DeliveryAssignment`, `App\DeliveryRiderLocation`. - **Storage:** Rider photos stored under `storage/app/public/delivery_riders/` (served via the `public` disk symlink). - **API key:** Reuses the existing `GOOGLE_MAP_API_KEY` `.env` setting (same key already used by the Contact Google Maps integration). #### UI / UX Changes - **New top-level sidebar menu** *Delivery* (truck-fast icon) with sub-items: Live Map, Riders, Assignments, Performance Report. Visible only when the user has the `delivery.view` permission. - **Modern dashboard styling:** Gradient stat cards, rounded-corner Google Map, side panel of active riders with click-to-pan, on-map legend, custom SVG vehicle pins coloured by availability, custom drop-off pin. --- ## Version 8.86.3 **Release Date:** 2026-05-04 ### Module: Purchase Return #### Bug Fixes - **Purchase Return grand total was showing Rs 0.00 in the list:** Each purchase return entry in the Purchase Return list was displaying a grand total of Rs 0.00, even though the correct amount was visible when opening the return to edit it. The list now shows the accurate return amount for all entries. - **Footer totals on the Purchase Return list were showing Rs 0.00:** The *Grand Total* and *Payment Due* amounts at the bottom of the Purchase Return list were always displaying zero, regardless of the records shown. The footer now correctly shows the combined total for all matching purchase return records across all pages, including any active filters (location, supplier, date range). --- ### Module: Dashboard — Today at a Glance #### Bug Fixes - **Today's Revenue and Total Due Amount now subtract returns:** The dashboard's *Today's Revenue* card was displaying gross sales without deducting sale returns, and the *Total Due Amount* card was summing invoice due and purchase due without offsetting outstanding sale-return and purchase-return amounts. *Today's Revenue* now shows net sales = sales − sale returns. *Total Due Amount* now shows (invoice due − outstanding sale-return refunds) + (purchase due − outstanding purchase-return refunds). --- ### Module: Sales — Sale Return #### Bug Fixes - **Sale Return view modal showed an empty product list:** Opening the *Sale Details* modal for a sale-return invoice (e.g. `SR…`) displayed no products and a *Total Qty* of `0.000`, even though the same return correctly listed its products on the *Sale Return Edit* page. The modal now automatically opens the dedicated *Sell Return* details view, so the returned products, return quantities, unit prices, and subtotals are shown correctly. - **Footer totals on the Sale Return list only reflected the current page:** The *Grand Total* and *Payment Due* amounts shown at the bottom of the Sale Return list were summing only the rows visible on screen. If there were multiple pages of results, the footer was understating the true totals. The footer now always shows the correct combined total for all matching records, regardless of how many pages there are. --- ### Module: Reports — Profit & Loss #### Bug Fixes - **Total Sale Return figure in the Profit & Loss report was overstated:** The *Total Sale Return* amount shown in the Profit & Loss report was higher than the actual figure visible on the Sale Return list (for example, showing ₨73,900 when the correct total was ₨40,900). This was caused by an internal calculation that was counting the same sale return multiple times when a return had more than one product line. The figure is now calculated correctly and matches what is shown on the Sale Return page. --- ### Module: Reports — Sales & Returns Report #### Bug Fixes - **Footer totals on the Sales & Returns Report were overstated:** The report's footer (TOTAL, INV. TAX, TAX, DISCOUNT, PAID, REMAINING, TOTAL BEFORE TAX) was *adding* sale-return amounts to sale amounts instead of subtracting them, causing the displayed total to exceed the true net sales (e.g. it showed `2,336,000` instead of `2,320,200` when sales were `2,328,100` and returns were `7,900`). Sale-return rows now display their monetary columns as negative values (matching the existing Purchases & Returns Report behaviour), so the footer correctly reflects net sales = sales − returns. --- ### Module: Reports — Sale Invoices Report #### Bug Fixes - **"Item Quantity" column showed 0 for Sale Returns in the Totals tab:** When the *Sale Invoices Report* filter *Sale Type* was set to **Sale Returns**, the *Item Quantity* column on the *Totals* tab always displayed `0.000`, while the *Total* and *Invoice Quantity* columns were correct. The aggregation has been fixed so that returned-quantity totals are correctly read from the parent sale's lines for each sale-return entry. --- ### Module: Settings — Modules #### New Features - **New "Custom Designer" toggle added under Settings → Business Settings → Modules tab:** A new on/off switch called *Custom Designer* is now available in the Modules tab. When turned on, the *Invoice Designer* and *Label Designer* options become visible in the sidebar menu under Settings. When turned off, these options are hidden. This setting is off by default. --- ### Module: Products #### Bug Fixes - **Group Price not showing in the Product list:** On the *Products* page, the *Group Price* column was appearing blank for products that had selling group prices assigned. This is now fixed — the correct prices for each price group are displayed as expected. --- ### Module: Manufacturing — Sidebar Menu #### UI / UX Changes - **Reordered the Manufacturing sidebar for a clearer workflow.** The menu now follows the production lifecycle: *Dashboard → Recipe → Production → Add Demand Order → Reports → Settings*. This grouping makes day-to-day actions easier to reach and matches how production teams actually use the module. - **New "Reports" dropdown added to the Manufacturing sidebar.** All reporting screens are now grouped under a single *Reports* menu containing *Demand Order*, *Demand Ingredient Report*, *Manufacturing Report*, and *Recipe Report*. This reduces sidebar clutter and gives reports a single, predictable location. - **"Add Demand Order" promoted to a top-level shortcut.** Users can now create a new demand order in one click from the sidebar instead of opening the demand-order list first. --- ## Version 8.86.2 **Release Date:** 2026-05-03 ### Module: Settings — Invoice / Receipt Design #### New Features - **New receipt layout "Slim 4" added for 80mm thermal printers:** A new thermal receipt design called *Slim 4* is now available under *Settings → Invoice Settings → Layout*. In this layout, each product in the receipt table is displayed across two lines — the first line shows the item number and product name, and the second line shows the quantity, unit price, discount, and subtotal. This makes product details easier to read on narrow 80mm receipt paper. --- ### Module: HRM — Payroll #### Bug Fixes - **Employee not appearing in the Advance Payment form after selecting a location:** When opening the *Add Advance Payment* form and choosing a location from the *Location* dropdown, the *Employee* list was not updating — so staff assigned to that location would not show up. This is now fixed. Selecting a location correctly refreshes the employee list to show only the employees whose primary work location matches the one you picked. --- ## Version 8.85.2 **Release Date:** 2026-05-02 ### Module: Manufacturing — Recipe Import #### New Features - **"Download Excel" button on the Recipe list page:** Mirrors the same UX as the Products page. Exports **all existing recipes** for the current business in the same format the importer accepts. Edit any value (quantities, units, instructions, waste %, extra cost, cost type) and re-upload from *Import Recipes* — matching recipes (by Product SKU) are updated in place; new Product SKUs at the bottom are added as brand-new recipes. Yellow-highlighted rows mark the first row of each recipe so the recipe-level fields are visually obvious. #### Improvements - **Simpler "Import Recipes" file format for everyday users:** The recipe import sheet has been redesigned to be much friendlier for non-technical staff. Each ingredient is now on its own row, and you simply repeat the same **Product SKU** for every ingredient that belongs to the same recipe — no more cryptic codes like `RAW-001:2:Pcs:0|RAW-002:0.5:Kg:1` packed into a single cell. - **Recipe-level fields are filled only on the first row of each recipe:** *Total Quantity*, *Recipe Unit*, *Extra Cost*, *Production Cost Type*, and *Instructions* only need to be entered on the first row of each recipe. Leaving them blank on the following rows automatically inherits the values from the first row. - **Sensible defaults for blank fields:** *Total Quantity* defaults to 1 if left blank, *Production Cost Type* defaults to **fixed**, and units default to the product's base unit — so users can produce a working import sheet with the bare minimum of typing. - **Improved downloadable template:** The Excel template now ships with a styled header row, three full worked examples (a cake recipe with three ingredients, a juice recipe with two ingredients, and a single-ingredient pack), plus a built-in "INSTRUCTIONS" section right inside the sheet so users don't need to leave Excel to know what to do. - **New "Download Sample (with example data)" button:** A second download option provides a fully-populated sample workbook with **5 realistic recipes** (Chocolate Cake, Vanilla Cupcake, Mango Juice, Veg Burger, Sugar Pack) totalling 27 ingredient rows. The first row of each recipe is highlighted yellow so users can see at a glance which row carries the recipe-level fields. A pre-built copy of this file is also stored in the codebase at `cp-docs/samples/recipe_import_sample.xlsx`. - **Backward compatible:** Old import sheets that use the previous one-recipe-per-row pipe-encoded format still work — the importer auto-detects the format from the header row and processes either layout. #### UI / UX Changes - **Redesigned "Import Recipes" page:** The on-screen documentation now clearly marks which columns are required, which apply only to the first row of each recipe, and shows a side-by-side example layout so users can see exactly how to repeat the Product SKU across multiple ingredient rows. - A new green tip box at the top of the page summarises the simple format in three short bullet points. #### Technical Updates - `RecipeImportTemplateExport` rewritten with `WithEvents` to apply header styling, borders, auto-sized columns, and an embedded instructions block. - `RecipeController::importRecipes()` refactored: header-row sniffing routes the file to either `importSimpleRows()` (new layman format) or `importLegacyRows()` (legacy format). Persistence consolidated in `saveImportedRecipe()` to remove duplication. --- ### Module: Sales / POS / Discounts #### Bug Fixes - **"Buy For Quantity" discount now enforces the bundle price even when the unit is cheaper.** Previously, if a product's unit price multiplied by the qualifying quantity already came out *below* the bundle's total price (e.g. unit price ≈ £1.00 each, but a *Buy 2 for £9.99* bundle was active), the POS computed a negative discount and silently skipped the rule — so the line stayed at the cheap unit total (£1.99 for two units) instead of the agreed bundle price. POS now treats the bundle as a forced override: every full bundle of `buy_qty` units is billed at exactly `buy_price`, regardless of whether the variation's normal price is higher or lower. Any units beyond the last full bundle continue to bill at the original unit price. - **Discount-type select now reliably switches to "Fixed" when the rule fires.** The buy-for handler used to flip the per-line discount type by toggling the `selected` HTML attribute, which does not always update the select's actual value (some browsers / select2 builds kept the old `percentage` selection in memory). The handler now also calls `.val('fixed')` so the change cascade reads the correct discount type. - **Robust fallback when the discount column is hidden.** If the POS layout has the per-line *Discount* column turned off, there is no `row_discount_amount` input to write to. The handler now detects this and writes the calculated bundle unit price directly to the line's *Unit Price* field, so the line total still resolves to the agreed bundle amount. #### Technical Updates - `getBuyForDiscounts()` in `public/js/pos.js` rewritten for the `buy_for` branch: explicit inline-only unit-price selector (ignores any modal-rendered `pos_unit_price` inputs), unconditional bundle-price override path, and proper `.val('fixed')` selection on the discount-type select. --- ### Module: Fiji FRCS Integration #### New Features - **New "Fiji FRCS" module added** to help businesses in Fiji follow the Fiji Revenue & Customs Service rules for sending sales receipts to the government in real time. - **Register your fiscal device (EFD):** A new screen lets you enrol your shop's fiscal device with FRCS using the activation code given to you on the FRCS portal. You can switch between **Sandbox** (for testing) and **Production** (for live use) with one click. - **Send sales receipts to FRCS automatically:** Every sale (and refund) made on the POS is automatically sent to FRCS. The module supports four receipt types — **Normal Sale**, **Refund / Credit Note**, **Training**, and **Proforma**. - **Choose how receipts are sent:** Pick the mode that suits you — *Instant* (sent at the moment of sale), *Queued* (sent in the background), *Daily* (sent once a day), or *Manual* (you click a button to send). - **Works even when the internet is down:** If FRCS cannot be reached, receipts are saved safely on your computer and sent automatically as soon as the connection comes back. - **X-Reports and Z-Reports:** Generate the daily *X-Report* (read-only summary you can check anytime) and the end-of-day *Z-Report* (closes the day and is sent to FRCS). Z-Reports can also be generated automatically every night. - **FRCS QR code on every receipt:** Once a receipt is accepted, the official FRCS verification code and QR are stored on the receipt and printed on the customer's PDF copy so customers can verify the receipt with FRCS. - **Easy Settings page:** From one screen you can set your TIN, VAT number, choose the sending mode, decide when a buyer's TIN is required (for example for sales above FJD 1,000), turn the FRCS QR on/off on receipts, set the time for the auto Z-Report, and add an email to be notified about any submission errors. - **Submission history & audit trail:** A new page lists every receipt sent to FRCS with its status (Pending / Submitted / Accepted / Failed), so you can search, filter, view details, and re-send any failed receipt with a single click. A separate "API Logs" page shows every conversation with FRCS for full traceability. - **Bulk submit pending receipts:** A "Submit All Pending" button lets you push all unsent receipts to FRCS in one go. - **Permissions you can assign to staff:** *Access Fiji FRCS Module*, *Manage EFD Onboarding*, *Submit Fiscal Receipts*, and *Generate X / Z Reports* — so only the right users can perform sensitive actions. - **Sold as an add-on:** The module can be enabled per business through the Superadmin subscription packages. --- ### Module: Accounting — Chart of Accounts #### Bug Fixes - **Parent Account dropdown was empty when adding a new account:** When opening the *Add Account* form, the *Parent Account* dropdown showed no options. It now correctly lists all available parent accounts, the same as it does on the Edit form. - **Accounts marked as "Non Posting" (e.g. Bank Account) were not showing in the Parent Account dropdown:** If a non-posting account was created under another account (for example a *Bank* group under *Cash and Cash Equivalents*), it would not appear as a selectable parent when creating or editing another account. This is now fixed — all active non-posting accounts are visible in the Parent Account dropdown regardless of where they sit in the account hierarchy. --- ### Module: POS — Quick Menu Buttons #### Bug Fixes - **Same product added as a new row instead of increasing quantity:** When the business setting *Sales Item Addition Method* was set to *"Increase item quantity if it already exists"*, clicking a quick menu button quickly (or when the screen was a bit slow) would sometimes add the same product as a separate new row instead of increasing the quantity on the existing row. This is now fixed — rapid clicks on the same product always increase the quantity on the existing row. - **Quick menu button not respecting the configured quantity:** If a quick menu button had no quantity configured, clicking it would sometimes add the product with a blank quantity. Fixed — it now always defaults to quantity 1 when no quantity is set on the button. --- ### Module: Purchases #### Improvements - **Purchase details now show gross profit and sell price:** When these fields are enabled for purchases, the purchase details popup now also shows **G.P %** and **Sell Price** after the **Subtotal** column, making it easier to review item pricing without opening the edit screen. --- ### Module: Accounting — Chart of Account Report #### New Features - **Chart of Account Report** added under *Accounting → Reports*. Lists all accounts in the chart of accounts, organised by account type (Asset, Liability, Equity, Income, Expenses) and sub-type, with columns for GL Code, Account Name, Account Sub Type, and Status. - **Show Balances** checkbox (default unticked) — when ticked and *Apply Filters* clicked, a Balance column is appended showing the current live balance for each account, plus sub-type and account-type totals. - **Print** button sends the report directly to the laser printer via `window.print()`, hiding all navigation, filters, and sidebars and rendering a clean print-optimised layout. --- ### Module: Accounting — Transactions (Payroll Advance Payments) #### New Features - **Payroll Advance Payments now visible in Accounting → Transactions:** A new *Advance Payments* tab has been added. It shows all advance and loan payments made to employees, including the employee name, type (Advance or Loan), payment status, and amount. A date filter is available to narrow the list. - **Chart of Accounts mapping for advance payments:** Each advance payment row now has a *Map* button. Clicking it opens the account mapping screen with the correct accounts already pre-selected — the payment method account is credited and the *Payroll Advance Payments* account is debited — matching the same auto-mapping logic used by other payroll transactions. --- ### Module: POS #### New Features - **Draft button opens your saved drafts when the screen is empty:** If you click the *Draft* button on the POS screen without adding any products first, it now opens the Recent Transactions popup and goes straight to the *Draft* tab — so you can quickly pick up a previously saved order without any extra steps. - **Recent Transactions popup remembers which tab to open:** When you open the Recent Transactions popup using the *Draft* button, it automatically lands on the *Draft* tab. When you open it using the *Transactions* button, it lands on the *Final Paid* tab as expected. - **First transaction selected automatically when a tab loads:** When you switch to any tab in the Recent Transactions popup, the most recent transaction in that tab is automatically highlighted and ready to edit, delete, or print — no need to click first. #### UI / UX Changes - **Payment icons added to POS screen navbar:** Two quick-action buttons — *Receive Customer Payment* (green, `fa-hand-holding-usd`) and *Pay Supplier* (yellow, `fa-money-bill-alt`) — have been added to the POS header action bar, matching the same icons and workflow used in the main software navbar. Clicking either button opens the existing contact-search payment modal, filtered by contact type (`customer` / `supplier`), allowing cashiers to process payments without leaving the POS screen. Both buttons respect the existing `sell.payments` and `purchase.payments` permissions respectively, and the Pay Supplier button is only shown when the Purchases module is enabled. ### Module: Security Roles #### Improvements - **Draft permissions moved to the POS tab:** The *View All Drafts*, *View Own Drafts*, *Edit Draft*, and *Delete Draft* permission options have been moved from the *Sales* tab to the *POS* tab when creating or editing a security role. This makes it easier to manage all POS-related access in one place. - **Cashiers can now see and use drafts on the POS screen:** When a cashier role is given *View All Drafts* or *View Own Drafts* permission under the POS tab, that cashier will now see the *Draft* button on the POS screen and can view the saved drafts list inside the Recent Transactions popup. Previously, enabling these permissions had no effect on the POS screen. --- ### Module: Reports — Purchase Analysis #### New Features - **Purchase Analysis report** added under *Reports → Purchase Reports*. Mirrors the existing Sales Analysis report but analyses purchase transactions (`type = 'purchase'`, `status = 'received'`). Supports all period views: **Yearly**, **Monthly** (with optional Compare Previous year toggle), **Weekly**, **Daily**, **Day of Week**, and **Hourly**. Can be filtered by Business Location and report metric — **Amount** or **Number of Purchases**. Includes a Print button. --- ### Module: Reports — Product Sale Report #### New Features - **New "Not Sold (Combo)" tab added to Product Sale Report:** A new tab now appears in the Product Sale Report, placed right after the "Not Sold" tab. It shows only **combo and package** type products that had no sales in the selected date range. All existing filters (location, date range, category, brand, supplier, etc.) apply to this tab as well. --- ### Module: Expense #### New Features - **Sub-category field added to Add Expense modal:** The Expense Sub Category dropdown now appears directly inside the Add Expense modal (between the Expense Category and Expense For fields). When a category is selected, the sub-category list loads dynamically via AJAX — matching the behaviour already present on the full Create and Edit expense pages. #### Bug Fixes - **Category / Sub-category dropdowns appearing in the wrong place when the Add Expense form was scrolled:** When you scrolled inside the Add Expense pop-up and then clicked a dropdown (Category, Sub Category, etc.), the list would open in the wrong spot — sometimes well above or below the field. The dropdowns now always open neatly attached to the field you clicked, no matter how far you've scrolled. #### UI / UX Changes - The Expense Details section of the Add Expense modal now displays three fields per row — Expense Category, Sub Category, and Expense For — using `col-md-4` columns (previously two `col-md-6` columns showing only Category and Expense For). --- ### Module: HRM — Payroll #### Bug Fixes - **Old "Payroll for March 2026" entry could not be deleted from the screen:** A leftover payroll record was still showing under *HRM → Payroll* even after its payments had been cleared, and the Delete option in the Actions menu was not removing it. This old entry has now been cleaned up, so the Payroll list shows correctly with no leftover records. --- ### Module: Reports — Stock Adjustment Report #### New Features - **New "Products Summary" tab** added to `reports/stock-adjustment-report`. Aggregates all stock-adjustment lines by product/variation across the active date range and location filter, showing per-product **count of adjustments**, **total quantity adjusted**, and **total value** (sum of qty × unit_price). Inherits the same date-range / location filter as the other tabs and reloads in real time when filters change. #### Bug Fixes - **Summary tab would not open and the Detailed tab was stuck on "Processing…":** Clicking the Summary or Detailed tabs on the Stock Adjustment Report did nothing or kept loading forever. All three tabs (Totals, Summary, Detailed) now open instantly when clicked and their tables load properly. - **Date-range dropdown did not close on its own after picking a preset (Today / Yesterday / Last 7 Days, etc.):** Choosing a preset from the date picker no longer requires you to click outside to close it — the picker now closes automatically as soon as you select a range. - **Daily Totals tab always showed 0 in the Stock Adjustment column:** The Stock Adjustment column on the Daily Totals tab was incorrectly showing zero for every day. It now shows the correct totals. - **Detailed tab stuck on "Processing…" with a server error:** The Detailed tab failed to load because of a clash inside the report query. The query has been corrected and the Detailed tab now loads its data without errors. - **Date-range / location filter did not refresh the tabs in real time:** Changing the date range or business location only updated the tab you were currently looking at, and the other tabs would still show the old data until you manually clicked them. Now, changing the date range or location refreshes all three tabs (Totals, Summary, Detailed) together so every tab stays in sync with your filter. #### Improvements - **Date-range filter now applies to all three tabs:** Selecting a date range (or location) on the report page now reloads the Totals, Summary and Detailed tables together, so every tab stays in sync with the filter. - **Tables auto-resize when their tab is shown:** Switching between the Totals, Summary and Detailed tabs now redraws the table columns to the correct width, fixing the squashed / misaligned columns that sometimes appeared the first time a tab was opened. --- ### Module: Reports — Sale Invoices Report #### Improvements - **Pagination added to the Detailed tab** of the Sale Invoices Report. Instead of loading all invoices at once — which could cause the page to freeze or time out on large date ranges — results are now shown in pages. By default, 25 invoices are shown per page. A counter at the top shows how many invoices are being displayed out of the total. Use the *Invoices per page* dropdown (options: 10, 25, 50, 100, 200, All) to control how many appear at a time. Page navigation buttons appear below the table. When viewing multiple pages, a **Grand Totals** row shows the combined Total Amount, Paid, and Due across all pages — not just the current page. --- ### Module: Accounting — Transactions / Payroll Advance Tab #### Bug Fixes - **Payroll Advance Payments now show up under *Accounting → Transactions → Payroll Advance Payments* tab.** Any record added from *HRM → Payroll → Advance Payment* (both **Advance Payment** and **Loan Payment**) is now visible here with its date, reference number, type, employee, payment status, and amount. - Each row also shows a button — green **Edit Mapping** if the entry is already linked to the chart of accounts, or blue **Map Transaction** if it still needs to be linked. --- ## Version 8.85.1 **Release Date:** 2026-05-01 ### Module: HRM / Payroll & Accounting #### Improvements - **Auto Chart-of-Accounts mapping for Payroll Advance Payments (Advance & Loan):** When a record is added under **HRM → Payroll → Advance Payment** tab (both `Advance Payment` and `Loan Payment` sub-types), the system now automatically posts a journal entry into the **Chart of Accounts**: - **Debit:** `Payroll Advance Payments` (asset) - **Credit:** the **Payment Method account** mapped on the Business Location's *Default Payment Accounts* for the chosen method (Cash / Bank Transfer / Card / Cheque / etc.) - Added a safe fallback to **Cash in Hand** when the selected payment method has no default account configured for the location, so the entry is no longer silently skipped. --- ## Version 8.85.0 **Release Date:** 2026-04-30 ### Module: Backup #### New Features - **Google Drive Auto-Sync via Centralized Rsync:** Implemented an advanced Google Drive architecture using OS-level `rsync` mounts to bypass the limitations and complexity of Google's API limit tokens. - Local backups generated by the tenant now asynchronously dispatch an Rsync Job to a globally shared Redis queue (`gdrive-sync`). - Server executes uploads sequentially (one at a time) across all 50+ subdomains to eliminate Google connection bans. #### Improvements - **Two-way Sync Deletion:** Native integration with Laravel Spatie Backup cleanup. When Spatie deletes an old backup locally, `rsync --delete` automatically trims it from Google Drive exactly. - **Real-time UI Tracking:** Added a webhook callback that updates the tenant's local UI to accurately show "Sync Pending" or "Synced to Cloud" rather than querying the Drive API. ## Version 8.84.11 **Release Date:** 2026-04-28 ### Module: POS / Quick Menu Tables #### Improvements - **Table CHECKOUT and PRINT BILL now punch products to the POS screen almost instantly.** On the POS screen, when a Quick Menu **Table** button has multiple existing orders, opening the table modal and clicking **CHECKOUT** or **PRINT BILL** previously froze the screen for several seconds before the merged order lines appeared in the products section. The freeze grew with the number of order lines (a table with 15 lines could block for 8–10 seconds). All lines now load in roughly the time of a single product punch — one HTTP round-trip instead of N — regardless of how many lines the merged orders contain. - The same speed-up applies to the **Edit Order & Re-Print Bill** flow on already-billed table orders, the **delete-table-order edit re-fetch** flow, and the user-authentication confirmation flow that re-pulls a table's orders into POS. - **Quick Menu single Product button feels instant.** Clicking a `Product`-type quick button no longer freezes the browser UI for the duration of the server round-trip — the row appears asynchronously without locking the screen, so rapid taps remain responsive. - **Quick Menu Product Set button is much faster.** Selecting set + addon products in the Product Set modal and clicking **Add** previously fired the get-product-row request once per chosen variation, sequentially and synchronously. All variations are now fetched in one batched server call and appended in a single DOM write, while still being correctly grouped under the same `set_group_id` header. - **"Get products from sale invoice" (Send For / Sell-Return invoice lookup)** also benefits — products listed under the entered invoice are now fetched in the same batched call instead of one-at-a-time. --- ### Module: Superadmin / Subscriptions #### Bug Fixes - **Edit Subscription date pickers now open above the modal.** On `superadmin/superadmin-subscription`, opening the Edit modal and clicking **Start Date**, **End Date**, or **Trial End Date** showed the calendar behind the modal (z-index conflict), making it impossible to pick a date. The date pickers are now anchored inside the modal and render correctly on top. --- **Release Date:** 2026-04-28 ### Module: POS / Sales Finalize Performance #### Improvements - **POS bill finalize is faster (especially with FBR PRAL, FBR DI and ZATCA enabled).** Pressing **Final / Save & Print** previously rebuilt the full receipt details up to three times (once for FBR PRAL, once for FBR DI, and again when rendering the print receipt) and re-fetched the same Invoice Layout for each. The receipt object and invoice layout are now memoised per request so the heavy work runs once. No change to what's printed, what's reported to FBR/ZATCA, or what's saved. - **Removed the per-bill internet-probe stall on FBR-enabled locations.** The FBR PRAL submission used to do a fresh `fsockopen` connectivity probe on every checkout, which could block for up to 3 seconds when the link was flaky. The probe result is now cached for 30 seconds, so back-to-back bills don't pay the probe cost each time. If connectivity is genuinely down, FBR is skipped exactly as before (`fbr_invoice_no` saved as `0`). ### Module: Sales / POS / Discounts #### Bug Fixes - **"Buy For Quantity" discount now charges the correct total at POS.** When a discount of type **Buy For Quantity** was configured (e.g. *2 for £9.99* on a product with a unit price of £5.99), punching the qualifying quantity at POS was applying the discount in reverse — the line subtotal showed the discount amount itself (£1.99) instead of the agreed bundle price (£9.99). The line now correctly bills £9.99 for two units, and partial bundles (e.g. 3 units at *2 for £9.99*) correctly charge £15.98 (one bundle + one extra at full price). --- ## Version 8.84.8 **Release Date:** 2026-04-26 ### Module: Products / POS / Sell / Purchases #### Improvements - **F10 Product Search modal much faster.** The product search datatable used by **F10** on POS, the **Sell** screen and the **Purchases** screen now returns rows in a single round-trip instead of running per-row sub-queries. - **F10 modal stops building columns it never displays.** The modal does not show the action dropdown, image, mass-delete checkbox or product-locations cell, but those builders were running for every row anyway. They are now skipped, along with the heavy eager-loads that fed them. - **POS / Sell / Purchase punch — fewer business-detail queries.** Punching a product no longer re-runs the joined `business + tax_rates + currencies` query each time within the same request. --- **Release Date:** 2026-04-25 ### Module: Documentation Hub #### New Features - **Manufacturing module documentation expanded.** The page at `/documentation/module-manufacturing` now serves the full **Manufacturing User Guide** (previously it auto-generated a thin overview). New sections cover every tab in the module's top navigation, including the previously undocumented **Demand Orders** workflow and **Demand Ingredient Report**. - New section **Importing Recipes from a Spreadsheet** with step-by-step instructions and a download-template tip. - New section **Restoring a Deleted Recipe** for accidental deletions. - New section **Demand Orders** with full status table (Draft / Pending / Approved / In Production / Partially Completed / Completed / Cancelled), priority levels, approval flow, and inline status changes. - New section **Demand Ingredient Report** explaining the shortage column and how to use it as a procurement shopping list. #### Improvements - **Contacts guide** now clarifies that a contact saved with type **Both** is treated as a **Barterer** and appears under **Contacts → Barterer** in the sidebar (in addition to the customer and supplier lists). The contact-types table and the *Add a New Contact* steps both call this out. - **Manufacturing → Getting Started** section rewritten with the correct add-on activation flow (sidebar check → Contact Superadmin → log out / log back in) instead of the previous "ask the Superadmin to enable it in Business Settings" wording. - **Module Overview** table on the Manufacturing page now lists every top-nav feature, including Reverse Production, Manufacturing Report, Recipe Report, Demand Orders and Demand Ingredient Report. - **Permissions** table on the Manufacturing page now includes *Access / Add / Edit / Delete / Approve Demand Order*. - **Quick Reference → Navigation Paths** updated to include all new screens. --- ## Version 4.25.26.8 **Release Date:** 2026-04-25 ### Module: Documentation Hub #### Bug Fixes - **Add-on activation instructions corrected.** The auto-generated overview for add-on modules (Accounting, CRM, Manufacturing, Gym, HMS, Repair, Project, FoodPanda, Field Force, Truckmate, Shopify, WooCommerce, Ecommerce, Connector, Spreadsheet, Recruitment, AI Assistance) was wrongly telling users to "tick the box in *Settings → Business Settings → Modules*". Add-ons are not in that tab — that tab only toggles **core base features** (POS, Sale, Products, Purchases, Stock, Expenses, Reports, Notifications, Restaurant tables, Quick Menu, Bookings, etc.). Add-ons are activated by the **Superadmin** as part of the subscription plan. The page now explains the correct flow: check the sidebar → if missing, contact the Superadmin → log out and back in once activated. - Fixed the **Add-on Modules → About Add-on Modules** page (`MODULES_OVERVIEW.md`): replaced the "How to Enable or Disable Modules" section and the related FAQ entries with the correct subscription-based activation flow, plus a clear note distinguishing add-ons from the core feature toggles in Business Settings → Modules. - Fixed the **FoodPanda Troubleshooting** checklist and table: removed the "enable in Business Settings → Modules" instruction and replaced it with a check for the FoodPanda menu in the sidebar plus a request-to-Superadmin step. --- **Release Date:** 2026-04-25 ### Module: Documentation Hub #### New Features - The **Documentation** page has been rebuilt as a true end-user manual. The sidebar is now organised into clear, task-based categories that match how a shop user thinks about their day: - **Getting Started**, **Customers & Suppliers**, **Products & Stock**, **Purchases**, **Sales & POS**, **Money & Expenses**, **Tax, Invoices & Barcodes**, **Reports**, **Users & Permissions**, **Notifications**, **Backup & Data Safety**, **Restaurant Features**, **Add-on Modules**, **Superadmin**, **Contact Superadmin**, **Version Log**. - All add-on modules are now grouped under a single **Add-on Modules** tab instead of producing one tab per module, removing visual noise from the sidebar. #### Improvements - Auto-generated module overview pages now show a friendly description and clear "How to turn it on" steps that point to **Settings → Business Settings → Modules** in the UI. - Superadmin overview page now describes the role in plain language and lists current Superadmin accounts as a friendly bullet list. - Search index updated to match the new layman-friendly page titles and keywords. #### Bug Fixes - Internal developer notes stored in `cp-docs/dev/` no longer leak into the public manual. The language-fallback chain now stops at English; developer reference files are never surfaced to end users. #### UI / UX Changes - Removed all references to codebase paths, environment variables, terminal commands and module folder names from user-facing pages. - Removed the green/orange "module enabled / disabled" badges from sidebar tab labels — the sidebar now reads as a clean topic list. - Renamed several pages to action-oriented titles (for example: "Welcome & First Steps", "Set Up Your Business", "Adding & Managing Products", "Selling at the Point of Sale", "Reading Your Reports", "Email & SMS Templates", "What's New"). - FoodPanda section now exposes only the three pages a user actually needs: **Integration Overview**, **Quick Reference**, **Troubleshooting**. --- **Release Date:** 2026-04-25 ### Module: Reports / POS Reports #### New Features - **Summary Income Report** now supports two print modes: - **Print A4** — prints a centered receipt-style summary card on a standard A4 page. - **Print Thermal (80mm)** — prints a compact monospaced layout sized for 80mm thermal printers (76mm printable, dashed dividers, inverted highlight row for *Receivable Cash*). #### Improvements - Filter row is now responsive: filter inputs collapse to two-per-row on small screens and stack on mobile (`col-md-3 col-sm-6`); action buttons wrap with `flex-wrap` and `gap` for tablet / phone widths. - The summary card itself is responsive (reduced padding and font sizes below 600px). #### Bug Fixes - **Print preview was blank.** Clicking the Print button on the Summary Income Report used to open a blank print preview. The Print A4 and Print Thermal buttons now correctly show the receipt-style summary in the preview every time. #### UI / UX Changes - Replaced the single *Print* button with two clearly labeled buttons: **Print A4** (green) and **Print Thermal (80mm)** (blue). --- ## Version 4.25.26.5 **Release Date:** 2026-04-25 ### Module: Reports / POS Reports #### New Features - **Summary Income Report** added under *Reports → POS Reports*. Renders a Closing-Summary style report with three sections: **Sales Summary** (Sale, Sale Return, Gross Sale, Discount, Sales Tax, Service Charges, Net Sales), **Service Sales Analysis** (per `types_of_service` breakdown with percentage and amount), and **Cash Details** (Cash Sale, Credit Card Sale, Credit Sale, Opening Cash, Receivable Cash, Cash Received, Difference). Filters: Business Location, Cashier (User), Date Range. Includes a Print button that prints only the summary card. #### Improvements - None. #### Bug Fixes - None. #### UI / UX Changes - New sidebar menu item *Summary Income Report* placed directly under *Register Report* in the **POS Reports** dropdown (icon: `fa-file-invoice-dollar`). --- ## Version 4.25.26 **Release Date:** 2026-04-25 ### Module: POS / Sell #### New Features - F10 Product Search Modal — the text search field now searches across **every column the user has chosen to display** in *Users → Settings → Product tab → Product Search Screen Columns*, not just SKU and Product Name. Newly searchable columns: Other Name, Brand, Category (and Sub-Category), Supplier (name + business name), Rack details (rack / row / position), Custom Field 1–4. Variation name and sub-SKU remain searchable as before. #### Improvements - Significantly faster POS bill / invoice finalization. Email, SMS and WhatsApp customer notifications now run after the HTTP response is flushed, so cashiers no longer wait for SMTP / SMS gateway / Meta WhatsApp Cloud API round-trips before the receipt appears. - FBR submission now short-circuits early when the location has no `fbr_pos_id`, when the transaction already has an FBR invoice number, or when it is a quotation. This skips a 3-second `fsockopen` connectivity probe and a heavy receipt-details build for transactions that would never have been submitted to FBR anyway. - Offline mode (`IS_OFFLINE=true`) is now much faster on POS finalize and across the app. Auto FBR submission, FBR Digital Invoicing, ZATCA instant sync, customer email / SMS auto-notifications and the Meta WhatsApp Cloud API call now exit immediately when the app is in offline mode instead of waiting for connect / read timeouts (previously up to ~3 sec each, more if the gateway hung). Manual sync actions (e.g. "Sync FBR Sales") still work as before. - Faster POS product search (typeahead on the POS screen and the F10 product search modal). The `purchase_lines` join used for serial-number / IMEI search is now only added when the **Enable serial number** business setting is on; previously it ran on every keystroke and contained an `OR pl2.imei_numbers IS NOT NULL` clause that produced a near-cartesian product, making search 5\u201320 \u00d7 slower on stores with many purchase lines. The `JSON_SEARCH(imei_numbers, ...)` filter is also gated behind the same setting. - Faster product "punch" (clicking a product to add it as a POS cart line). The tax-rate dropdown and the warranty dropdown are now cached per business for 5 minutes (with automatic invalidation when an admin edits a tax rate or warranty), so the same lookups don't hit the database on every product click. The customer default-tax lookup now selects only the column it needs instead of fetching the full Contact row. #### Bug Fixes - **POS product search made safer and slightly faster.** The product search used on POS has been tightened so that special characters typed into the search box can never affect the database, and repeat searches now reuse the same prepared query for a small speed boost. #### UI / UX Changes - None. ## Version 4.21.26 **Release Date:** 2026-04-21 ### Module: Quotations #### New Features - None. #### Improvements - None. #### Bug Fixes - Fixed the quotations index action menu PDF download so the generated quotation PDF is streamed to the browser instead of opening a blank tab. #### UI / UX Changes - None. ### Module: Product Masters (Brands, Gender, Procurement Source) #### New Features - Added parent-child hierarchy support for Brands, Gender, and Procurement Source, similar to product sub-category behavior. - Added "Add as sub taxonomy" option in create and edit popups for all three modules. #### Improvements - Improved list ordering to show parent items grouped with their sub-items. - Added indented visual display in master lists to make hierarchy easier to read. #### Bug Fixes - Fixed Products Card tab search so the Search SKU or Name field now returns matches by product name and variation name in addition to SKU. #### UI / UX Changes - Updated add/edit forms for Brands, Gender, and Procurement Source with parent selection controls. ### Module: Products #### New Features - Added a new products index tab: Products Card. - Added a dedicated variable-only storefront-style card view to list variable product variations separately from the full product list. #### Improvements - Improved variable-product workflow by applying all existing index filters while forcing product type to variable in the new tab. - Added quick summary cards in the new tab to show filtered variation count and current-page row count. - Enhanced variation display by converting recognized colors into swatches and other variation values into option pills. #### Bug Fixes - None. #### UI / UX Changes - Renamed the variable-product tab to Products Card. - Added a modern storefront-style variable product layout with larger imagery, cleaner action placement, color swatches, and size/option pills. - Added variable-tab search targeting from the product search modal shortcuts.
Need Help?

If something on your Dashboard doesn't look right, use the Contact Superadmin tab in the Documentation section to get help from your system administrator.