Commit Graph
100 Commits
Author SHA1 Message Date
Darko Gjorgjijoski 20ace694fe Fix UpdateController auth: use Bouncer ability instead of company owner check
ensureOwner() checked isOwner() which only verifies company ownership,
not super admin status. Replace with authorize('manage update app')
which uses the proper Bouncer ability gate for platform administration.
2026-04-03 21:45:40 +02:00
Darko Gjorgjijoski 3f5accc0f0 Consolidate Admin/Update: 8 controllers into 1 UpdateController
Merge 7 single-action pipeline controllers (checkVersion, download,
unzip, copy, delete, migrate, finish) into UpdateController with named
methods. Remove dead UpdateController that duplicated the same logic
but wasn't referenced in routes. Extract shared owner check into
private ensureOwner() helper. Route URLs unchanged.
2026-04-03 21:42:45 +02:00
Darko Gjorgjijoski 7bb6d9bcc3 Consolidate Admin/Settings: merge GetSettingsController + UpdateSettingsController into SettingsController 2026-04-03 21:21:13 +02:00
Darko Gjorgjijoski 142899cfd7 Consolidate Admin/Backup: merge ApiController and DownloadBackupController into BackupsController
Inline the respondSuccess() helper, add download() method. Remove the
unnecessary ApiController base class and DownloadBackupController.
2026-04-03 21:18:45 +02:00
Darko Gjorgjijoski d505677a74 Consolidate Admin/Modules: 10 single-action controllers into 2
ModulesController: index, show, checkToken, enable, disable
ModuleInstallationController: download, upload, unzip, copy, complete
2026-04-03 21:16:18 +02:00
Darko Gjorgjijoski e9ee74cd01 Add return types and typed parameters to remaining 10 models
Complete the type modernization across all models. Adds Builder-typed
$query parameters and return types to all scope methods, typed parameters
on accessors, and PHPDoc on scopePaginateData/scopeApplyFilters.

Models updated: Address, EstimateItem, Expense, ExpenseCategory,
InvoiceItem, Item, Note, Tax, TaxType, Unit.

5 models needed no changes (Country, Currency, ImpersonationLog,
Module, UserSetting) as they had no untyped public methods.
2026-04-03 20:53:41 +02:00
Darko Gjorgjijoski 0fa1aac748 Add return types, typed parameters, and PHPDoc to all model methods
Modernize all 16 models with missing type declarations:
- Return types on ~87 methods (string, bool, void, array, mixed, etc.)
- Typed parameters where missing
- PHPDoc blocks on non-obvious methods explaining their purpose

Models updated: Invoice, Estimate, Payment, User, Company, Customer,
RecurringInvoice, Setting, CompanySetting, FileDisk, Transaction,
EmailLog, ExchangeRateLog, PaymentMethod, CustomField, CustomFieldValue.
2026-04-03 20:46:26 +02:00
Darko Gjorgjijoski c794f92932 Remove unused model constants
- Company: COMPANY_LEVEL, CUSTOMER_LEVEL (never referenced)
- Payment: all 5 PAYMENT_MODE_* constants (never referenced)
- Transaction: PENDING (never referenced)

RecurringInvoice constants (ACTIVE, ON_HOLD, NONE, COUNT, DATE) are kept
as they are used via hardcoded strings in services, factories, and migrations.
2026-04-03 20:39:21 +02:00
Darko Gjorgjijoski c90dd1f2ac Remove dead model methods now handled by services
Remove createItem/updateItem from Item, createTransaction/
completeTransaction/failedTransaction from Transaction,
createCustomField/updateCustomField from CustomField, all business
methods from ExchangeRateProvider (CRUD + API checks + URL helpers),
and validateCredentials/createDisk/updateDisk/updateDefaultDisks/
setAsDefaultDisk from FileDisk.

All logic now lives in their respective service classes.
2026-04-03 20:32:02 +02:00
Darko Gjorgjijoski 85b62dfdf8 Refactor exchange rate providers into driver-based architecture
Replace duplicated switch/case blocks across 4 methods with a clean
abstract driver pattern:

- ExchangeRateDriver (abstract): defines getExchangeRate(),
  getSupportedCurrencies(), validateConnection()
- CurrencyFreakDriver, CurrencyLayerDriver, OpenExchangeRateDriver,
  CurrencyConverterDriver: concrete implementations
- ExchangeRateDriverFactory: resolves driver name to class, with
  register() method for module extensibility

