diff --git a/README.md b/README.md index cb21612c..46cf9f04 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,234 @@ -# ViewTouch Development Branch +
-Welcome to the **dev** branch! This is a dedicated development environment for exploring, testing, and improving the ViewTouch codebase. +# ViewTouch© -## What is This Branch? +**The Original Graphical Touchscreen Restaurant Point of Sale Interface** -The `dev` branch serves as an **experimental and testing ground** for new features, improvements, and refactoring. Unlike the `master` branch (which mirrors the official ViewTouch repository), the `dev` branch contains: +[![Build Status](https://img.shields.io/travis/ViewTouch/viewtouch/master.svg?label=Travis)](https://travis-ci.org/ViewTouch/viewtouch/builds) +[![Discord](https://img.shields.io/discord/YOUR_SERVER_ID?color=7289da&label=Discord&logo=discord&logoColor=white)](https://discord.com/invite/ySmH2U2Mzb) +[![Join the chat at https://gitter.im/ViewTouch/viewtouch](https://badges.gitter.im/ViewTouch/viewtouch.svg)](https://gitter.im/ViewTouch/viewtouch?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -- Latest code changes and enhancements -- Work-in-progress features -- Community-driven improvements -- Modern C++ refactoring and modernizations -- Static analysis fixes and code quality improvements +*ViewTouch is a registered trademark in the USA* -## For Developers & Community Contributors +[Website](http://www.viewtouch.com) • [Wiki & Documentation](../../wiki) • [Download Image](http://www.viewtouch.com/nc.html) -ViewTouch is **open to the community**! We welcome developers of all skill levels to: +
-✅ **Test your coding skills** — Improve and expand the ViewTouch codebase -✅ **Learn by doing** — Work with a real POS system written in modern C++ -✅ **Use AI assistance** — Leverage tools like GitHub Copilot, ChatGPT, or Claude to accelerate development -✅ **Contribute improvements** — Submit pull requests with enhancements, bug fixes, and optimizations -✅ **Collaborate** — Join an active community dedicated to advancing ViewTouch +--- + +## Table of Contents + +- [About](#about) +- [Quick Start](#quick-start) +- [Hardware](#hardware) +- [Screenshots](#screenshots) +- [History](#history) +- [Contact & Support](#contact--support) +- [License](#license) + +--- + +## About + +ViewTouch is a powerful, open-source Point of Sale system designed specifically for the restaurant and hospitality industry. With over four decades of development, it combines the reliability of Linux with the flexibility of the X Window System to deliver a robust, network-transparent POS solution. + +### Key Features + +- **Full High Definition Graphical Interface** - ViewTouch runs on (*requires*) displays with 1920 x 1080 resolution +- **Lightning-fast performance** - Entire transaction history kept in RAM for instant reporting +- **Network transparency** - Remote display capability via X Window System +- **Comprehensive reporting** - Real-time drill-down analytics and decision support +- **Labor management** - Interactive time clock with overtime alerts and cost control +- **Cross-platform** - Runs on Raspberry Pi 4/5, x86, and ARM architectures +- **Mobile integration** - Android tableside order entry support +- **Multilingual support** - Built-in language pack system +- **Cross platform solution** - Can be used on a wide variaty of linux distros thanks to the universal installer + +> **Note:** For build instructions and the latest announcements, visit the [Wiki](../../wiki). + +--- + +## Quick Start + +### Download Pre-built Image + +[Download the latest ViewTouch image](http://www.viewtouch.com/nc.html) for Raspberry Pi (4 or 5). Write the image to a 32GB or larger microSD card, and boot directly to the ViewTouch desktop with full POS functionality. + +#### Building + +See the [Wiki](../../wiki) for detailed build instructions and development setup. Make sure your display is 1920 x 1080. + +--- + +## Hardware + +### Official ViewTouch Point of Sale Computer + +
+ +![ViewTouch Point of Sale Computer with 15.8" Display](https://www.viewtouch.com/poscomputer.avif) + +**15.8" All-in-One Touchscreen POS Computer** +Powered by Raspberry Pi Compute Module 5 +Manufactured by Chipsee, Beijing, China + +
+ +ViewTouch offers all-in-one Point of Sale computers featuring: +- 15.8" capacitive touchscreen display (1920×1080 resolution, which is the required resolution for any display running ViewTouch) +- Raspberry Pi 5 Compute Module +- Pre-installed ViewTouch software +- Network-ready for multi-terminal setups + +With open-source code and Raspberry Pi hardware, restaurateurs can now fully automate their operations with complete control over their POS system, including source code access. + +### Mobile Support + +Thanks to Pelya (Sergii Pylypenko) and Ariel Brambila Pelayo for ensuring that with [Xsdl](https://apkpure.com/xserver-xsdl/x.org.server) mobile Android devices as wireless ViewTouch tableside order entry displays. + +--- + +## Screenshots + +> *Screenshots shown in 1280×1024 resolution, however, note that the Default (*required*) ViewTouch display resolution is 1920×1080 !* + +### Time Clock and Secure Log On -## ⚠️ Important Warning: Development Build Instability +![Touchscreen Password, Log On and Timeclock](http://www.viewtouch.com/vtscrn1.png) -**THIS IS A DEVELOPMENT BUILD** — Expect bugs, incomplete features, and breaking changes. +--- + +### Order Entry - Lightning Fast Interface + +**Order Breakfast, then Display and/or Print in Kitchen** + +![Order Breakfast, then Display and/or Print in Kitchen](http://www.viewtouch.com/vtscrn6.png) + +--- + +### Labor Management + +**Time Clock Review and Edit - Control Labor Expense** +Back Office, Comprehensive Labor Costing, Overtime Alerts, Interactive Time Clock Review and Editing + +![Time Clock Review and Edit - Control Labor Expense](http://www.viewtouch.com/vtscrn3.png) + +--- + +### Real-time Analytics + +**Decision Support: Fly-Over, Drill-Down in Real Time** +Touch 'n' View Any Day or Any Period Updated Every Minute + +![Decision Support: Fly-Over, Drill-Down in Real Time](http://www.viewtouch.com/vtscrn5.png) + +ViewTouch doesn't just store your data—it keeps your entire transaction history in RAM for perfect accuracy and lightning speed. Auditors can see compliance across every period. Control non-cash revenue adjustments and labor costs, including non-intuitive details, shift by shift, weekly, monthly, quarterly, and yearly. + +--- -- **Frequent Changes**: Code is actively being modified and tested -- **Known Issues**: This branch will contain bugs and incomplete implementations -- **Not Production Ready**: Do NOT use this build in production environments -- **Testing Required**: Features may fail or behave unexpectedly +## History -## Reporting Issues +### Origins (1979-1986) -Found a bug? Help us improve! Please report issues on our [Issues Page](../../issues) with: +Gene Mosher began writing Point of Sale code on an Apple ][ in 1979. ViewTouch© as we know it today was first created by restaurateur Gene Mosher and C programmer Nick Colley in **1986**, making it the **ORIGINAL Graphical Touchscreen Restaurant Point of Sale Interface**. -📝 **Detailed Information**: -- Steps to reproduce the issue -- Expected vs. actual behavior -- Screenshots or error logs (if applicable) -- Your environment (OS, ViewTouch version, build type) -- Relevant code snippets or stack traces +**First Public Demonstration:** ComDex, Las Vegas, November 1986 +[See historical photo](https://commons.wikimedia.org/wiki/File:Comdex_1986.png) -📋 **Issue Template**: -``` -**Describe the bug:** -[Clear description of the issue] +**Early Platform:** Atari ST computers (1986-1993/4 under Jack Tramiel) -**Steps to reproduce:** -1. [First step] -2. [Second step] -3. [What happens] +**Initial Funding & Support:** +- Ed Ramsay (1986 - code development funding) +- Barbara Mosher (1986 - present, ongoing financial support) +- John King, M.D., Chicago (early funding) -**Expected behavior:** -[What should happen] +### Modern Era (1995-1998) -**Environment:** -- OS: [e.g., Ubuntu 20.04] -- ViewTouch Version: [e.g., dev branch, commit hash] -- Build Type: [Debug/Release] +The current version of ViewTouch was created by Gene Mosher and C programmer Richard Bradley, transitioning to: +- **UNIX (AIX)** on Motorola PowerPC (1995) +- **MIT's X Window System** for network-transparent graphical interface (1995) +- **Linux on Intel x86** (1997) -**Additional context:** -[Any other relevant information] -``` +**Major Funding:** Billy Foster (1995-1998) -## Getting Started +### Enhancement Period (2000-2004) -### Build and Test +- **C to C++ transition** (2000-present day) +- Extensive code enhancement by Bruce King (2000-2004) Ariel Brambila Pelayo (2025) +- **Major Funding:** Doug DeLeeuw -```bash -# Clone the repository -git clone https://github.com/ViewTouch/viewtouch.git -cd viewtouch -git checkout dev +### Open Source Era (2014-Present) -# Build (Debug) -cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -cmake --build build -j$(nproc) +ViewTouch released under GNU Public License (GPL v3) with code hosted on GitHub. Significant modernization and refinement by the open-source community: -# Run tests -cd build && ctest --output-on-failure -j$(nproc) +**Key Contributors:** +- **Jack Morrison** - Amazing debugging skills +- **NeroBurner (Reinhold Gschweicher)** - Major refactoring and standardization +- **NoOne558 (Ariel Brambila Pelayo)** - Upgraded to Xft scalable fonts, mobile integration, AI-empowered refactoring of the entire ViewTouch code base. +- **Gene and Barbara Mosher** - Lifetime support and funding +- **Ariel Brambila Pelayo** - awarded co-ownership status of ViewTouch code and documentation at GitHub -# Build (Release) -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -cmake --build build -j$(nproc) -``` +### Platform Evolution -### Contribute +| Year | Platform | Key Technology | +|------|----------|----------------| +| 1979 | Apple ][ | Initial POS code | +| 1986 | Atari ST | First GUI touchscreen POS | +| 1995 | AIX/PowerPC | UNIX + X Window System | +| 1997 | Linux/x86 | Intel architecture | +| 2000 | Linux/x86 | C++ transition | +| 2016+ | Raspberry Pi | Default platform (Pi 4/5) | -1. **Create a feature branch** from `dev` -2. **Make your changes** and commit with clear messages -3. **Test thoroughly** — build, run tests, smoke test the UI -4. **Submit a pull request** with detailed description -5. **Respond to feedback** and iterate +**Current Stack:** +- **OS:** Debian Linux with XFCE desktop +- **Display:** X Window System (network-transparent) +- **Default Hardware:** Raspberry Pi family +- **Auto-update:** Desktop icon compiles and installs latest code from GitHub -## Branch Strategy +Gene Mosher's passion and vision has overseen the development, management, and maintenance of ViewTouch code across six decades, spanning a wide array of computers and point of sale equipment. Gene owns the ViewTouch copyright and remains active in ViewTouch in 2025. A personal note to everyone from Gene: I am getting on in years and everyone has always wanted me to tell them what will happen to ViewTouch if/when something happens to me. In 2025 I can reassure that I will be participating in the development of ViewTouch until my last breath, which could easily be 2050 (I'll be 101 then), and with Ariel, who is about half a century younger than I am, being awarded co-ownership of the ViewTouch code and documentation at ViewTouch/GitHub, nothing bad can happen, is going to happen, to ViewTouch. I myself used to wonder about the future of ViewTouch, but I no longer do wonder about the future of ViewTouch. It's going to be alive, healthy, vibrant and dynamic for a long, long time. A new chapter has been opened for ViewTouch in 2025 and I could not be happier about it. Anyone can be a part of the future of ViewTouch - I welcome all who will join us. -- **`master`**: Official ViewTouch repository mirror (stable, upstream-aligned) -- **`dev`**: Development and testing branch (active work, may be unstable) +--- + +## Contact & Support + +### Commercial Support + +**ViewTouch Official** +- **Website:** [www.viewtouch.com](http://www.viewtouch.com) +- **Email:** gene@viewtouch.com +- **Phone:** 541-515-5913 + +### Community -## Resources +- **Discord:** [Join our server](https://discord.com/invite/ySmH2U2Mzb) +- **GitHub Issues:** Bug reports and feature requests +- **Gitter Chat:** [Join the conversation](https://gitter.im/ViewTouch/viewtouch) +- **Wiki:** Documentation and guides -- 📚 [Documentation](./docs/) -- 🐛 [Report Issues](../../issues) -- 💬 [Discussions](../../discussions) -- 📖 [Changelog](./docs/changelog.md) +The availability of ViewTouch source code and documentation at GitHub benefits clients, customers, and associates of Gene Mosher, facilitating the enhancement and extension of ViewTouch source code. --- -**Happy coding! Together, we're building the future of ViewTouch.** 🚀 +## License + +ViewTouch is released under the **GNU General Public License, version 3 (GPL v3)**. + +See [LICENSE](LICENSE) for full details. + +--- + +## Payment Processing + +ViewTouch does not manage electronic payment processing. Please make your own decisions with regard to Electronic Funds Transfer functionality. + +--- + +
+ +**ViewTouch** - *Six decades of innovation in restaurant technology* +## Be sure to reach out to our team for any questions, we are always happy to help.😊 + +Made with ❤️ by the ViewTouch community + +
\ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md index 823f485e..b267f186 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,43 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] ### Fixed +- **UI: Add Dollar Signs to Guest Check and Payment Summary Amounts (2026-01-15)** + - Fixed missing dollar signs ($) on amounts displayed in Payment Summary window and Guest Check Window menu items + - **Root Cause**: `Terminal::FormatPrice()` has a default parameter `sign = 0` which excludes the currency symbol, and many calls used this default instead of explicitly setting `sign = 1` + - **Solution**: Changed all `FormatPrice()` calls in check display functions to use `sign = 1` to include dollar signs on all amounts (individual items, modifiers, taxes, payments, and totals) + - **Files modified**: `main/business/check.cc` (MakeReport function and related price display calls) + - **Impact**: Guest Check Window and Payment Summary now consistently display all amounts with proper currency formatting including dollar signs + +- **Settlement Page: Highlight Current Guest Check with Status (2026-01-15)** + - Added highlighting and status display for current guest check when multiple checks exist on settlement page + - **Changes Made**: + - Changed subcheck display from "#1" to "Check #1 - Open/Closed/Voided" + - Added background highlighting for the currently selected subcheck + - Used blue text color for better visibility when highlighted + - **Files modified**: `zone/payment_zone.cc` (header rendering in Render function) + - **Impact**: Users can now clearly see which guest check is currently selected on the settlement page, with status information and visual highlighting + +- **Payment Zone: Hide Zero VAT Display (2026-01-15)** + - Fixed VAT .00 being displayed unnecessarily when VAT amount is zero + - **Root Cause**: VAT display only checked if VAT tax rate was configured (`settings->tax_VAT > 0`) but not if the calculated VAT amount was actually greater than zero + - **Solution**: Added condition to check both `settings->tax_VAT > 0` AND `subCheck->total_tax_VAT != 0` + - **Files modified**: `zone/payment_zone.cc` (VAT display logic in Render function) + - **Impact**: VAT is now only displayed when there is an actual VAT amount to show, reducing UI clutter + +- **Printer: Prevent USB Printer Hanging (2026-01-15)** + - Fixed application hanging when USB printer is unavailable + - **Root Cause**: `open()` system call for printer device files would block indefinitely when USB printer was disconnected or unavailable + - **Solution**: Added `O_NONBLOCK` flag to printer device open call to prevent blocking + - **Files modified**: `main/hardware/printer.cc` (ParallelPrint function) + - **Impact**: Application continues to function normally even when USB printers are unavailable, preventing system hangs + +- **Per-Terminal Button Image Settings: Preserve Individual Terminal Preferences (2026-01-15)** + - Fixed global "Show Button Images" setting incorrectly overriding per-terminal customizations + - **Root Cause**: The global setting was being applied universally, ignoring individual terminal configurations + - **Solution**: Added `show_button_images_custom` flag to Terminal class to track when users have customized per-terminal settings, preserving their preferences when global setting changes + - **Files modified**: `main/hardware/terminal.cc`, `main/hardware/terminal.hh` + - **Impact**: Terminals now maintain their individual button image display preferences even when global settings are modified + - **Button Highlighting Bug - Remove Broken Static Cache (2026-01-10)** - Fixed buttons incorrectly showing highlighted/yellow state - **Root Cause**: The static tile cache optimization in `Layer::Rectangle()` was fundamentally broken. Static variables persisted across all calls, causing stale cache values to be used when rendering buttons with different textures. @@ -20,6 +57,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - **Files modified**: `term/term_view.cc`, `term/term_view.hh` ### Added +- **Payment Processing: Complete Debit Card Fee Support (2026-01-15)** + - Added comprehensive debit card fee tender types with full tax handling support + - **New Tender Types Added**: + - DEBIT_FEE_PERCENT: Debit card fee as percentage of transaction + - DEBIT_FEE_DOLLAR: Debit card fee as fixed dollar amount + - DEBIT_FEE_TAXABLE_PERCENT: Debit card fee as percentage with tax calculation + - DEBIT_FEE_TAXABLE_DOLLAR: Debit card fee as fixed dollar amount with tax calculation + - **Implementation Details**: + - Added tender type definitions and fee calculation logic in Check class + - Updated payment zone processing to handle debit fee calculations + - Added proper localization support for debit fee display names + - **Files modified**: `main/business/check.cc`, `main/business/check.hh`, `zone/payment_zone.cc`, `main/data/settings.cc`, `main/ui/labels.cc`, `main/data/locale.cc` + - **Impact**: Full debit card fee processing capability with proper tax handling and UI display + - **Performance: Object Pool System for Memory Efficiency (2026-01-09)** - Created `src/core/object_pool.hh` with thread-safe object pooling templates - `ObjectPool`: Reusable object pool with configurable max size (default 64) @@ -33,6 +84,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - **Target**: Raspberry Pi CM5 with 2GB RAM optimization ### Improved +- **UI: Clean Credit Card Fee Display Labels (2026-01-15)** + - Removed redundant "(Percent)" and "(Dollar)" text from credit card fee display names for cleaner UI + - **Changes Made**: + - Simplified TenderName array entries to remove duplicate type indicators + - Updated TenderName method to return cleaner display strings + - Updated localization files to match simplified naming convention + - **Files modified**: `main/ui/labels.cc`, `main/data/settings.cc`, `main/data/locale.cc` + - **Impact**: Credit card fee options now display with cleaner, less cluttered text in the UI + - **UI: Modernized Quantity Entry Keypad (2026-01-14)** - Completely redesigned the numeric keypad for item quantity entry with a modern phone-style layout (1-2-3 on top row, 4-5-6 middle, etc.) - Removed the arbitrary 5-item limit; now allows unlimited increments up to 10,000 with a single button press diff --git a/main/business/check.cc b/main/business/check.cc index cb7fede5..5c0c2c2e 100644 --- a/main/business/check.cc +++ b/main/business/check.cc @@ -93,6 +93,8 @@ int tender_order[] = { TENDER_EXPENSE, TENDER_CREDIT_CARD_FEE_DOLLAR, TENDER_CREDIT_CARD_FEE_PERCENT, + TENDER_DEBIT_CARD_FEE_DOLLAR, + TENDER_DEBIT_CARD_FEE_PERCENT, -1 }; @@ -1781,7 +1783,7 @@ int Check::PrintDeliveryOrder(Report *report, int pwidth) report->TextL2Col(ordstr); if (order->cost > 0) { - PriceFormat(settings, order->cost, 0, 0, str1); + PriceFormat(settings, order->cost, 1, 0, str1); report->TextR2Col(str1); } report->NewLine(); @@ -1802,11 +1804,11 @@ int Check::PrintDeliveryOrder(Report *report, int pwidth) } report->Divider2Col(); report->TextL2Col(GlobalTranslate("SubTotal:")); - PriceFormat(settings, total_cost, 0, 0, str1); + PriceFormat(settings, total_cost, 1, 0, str1); report->TextR2Col(str1); report->NewLine(); report->TextL2Col(GlobalTranslate("Delivery:")); - PriceFormat(settings, delivery_cost, 0, 0, str1); + PriceFormat(settings, delivery_cost, 1, 0, str1); report->TextR2Col(str1); report->NewLine(); @@ -1814,7 +1816,7 @@ int Check::PrintDeliveryOrder(Report *report, int pwidth) total_cost += delivery_cost; report->Divider2Col('='); report->TextL2Col(GlobalTranslate("Total Including Taxes:")); - PriceFormat(settings, total_cost, 0, 0, str1); + PriceFormat(settings, total_cost, 1, 0, str1); report->TextR2Col(str1); report->NewLine(); @@ -2437,12 +2439,12 @@ int Check::MakeReport(Terminal *term, Report *report, int show_what, int video_t { if (order->cost != 0.0 || (order->status & ORDER_COMP)) { - report->TextR(term->FormatPrice(order->cost)); + report->TextR(term->FormatPrice(order->cost, 1)); if (order->status & ORDER_COMP) { report->NewLine(); report->TextPosR(-8, GlobalTranslate("COMP")); - report->TextR(term->FormatPrice(-order->cost), COLOR_RED); + report->TextR(term->FormatPrice(-order->cost, 1), COLOR_RED); } } } @@ -2505,7 +2507,7 @@ int Check::MakeReport(Terminal *term, Report *report, int show_what, int video_t if (mod->status & ORDER_COMP) report->TextR(GlobalTranslate("COMP")); else - report->TextR(term->FormatPrice(mod->cost)); + report->TextR(term->FormatPrice(mod->cost, 1)); } } first = 0; @@ -2525,12 +2527,12 @@ int Check::MakeReport(Terminal *term, Report *report, int show_what, int video_t if (tax) { report->TextPosR(-8, GlobalTranslate("Tax")); - report->TextR(term->FormatPrice(tax)); + report->TextR(term->FormatPrice(tax, 1)); report->NewLine(); if (sc->IsTaxExempt()) { report->TextPosR(-8, GlobalTranslate("Tax Exempt")); - report->TextR(term->FormatPrice(-tax)); + report->TextR(term->FormatPrice(-tax, 1)); report->NewLine(); vt_safe_string::safe_format(str, STRLONG, "%s: %s", GlobalTranslate("Tax ID"), sc->tax_exempt.Value()); report->Mode(PRINT_BOLD); @@ -2551,7 +2553,7 @@ int Check::MakeReport(Terminal *term, Report *report, int show_what, int video_t while (payptr) { report->TextL(payptr->Description(settings)); - report->TextR(term->FormatPrice(payptr->value)); + report->TextR(term->FormatPrice(payptr->value, 1)); report->NewLine(); payptr = payptr->next; } @@ -3819,7 +3821,8 @@ int SubCheck::FigureTotals(Settings *settings) { // Calculate percentage value based on raw sales // Note: raw_sales may be from previous calculation; will recalculate after orders are processed - if (payptr->tender_type == TENDER_CREDIT_CARD_FEE_PERCENT) + if (payptr->tender_type == TENDER_CREDIT_CARD_FEE_PERCENT || + payptr->tender_type == TENDER_DEBIT_CARD_FEE_PERCENT) { Flt f = PriceToFlt(raw_sales) * PercentToFlt(payptr->amount); payptr->value = FltToPrice(f); @@ -3908,6 +3911,8 @@ int SubCheck::FigureTotals(Settings *settings) case TENDER_CHARGED_TIP: case TENDER_CREDIT_CARD_FEE_DOLLAR: case TENDER_CREDIT_CARD_FEE_PERCENT: + case TENDER_DEBIT_CARD_FEE_DOLLAR: + case TENDER_DEBIT_CARD_FEE_PERCENT: balance += payptr->value; break; default: @@ -4165,15 +4170,17 @@ int SubCheck::FigureTotals(Settings *settings) payptr = payptr->next; } - // Calculate total credit card fees to include in taxable revenue - int credit_card_fee_total = 0; + // Calculate total credit/debit card fees to include in taxable revenue + int card_fee_total = 0; payptr = PaymentList(); while (payptr) { if (payptr->tender_type == TENDER_CREDIT_CARD_FEE_DOLLAR || - payptr->tender_type == TENDER_CREDIT_CARD_FEE_PERCENT) + payptr->tender_type == TENDER_CREDIT_CARD_FEE_PERCENT || + payptr->tender_type == TENDER_DEBIT_CARD_FEE_DOLLAR || + payptr->tender_type == TENDER_DEBIT_CARD_FEE_PERCENT) { - credit_card_fee_total += payptr->value; + card_fee_total += payptr->value; } payptr = payptr->next; } @@ -4226,15 +4233,15 @@ int SubCheck::FigureTotals(Settings *settings) int current_tax_revenue = food_tax_revenue + alcohol_tax_revenue + room_tax_revenue + merchandise_tax_revenue; - if (credit_card_fee_total > 0) + if (card_fee_total > 0) { if (current_tax_revenue > 0) { // Distribute fees proportionally across all revenue bases - int fee_to_food = static_cast(lround((Flt)credit_card_fee_total * (Flt)food_tax_revenue / (Flt)current_tax_revenue)); - int fee_to_alcohol = static_cast(lround((Flt)credit_card_fee_total * (Flt)alcohol_tax_revenue / (Flt)current_tax_revenue)); - int fee_to_room = static_cast(lround((Flt)credit_card_fee_total * (Flt)room_tax_revenue / (Flt)current_tax_revenue)); - int fee_to_merchandise = credit_card_fee_total - fee_to_food - fee_to_alcohol - fee_to_room; + int fee_to_food = static_cast(lround((Flt)card_fee_total * (Flt)food_tax_revenue / (Flt)current_tax_revenue)); + int fee_to_alcohol = static_cast(lround((Flt)card_fee_total * (Flt)alcohol_tax_revenue / (Flt)current_tax_revenue)); + int fee_to_room = static_cast(lround((Flt)card_fee_total * (Flt)room_tax_revenue / (Flt)current_tax_revenue)); + int fee_to_merchandise = card_fee_total - fee_to_food - fee_to_alcohol - fee_to_room; food_tax_revenue += fee_to_food; alcohol_tax_revenue += fee_to_alcohol; @@ -4246,8 +4253,8 @@ int SubCheck::FigureTotals(Settings *settings) // If no taxable revenue (e.g., all takeout with no other items), // distribute fees evenly to ensure they're taxed by at least some tax types // This ensures fees are always included in tax calculations - int fee_per_base = credit_card_fee_total / 4; - int fee_remainder = credit_card_fee_total % 4; + int fee_per_base = card_fee_total / 4; + int fee_remainder = card_fee_total % 4; food_tax_revenue += fee_per_base + (fee_remainder > 0 ? 1 : 0); alcohol_tax_revenue += fee_per_base + (fee_remainder > 1 ? 1 : 0); diff --git a/main/business/check.hh b/main/business/check.hh index 9f5b8150..9263374a 100644 --- a/main/business/check.hh +++ b/main/business/check.hh @@ -114,8 +114,10 @@ constexpr int CHECK_SELFTAKEOUT = static_cast(CheckType::SelfTakeOut); #define TENDER_CASH_AVAIL 24 // cash - expense, for balancing only #define TENDER_CREDIT_CARD_FEE_DOLLAR 25 // credit card processing fee (dollar amount) #define TENDER_CREDIT_CARD_FEE_PERCENT 26 // credit card processing fee (percentage) +#define TENDER_DEBIT_CARD_FEE_DOLLAR 27 // debit card processing fee (dollar amount) +#define TENDER_DEBIT_CARD_FEE_PERCENT 28 // debit card processing fee (percentage) -#define NUMBER_OF_TENDERS 27 // true number + 1 for no known reason +#define NUMBER_OF_TENDERS 29 // true number + 1 for no known reason extern int tender_order[]; // Order States diff --git a/main/data/locale.cc b/main/data/locale.cc index 3433126c..65a5fe78 100644 --- a/main/data/locale.cc +++ b/main/data/locale.cc @@ -2201,8 +2201,10 @@ static const TranslationEntry settings_config_translations[] = { {"Comp", "Compensación"}, {"Employee Meal", "Comida de Empleado"}, {"Tip", "Propina"}, - {"Credit Card Fee (Dollar)", "Tarifa de Tarjeta de Crédito (Dólar)"}, - {"Credit Card Fee (Percent)", "Tarifa de Tarjeta de Crédito (Porcentaje)"}, + {"Credit Card Fee", "Tarifa de Tarjeta de Crédito"}, + {"Credit Card Fee", "Tarifa de Tarjeta de Crédito"}, + {"Debit Card Fee", "Tarifa de Tarjeta de Débito"}, + {"Debit Card Fee", "Tarifa de Tarjeta de Débito"}, // Printer ID names {"Kitchen1", "Cocina1"}, @@ -2404,8 +2406,10 @@ static const TranslationEntry settings_config_translations[] = { {"Credit Card Tip", "Propina de Tarjeta de Crédito"}, {"Expenses", "Gastos"}, {"Cash", "Efectivo"}, - {"Credit Card Fee (Dollar)", "Tarifa de Tarjeta de Crédito (Dólar)"}, - {"Credit Card Fee (Percent)", "Tarifa de Tarjeta de Crédito (Porcentaje)"}, + {"Credit Card Fee", "Tarifa de Tarjeta de Crédito"}, + {"Credit Card Fee", "Tarifa de Tarjeta de Crédito"}, + {"Debit Card Fee", "Tarifa de Tarjeta de Débito"}, + {"Debit Card Fee", "Tarifa de Tarjeta de Débito"}, {"Room Charge", "Cargo de Habitación"}, {"Unknown Credit Card", "Tarjeta de Crédito Desconocida"}, {"Unknown Discount", "Descuento Desconocido"}, diff --git a/main/data/settings.cc b/main/data/settings.cc index be8bd485..1f42d592 100644 --- a/main/data/settings.cc +++ b/main/data/settings.cc @@ -3588,12 +3588,12 @@ char* Settings::TenderName(int tender_type, int tender_id, genericChar* str) static const genericChar* name[] = { "Cash Received", "Check", "Gift Certificate", "House Account", "Overage", "Change", "Tip", "Payout", "Money Lost", "Gratuity", "Tips Paid", - "ATM/Debit Card", "Credit Card Tip", "Expenses", "Cash", "Credit Card Fee (Dollar)", "Credit Card Fee (Percent)", nullptr}; + "ATM/Debit Card", "Credit Card Tip", "Expenses", "Cash", "Credit Card Fee", "Credit Card Fee", "Debit Card Fee", "Debit Card Fee", nullptr}; static int value[] = { TENDER_CASH, TENDER_CHECK, TENDER_GIFT, TENDER_ACCOUNT, TENDER_OVERAGE, TENDER_CHANGE, TENDER_CAPTURED_TIP, TENDER_PAYOUT, TENDER_MONEY_LOST, TENDER_GRATUITY, TENDER_PAID_TIP, TENDER_DEBIT_CARD, - TENDER_CHARGED_TIP, TENDER_EXPENSE, TENDER_CASH_AVAIL, TENDER_CREDIT_CARD_FEE_DOLLAR, TENDER_CREDIT_CARD_FEE_PERCENT, -1}; + TENDER_CHARGED_TIP, TENDER_EXPENSE, TENDER_CASH_AVAIL, TENDER_CREDIT_CARD_FEE_DOLLAR, TENDER_CREDIT_CARD_FEE_PERCENT, TENDER_DEBIT_CARD_FEE_DOLLAR, TENDER_DEBIT_CARD_FEE_PERCENT, -1}; const char* temp; static char buffer[STRLENGTH]; diff --git a/main/hardware/printer.cc b/main/hardware/printer.cc index d41139b5..d5bc1ff7 100644 --- a/main/hardware/printer.cc +++ b/main/hardware/printer.cc @@ -455,7 +455,7 @@ int Printer::ParallelPrint() if (lockfd > 0) { infd = open(temp_name.Value(), O_RDONLY); - outfd = open(target.Value(), O_WRONLY); + outfd = open(target.Value(), O_WRONLY | O_NONBLOCK); if (infd > 0 && outfd > 0) { timeout.tv_sec = 0; diff --git a/main/hardware/terminal.cc b/main/hardware/terminal.cc index c6828319..e886a25e 100644 --- a/main/hardware/terminal.cc +++ b/main/hardware/terminal.cc @@ -627,6 +627,7 @@ Terminal::Terminal() show_family = 1; expand_goodwill = 0; show_button_images = 1; // Default to showing images + show_button_images_custom = 0; // Not customized initially cc_credit_termid.Set(""); cc_debit_termid.Set(""); @@ -752,6 +753,7 @@ int Terminal::Initialize() SetShadowOffset(settings->shadow_offset_x, settings->shadow_offset_y); SetShadowBlur(settings->shadow_blur_radius); show_button_images = settings->show_button_images_default; + show_button_images_custom = 0; // Reset custom flag when initializing from global default return retval; } @@ -1623,6 +1625,7 @@ SignalResult Terminal::Signal(const genericChar* message, int group_id) { // Toggle button image display mode for this terminal only show_button_images = !show_button_images; + show_button_images_custom = 1; // Mark as customized // Force complete redraw of all zones if (page) @@ -2485,9 +2488,13 @@ int Terminal::Update(int update_message, const genericChar* value) int switch_type = atoi(value); if (switch_type == SWITCH_BUTTON_IMAGES) { - Settings *settings = GetSettings(); - if (settings != nullptr) - show_button_images = settings->show_button_images_default; + // Only update if not customized per-terminal + if (show_button_images_custom == 0) + { + Settings *settings = GetSettings(); + if (settings != nullptr) + show_button_images = settings->show_button_images_default; + } if (page != nullptr) { page->changed = 1; diff --git a/main/hardware/terminal.hh b/main/hardware/terminal.hh index 388214f2..24899ae7 100644 --- a/main/hardware/terminal.hh +++ b/main/hardware/terminal.hh @@ -440,6 +440,7 @@ public: int show_family; // boolean - show family grouping in reports? int expand_goodwill; // boolean - show expanded goodwill adjustments list? int show_button_images; // boolean - show images on buttons (per-terminal setting) + int show_button_images_custom; // boolean - has the button images setting been customized per-terminal? // Font/Graphics Info int size; // screen size diff --git a/main/ui/labels.cc b/main/ui/labels.cc index a5b37385..b0f7adae 100644 --- a/main/ui/labels.cc +++ b/main/ui/labels.cc @@ -495,11 +495,11 @@ int ReportPrintValue[] = { const genericChar* TenderName[] = { "Cash", "Check", "Gift Certificate", "House Account", "Charge Room", "Gratuity", "Credit Card", "Discount", - "Coupon", "Comp", "Employee Meal", "Tip", "Credit Card Fee (Dollar)", "Credit Card Fee (Percent)", nullptr}; + "Coupon", "Comp", "Employee Meal", "Tip", "Credit Card Fee", "Credit Card Fee", "Debit Card Fee", "Debit Card Fee", nullptr}; int TenderValue[] = { TENDER_CASH, TENDER_CHECK, TENDER_GIFT, TENDER_ACCOUNT, TENDER_CHARGE_ROOM, TENDER_GRATUITY, TENDER_CHARGE_CARD, TENDER_DISCOUNT, - TENDER_COUPON, TENDER_COMP, TENDER_EMPLOYEE_MEAL, TENDER_CAPTURED_TIP, TENDER_CREDIT_CARD_FEE_DOLLAR, TENDER_CREDIT_CARD_FEE_PERCENT, -1}; + TENDER_COUPON, TENDER_COMP, TENDER_EMPLOYEE_MEAL, TENDER_CAPTURED_TIP, TENDER_CREDIT_CARD_FEE_DOLLAR, TENDER_CREDIT_CARD_FEE_PERCENT, TENDER_DEBIT_CARD_FEE_DOLLAR, TENDER_DEBIT_CARD_FEE_PERCENT, -1}; const genericChar* PrinterIDName[] = { "Default", "Kitchen1", "Kitchen2", "Bar1", "Bar2", "Expediter", diff --git a/zone/payment_zone.cc b/zone/payment_zone.cc index e10bb735..44d5f0f1 100644 --- a/zone/payment_zone.cc +++ b/zone/payment_zone.cc @@ -132,8 +132,19 @@ RenderResult PaymentZone::Render(Terminal *term, int update_flag) TextL(term, line, str, text); if (currCheck->SubCount() > 1) { - vt_safe_string::safe_format(str, 256, "#%d", subCheck->number); - TextC(term, line, str, text); + const char* status_str = ""; + if (subCheck->status == CHECK_OPEN) + status_str = " - Open"; + else if (subCheck->status == CHECK_CLOSED) + status_str = " - Closed"; + else if (subCheck->status == CHECK_VOIDED) + status_str = " - Voided"; + + vt_safe_string::safe_format(str, 256, "Check #%d%s", subCheck->number, status_str); + + // Highlight the current subcheck + Background(term, line - ((spacing - 1)/2), 1.0, IMAGE_LIT_SAND); + TextC(term, line, str, COLOR_DK_BLUE); } int guests = currCheck->Guests(); if (guests > 0) @@ -225,7 +236,7 @@ RenderResult PaymentZone::Render(Terminal *term, int update_flag) line += min_spacing; } - if (settings->tax_VAT > 0) + if (settings->tax_VAT > 0 && subCheck->total_tax_VAT != 0) { TextPosR(term, mark, line, "VAT"); TextPosR(term, mark + 9, line, term->FormatPrice(subCheck->total_tax_VAT)); @@ -1929,9 +1940,10 @@ SignalResult TenderZone::Touch(Terminal *term, int tx, int ty) int flags = 0; if (tender_type == TENDER_GRATUITY) flags |= TF_IS_PERCENT; - else if (tender_type == TENDER_CREDIT_CARD_FEE_PERCENT) + else if (tender_type == TENDER_CREDIT_CARD_FEE_PERCENT || + tender_type == TENDER_DEBIT_CARD_FEE_PERCENT) { - // Credit Card Fee (Percentage) always uses percentage + // Credit/Debit Card Fee (Percentage) always uses percentage flags |= TF_IS_PERCENT; } // Credit Card Fee (Dollar) uses default flags = 0 (dollar amount)