- Combine RUN commands to reduce layers
- Add --no-install-recommends and clean apt cache
- Use COPY --chown to set ownership during copy
- Update .dockerignore to exclude dev files and build configs
Saves ~260MB (21%) in image size
The build-database task previously concatenated tables.sql and constraints.sql
into database.sql. Since we now use initial_schema.sql directly in migrations,
this task is no longer needed.
- Remove gulp task 'build-database'
- Keep all other build tasks intact
These files have been replaced by initial_schema.sql which is now the
authoritative source for the database schema. The initial migration
loads this schema on fresh installs.
- Remove app/Database/tables.sql
- Remove app/Database/constraints.sql
- Schema is frozen in app/Database/Migrations/sqlscripts/initial_schema.sql
- Convert Travis CI configuration to GitHub Actions workflows
- Add multi-arch Docker builds (amd64/arm64)
- Implement initial schema migration for fresh database installs
- Add multi-attribute search with AND logic and sort by attribute columns
- Address various PR review feedback and formatting fixes
- Use 'Bénéfice' in French Reports.php for consistency with 'profit' key
- Fix Italian grammar: 'Il numero di telefono è richiesto'
- Use 'Responsabile' for 'manager' in Italian Common.php
- Add 'sale_not_found' translation key to missing languages (km, ml, ta, ur)
- Tamil (ta) gets proper translation, others get English fallback
- Add Calendar.php translation file for es-ES, nl-NL, de-DE
- Fill empty string translations in Common.php for de-DE, nl-NL, fr, it, pt-BR
- Translate UBL invoice strings (ubl_invoice, download_ubl, ubl_generation_failed) in Sales.php
- Add toggle_cost_and_profit in Reports.php for all languages
- Translate error_deleting_admin and error_updating_admin in Employees.php
- Translate csv_import_invalid_location error message in Items.php
- Update various missing translations for administrator, clerk, manager, dashboard, etc.
Languages updated: Spanish (es-ES), Dutch (nl-NL), German (de-DE), French (fr), Italian (it), Portuguese (pt-BR)
The clear_all() calls in postComplete() were placed after return
statements, making them unreachable dead code. This caused the
completed sale to remain in the session and appear in the Register
when navigating back.
The fix moves clear_all() and clear_mode() calls before the return
statements so they are actually executed, properly clearing the sale
cart, customer, and payments from the session after sale completion.
This fixes the regression reported by @odiea where users had to
manually cancel sales after each transaction.
Users without the 'employees' permission can no longer impersonate other
employees when creating or editing expenses and receivings. The employee
field is now restricted to the current user for new records and shows the
stored employee for existing records.
Changes:
- Expenses controller: Add permission check in getView() and postSave()
- Receivings controller: Add permission check in getEdit() and postSave()
- Form views: Conditionally display dropdown or read-only field
Fixes#3616
- Add setUp() to seed test data: items, sales, sales_items, sales_items_taxes
- Add tearDown() to clean up seeded data after tests
- Remove skip conditions since we now have guaranteed test data
- Add testTaxDataIsGroupedByTaxNameAndPercent to verify grouping
- Use narrow date range to isolate seeded data
Tests now:
- Use DatabaseTestTrait for real database integration
- Actually call getData() and getSummaryData() methods
- Verify row totals (subtotal + tax = total) from real queries
- Verify summary data matches sum of rows
- Test getDataColumns() returns expected structure
- Use assertEqualsWithDelta for float comparisons with tolerance
These tests exercise the actual SQL queries and verify the
mathematical consistency of the calculations returned.
- Ensure total = subtotal + tax by deriving total from rounded components
- Use assertEqualsWithDelta for float comparisons in tests
- Add defensive null coalescing in calculateSummary helper
- Add missing 'count' key to test data rows
- Add testRoundingAtBoundary test case
The report had calculation inconsistencies where:
1. Per-line totals (subtotal + tax) didn't equal the total column
2. Column totals didn't match the sum of individual rows
Root cause: subtotal, tax, and total were calculated independently
using different formulas and rounding at different stages, leading to
cumulative rounding errors.
Fix:
- Use item_tax_amount from database as the source of truth for tax
- Derive subtotal from sale_amount (handling both tax_included and
tax_not_included modes correctly)
- Calculate total = subtotal + tax consistently for each line
- Override getSummaryData() to sum values from getData() rows,
ensuring summary totals match the sum of displayed rows
Fixes#4112
Add 'only_debit' filter to Daily Sales and Takings dropdown. Reuses
existing 'Sales.debit' language string for the filter label. Includes
filter default initialization in getSearch() to prevent PHP warnings.
Fixes#4439
- Remove incorrect %C mapping (was mapping century to full year)
- Add special handling for %C (century), %c (datetime), %n (newline), %t (tab), %x (date)
- Add %h mapping (same as %b for abbreviated month)
- Tighten edge-case test assertions to use assertSame/assertMatchesRegularExpression
- Add tests for new directives: %C, %c, %n, %t, %x, %h
- Fixed bug where render() was not passing caller-supplied to
generate(), causing ad-hoc tokens to be ignored
- Added %F (yyyy-MM-dd) and %D (MM/dd/yy) composite date formats to
the IntlDateFormatter pattern map
- Added test coverage for composite date format directives (%F, %D, %T, %R)
- Replaced deprecated strftime() with IntlDateFormatter
- Added proper handling for edge cases:
- Strings with '%' not in date format (e.g., 'Discount: 50%')
- Invalid date formats (e.g., '%-%-%', '%Y-%q-%bad')
- Very long strings
- Added comprehensive unit tests for Token_lib
- All date format specifiers now mapped to IntlDateFormatter patterns