Delete ExchangeRateProvidersTrait — all logic now lives in driver
classes and ExchangeRateProviderService. Adding a new exchange rate
provider only requires implementing ExchangeRateDriver and calling
ExchangeRateDriverFactory::register() in a module service provider.
2026-04-03 20:24:03 +02:00
Darko Gjorgjijoski 8f29e8f5de Extract business logic from remaining models to services
New services:
- ExchangeRateProviderService: CRUD, API status checks, currency converter
  URL resolution (extracted 122 lines from ExchangeRateProvider model)
- FileDiskService: create, update, setAsDefault, validateCredentials
  (extracted 97 lines from FileDisk model)
- ItemService: create/update with tax handling (extracted from Item model)
- TransactionService: create/complete/fail (extracted from Transaction model)
- CustomFieldService: create/update with slug generation (extracted from
  CustomField model)

Controllers updated to use constructor-injected services:
ExchangeRateProviderController, DiskController, ItemsController,
CustomFieldsController.
2026-04-03 19:32:37 +02:00
Darko Gjorgjijoski ece6ce737b Rename Services/Installation to Services/Setup to match controllers 2026-04-03 19:23:32 +02:00
Darko Gjorgjijoski 00599b6943 Move Bouncer DefaultScope from app/Bouncer to app/Support/BouncerDefaultScope 2026-04-03 19:21:56 +02:00
Darko Gjorgjijoski 4f47db9258 Move Mobile/AuthController to Company/Auth and remove Mobile namespace
The Mobile namespace only contained an API auth controller (Sanctum token
login/logout/check) that is not mobile-specific. Relocated to
Company/Auth/AuthController alongside the other auth controllers.
2026-04-03 19:19:09 +02:00
Darko Gjorgjijoski 64c481e963 Rename controller namespaces: drop V1 prefix, clarify roles
V1/Admin     -> Company       (company-scoped controllers)
V1/SuperAdmin -> Admin        (platform-wide admin controllers)
V1/Customer  -> CustomerPortal (customer-facing portal)
V1/Installation -> Setup      (installation wizard)
V1/PDF       -> Pdf           (consistent casing)
V1/Modules   -> Modules       (drop V1 prefix)
V1/Webhook   -> Webhook       (drop V1 prefix)

The V1 prefix served no purpose - API versioning is in the route prefix
(/api/v1/), not the controller namespace. "Admin" was misleading for
company-scoped controllers. "SuperAdmin" is now simply "Admin" for
platform administration.
2026-04-03 19:15:20 +02:00
Darko Gjorgjijoski 0aaf0419c3 Reorganize Admin/General: 14 controllers down to 6
Move global reference data to SuperAdmin:
- CountriesController, CurrenciesController (not company-scoped)

Merge exchange rate operations into ExchangeRateProviderController:
- GetAllUsedCurrenciesController -> usedCurrenciesWithoutRate()
- BulkExchangeRateController -> bulkUpdate()

Consolidate single-action controllers:
- DateFormatsController + TimeFormatsController + TimezonesController -> FormatsController
- NextNumberController + NumberPlaceholdersController -> SerialNumberController
- SearchUsersController merged into SearchController::users()
2026-04-03 19:03:57 +02:00
Darko Gjorgjijoski c0454613a8 Move customer stats logic from CustomerStatsController to CustomerService 2026-04-03 18:10:59 +02:00
Darko Gjorgjijoski 92872e7e1c Merge ShowReceiptController and UploadReceiptController into ExpensesController 2026-04-03 18:07:07 +02:00
Darko Gjorgjijoski 2191417151 Consolidate ExchangeRate single-action controllers into ExchangeRateProviderController
Merge 4 invocable controllers (GetActiveProvider, GetExchangeRate,
GetSupportedCurrencies, GetUsedCurrencies) as methods on the existing
resource controller: activeProvider(), getRate(), supportedCurrencies(),
usedCurrencies().
2026-04-03 18:03:24 +02:00
Darko Gjorgjijoski 5f389ea3b0 Consolidate single-action controllers into resource controllers
Merge 11 single-action controllers into their parent resource controllers:
- Invoice: send, sendPreview, clone, changeStatus -> InvoicesController
- Estimate: send, sendPreview, clone, convertToInvoice, changeStatus -> EstimatesController
- Payment: send, sendPreview -> PaymentsController

Extract clone and convert business logic from controllers into services:
- InvoiceService: add clone(), changeStatus()
- EstimateService: add clone(), convertToInvoice(), changeStatus()

