Ports the net behaviour from three master commits into v3.0 as a single change, because v3.0 has already diverged structurally (controller moved from V1/Admin/Report to Company/Report, blade has its own CSS rework using the bundled fonts partial, and v3.0's App\Facades\Pdf replaces Barryvdh\DomPDF\Facade\Pdf). The three source commits are: 834b53ea (grouped itemized expenses), e22050bc (DomPDF facade + Pint — adapted to v3.0's App\Facades\Pdf), 0e9f18d4 (expenses.uncategorized + pdf_expense_group_total_label i18n keys + View|Response return type).
Controller: replaces the expenseCategories aggregate fetch with an itemized Expense query ordered by date, groups by category name with expenses.uncategorized fallback, and shares an expenseGroups collection of {name, expenses, total} plus the overall totalExpense. Adds expense_category_id to applyFilters. Updates the docblock return type from JsonResponse to View|Response. Keeps v3.0's App\Facades\Pdf.
Blade: replaces the single expenseCategories aggregate table with a per-group itemized table (date / note / amount columns + per-group total line using the new pdf_expense_group_total_label i18n key). Adds the item-table-* CSS classes and removes the old expense-total-table bottom block.
lang/en.json: adds expenses.uncategorized = "Uncategorized" and pdf_expense_group_total_label = "Group total:".
Closes the audit gaps from the original font system commit. The bundled NotoSans only covered Latin/Greek/Cyrillic but the descriptions claimed Arabic, Thai and Hindi too — that was false. DejaVu Sans, the prior dompdf default, did cover Hebrew, Arabic, Armenian and Georgian, so swapping it for NotoSans had silently regressed those scripts. The Thai conditional include was also dropped from every PDF template in that commit, leaving th locales rendering boxes despite THSarabunNew still sitting in resources/static/fonts/.
Adds four on-demand Font Packages — Noto Sans Hebrew, Noto Naskh Arabic (covering Arabic, Persian, Urdu, Sorani Kurdish), Noto Sans Devanagari (Hindi, Marathi, Sanskrit, Nepali) and Sarabun (Thai) — sourced from openmaptiles/fonts and google/fonts as static TTF. Static is mandatory because dompdf's PHP-Font-Lib does not parse variable fonts. Sarabun replaces THSarabunNew as the Thai face: same designer, OFL-licensed, maintained on a stable upstream URL, and surfaces through the same install flow as every other non-Latin script. The bundled THSarabunNew TTF files and the dead app/pdf/locale/th.blade.php legacy partial are removed as part of the migration.
Unifies the bundled Noto Sans into FONT_PACKAGES as a noto-sans entry with bundled => true and files served from resources/static/fonts/ instead of storage/fonts/. FontService::isInstalled, downloadPackage, getInstalledFontFaces and getPackageStatuses honor the flag through a new packageDir() helper. The hardcoded @font-face block in the PDF partial is gone — fonts.blade.php collapses to a single getInstalledFontFaces() call so the package array is the only source of truth for every face, bundled or on-demand. Admin → Font Packages now lists Noto Sans at the top with a primary-colored Bundled pill (new settings.fonts.bundled string) alongside the existing Installed badge / Install button states.
Also fixes the misleading settings.fonts.description and settings.fonts.bundled_info copy to actually describe what ships out of the box vs. what's optional, and rebuilds the en locale chunk.
Bundle Noto Sans (Regular/Bold/Italic/BoldItalic) under resources/static/fonts/ as the default PDF face — it covers Latin, Cyrillic, Greek, Arabic, Thai and Hindi out of the box, replacing the limited DejaVu Sans fallback. Move all @font-face declarations into app.pdf.partials.fonts and include it from every invoice/estimate/payment/report template, dropping per-template font-family hardcodes and the conditional Thai locale include.
Introduce FontService + FontController to download static Noto Sans CJK packages (zh, zh_CN, ja, ko) from life888888/cjk-fonts-ttf on demand. GeneratesPdfTrait::ensureFontsForLocale primes the family before rendering and the partial emits @font-face rules for installed packages so dompdf resolves them through standard CSS — no separate registerFont() instance required. Static TTFs are mandatory because dompdf's PHP-Font-Lib does not parse variable fonts (fvar/gvar tables), which is why Google Fonts' NotoSansTC[wght].ttf rendered empty boxes.
Expose status/install via /api/v1/fonts/status and /api/v1/fonts/{package}/install with matching FONTS_STATUS / FONTS_INSTALL constants in scripts-v2/api/endpoints.ts. Flip DOMPDF_ENABLE_REMOTE default to true for remote asset loading.
The @font-face URLs in resources/views/app/pdf/locale/th.blade.php pointed to resource_path('static/static/fonts/THSarabunNew*.ttf'), which does not exist on disk, so dompdf fell back to a default face when rendering Thai PDFs. Drop the duplicated segment so the bundled THSarabunNew TTFs resolve correctly.
Relocate all 14 files from the catch-all app/Space namespace into proper
locations: data providers to Support/Formatters, installation utilities to
Services/Installation, PDF utils to Services/Pdf, module/update classes to
Services/Module and Services/Update, SiteApi trait to Traits, and helpers
to Support.
Extract ~1,400 lines of business logic from 8 fat models (Invoice, Payment,
Estimate, RecurringInvoice, Company, Customer, Expense, User) into 9 new
service classes with constructor injection. Controllers now depend on
services instead of calling static model methods. Shared item/tax creation
logic consolidated into DocumentItemService.
* feat: Tax included
* Added a toggle switch in tax settings to enable the feature.
* Database migration adding tax_included field into estimates, invoices
and recurring invoices table.
* Toggle switch to enable and store the tax_included by estimates,
invoices and recurring invoices.
* In case of tax included enabled, total taxes will be recalculated and
the invoices, estimates and recurring invoices total won't be sum with
taxes.
* Apply tax included when discount_per_item/tax_per_item item is enabled.
* Custom component to show the net total when tax included is enabled.
* Update invoice and estimates pdfs with net total.
* chore: Tax included by default
A switch button inside the tax settings to enable the tax included by
default in invoices, estimates and recurring invoices.
* Possibility to set a fixed amount on tax types settings
* Pint and manage flat taxes on items
* Fix display errors and handle global taxes
* Tests
* Pint with PHP 8.2 cause with PHP 8.3 version it cause workflow error
* Merging percent and fixed amount into one column
* Now display the currency on SelectTaxPopup on fixed taxes
* add thai language config
* update thai translation
* update thai translation
* add THSarabunNew fonts to using in pdf
* update: pdf file to support thai language by checking isLocale('th') and include thai font-family
* update: thai translation
* remove the index.php file (not used)
* move THSarabunNew fonts to resoureces/static/fonts
* Add .gitkeep to storage/fonts to pre-build the fonts directory
Co-authored-by: Ritthikrai (Champ) Wiengchai <ritthikrai.w@aware.co.th>