Vendors / Open source & self-hostable
Kriolos POS
Kriolos POS (kriolos-obiz)
The most genuinely active project in this open-source batch by commit cadence — merged PRs as recently as 2026-07-29 and a rolling alpha release tagged v1.0.0-alpha-2026-07-12-Cabo-Verde — but its own README still carries a 'IN DEVELOPMENT (NOT RELEASE YET)' warning and it has never cut a stable 1.0, so it is a maintained uniCenta successor rather than a deployable restaurant POS.
scored live legacy rubric
- Claims in scope
- 278
- Scored
- 45
- Assessed
- 42
- Unknown
- 236
- Not applicable
- 36
- Cells challenged
- 0
unknown, never as no.Identity
- Owner
- KriolOS Team (community project, GPL-3.0; a continuation of the uniCenta/Openbravo Java POS lineage, related to poolborges/unicenta-pos)
- Who it is for
- Small retail and hospitality operators on the Openbravo/uniCenta Java lineage who want a maintained, GPL-licensed successor to uniCenta rather than a subscription POS
- Site
- https://github.com/kriolos-obiz/kriolos-pos
Pricing
transparency: unknown · unit: free (GPL-3.0, self-hosted) · processor lock-in: no
- Software
- Free and open source under GPL-3.0, self-hosted. No published commercial tiers, subscription, or per-terminal pricing. Distributed as GitHub pre-releases only.
Capabilities
Every claim is binary and checkable. Grades: A primary documentation · B product documentation · C pricing or feature page · D marketing claim · E third-party reporting · F inference with no source. A yes on a differentiator claim requires A or B.
Order capture & FOH workflow
order-capture-floor-plan-editor
Not scored by this record.
order-capture-seat-level
Not scored by this record.
order-capture-coursing-hold-fire
Not scored by this record.
order-capture-split-merge
Split and merge both exist, but only in item-move form. btnSplit on the sale panel (enabled when the user holds sales.Total and the ticket has more than one article) opens ReceiptSplit, a two-pane dialog whose only controls are move-one and move-all buttons (jBtnToRightOne/All, jBtnToLeftOne/All) shifting whole lines between the current ticket and one new ticket; on OK the split-off ticket goes straight to payment via closeTicket(). Tables merge in JTicketsBagRestaurantMap: after the 'This will Merge tables' confirmation, every line of the clipboard table's ticket is appended to the target ticket and the source shared ticket is deleted. Shortfall: splitting is by whole line item into exactly two checks per pass - there is no seat concept on a ticket (places.SEATS is table capacity in the floor-plan editor; ticketlines has no seat column), no even N-way split, and no split by arbitrary dollar or percentage amount anywhere in the payment flow. The after-partial-payment case cannot arise at all, because payment closes a receipt: an open ticket carries no payments to split around. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/ReceiptSplit.java · retrieved 2026-08-04
order-capture-bar-tab-preauth differentiator
Not scored by this record.
order-capture-transfer-audit
Not scored by this record.
order-capture-native-handheld
Not scored by this record.
order-capture-offline-order-entry
Self-hosted Java desktop POS against a local database; internet is not in the order-entry path. No published offline matrix. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
order-capture-qr-same-check differentiator
Not scored by this record.
order-capture-kiosk-first-party differentiator
Not scored by this record.
order-capture-drive-thru
Not scored by this record.
order-capture-drive-thru-timers
Not scored by this record.
order-capture-voice-ai differentiator
Not scored by this record.
order-capture-throttling differentiator
Not scored by this record.
order-capture-scheduled-orders
The full Liquibase schema is public. receipts carries only (ID, MONEY, DATENEW, ATTRIBUTES, PERSON), tickets only (ID, TICKETTYPE, TICKETID, PERSON, CUSTOMER, STATUS) and sharedtickets only (ID, NAME, CONTENT, APPUSER, PICKUPID, LOCKED) - there is no future fire-time, promise-time or lead-time column anywhere, so a held ticket cannot be dated forward or auto-fired. The reservations table (CREATED, DATENEW, TITLE, CHAIRS, ISDONE, DESCRIPTION) is a table-booking calendar, not an order. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
order-capture-catering
Not scored by this record.
order-capture-order-ready-signal differentiator
Not scored by this record.
order-capture-void-comp-controls
Not scored by this record.
Menu, modifiers & pricing engine
menu-pricing-nested-modifiers
The shipped Liquibase DDL enumerates every product-composition mechanism the application has, and none of them is a nestable modifier group. A product row carries exactly one ATTRIBUTESET_ID; attributeset is (ID, NAME); attributeuse is (ID, ATTRIBUTESET_ID, ATTRIBUTE_ID, LINENO); attribute is (ID, NAME); attributevalue is (ID, ATTRIBUTE_ID, VALUE). That is a fixed two-level flat picker - set, then one ordered row of attributes each with a flat value list - with no parent-group self-reference, no MIN/MAX selection columns and no required/forced flag anywhere. The only other structures are products_com (ID, PRODUCT, PRODUCT2), an unqualified auxiliary-product pair, and products_bundle (ID, PRODUCT, PRODUCT_BUNDLE, QUANTITY), a back-office component list that is never presented to the cashier as a choice; neither carries min/max or a required flag either. The nearest thing to forced selection is a single product-level boolean, ISVERPATRIB, surfaced in ProductsEditor as the 'mandatory' checkbox, which prompts for the whole attribute set once - not per group, and not at a third level. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-04
menu-pricing-modifier-price-by-parent-size
Modifiers are modelled as product attributes: attribute(ID, NAME), attributevalue(ID, ATTRIBUTE_ID, VALUE), attributeuse and attributesetinstance carry no price column at all, so an attribute value cannot hold a price, let alone a per-parent/per-size matrix. The only priced alternative is a complement product (products_com joins PRODUCT to PRODUCT2), and products holds a single PRICESELL per row, so a differently priced topping requires a duplicated product record. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
menu-pricing-fractional-placement differentiator
Not scored by this record.
menu-pricing-half-and-half-rule differentiator
Not scored by this record.
menu-pricing-topping-quantity-tiers
No quantity-tier or price-multiplier field exists: attributevalue is (ID, ATTRIBUTE_ID, VALUE) with no numeric price or factor, and ticketlines carries only UNITS and PRICE. Light/regular/extra can only be expressed by adding the complement product again or by creating separate products. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
menu-pricing-size-style-matrix differentiator
Not scored by this record.
menu-pricing-included-allowance differentiator
Not scored by this record.
menu-pricing-combos
Not scored by this record.
menu-pricing-upsell-prompts differentiator
Not scored by this record.
menu-pricing-86-propagation
Not scored by this record.
menu-pricing-countdown-auto-86 differentiator
Not scored by this record.
menu-pricing-dayparting
Not scored by this record.
menu-pricing-channel-price-books
Not scored by this record.
menu-pricing-dual-pricing differentiator
Not scored by this record.
menu-pricing-allergen-nutrition
Not scored by this record.
menu-pricing-recipe-linkage differentiator
Not scored by this record.
menu-pricing-3p-menu-push
Not scored by this record.
menu-pricing-dynamic-pricing
Not scored by this record.
Payments & money movement
payments-processor-choice differentiator
Not scored by this record.
payments-published-rates differentiator
Not scored by this record.
payments-dual-pricing differentiator
Not scored by this record.
payments-surcharge-guardrails differentiator
Not scored by this record.
payments-emv-nfc
Community software project with no first-party payment terminal line; nothing to certify for EMV or NFC. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
payments-softpos-tap-to-pay differentiator
Not scored by this record.
payments-pay-at-table
Not scored by this record.
payments-qr-guest-pay differentiator
Not scored by this record.
payments-tip-adjust
Not scored by this record.
payments-tip-pooling differentiator
Not scored by this record.
payments-offline-store-and-forward differentiator
Not scored by this record.
payments-offline-decline-liability differentiator
Not scored by this record.
payments-gift-cards
First-party gift vouchers are native, not an integration: a vouchers table (ID, VOUCHER_NUMBER, CUSTOMER, AMOUNT, STATUS CHAR(1)) is created by the shipped changelog, a Vouchers back-office panel issues them, JPaymentVoucher is a first-class tender, and vouchers carries no location column so a voucher is redeemable at any terminal on the shared database. Shortfall: there is no balance. VoucherInfo defines STATUS as a binary flag - 'A' available, 'D' redeemed - with no remaining-balance field, and JPaymentVoucher.setStates() loads the whole AMOUNT and calls moneyEditor.setEnabled(false), so redemption is all-or-nothing: a 50 voucher spent on a 12 ticket is consumed entirely and the 38 is lost. Partial redemption, reload and running-balance tracking therefore do not exist. There is also no online-ordering channel in the product at all (it is a desktop Java POS with no web ordering module), so the redeem-through-online-ordering half of the claim has nothing to run on. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/payment/JPaymentVoucher.java · retrieved 2026-08-04
payments-house-accounts
Not scored by this record.
payments-split-tender
Not scored by this record.
payments-refund-void-controls
Authorization is genuinely role-based: the shipped role files grant discrete permissions sales.RefundTicket, sales.DeleteLines, sales.DeleteTicket, refund.cash/cheque/voucher/magcard, button.opendrawer, button.linediscount and button.totaldiscount, and Role.Employee.xml deliberately omits every refund, delete-ticket and open-drawer entry. Voids and no-sales are logged - JPanelTicket calls dlSystem.execLineRemoved(user name, ticket id, product, units) into the lineremoved table, draweropened records (OPENDATE, NAME, TICKETID), and both blocks print on the close-cash report. Shortfall: the log records the logged-in operator, never an approving manager; there is no per-user approval prompt (the optional override is a single shared static PIN read from the override.pin application property in JPanelTicket.changeCount()); discounts and refunds are written to no audit table at all; and lineremoved/draweropened are ordinary mutable tables with no immutability guarantee. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Role.Manager.xml · retrieved 2026-08-03
payments-chargeback-tooling differentiator
Not scored by this record.
payments-card-on-file differentiator
Not scored by this record.
payments-payout-timing differentiator
Not scored by this record.
payments-p2pe-pci4
Not scored by this record.
Kitchen & production
kitchen-station-routing
Per-item routing exists and an admin can configure it without vendor involvement: products.PRINTTO is a per-product field rendered in ProductsEditor as a combo box with the fixed values 0-6, script.SendOrder.bs loops the ticket lines and branches on line property product.printer to print templates Printer.Ticket.P1 through P6, and DeviceTicket binds machine.printer.1..6 to actual devices. Shortfalls: (1) the destinations are kitchen printers, not KDS stations - the only KDS code in the tree, KitchenDisplay.java, inserts into a KITCHENDISPLAY table that no changelog ever creates and the class is never instantiated anywhere in the repository, so there is no shipped KDS to route to; (2) routing keys off the product row only - there is no rule by category, order type or revenue centre, so a category-wide change means editing every product; (3) the six destinations are a hard-coded 0-6 enumeration, not an extensible station list; and (4) the printer-to-device binding lives in per-terminal machine.printer.N application properties, so routing is configured per workstation rather than centrally per location. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/script.SendOrder.bs · retrieved 2026-08-04
kitchen-expo-consolidation
No expo or consolidation view ships. Kitchen routing is per-line only: script.SendOrder.bs branches on line.getProperty('product.printer') values 1-6 and prints Printer.Ticket.P1..P6, while RemoteOrderDisplay.remoteOrderDisplay() deletes and re-inserts one orders row per ticket line carrying a per-line display id, for an external display client that is not part of this repository. Nothing aggregates several stations into one order view and nothing gates order completion on every contributing station having bumped. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/RemoteOrderDisplay.java · retrieved 2026-08-03
kitchen-course-firing differentiator
Not scored by this record.
kitchen-prep-time-pacing differentiator
Not scored by this record.
kitchen-order-throttling differentiator
Not scored by this record.
kitchen-channel-pause-propagation differentiator
Not scored by this record.
kitchen-order-ready-callback differentiator
Not scored by this record.
kitchen-bump-bar-hardware
The kriolos-opos-hardware module enumerates every supported peripheral class - DevicePrinterESCPOS/JavaPOS/Plain/Printer/Null, DeviceFiscalPrinter, DeviceDisplay (ESCPOS, JavaPOS, LED8, PDLED8, SurePOS, serial, window and dual-screen), DeviceScale and DeviceScanner. There is no bump bar, programmable keypad or KDS input device among them, and the strings 'bump' and 'bumpbar' do not occur anywhere in the repository. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-hardware/src/main/java/com/openbravo/pos/printer/DeviceTicket.java · retrieved 2026-08-03
kitchen-all-day-counts
Not scored by this record.
kitchen-sla-alerts
Not scored by this record.
kitchen-printer-fallback differentiator
Not scored by this record.
kitchen-offline-operation differentiator
Not scored by this record.
kitchen-item-build-screens differentiator
Not scored by this record.
kitchen-pizza-fractional-display differentiator
Not scored by this record.
kitchen-recall-refire
Not scored by this record.
kitchen-order-modification-alerts differentiator
Not scored by this record.
kitchen-guest-ready-notification differentiator
Not scored by this record.
kitchen-waste-logging
Not scored by this record.
kitchen-speed-of-service-reporting
Not scored by this record.
kitchen-prep-forecasting
Not scored by this record.
Delivery, dispatch & third-party channels
delivery-driver-roster
The complete GPL source is the product, and it contains no driver concept at all. The shipped Liquibase changelog creates 53 tables and none is a driver, run, dispatch or delivery table; the only staff entities are people (POS operators with role, password and card) and the shifts/shift_breaks timekeeping tables, which carry no assignment-state or run column. A repository-wide search for driver, dispatch, courier and delivery matches only JDBC driver classes, Swing event-dispatch comments, the Courier New font and a supplier delivery-note tooltip. With no driver entity, clock-in state, run history or driver report anywhere in the tree, an in-house driver module does not exist. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-04
delivery-dispatch-board
No dispatch or expo board ships anywhere in the source. The only order-display code is RemoteOrderDisplay, which deletes and re-inserts one orders row per ticket line for an external display client that is not part of the repository - it shows nothing itself and knows nothing about drivers. The schema has no dispatch, run or driver table to drive such a board, no undispatched-order state, no elapsed-time tracking beyond the ticket timestamp, and no structure for batching multiple orders into one run. The sales screens in kriolos-opos-app are the register, the floor-plan map (JTicketsBagRestaurantMap) and the shared-ticket list; there is no dispatch view among them. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/RemoteOrderDisplay.java · retrieved 2026-08-04
delivery-route-map differentiator
Not scored by this record.
delivery-driver-tracking differentiator
Not scored by this record.
delivery-zones-polygon differentiator
Not scored by this record.
delivery-zone-pricing
There is no delivery entity in the schema at all - no zone, fee, promise-time or dispatch table. Guest addresses live as free text on customers (ADDRESS, ADDRESS2, POSTAL, CITY, REGION, COUNTRY) with no geocoding, zone assignment or per-zone fee/minimum, so a delivery charge can only be rung in as an ordinary product line. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
delivery-address-validation
Not scored by this record.
delivery-driver-comp differentiator
Not scored by this record.
delivery-cash-reconcile
Not scored by this record.
delivery-daas-dispatch
Not scored by this record.
delivery-daas-fallback differentiator
Not scored by this record.
delivery-3p-direct-integration differentiator
Not scored by this record.
delivery-3p-injection
Not scored by this record.
delivery-menu-push
Not scored by this record.
delivery-86-sync
Not scored by this record.
delivery-store-pause
Not scored by this record.
delivery-3p-reconciliation differentiator
Not scored by this record.
delivery-injection-error-visibility differentiator
Not scored by this record.
delivery-tracking-page
Not scored by this record.
delivery-promise-time differentiator
Not scored by this record.
delivery-offline-behavior
Not scored by this record.
Digital ordering & guest-facing channels
digital-first-party-web
The Maven reactor enumerates the entire product - kriolos-opos-spi, assets-reports, assets-image, thirdparty, base, hardware, domain, i18n, i18n_pt, lib-report, app, jpackage and docs - and none of these modules is or contains a web server, ordering site or HTTP endpoint; the application is a Swing desktop POS. The only e-commerce traces in the tree are three author comments inherited from uniCenta ('outline/prep for eCommerce connector' in OrderCustomerList, OrderSupplierList and TicketSelector) marking scaffolding that was never built. There is no first-party web ordering channel of any kind, commissioned or not. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/pom.xml · retrieved 2026-08-04
digital-menu-single-source
There is no digital menu to keep in sync. The POS menu record (products/categories in the application database) is the only menu the product has: the Maven reactor contains no web, app or kiosk module, no ordering API and no menu-export or menu-publish code anywhere in the tree, so no first-party digital channel exists for an item edit to propagate to. The single-source-of-truth capability is absent because the digital side of it does not exist in the product. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/pom.xml · retrieved 2026-08-04
digital-native-app differentiator
Not scored by this record.
digital-account-saved-payment
The product is a Java desktop application with no guest-facing channel: the Maven reactor is app, base, domain, hardware, i18n, jpackage, lib-report, spi, thirdparty and asset modules, with no web or ordering server. There is no card-on-file vault - payments stores per-transaction TRANSID, CARDNAME and RETURNMSG with no customer token relation - and no guest login, saved address or reorder concept exists in the schema. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
digital-upsell-engine differentiator
Not scored by this record.
digital-scheduled-pacing
Not scored by this record.
digital-fulfillment-modes
Not scored by this record.
digital-qr-table
Not scored by this record.
digital-kiosk differentiator
Not scored by this record.
digital-group-ordering
Not scored by this record.
digital-catering-portal differentiator
Not scored by this record.
digital-voice-ai-phone differentiator
Not scored by this record.
digital-drivethru-ai
Not scored by this record.
digital-sms-ordering
Not scored by this record.
digital-google-order differentiator
Not scored by this record.
digital-apple-business-connect
Not scored by this record.
digital-loyalty-attach
Not scored by this record.
digital-subscriptions
Not scored by this record.
digital-promo-parity
Not scored by this record.
digital-guest-data-ownership differentiator
Not scored by this record.
digital-checkout-pci-sca
Not scored by this record.
digital-surcharge-transparency differentiator
Not scored by this record.
Guest data, loyalty & marketing
guest-loyalty-unified-profile
customers is the only guest record and it can only be populated from the POS; there is no first-party web, app or kiosk channel in the product to merge from, and no dedup or merge machinery in the schema - no alias, match or merge table, and CARD, EMAIL and PHONE are plain nullable columns with no uniqueness or match rule. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
guest-loyalty-thirdparty-identity-attach differentiator
Not scored by this record.
guest-loyalty-accrual-models
The schema contains no points, visit, punch, tier or accrual table. The only guest-value constructs are customers.DISCOUNT (a flat per-customer percentage), customers.ISVIP, the MAXDEBT/CURDEBT house-account fields, and vouchers(ID, VOUCHER_NUMBER, CUSTOMER, AMOUNT, STATUS), which is stored value rather than an accrual program. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
guest-loyalty-tiers differentiator
Not scored by this record.
guest-loyalty-offline-behavior differentiator
Not scored by this record.
guest-loyalty-offer-stacking-rules differentiator
Not scored by this record.
guest-loyalty-targeted-offers differentiator
Not scored by this record.
guest-loyalty-rfm-segmentation differentiator
Not scored by this record.
guest-loyalty-lifecycle-automation
No campaign, message, segment or scheduler table exists in the schema and no mail or SMS transport ships in any module, so birthday, first-visit and lapsed win-back automations cannot be configured. customers does not even carry a birth date column. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
guest-loyalty-native-email-sms differentiator
Not scored by this record.
guest-loyalty-consent-management
Not scored by this record.
guest-loyalty-10dlc-registration
Not scored by this record.
guest-loyalty-campaign-attribution differentiator
Not scored by this record.
guest-loyalty-data-export-portability differentiator
Not scored by this record.
guest-loyalty-review-capture-routing differentiator
Not scored by this record.
guest-loyalty-referral-program
Not scored by this record.
guest-loyalty-wallet-pass differentiator
Not scored by this record.
guest-loyalty-privacy-rights-tooling
Not scored by this record.
guest-loyalty-redemption-fraud-controls
Not scored by this record.
guest-loyalty-ai-offer-recommendation differentiator
Not scored by this record.
guest-loyalty-stored-value-gift
Not scored by this record.
Labor & workforce
labor-clock-in-at-pos
JPanelEmployeePresence is a POS-resident panel with Check In and Check Out buttons plus a row of configurable break buttons; DataLogicPresenceManagement writes INSERT INTO shifts(ID, STARTSHIFT, PPLID) and UPDATE shifts SET ENDSHIFT = ? WHERE ENDSHIFT IS NULL AND PPLID = ?, with breaks recorded in shift_breaks(SHIFTID, BREAKID, STARTTIME, ENDTIME). Identification is the POS login itself - people carries APPPASSWORD and CARD, so PIN or magnetic card - and no separate time-clock hardware is required. The epm_dailypresence, epm_dailyschedule and epm_performance reports read the same tables. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/epm/JPanelEmployeePresence.java · retrieved 2026-08-03
labor-photo-punch-verification differentiator
Not scored by this record.
labor-offline-time-punch differentiator
Not scored by this record.
labor-granular-rbac
Permissions are per discrete action rather than fixed tiers: role XML grants individual entries including sales.Override, sales.DeleteLines, sales.EditLines, sales.EditTicket, sales.RefundTicket, sales.DeleteTicket, sales.ChangeTaxOptions, sales.Total, button.opendrawer, button.linediscount, button.totaldiscount, per-tender payment.* and refund.* entries, and one entry per report script (e.g. /com/openbravo/reports/sales_cashflow.bs), all checked at runtime through m_App.hasPermission(...). Roles are editable in the Roles admin panel. Shortfall: grants are global to the role - roles(ID, NAME, PERMISSIONS) has no location column and people(ROLE) assigns exactly one role per user with no location scoping, so per-location permission grants cannot be expressed. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Role.Employee.xml · retrieved 2026-08-03
labor-manager-override-audit
The only override mechanism is JPanelTicket.changeCount(), which reads a single shared static PIN from the override.pin application property and compares it against a JPasswordDialog entry ('Enter PIN Number' / 'PIN Number Incorrect'). It is one secret shared by all managers, it is tied to no user record, and nothing is persisted on success - no row, no timestamp, no approver identity. The sales.Override permission itself only widens shared-ticket visibility in JTicketsBagShared. lineremoved and draweropened record the operator who acted, never an approver. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/JPanelTicket.java · retrieved 2026-08-03
labor-native-scheduling differentiator
Not scored by this record.
labor-demand-labor-forecast differentiator
Not scored by this record.
labor-realtime-labor-percent differentiator
Not scored by this record.
labor-overtime-prevention differentiator
Not scored by this record.
labor-break-compliance-by-state differentiator
Not scored by this record.
labor-minor-labor-rules
Not scored by this record.
labor-tip-pooling-rules
Not scored by this record.
labor-tip-distribution-audit-trail
Not scored by this record.
labor-qualified-tips-w2-reporting differentiator
Not scored by this record.
labor-native-payroll differentiator
Not scored by this record.
labor-payroll-export-formats
Not scored by this record.
labor-shift-swap-workflow differentiator
Not scored by this record.
labor-server-performance-metrics differentiator
Not scored by this record.
Inventory, purchasing & cost control
inventory-recipe-bom-costing
The multi-level structure is real: products_bundle (ID, PRODUCT, PRODUCT_BUNDLE, QUANTITY) defines a component list per product, and DataLogicSales.adjustStock() calls getProductsBundle() and recurses into each component, multiplying quantity at each level, so a bundle whose component is itself a bundle explodes all the way down to raw stock on sale. Shortfall: none of it is costing. Nothing in the tree rolls component cost up to a parent - products.PRICEBUY is a hand-entered per-row field, and every reference to it (StockDiaryEditor, StockManagement, the inventory and label reports) reads it as stored; no code computes a parent's PRICEBUY or a plate cost from its components, so changing an ingredient cost updates nothing upstream. The bundle explosion in deleteTicket() even values components at getPriceSell(), not cost. There is no yield or conversion factor to cost against either: UomEditor is a single name field. Plate cost must be maintained by hand exactly as the claim warns against. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/forms/DataLogicSales.java · retrieved 2026-08-04
inventory-unit-conversion-yields
The unit-of-measure editor exposes a single field, name (UomEditor declares only m_jName), and the uom table is (ID, NAME). products references one uom column plus scalar STOCKCOST, STOCKVOLUME and STOCKUNITS. There is no purchase/recipe/count unit distinction, no conversion factor between units, and no yield or waste percentage field anywhere in the schema. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/inventory/UomEditor.java · retrieved 2026-08-03
inventory-theoretical-vs-actual differentiator
Not scored by this record.
inventory-realtime-depletion differentiator
Not scored by this record.
inventory-86-auto-sync differentiator
Not scored by this record.
inventory-count-modes
The movement-reason enumeration is closed and complete - IN_PURCHASE, IN_REFUND, IN_MOVEMENT, OUT_SALE, OUT_REFUND, OUT_BREAK, OUT_MOVEMENT, OUT_SAMPLE, OUT_FREE, OUT_USED, OUT_SUBTRACT, OUT_CROSSING - and contains no stocktake or count reason. The schema has no count-session table either: stockdiary is a flat movement log and stockcurrent holds only (LOCATION, PRODUCT, ATTRIBUTESETINSTANCE_ID, UNITS). A physical count can therefore only be keyed in as Adjust Add / Adjust Subtract movements, with no full-count, spot-count or scheduled cycle-count workflow and no per-count variance history. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/inventory/MovementReason.java · retrieved 2026-08-03
inventory-mobile-count-offline
Not scored by this record.
inventory-vendor-catalogs-edi differentiator
Not scored by this record.
inventory-invoice-ocr differentiator
Not scored by this record.
inventory-price-change-alerts differentiator
Not scored by this record.
inventory-par-auto-suggest differentiator
Not scored by this record.
inventory-waste-logging
Not scored by this record.
inventory-shelf-life-expiry
Not scored by this record.
inventory-bar-partial-bottle
Not scored by this record.
inventory-cogs-gl-export
Not scored by this record.
inventory-native-not-partner differentiator
Not scored by this record.
inventory-menu-margin-linkage differentiator
Not scored by this record.
Reporting, BI & data access
reporting-realtime-dashboard
Repo has active work on JasperReports-style report files, but no browser or mobile off-premise dashboard is documented.
reporting-eod-closeout
Printer.CloseCash.xml produces one close-cash document per cash session covering payments broken out by tender type with amounts, Total Sales, number of payments, a tax-analysis line per tax rate, a Line Voids block (ticket, user, product, units) from lineremoved, a No Sales block (user, ticket) from draweropened, receipt count, SubTotal / Taxes / Totals, and closed-by user, terminal, sequence and start/end date. Shortfall: no tip total is printed even though payments.TIP is stored, no discount total appears, and there is no counted-cash versus expected-cash reconciliation line, so the deposit still has to be derived off the report. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Printer.CloseCash.xml · retrieved 2026-08-03
reporting-pmix-modifier-level
sales_extproducts.bs is a real product-mix report: it groups ticketlines by product reference and name (and category and customer) returning SUM(UNITS) as TOTALunits with TOTALnet, TOTALtax and TOTALgross, filterable by date interval, customer and product/category. Shortfall: it is item-level only. Modifiers are stored as an opaque ATTRIBUTES blob on ticketlines and are never joined or aggregated by any shipped report, and the only time filter is a start/end datetime interval - there is no daypart grouping, and the schema has no revenue-centre concept to filter on. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-assets-reports/src/main/resources/com/openbravo/reports/sales_extproducts.bs · retrieved 2026-08-03
reporting-comps-voids-audit
Not scored by this record.
reporting-cash-over-short
Not scored by this record.
reporting-labor-productivity
Not scored by this record.
reporting-server-scorecards differentiator
Not scored by this record.
reporting-channel-profitability differentiator
Not scored by this record.
reporting-scheduled-delivery
Not scored by this record.
reporting-public-api differentiator
Not scored by this record.
reporting-webhooks differentiator
Not scored by this record.
reporting-api-not-upcharged differentiator
Not scored by this record.
reporting-tier-paywall differentiator
Not scored by this record.
reporting-history-retention differentiator
Not scored by this record.
reporting-anomaly-alerts differentiator
Not scored by this record.
reporting-nl-query
Not scored by this record.
reporting-guest-cohorts differentiator
Not scored by this record.
reporting-sales-forecast differentiator
Not scored by this record.
reporting-tip-tax-compliance
Not scored by this record.
Multi-location, franchise & enterprise governance
multi-location-org-hierarchy
locations is (ID, NAME, ADDRESS) with no parent, group or level column, and nothing else in the schema references a location grouping. It is a flat warehouse list used for stock movements; there is no enterprise/region/location hierarchy for reporting or permissions to be scoped to. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
multi-location-central-menu-publish
An install is a single application database shared by its terminals - products, categories and prices exist once, with no location column and no store-level copy to publish to. The schema contains no publish, version, changeset or deployment-history table, and no module in the reactor performs cross-database menu distribution. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
multi-location-price-zones
products carries exactly one PRICEBUY and one PRICESELL and there is no price-list, price-tier or channel-price table in the schema; ticketlines stores the resolved PRICE per line. The only price-variation mechanisms are customers.DISCOUNT (a flat percentage on one guest) and the isvprice variable-price flag, so per-location-group, per-channel or per-daypart pricing requires duplicating the product. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml · retrieved 2026-08-03
multi-location-consolidated-reporting
Not scored by this record.
multi-location-cross-location-giftcard
Not scored by this record.
multi-location-cross-location-loyalty
Not scored by this record.
multi-location-multi-brand differentiator
Not scored by this record.
multi-location-multi-tax-jurisdiction
Not scored by this record.
multi-location-central-labor-policy
Not scored by this record.
Hardware & physical footprint
hardware-commodity-devices differentiator
Not scored by this record.
hardware-os-platforms
Java/Maven desktop build implies Windows, macOS and Linux, but no minimum OS versions or device specs are published.
hardware-handheld-purpose-built
Not scored by this record.
hardware-handheld-battery-swap differentiator
Not scored by this record.
hardware-handheld-lte
Not scored by this record.
hardware-offline-mode
On-premise architecture runs without internet; no vendor statement enumerates which functions degrade. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
hardware-kds
No first-party KDS exists. The only KDS code in the tree is KitchenDisplay.java, whose addRecord() inserts (ID, ORDERTIME, PLACE, PICKUPID, PRODUCT, MULTIPLY, ATTRIBUTES) into a KITCHENDISPLAY table that no Liquibase changelog creates, and the class is never instantiated anywhere in the repository - dead code with no display UI behind it. Kitchen output actually ships as printing: script.SendOrder.bs routes lines by product.printer 1-6 to Printer.Ticket.P1..P6 templates on locally bound printers ('Print to Kitchen Printer' in the shipped strings). The hardware module's peripheral enumeration (printers, fiscal printer, customer displays, scale, scanner) includes no KDS screen or bump-bar input device, and nothing anywhere implements station routing to a display or course/fire timing. RemoteOrderDisplay presupposes an external display client that is not part of the product. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/sales/KitchenDisplay.java · retrieved 2026-08-04
hardware-kiosk differentiator
Not scored by this record.
hardware-drive-thru
Not scored by this record.
hardware-printer-compatibility
Not scored by this record.
hardware-peripherals
Not scored by this record.
hardware-p2pe-terminal
Not scored by this record.
hardware-tap-to-phone differentiator
Not scored by this record.
hardware-pricing-transparency differentiator
Not scored by this record.
hardware-ownership-vs-lease differentiator
Not scored by this record.
hardware-usable-after-churn differentiator
Not scored by this record.
hardware-rma-sla differentiator
Not scored by this record.
hardware-byod
Not scored by this record.
hardware-remote-device-management differentiator
Not scored by this record.
hardware-selfpour-scales
Not scored by this record.
hardware-callerid-integration
Not scored by this record.
Integrations, API & extensibility
extensibility-public-api-docs
AsciiDoc project docs and full GPL-3.0 source are public, but there is no self-serve REST API reference. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
extensibility-api-access-cost differentiator
Not scored by this record.
extensibility-free-sandbox differentiator
Not scored by this record.
extensibility-oauth-partner-apps
Desktop application with direct database access; no OAuth 2.0 authorization server or scoped third-party app grants. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
extensibility-webhooks-push
The extension points that ship are in-process BeanShell scripts stored as application resources - customer.created.bs, customer.updated.bs, customer.deleted.bs, event.addline.bs, event.removeline.bs, event.setline.bs, script.Event.Total.bs - executed inside the terminal JVM. There is no outbound HTTP event delivery, no subscription registry, no signing and no retry. The one networked hook, script.poshubclient.bs, has both its import and its only call commented out and merely prints a debug line. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/script.poshubclient.bs · retrieved 2026-08-03
extensibility-webhook-reliability differentiator
Not scored by this record.
extensibility-order-injection-api
Not scored by this record.
extensibility-menu-write-api differentiator
Not scored by this record.
extensibility-doordash-preferred differentiator
Not scored by this record.
extensibility-first-party-delivery-integrations differentiator
Not scored by this record.
extensibility-middleware-compatibility
Not scored by this record.
extensibility-accounting-connectors
Not scored by this record.
extensibility-payroll-export
Not scored by this record.
extensibility-app-marketplace
Not scored by this record.
extensibility-headless-embedded
Not scored by this record.
extensibility-data-portability-exit differentiator
Not scored by this record.
Reliability, offline & operations
reliability-offline-order-entry
Local install and local database make order entry and printing independent of internet connectivity. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
reliability-offline-card-auth differentiator
Not scored by this record.
reliability-offline-decline-liability differentiator
Not scored by this record.
reliability-lan-degraded-multi-terminal differentiator
Not scored by this record.
reliability-local-transaction-engine differentiator
Not scored by this record.
reliability-offline-kds-printing
Kitchen routing runs entirely on the terminal with no network service in the path: script.SendOrder.bs reads line.getProperty('product.printer') and calls sales.printTicket('Printer.Ticket.P1') through P6, and DeviceTicket binds each machine.printer.N property to a locally attached serial, USB, file, JavaPOS or system printer via DevicePrinterESCPOS/JavaPOS/Plain/Printer. An internet outage cannot affect kitchen printing. The terminal does still need its database connection, and no display client ships for the KDS half of the claim. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/script.SendOrder.bs · retrieved 2026-08-03
reliability-printer-fallback
DeviceTicket.getDevicePrinter(key) ends 'return printer == null ? m_nullprinter : printer' - a DevicePrinterNull that silently discards output when the configured printer is missing. Printer initialisation failures are swallowed into logger.log(Level.WARNING, e.getMessage(), e) with no user-visible alert, and machine.printer.1 through machine.printer.6 are independent named destinations with no backup, failover or alternate-station property. There is no fallback path. https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-hardware/src/main/java/com/openbravo/pos/printer/DeviceTicket.java · retrieved 2026-08-03
reliability-sync-conflict-handling
Not scored by this record.
reliability-offline-feature-matrix
Not scored by this record.
reliability-public-status-page
Not scored by this record.
reliability-247-live-support
Not scored by this record.
reliability-onsite-install differentiator
Not scored by this record.
reliability-menu-build-service differentiator
Not scored by this record.
reliability-hardware-replacement-sla
Not scored by this record.
reliability-pci-dss-4-attestation
Not scored by this record.
reliability-mfa-role-based-access
Not scored by this record.
reliability-self-serve-training
Not scored by this record.
reliability-failover-terminal-role differentiator
Not scored by this record.
reliability-cellular-backup
Not scored by this record.
Commercial, compliance & data ownership
commercial-month-to-month-contract differentiator
Not scored by this record.
commercial-no-early-termination-fee differentiator
Not scored by this record.
commercial-autorenew-terms-published
GPL-3.0 software with no subscription, so no auto-renewal term or cancellation notice window exists.
commercial-processing-not-bundled differentiator
Not scored by this record.
commercial-interchange-plus-published differentiator
Not scored by this record.
commercial-rate-increase-clause differentiator
Not scored by this record.
commercial-pricing-published
Unambiguously free: GPL-3.0 licensed with releases distributed on GitHub and no commercial tier offered. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
commercial-module-unbundling differentiator
Not scored by this record.
commercial-hardware-purchase-outright
No first-party hardware sold, so no mandatory lease; operators buy commodity hardware themselves. https://github.com/kriolos-obiz/kriolos-pos · retrieved 2026-08-01
commercial-hardware-not-locked differentiator
Not scored by this record.
commercial-data-export-self-serve
Not scored by this record.
commercial-export-customer-and-loyalty differentiator
Not scored by this record.
commercial-post-termination-export-window differentiator
Not scored by this record.
commercial-data-ownership-clause differentiator
Not scored by this record.
commercial-pci-p2pe-tokenization
Not scored by this record.
commercial-pci-dss-4-controls
Not scored by this record.
commercial-privacy-dsar-tooling
Not scored by this record.
commercial-wcag-kiosk-accessibility differentiator
Not scored by this record.
commercial-dual-pricing-compliant differentiator
Not scored by this record.
Adversarial verification
An independent pass was instructed to refute this record, defaulting to downgrade when uncertain. It challenged 34 values — 0 upheld, 0 downgraded, 0 upgraded. This is published in full because a reader who can see which values were contested, on what evidence, and which way they moved has something no affiliate-funded comparison offers.
Capability claims
| Claim | As first scored | Verdict | What the verifier found |
|---|---|---|---|
| order-capture-scheduled-orders | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The full Liquibase schema is public. receipts carries only (ID, MONEY, DATENEW, ATTRIBUTES, PERSON), tickets only (ID, TICKETTYPE, TICKETID, PERSON, CUSTOMER, STATUS) and sharedtickets only (ID, NAME, CONTENT, APPUSER, PICKUPID, LOCKED) - there is no future fire-time, promise-time or lead-time column anywhere, so a held ticket cannot be dated forward or auto-fired. The reservations table (CREATED, DATENEW, TITLE, CHAIRS, ISDONE, DESCRIPTION) is a table-booking calendar, not an order. source |
| menu-pricing-modifier-price-by-parent-size | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | Modifiers are modelled as product attributes: attribute(ID, NAME), attributevalue(ID, ATTRIBUTE_ID, VALUE), attributeuse and attributesetinstance carry no price column at all, so an attribute value cannot hold a price, let alone a per-parent/per-size matrix. The only priced alternative is a complement product (products_com joins PRODUCT to PRODUCT2), and products holds a single PRICESELL per row, so a differently priced topping requires a duplicated product record. source |
| menu-pricing-topping-quantity-tiers | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | No quantity-tier or price-multiplier field exists: attributevalue is (ID, ATTRIBUTE_ID, VALUE) with no numeric price or factor, and ticketlines carries only UNITS and PRICE. Light/regular/extra can only be expressed by adding the complement product again or by creating separate products. source |
| payments-refund-void-controls | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | Authorization is genuinely role-based: the shipped role files grant discrete permissions sales.RefundTicket, sales.DeleteLines, sales.DeleteTicket, refund.cash/cheque/voucher/magcard, button.opendrawer, button.linediscount and button.totaldiscount, and Role.Employee.xml deliberately omits every refund, delete-ticket and open-drawer entry. Voids and no-sales are logged - JPanelTicket calls dlSystem.execLineRemoved(user name, ticket id, product, units) into the lineremoved table, draweropened records (OPENDATE, NAME, TICKETID), and both blocks print on the close-cash report. Shortfall: the log records the logged-in operator, never an approving manager; there is no per-user approval prompt (the optional override is a single shared static PIN read from the override.pin application property in JPanelTicket.changeCount()); discounts and refunds are written to no audit table at all; and lineremoved/draweropened are ordinary mutable tables with no immutability guarantee. source |
| kitchen-expo-consolidation | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | No expo or consolidation view ships. Kitchen routing is per-line only: script.SendOrder.bs branches on line.getProperty('product.printer') values 1-6 and prints Printer.Ticket.P1..P6, while RemoteOrderDisplay.remoteOrderDisplay() deletes and re-inserts one orders row per ticket line carrying a per-line display id, for an external display client that is not part of this repository. Nothing aggregates several stations into one order view and nothing gates order completion on every contributing station having bumped. source |
| kitchen-bump-bar-hardware | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The kriolos-opos-hardware module enumerates every supported peripheral class - DevicePrinterESCPOS/JavaPOS/Plain/Printer/Null, DeviceFiscalPrinter, DeviceDisplay (ESCPOS, JavaPOS, LED8, PDLED8, SurePOS, serial, window and dual-screen), DeviceScale and DeviceScanner. There is no bump bar, programmable keypad or KDS input device among them, and the strings 'bump' and 'bumpbar' do not occur anywhere in the repository. source |
| delivery-zone-pricing | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | There is no delivery entity in the schema at all - no zone, fee, promise-time or dispatch table. Guest addresses live as free text on customers (ADDRESS, ADDRESS2, POSTAL, CITY, REGION, COUNTRY) with no geocoding, zone assignment or per-zone fee/minimum, so a delivery charge can only be rung in as an ordinary product line. source |
| digital-account-saved-payment | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The product is a Java desktop application with no guest-facing channel: the Maven reactor is app, base, domain, hardware, i18n, jpackage, lib-report, spi, thirdparty and asset modules, with no web or ordering server. There is no card-on-file vault - payments stores per-transaction TRANSID, CARDNAME and RETURNMSG with no customer token relation - and no guest login, saved address or reorder concept exists in the schema. source |
| guest-loyalty-unified-profile | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | customers is the only guest record and it can only be populated from the POS; there is no first-party web, app or kiosk channel in the product to merge from, and no dedup or merge machinery in the schema - no alias, match or merge table, and CARD, EMAIL and PHONE are plain nullable columns with no uniqueness or match rule. source |
| guest-loyalty-accrual-models | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The schema contains no points, visit, punch, tier or accrual table. The only guest-value constructs are customers.DISCOUNT (a flat per-customer percentage), customers.ISVIP, the MAXDEBT/CURDEBT house-account fields, and vouchers(ID, VOUCHER_NUMBER, CUSTOMER, AMOUNT, STATUS), which is stored value rather than an accrual program. source |
| guest-loyalty-lifecycle-automation | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | No campaign, message, segment or scheduler table exists in the schema and no mail or SMS transport ships in any module, so birthday, first-visit and lapsed win-back automations cannot be configured. customers does not even carry a birth date column. source |
| labor-clock-in-at-pos | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-yes | JPanelEmployeePresence is a POS-resident panel with Check In and Check Out buttons plus a row of configurable break buttons; DataLogicPresenceManagement writes INSERT INTO shifts(ID, STARTSHIFT, PPLID) and UPDATE shifts SET ENDSHIFT = ? WHERE ENDSHIFT IS NULL AND PPLID = ?, with breaks recorded in shift_breaks(SHIFTID, BREAKID, STARTTIME, ENDTIME). Identification is the POS login itself - people carries APPPASSWORD and CARD, so PIN or magnetic card - and no separate time-clock hardware is required. The epm_dailypresence, epm_dailyschedule and epm_performance reports read the same tables. source |
| labor-granular-rbac | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | Permissions are per discrete action rather than fixed tiers: role XML grants individual entries including sales.Override, sales.DeleteLines, sales.EditLines, sales.EditTicket, sales.RefundTicket, sales.DeleteTicket, sales.ChangeTaxOptions, sales.Total, button.opendrawer, button.linediscount, button.totaldiscount, per-tender payment.* and refund.* entries, and one entry per report script (e.g. /com/openbravo/reports/sales_cashflow.bs), all checked at runtime through m_App.hasPermission(...). Roles are editable in the Roles admin panel. Shortfall: grants are global to the role - roles(ID, NAME, PERMISSIONS) has no location column and people(ROLE) assigns exactly one role per user with no location scoping, so per-location permission grants cannot be expressed. source |
| labor-manager-override-audit | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The only override mechanism is JPanelTicket.changeCount(), which reads a single shared static PIN from the override.pin application property and compares it against a JPasswordDialog entry ('Enter PIN Number' / 'PIN Number Incorrect'). It is one secret shared by all managers, it is tied to no user record, and nothing is persisted on success - no row, no timestamp, no approver identity. The sales.Override permission itself only widens shared-ticket visibility in JTicketsBagShared. lineremoved and draweropened record the operator who acted, never an approver. source |
| inventory-unit-conversion-yields | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The unit-of-measure editor exposes a single field, name (UomEditor declares only m_jName), and the uom table is (ID, NAME). products references one uom column plus scalar STOCKCOST, STOCKVOLUME and STOCKUNITS. There is no purchase/recipe/count unit distinction, no conversion factor between units, and no yield or waste percentage field anywhere in the schema. source |
| inventory-count-modes | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The movement-reason enumeration is closed and complete - IN_PURCHASE, IN_REFUND, IN_MOVEMENT, OUT_SALE, OUT_REFUND, OUT_BREAK, OUT_MOVEMENT, OUT_SAMPLE, OUT_FREE, OUT_USED, OUT_SUBTRACT, OUT_CROSSING - and contains no stocktake or count reason. The schema has no count-session table either: stockdiary is a flat movement log and stockcurrent holds only (LOCATION, PRODUCT, ATTRIBUTESETINSTANCE_ID, UNITS). A physical count can therefore only be keyed in as Adjust Add / Adjust Subtract movements, with no full-count, spot-count or scheduled cycle-count workflow and no per-count variance history. source |
| reporting-eod-closeout | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | Printer.CloseCash.xml produces one close-cash document per cash session covering payments broken out by tender type with amounts, Total Sales, number of payments, a tax-analysis line per tax rate, a Line Voids block (ticket, user, product, units) from lineremoved, a No Sales block (user, ticket) from draweropened, receipt count, SubTotal / Taxes / Totals, and closed-by user, terminal, sequence and start/end date. Shortfall: no tip total is printed even though payments.TIP is stored, no discount total appears, and there is no counted-cash versus expected-cash reconciliation line, so the deposit still has to be derived off the report. source |
| reporting-pmix-modifier-level | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | sales_extproducts.bs is a real product-mix report: it groups ticketlines by product reference and name (and category and customer) returning SUM(UNITS) as TOTALunits with TOTALnet, TOTALtax and TOTALgross, filterable by date interval, customer and product/category. Shortfall: it is item-level only. Modifiers are stored as an opaque ATTRIBUTES blob on ticketlines and are never joined or aggregated by any shipped report, and the only time filter is a start/end datetime interval - there is no daypart grouping, and the schema has no revenue-centre concept to filter on. source |
| multi-location-org-hierarchy | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | locations is (ID, NAME, ADDRESS) with no parent, group or level column, and nothing else in the schema references a location grouping. It is a flat warehouse list used for stock movements; there is no enterprise/region/location hierarchy for reporting or permissions to be scoped to. source |
| multi-location-central-menu-publish | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | An install is a single application database shared by its terminals - products, categories and prices exist once, with no location column and no store-level copy to publish to. The schema contains no publish, version, changeset or deployment-history table, and no module in the reactor performs cross-database menu distribution. source |
| multi-location-price-zones | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | products carries exactly one PRICEBUY and one PRICESELL and there is no price-list, price-tier or channel-price table in the schema; ticketlines stores the resolved PRICE per line. The only price-variation mechanisms are customers.DISCOUNT (a flat percentage on one guest) and the isvprice variable-price flag, so per-location-group, per-channel or per-daypart pricing requires duplicating the product. source |
| extensibility-webhooks-push | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The extension points that ship are in-process BeanShell scripts stored as application resources - customer.created.bs, customer.updated.bs, customer.deleted.bs, event.addline.bs, event.removeline.bs, event.setline.bs, script.Event.Total.bs - executed inside the terminal JVM. There is no outbound HTTP event delivery, no subscription registry, no signing and no retry. The one networked hook, script.poshubclient.bs, has both its import and its only call commented out and merely prints a debug line. source |
| reliability-offline-kds-printing | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-yes | Kitchen routing runs entirely on the terminal with no network service in the path: script.SendOrder.bs reads line.getProperty('product.printer') and calls sales.printTicket('Printer.Ticket.P1') through P6, and DeviceTicket binds each machine.printer.N property to a locally attached serial, USB, file, JavaPOS or system printer via DevicePrinterESCPOS/JavaPOS/Plain/Printer. An internet outage cannot affect kitchen printing. The terminal does still need its database connection, and no display client ships for the KDS half of the claim. source |
| reliability-printer-fallback | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | DeviceTicket.getDevicePrinter(key) ends 'return printer == null ? m_nullprinter : printer' - a DevicePrinterNull that silently discards output when the configured printer is missing. Printer initialisation failures are swallowed into logger.log(Level.WARNING, e.getMessage(), e) with no user-visible alert, and machine.printer.1 through machine.printer.6 are independent named destinations with no backup, failover or alternate-station property. There is no fallback path. source |
| menu-pricing-nested-modifiers | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The shipped DDL enumerates the whole model: products has one ATTRIBUTESET_ID, attributeset(ID, NAME), attributeuse(ID, ATTRIBUTESET_ID, ATTRIBUTE_ID, LINENO), attribute(ID, NAME), attributevalue(ID, ATTRIBUTE_ID, VALUE). Flat two levels, no self-referencing parent group, no MIN/MAX columns, no required flag. products_com and products_bundle are the only other composition tables and carry none of those either. The one forced-selection control is a single product-level boolean, ISVERPATRIB ('mandatory' in ProductsEditor), which prompts for the entire attribute set once. source |
| payments-gift-cards | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | Native first-party vouchers do exist - a vouchers table, a back-office issuing panel and JPaymentVoucher as a tender - and with no location column they work across the group on one shared database. But VoucherInfo's STATUS is binary 'A'/'D' with no balance field, and JPaymentVoucher disables moneyEditor and loads the full amount, so redemption is all-or-nothing and no real-time balance is tracked. No online-ordering channel exists in the product to redeem through. source |
| kitchen-station-routing | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | products.PRINTTO (a 0-6 combo in ProductsEditor) plus script.SendOrder.bs branching to Printer.Ticket.P1..P6 give genuine admin-configurable per-item routing. But the destinations are printers, not KDS stations - KitchenDisplay.java writes to a KITCHENDISPLAY table no changelog creates and is never instantiated - routing keys off the product row only with no category/order-type/revenue-centre rule, the six destinations are hard-coded, and printer bindings are per-terminal machine.printer.N properties rather than per-location config. source |
| inventory-recipe-bom-costing | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | products_bundle(PRODUCT, PRODUCT_BUNDLE, QUANTITY) plus the recursive DataLogicSales.adjustStock() give real multi-level component explosion down to raw stock, so sub-recipes exist structurally. The costing half does not: products.PRICEBUY is hand-entered and every consumer reads it as stored; no code rolls component cost up to a parent, deleteTicket() even values exploded components at PRICESELL, and UomEditor has no conversion or yield factor. An ingredient cost change propagates nowhere. source |
| order-capture-split-merge | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-partial | Both halves exist in item-move form only. btnSplit (gated on sales.Total and more than one article) opens ReceiptSplit, a two-pane dialog with move-one/move-all buttons shifting whole lines to one new ticket, which is then paid immediately via closeTicket(); JTicketsBagRestaurantMap merges tables by appending the clipboard table's lines into the target ticket and deleting the source shared ticket after a confirmation. Missing: any seat concept (places.SEATS is floor-plan table capacity; ticketlines has no seat column), even N-way splits, and dollar/percentage splits. Payment closes a receipt, so the after-partial-payment case is structurally impossible rather than supported. source |
| delivery-driver-roster | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The complete source contains no driver concept: none of the 53 Liquibase tables is a driver, run or dispatch table, the only staff entities are people plus the shifts/shift_breaks timekeeping pair with no assignment-state column, and a tree-wide search for driver/dispatch/courier/delivery matches only JDBC drivers, Swing EDT comments, the Courier New font and a supplier delivery-note tooltip. source |
| delivery-dispatch-board | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | No dispatch or expo screen ships: the sales views are the register, the floor-plan map and the shared-ticket list. The only order-display code, RemoteOrderDisplay, writes one orders row per ticket line for an external display client outside the repository, and the schema has no dispatch state, driver availability or run-batching structure for a board to show. source |
| digital-first-party-web | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The Maven reactor enumerates the whole product (spi, assets-reports, assets-image, thirdparty, base, hardware, domain, i18n, i18n_pt, lib-report, app, jpackage, docs) and contains no web server, ordering site or HTTP endpoint - it is a Swing desktop POS. The only e-commerce traces are three 'outline/prep for eCommerce connector' author comments inherited from uniCenta, marking scaffolding never built. source |
| digital-menu-single-source | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | There is no digital menu for the POS menu record to feed: no web, app or kiosk module exists in the reactor, and no menu-export or publish code exists anywhere in the tree. The capability is absent because the product has no first-party digital channel at all. source |
| hardware-kds | unknown (grade F) - "No public documentation located during the 2026-08-01 research pass.", a placeholder marking a cell nobody had examined. | resolve-to-no | The only KDS code, KitchenDisplay.java, inserts into a KITCHENDISPLAY table no changelog creates and is never instantiated - dead code with no display UI. Kitchen output ships as printing (script.SendOrder.bs to Printer.Ticket.P1..P6 on local printers), the hardware module's peripheral enumeration includes no KDS screen or bump-bar device, and nothing implements station routing to a display or course/fire timing. RemoteOrderDisplay presupposes an external display client not in the product. source |
Sources
Every URL this record cites. 24 in total.
- https://github.com/kriolos-obiz/kriolos-pos
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/pos_liquidbase/db-changelog-v4_5.xml
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Role.Manager.xml
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Role.Employee.xml
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/JPanelTicket.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/epm/JPanelEmployeePresence.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/epm/DataLogicPresenceManagement.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/inventory/UomEditor.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/inventory/MovementReason.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/Printer.CloseCash.xml
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-assets-reports/src/main/resources/com/openbravo/reports/sales_extproducts.bs
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-hardware/src/main/java/com/openbravo/pos/printer/DeviceTicket.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/script.SendOrder.bs
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/RemoteOrderDisplay.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/resources/com/openbravo/pos/templates/script.poshubclient.bs
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/inventory/ProductsEditor.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/forms/DataLogicSales.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/payment/JPaymentVoucher.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/voucher/VoucherInfo.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-domain/src/main/java/com/openbravo/pos/sales/KitchenDisplay.java
- https://api.github.com/repos/kriolos-obiz/kriolos-pos/git/trees/main?recursive=1
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/ReceiptSplit.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/kriolos-opos-app/src/main/java/com/openbravo/pos/sales/restaurant/JTicketsBagRestaurantMap.java
- https://raw.githubusercontent.com/kriolos-obiz/kriolos-pos/main/pom.xml