Previously this logic was inlined in controllers (~80-90 lines each).
2026-04-03 17:55:46 +02:00
Darko Gjorgjijoski f76f351244 Merge CompanyController into CompaniesController as show() method 2026-04-03 17:45:20 +02:00
Darko Gjorgjijoski 735eef6e9b Fix password update sending name and email to satisfy ProfileRequest validation 2026-04-03 17:42:14 +02:00
Darko Gjorgjijoski 4bfec37a53 Switch User Settings from horizontal tabs to sidebar layout
Match the Company Settings design pattern: sidebar navigation on desktop
with dropdown on mobile, child routes rendered via RouterView. Each tab
(General, Profile Photo, Security) is now a BaseSettingCard with its own
route under /admin/user-settings/{general,profile-photo,security}.
2026-04-03 17:41:18 +02:00
Darko Gjorgjijoski 1ca915a0a3 Split CompanyController and introduce standalone User Settings page
Backend:
- Extract user profile methods (show, update, uploadAvatar) from
  CompanyController into new UserProfileController
- CompanyController now only handles company concerns (updateCompany,
  uploadCompanyLogo)
- Remove Account Settings from setting_menu config

Frontend:
- New /admin/user-settings page with 3 tabs: General, Profile Photo,
  Security (password change)
- User dropdown now links to /admin/user-settings instead of
  /admin/settings/account-settings
- Settings sidebar defaults to Company Information as first item
- Remove old monolithic AccountSetting.vue
2026-04-03 17:35:41 +02:00
Darko Gjorgjijoski 6b5e4878fb Consolidate Admin Settings controllers: merge Get/Update pairs
Merge GetCompanySettingsController + UpdateCompanySettingsController into
CompanySettingsController with show() and update() methods.

Merge GetUserSettingsController + UpdateUserSettingsController into
UserSettingsController with show() and update() methods.

Absorb GetCompanyMailConfigurationController into
CompanyMailConfigurationController as getDefaultConfig() method.

Removes 5 single-action controllers, down to 4 Settings controllers.
2026-04-03 17:18:48 +02:00
Darko Gjorgjijoski bbf46577dc Move global admin controllers from Admin to SuperAdmin namespace
Backup, Update, Modules, and global Settings controllers (mail config,
PDF config, disk management, global settings) are application-wide features
not scoped to a company. Move them from Admin/ to SuperAdmin/ to match the
v3.0 UI structure where these live under Administration.

Company-scoped settings controllers remain in Admin/Settings/.
2026-04-03 16:52:18 +02:00
Darko Gjorgjijoski de06c335ac Remove dead code from app/Http: unused middleware, requests, and resources
Delete 23 unused files:
- AdminMiddleware (never registered, SuperAdminMiddleware used instead)
- 4 form requests with no controller references
- AbilityResource/Collection and ExchangeRateLogResource/Collection (zero usage)
- Customer/RecurringInvoiceResource and Collection (no controller or nested reference)
- 10 Customer Collection classes whose Resources are only used via new, never ::collection()
2026-04-03 16:41:33 +02:00
Darko Gjorgjijoski 62f31960ab Move CustomPathGenerator from app/Generators to app/Support 2026-04-03 16:21:36 +02:00
Darko Gjorgjijoski 129028518d Consolidate PDF classes under app/Services/Pdf with consistent naming
Split PDFService.php (3 classes + 2 interfaces in one file) into separate
files. Move GotenbergPDFDriver from app/Services/PDFDrivers/ into
app/Services/Pdf/. Normalize casing from ALL-CAPS PDF to Pdf throughout:
facade, provider, service, driver factory, and Gotenberg driver.

Fix PaymentService using Barryvdh DomPDF facade directly instead of the
app's PDF facade (bypassed the driver factory). Report controllers also
updated to use the app facade.
2026-04-03 16:18:25 +02:00
Darko Gjorgjijoski e0b8b86e06 Rename SerialNumberFormatter to SerialNumberService for consistency 2026-04-03 16:09:22 +02:00
Darko Gjorgjijoski e208e3ba56 Move Hashids classes from app/Hashids to app/Services/Hashids 2026-04-03 15:41:05 +02:00
Darko Gjorgjijoski 0ce88ab817 Remove app/Space folder and extract model business logic into services
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.
2026-04-03 15:37:22 +02:00
Darko Gjorgjijoski 23ff69026e Merge branch 'master' into v3.0 2026-04-03 14:36:24 +02:00
Darko Gjorgjijoski 55416bc633 Improve copyright handling 2026-04-03 13:34:33 +02:00
Darko Gjorgjijoski c469f64c79 Remove unused CompanySetting defaults from company setup
Remove invoice_auto_generate, payment_auto_generate, estimate_auto_generate
(defined but never read anywhere in the codebase) and duplicate save_pdf_to_disk
entries (now a global Setting, not per-company).
2026-04-03 10:36:48 +02:00
Darko Gjorgjijoski 9432da467e Add super-admin Administration section and restructure global vs company settings
- Add Administration sidebar section (super-admin only) with Companies, Users, and Global Settings pages
- Add super-admin middleware, controllers, and API routes under /api/v1/super-admin/
- Allow super-admins to manage all companies and users across tenants
- Add user impersonation with short-lived tokens, audit logging, and UI banner
- Move system-level settings (Mail, PDF, Backup, Update, File Disk) from per-company to Administration > Global Settings
- Convert save_pdf_to_disk from CompanySetting to global Setting
- Add per-company mail configuration overrides (optional, falls back to global)
- Add CompanyMailConfigService to apply company mail config before sending emails
2026-04-03 10:35:40 +02:00
Darko Gjorgjijoski 25986b7bd5 Update IDE helpers, Tailwind skill to v4, and refresh dependencies 2026-04-02 21:03:55 +02:00
Darko Gjorgjijoski 414531524c Remove unused cross-env dependency 2026-04-02 16:39:10 +02:00
Darko Gjorgjijoski 63d3a7fc8e Skip PHP CI jobs when only non-PHP files change
Replace workflow-level paths-ignore with per-job filtering using
dorny/paths-filter. PHP lint and test jobs now only run when PHP-related
files (app/, config/, database/, routes/, tests/, composer.*, phpunit.xml)
are modified.
2026-04-02 16:35:07 +02:00
Darko Gjorgjijoski 0be747a483 Pin axios to 1.14.0
Avoid possible supply chain attacks in future caused by compromised
author account or even rogue author.
2026-04-02 16:14:47 +02:00
Darko Gjorgjijoski a30b2e751b Pin PHP version to 8.4 in development Dockerfile 2026-02-06 00:57:13 +01:00
Darko 935fe06f9e Bump version 2025-09-19 15:50:54 +02:00
Darko Gjorgjijoski 05ab78942c Update JS dependencies 2025-09-01 20:58:43 +02:00
Darko Gjorgjijoski 233d3cb989 Update readme.md 2025-09-01 12:07:15 +02:00
Darko Gjorgjijoski 3d327a1735 Add SQLite command line utility to docker images 2025-08-31 21:35:15 +02:00
Darko Gjorgjijoski a6ce294497 Update sqlite path 2025-08-31 20:57:45 +02:00
Darko Gjorgjijoski 1998d15b25 Fix repository name 2025-08-31 16:18:29 +02:00
Darko Gjorgjijoski 3ed91545d1 Bump version 2025-08-31 03:27:33 +02:00
Darko Gjorgjijoski d1f45a790b Bump version 2025-02-01 10:41:19 +01:00
Darko Gjorgjijoski bec0c058a8 Bump version 2025-01-13 02:14:23 +01:00
Darko Gjorgjijoski e9e52c60a7 Reformat with pint 2025-01-12 18:37:08 +01:00
Darko Gjorgjijoski 34b9f52af7 Upgrade Laravel and other third-party packages 2025-01-12 18:22:51 +01:00
Darko Gjorgjijoski fcf64c0b26 Upgrade Vite, Vue and other thrid-party packages 2025-01-12 17:38:54 +01:00
Darko Gjorgjijoski 7e2d257f7d Update caniuse-lite package 2025-01-12 17:11:50 +01:00
Darko Gjorgjijoski 5ece0f43c0 Bump version 2024-09-24 19:05:06 +02:00
Darko Gjorgjijoski 91962f43b2 Add additional language and bump sqlite version 2024-08-04 21:40:15 +02:00
Darko Gjorgjijoski 50613fcff0 Remove unecessary debug calls 2024-08-04 19:50:14 +02:00
Darko Gjorgjijoski 468aec6bc1 Fix partially paid status appearing after invoice update 2024-08-04 19:45:08 +02:00
Darko Gjorgjijoski c799149d2d Improved logo display in Invoice/Estimate PDFs 2024-08-04 16:08:22 +02:00
Darko Gjorgjijoski c9e85f18da Merge branch 'develop' into pdf-templates-logo 2024-08-04 15:17:09 +02:00
Darko Gjorgjijoski 9a46f892ab Add support for release channels (insider release channel) in Updater 2024-08-04 03:04:10 +02:00
Darko Gjorgjijoski bcb89bc9ae Ignore .dev/docker-compose.yml to allow devs to customize one of those 2024-08-04 02:39:20 +02:00
Darko Gjorgjijoski fbac9abbc5 Expose port 5173 for the Dev environment 2024-08-04 02:38:02 +02:00
Darko Gjorgjijoski f16b4df44a Remove extensions from composer 2024-08-01 20:48:12 +02:00
Darko Gjorgjijoski f82937e85e Set app version on install and updates 2024-08-01 19:39:47 +02:00
Darko Gjorgjijoski a64701bda5 Set SESSION_DRIVER to file by default 2024-07-29 14:24:48 +02:00
Darko Gjorgjijoski da600d0144 Add database overwrite checkbox on Install wizard
Allows overwriting the existing database when installing InvoiceShelf
2024-07-29 14:21:34 +02:00
Darko Gjorgjijoski 56a555bc4a Fix installer wizard step highlighting 2024-07-29 14:06:21 +02:00
Darko Gjorgjijoski 6422da193b Improve .dev/php/entrypoint permissions setting 2024-07-29 13:01:43 +02:00
Darko Gjorgjijoski cc39f37b12 Update axios and vite 2024-07-29 13:00:54 +02:00
Darko Gjorgjijoski f95d03f281 Fix "declarations that appear after nested rules" deprecation warning 2024-07-29 12:55:29 +02:00
Darko Gjorgjijoski 4b9052079f Update docker context for the php image 2024-07-28 17:45:06 -07:00
Darko Gjorgjijoski bf5f95d29d Update file line ending format 2024-07-28 17:44:22 -07:00
Darko Gjorgjijoski 53343c64eb Update migrations formatting & namespace 2024-07-28 23:14:34 +02:00
Darko Gjorgjijoski dfc4b1982e Update namespace on 1.x migration 2024-07-28 23:13:53 +02:00
Darko Gjorgjijoski 8dd9d0c414 Consolidate migrations v2.0 should go after v1.x 2024-07-28 22:46:45 +02:00
Darko Gjorgjijoski 84a6181240 Merge master 2024-07-28 22:43:02 +02:00
Darko Gjorgjijoski 25fb260cd7 Update local links 2024-07-28 21:07:48 +02:00
Darko Gjorgjijoski 17082ea8c8 Improvements to SQLite dev setup 2024-07-28 21:02:49 +02:00
Darko Gjorgjijoski c4ade42a8f Update dev readme 2024-07-28 21:02:00 +02:00
Darko Gjorgjijoski 314abe4cc6 Add node and exif & update entrypoint 2024-07-28 19:54:07 +02:00
Darko Gjorgjijoski 45ff9c89a8 Add development environment 2024-07-28 17:25:32 +02:00
Darko Gjorgjijoski 9df5b306a2 Make artisan file executable 2024-07-28 17:24:57 +02:00
Darko Gjorgjijoski 310d05eab1 Set backup to point to the default database connection 2024-07-28 17:24:44 +02:00
Darko Gjorgjijoski f986454084 Set backup to point to the default database connection 2024-07-28 17:22:40 +02:00
Darko Gjorgjijoski 19bf467068 Add "none" as choice for MAIL_ENCRYPTION settings/install that translates to =NULL 2024-07-21 10:42:00 +02:00
Darko Gjorgjijoski 532a044bb9 Add APP_NAME in .env.example 2024-07-18 09:00:00 +02:00
Darko Gjorgjijoski a866187f71 Add default cache and queue configs 2024-07-17 11:32:42 +02:00
Darko Gjorgjijoski e212714c63 Pint 2024-07-13 15:19:00 +02:00
Darko Gjorgjijoski 429a8ae826 Add sqlite3 into the php requirements 2024-07-13 15:18:30 +02:00
Darko Gjorgjijoski 94cfe55555 Add sqlite3 validation 2024-07-13 15:18:10 +02:00
Darko Gjorgjijoski ad9d08c43c Create empty SQLite database if it doesn't exist 2024-07-13 15:12:54 +02:00
Darko Gjorgjijoski 27a511bc09 Update version
[ci-skip]
2024-07-13 03:11:14 +02:00
Darko Gjorgjijoski ba85f407d6 Revert "Add version.md file"
This reverts commit 75b0c264dc.
2024-07-13 02:49:02 +02:00
Darko Gjorgjijoski b37019f845 Set the default database to SQLite 2024-07-13 02:29:20 +02:00
Darko Gjorgjijoski 75b0c264dc Add version.md file 2024-07-13 02:14:41 +02:00
Darko Gjorgjijoski 98852686c7 Add doctrine/dbal and run pint 2024-07-13 02:03:22 +02:00
Darko Gjorgjijoski a907f8c932 Set the default database to be SQLite 2024-07-12 17:13:54 +02:00
Darko Gjorgjijoski 53866f721c Require dbal as dependency for migrations that changing columns 2024-07-12 12:37:04 +02:00
Darko Gjorgjijoski 9c0d79bf59 Add app version 2024-07-12 03:08:07 +02:00