Sfoglia il codice sorgente

add pint and refactor

3.x
wallo 2 anni fa
parent
commit
8fd4f2778e
100 ha cambiato i file con 1147 aggiunte e 1404 eliminazioni
  1. 6
    8
      app/Actions/FilamentCompanies/AddCompanyEmployee.php
  2. 2
    4
      app/Actions/FilamentCompanies/CreateCompany.php
  3. 1
    2
      app/Actions/FilamentCompanies/CreateConnectedAccount.php
  4. 3
    6
      app/Actions/FilamentCompanies/CreateNewUser.php
  5. 4
    7
      app/Actions/FilamentCompanies/CreateUserFromProvider.php
  6. 2
    4
      app/Actions/FilamentCompanies/DeleteUser.php
  7. 1
    1
      app/Actions/FilamentCompanies/HandleInvalidState.php
  8. 3
    6
      app/Actions/FilamentCompanies/InviteCompanyEmployee.php
  9. 1
    2
      app/Actions/FilamentCompanies/RemoveCompanyEmployee.php
  10. 1
    1
      app/Actions/FilamentCompanies/ResolveSocialiteUser.php
  11. 1
    2
      app/Actions/FilamentCompanies/SetUserPassword.php
  12. 2
    4
      app/Actions/FilamentCompanies/UpdateCompanyName.php
  13. 1
    2
      app/Actions/FilamentCompanies/UpdateUserPassword.php
  14. 1
    1
      app/Actions/OptionAction/CreateCurrency.php
  15. 1
    1
      app/Casts/MoneyCast.php
  16. 36
    0
      app/Console/Commands/CacheData.php
  17. 35
    0
      app/Console/Commands/ClearLog.php
  18. 71
    0
      app/Console/Commands/ConvertTimezones.php
  19. 71
    0
      app/Console/Commands/SortCsv.php
  20. 1
    1
      app/Console/Kernel.php
  21. 3
    5
      app/Enums/ContactType.php
  22. 3
    5
      app/Enums/DiscountType.php
  23. 2
    3
      app/Enums/DocumentType.php
  24. 0
    1
      app/Enums/EntityType.php
  25. 1
    1
      app/Enums/PrimaryColor.php
  26. 5
    1
      app/Enums/RecordsPerPage.php
  27. 4
    6
      app/Enums/TaxType.php
  28. 3
    1
      app/Events/CompanyDefaultEvent.php
  29. 4
    5
      app/Events/CompanyDefaultUpdated.php
  30. 5
    3
      app/Events/CompanyGenerated.php
  31. 0
    1
      app/Events/UpdateCompanyDefault.php
  32. 25
    0
      app/Faker/PhoneNumber.php
  33. 16
    0
      app/Faker/State.php
  34. 4
    6
      app/Filament/Company/Pages/CreateCompany.php
  35. 17
    23
      app/Filament/Company/Pages/Setting/Appearance.php
  36. 3
    5
      app/Filament/Company/Pages/Setting/CompanyDefault.php
  37. 18
    18
      app/Filament/Company/Pages/Setting/CompanyProfile.php
  38. 10
    22
      app/Filament/Company/Pages/Setting/Invoice.php
  39. 5
    9
      app/Filament/Company/Resources/Banking/AccountResource.php
  40. 2
    3
      app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php
  41. 3
    3
      app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php
  42. 2
    3
      app/Filament/Company/Resources/Core/DepartmentResource.php
  43. 8
    8
      app/Filament/Company/Resources/Setting/CategoryResource.php
  44. 2
    2
      app/Filament/Company/Resources/Setting/CategoryResource/Pages/CreateCategory.php
  45. 2
    2
      app/Filament/Company/Resources/Setting/CategoryResource/Pages/EditCategory.php
  46. 63
    60
      app/Filament/Company/Resources/Setting/CurrencyResource.php
  47. 2
    3
      app/Filament/Company/Resources/Setting/CurrencyResource/Pages/CreateCurrency.php
  48. 2
    2
      app/Filament/Company/Resources/Setting/CurrencyResource/Pages/EditCurrency.php
  49. 11
    18
      app/Filament/Company/Resources/Setting/DiscountResource.php
  50. 2
    3
      app/Filament/Company/Resources/Setting/DiscountResource/Pages/CreateDiscount.php
  51. 2
    2
      app/Filament/Company/Resources/Setting/DiscountResource/Pages/EditDiscount.php
  52. 9
    15
      app/Filament/Company/Resources/Setting/TaxResource.php
  53. 2
    3
      app/Filament/Company/Resources/Setting/TaxResource/Pages/CreateTax.php
  54. 2
    2
      app/Filament/Company/Resources/Setting/TaxResource/Pages/EditTax.php
  55. 0
    119
      app/Helpers/City.php
  56. 0
    294
      app/Helpers/Country.php
  57. 0
    123
      app/Helpers/LocationDataLoader.php
  58. 0
    131
      app/Helpers/State.php
  59. 0
    46
      app/Helpers/helpers.php
  60. 2
    1
      app/Http/Controllers/Controller.php
  61. 1
    1
      app/Http/Kernel.php
  62. 1
    1
      app/Http/Middleware/ApplyCurrentCompanyScope.php
  63. 1
    1
      app/Interfaces/Utility/DocumentNumber.php
  64. 2
    7
      app/Listeners/ConfigureCompanyDefault.php
  65. 2
    4
      app/Listeners/CreateCompanyDefaults.php
  66. 0
    2
      app/Listeners/SyncAssociatedModels.php
  67. 3
    6
      app/Listeners/SyncWithCompanyDefaults.php
  68. 6
    5
      app/Models/Banking/Account.php
  69. 7
    9
      app/Models/Common/Contact.php
  70. 8
    18
      app/Models/Company.php
  71. 1
    3
      app/Models/ConnectedAccount.php
  72. 6
    8
      app/Models/Core/Department.php
  73. 2
    4
      app/Models/Employeeship.php
  74. 61
    0
      app/Models/Locale/City.php
  75. 78
    0
      app/Models/Locale/Country.php
  76. 172
    0
      app/Models/Locale/Currency.php
  77. 50
    0
      app/Models/Locale/State.php
  78. 68
    0
      app/Models/Locale/Timezone.php
  79. 6
    11
      app/Models/Setting/Appearance.php
  80. 7
    8
      app/Models/Setting/Category.php
  81. 6
    14
      app/Models/Setting/CompanyDefault.php
  82. 8
    98
      app/Models/Setting/CompanyProfile.php
  83. 9
    11
      app/Models/Setting/Currency.php
  84. 8
    11
      app/Models/Setting/Discount.php
  85. 11
    21
      app/Models/Setting/DocumentDefault.php
  86. 8
    11
      app/Models/Setting/Tax.php
  87. 35
    41
      app/Models/User.php
  88. 1
    2
      app/Policies/CompanyPolicy.php
  89. 1
    2
      app/Policies/ConnectedAccountPolicy.php
  90. 6
    11
      app/Providers/AppServiceProvider.php
  91. 2
    7
      app/Providers/EventServiceProvider.php
  92. 32
    0
      app/Providers/Faker/FakerServiceProvider.php
  93. 4
    11
      app/Providers/Filament/AdminPanelProvider.php
  94. 6
    14
      app/Providers/Filament/UserPanelProvider.php
  95. 11
    35
      app/Providers/FilamentCompaniesServiceProvider.php
  96. 1
    2
      app/Providers/RouteServiceProvider.php
  97. 23
    0
      app/Providers/SquireServiceProvider.php
  98. 1
    3
      app/Scopes/CurrentCompanyScope.php
  99. 4
    12
      app/Services/CompanyDefaultService.php
  100. 0
    0
      app/Services/CurrencyService.php

+ 6
- 8
app/Actions/FilamentCompanies/AddCompanyEmployee.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Closure;
6
 use Closure;
8
 use Illuminate\Auth\Access\AuthorizationException;
7
 use Illuminate\Auth\Access\AuthorizationException;
9
 use Illuminate\Contracts\Validation\Rule;
8
 use Illuminate\Contracts\Validation\Rule;
10
-use Illuminate\Support\Facades\Gate;
11
-use Illuminate\Support\Facades\Validator;
9
+use Illuminate\Support\Facades\{Gate, Validator};
12
 use Wallo\FilamentCompanies\Contracts\AddsCompanyEmployees;
10
 use Wallo\FilamentCompanies\Contracts\AddsCompanyEmployees;
13
-use Wallo\FilamentCompanies\Events\AddingCompanyEmployee;
14
-use Wallo\FilamentCompanies\Events\CompanyEmployeeAdded;
11
+use Wallo\FilamentCompanies\Events\{AddingCompanyEmployee, CompanyEmployeeAdded};
15
 use Wallo\FilamentCompanies\FilamentCompanies;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
16
 use Wallo\FilamentCompanies\Rules\Role;
13
 use Wallo\FilamentCompanies\Rules\Role;
17
 
14
 
22
      *
19
      *
23
      * @throws AuthorizationException
20
      * @throws AuthorizationException
24
      */
21
      */
25
-    public function add(User $user, Company $company, string $email, string|null $role = null): void
22
+    public function add(User $user, Company $company, string $email, ?string $role = null): void
26
     {
23
     {
27
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
24
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
28
 
25
 
33
         AddingCompanyEmployee::dispatch($company, $newCompanyEmployee);
30
         AddingCompanyEmployee::dispatch($company, $newCompanyEmployee);
34
 
31
 
35
         $company->users()->attach(
32
         $company->users()->attach(
36
-            $newCompanyEmployee, ['role' => $role]
33
+            $newCompanyEmployee,
34
+            ['role' => $role]
37
         );
35
         );
38
 
36
 
39
         CompanyEmployeeAdded::dispatch($company, $newCompanyEmployee);
37
         CompanyEmployeeAdded::dispatch($company, $newCompanyEmployee);

+ 2
- 4
app/Actions/FilamentCompanies/CreateCompany.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Auth\Access\AuthorizationException;
6
 use Illuminate\Auth\Access\AuthorizationException;
8
-use Illuminate\Support\Facades\Gate;
9
-use Illuminate\Support\Facades\Validator;
7
+use Illuminate\Support\Facades\{Gate, Validator};
10
 use Wallo\FilamentCompanies\Contracts\CreatesCompanies;
8
 use Wallo\FilamentCompanies\Contracts\CreatesCompanies;
11
 use Wallo\FilamentCompanies\Events\AddingCompany;
9
 use Wallo\FilamentCompanies\Events\AddingCompany;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
10
 use Wallo\FilamentCompanies\FilamentCompanies;

+ 1
- 2
app/Actions/FilamentCompanies/CreateConnectedAccount.php Vedi File

4
 
4
 
5
 use Illuminate\Contracts\Auth\Authenticatable;
5
 use Illuminate\Contracts\Auth\Authenticatable;
6
 use Laravel\Socialite\Contracts\User as ProviderUser;
6
 use Laravel\Socialite\Contracts\User as ProviderUser;
7
-use Wallo\FilamentCompanies\ConnectedAccount;
8
 use Wallo\FilamentCompanies\Contracts\CreatesConnectedAccounts;
7
 use Wallo\FilamentCompanies\Contracts\CreatesConnectedAccounts;
9
-use Wallo\FilamentCompanies\Socialite;
8
+use Wallo\FilamentCompanies\{ConnectedAccount, Socialite};
10
 
9
 
11
 class CreateConnectedAccount implements CreatesConnectedAccounts
10
 class CreateConnectedAccount implements CreatesConnectedAccounts
12
 {
11
 {

+ 3
- 6
app/Actions/FilamentCompanies/CreateNewUser.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
7
-use Illuminate\Support\Facades\DB;
8
-use Illuminate\Support\Facades\Hash;
9
-use Illuminate\Support\Facades\Validator;
5
+use App\Models\{Company, User};
6
+use Illuminate\Support\Facades\{DB, Hash, Validator};
10
 use Wallo\FilamentCompanies\Contracts\CreatesNewUsers;
7
 use Wallo\FilamentCompanies\Contracts\CreatesNewUsers;
11
 use Wallo\FilamentCompanies\Features;
8
 use Wallo\FilamentCompanies\Features;
12
 
9
 
44
     {
41
     {
45
         $user->ownedCompanies()->save(Company::forceCreate([
42
         $user->ownedCompanies()->save(Company::forceCreate([
46
             'user_id' => $user->id,
43
             'user_id' => $user->id,
47
-            'name' => explode(' ', $user->name, 2)[0]."'s Company",
44
+            'name' => explode(' ', $user->name, 2)[0] . "'s Company",
48
             'personal_company' => true,
45
             'personal_company' => true,
49
         ]));
46
         ]));
50
     }
47
     }

+ 4
- 7
app/Actions/FilamentCompanies/CreateUserFromProvider.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Support\Facades\DB;
6
 use Illuminate\Support\Facades\DB;
8
 use Laravel\Socialite\Contracts\User as ProviderUserContract;
7
 use Laravel\Socialite\Contracts\User as ProviderUserContract;
9
-use Wallo\FilamentCompanies\Contracts\CreatesConnectedAccounts;
10
-use Wallo\FilamentCompanies\Contracts\CreatesUserFromProvider;
11
-use Wallo\FilamentCompanies\Features;
12
-use Wallo\FilamentCompanies\Socialite;
8
+use Wallo\FilamentCompanies\Contracts\{CreatesConnectedAccounts, CreatesUserFromProvider};
9
+use Wallo\FilamentCompanies\{Features, Socialite};
13
 
10
 
14
 class CreateUserFromProvider implements CreatesUserFromProvider
11
 class CreateUserFromProvider implements CreatesUserFromProvider
15
 {
12
 {
65
     {
62
     {
66
         $user->ownedCompanies()->save(Company::forceCreate([
63
         $user->ownedCompanies()->save(Company::forceCreate([
67
             'user_id' => $user->id,
64
             'user_id' => $user->id,
68
-            'name' => explode(' ', $user->name, 2)[0]."'s Company",
65
+            'name' => explode(' ', $user->name, 2)[0] . "'s Company",
69
             'personal_company' => true,
66
             'personal_company' => true,
70
         ]));
67
         ]));
71
     }
68
     }

+ 2
- 4
app/Actions/FilamentCompanies/DeleteUser.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Support\Facades\DB;
6
 use Illuminate\Support\Facades\DB;
8
-use Wallo\FilamentCompanies\Contracts\DeletesCompanies;
9
-use Wallo\FilamentCompanies\Contracts\DeletesUsers;
7
+use Wallo\FilamentCompanies\Contracts\{DeletesCompanies, DeletesUsers};
10
 
8
 
11
 class DeleteUser implements DeletesUsers
9
 class DeleteUser implements DeletesUsers
12
 {
10
 {

+ 1
- 1
app/Actions/FilamentCompanies/HandleInvalidState.php Vedi File

11
     /**
11
     /**
12
      * Handle an invalid state exception from a Socialite provider.
12
      * Handle an invalid state exception from a Socialite provider.
13
      */
13
      */
14
-    public function handle(InvalidStateException $exception, callable|null $callback = null): Response
14
+    public function handle(InvalidStateException $exception, ?callable $callback = null): Response
15
     {
15
     {
16
         if ($callback) {
16
         if ($callback) {
17
             return $callback($exception);
17
             return $callback($exception);

+ 3
- 6
app/Actions/FilamentCompanies/InviteCompanyEmployee.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Closure;
6
 use Closure;
8
 use Illuminate\Auth\Access\AuthorizationException;
7
 use Illuminate\Auth\Access\AuthorizationException;
9
 use Illuminate\Database\Query\Builder;
8
 use Illuminate\Database\Query\Builder;
10
-use Illuminate\Support\Facades\Gate;
11
-use Illuminate\Support\Facades\Mail;
12
-use Illuminate\Support\Facades\Validator;
9
+use Illuminate\Support\Facades\{Gate, Mail, Validator};
13
 use Illuminate\Validation\Rule;
10
 use Illuminate\Validation\Rule;
14
 use Wallo\FilamentCompanies\Contracts\InvitesCompanyEmployees;
11
 use Wallo\FilamentCompanies\Contracts\InvitesCompanyEmployees;
15
 use Wallo\FilamentCompanies\Events\InvitingCompanyEmployee;
12
 use Wallo\FilamentCompanies\Events\InvitingCompanyEmployee;
24
      *
21
      *
25
      * @throws AuthorizationException
22
      * @throws AuthorizationException
26
      */
23
      */
27
-    public function invite(User $user, Company $company, string $email, string|null $role = null): void
24
+    public function invite(User $user, Company $company, string $email, ?string $role = null): void
28
     {
25
     {
29
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
26
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
30
 
27
 

+ 1
- 2
app/Actions/FilamentCompanies/RemoveCompanyEmployee.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Auth\Access\AuthorizationException;
6
 use Illuminate\Auth\Access\AuthorizationException;
8
 use Illuminate\Support\Facades\Gate;
7
 use Illuminate\Support\Facades\Gate;
9
 use Illuminate\Validation\ValidationException;
8
 use Illuminate\Validation\ValidationException;

+ 1
- 1
app/Actions/FilamentCompanies/ResolveSocialiteUser.php Vedi File

17
         $user = Socialite::driver($provider)->user();
17
         $user = Socialite::driver($provider)->user();
18
 
18
 
19
         if (FilamentCompaniesSocialite::generatesMissingEmails()) {
19
         if (FilamentCompaniesSocialite::generatesMissingEmails()) {
20
-            $user->email = $user->getEmail() ?? ("{$user->id}@{$provider}".config('app.domain'));
20
+            $user->email = $user->getEmail() ?? ("{$user->id}@{$provider}" . config('app.domain'));
21
         }
21
         }
22
 
22
 
23
         return $user;
23
         return $user;

+ 1
- 2
app/Actions/FilamentCompanies/SetUserPassword.php Vedi File

3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
 use App\Models\User;
5
 use App\Models\User;
6
-use Illuminate\Support\Facades\Hash;
7
-use Illuminate\Support\Facades\Validator;
6
+use Illuminate\Support\Facades\{Hash, Validator};
8
 use Wallo\FilamentCompanies\Contracts\SetsUserPasswords;
7
 use Wallo\FilamentCompanies\Contracts\SetsUserPasswords;
9
 
8
 
10
 class SetUserPassword implements SetsUserPasswords
9
 class SetUserPassword implements SetsUserPasswords

+ 2
- 4
app/Actions/FilamentCompanies/UpdateCompanyName.php Vedi File

2
 
2
 
3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Auth\Access\AuthorizationException;
6
 use Illuminate\Auth\Access\AuthorizationException;
8
-use Illuminate\Support\Facades\Gate;
9
-use Illuminate\Support\Facades\Validator;
7
+use Illuminate\Support\Facades\{Gate, Validator};
10
 use Wallo\FilamentCompanies\Contracts\UpdatesCompanyNames;
8
 use Wallo\FilamentCompanies\Contracts\UpdatesCompanyNames;
11
 
9
 
12
 class UpdateCompanyName implements UpdatesCompanyNames
10
 class UpdateCompanyName implements UpdatesCompanyNames

+ 1
- 2
app/Actions/FilamentCompanies/UpdateUserPassword.php Vedi File

3
 namespace App\Actions\FilamentCompanies;
3
 namespace App\Actions\FilamentCompanies;
4
 
4
 
5
 use App\Models\User;
5
 use App\Models\User;
6
-use Illuminate\Support\Facades\Hash;
7
-use Illuminate\Support\Facades\Validator;
6
+use Illuminate\Support\Facades\{Hash, Validator};
8
 use Wallo\FilamentCompanies\Contracts\UpdatesUserPasswords;
7
 use Wallo\FilamentCompanies\Contracts\UpdatesUserPasswords;
9
 
8
 
10
 class UpdateUserPassword implements UpdatesUserPasswords
9
 class UpdateUserPassword implements UpdatesUserPasswords

+ 1
- 1
app/Actions/OptionAction/CreateCurrency.php Vedi File

22
             'symbol_first' => $currency_code->isSymbolFirst(),
22
             'symbol_first' => $currency_code->isSymbolFirst(),
23
             'decimal_mark' => $currency_code->getDecimalMark(),
23
             'decimal_mark' => $currency_code->getDecimalMark(),
24
             'thousands_separator' => $currency_code->getThousandsSeparator(),
24
             'thousands_separator' => $currency_code->getThousandsSeparator(),
25
-            'enabled' => !$hasDefaultCurrency,
25
+            'enabled' => ! $hasDefaultCurrency,
26
         ]);
26
         ]);
27
     }
27
     }
28
 }
28
 }

+ 1
- 1
app/Casts/MoneyCast.php Vedi File

26
 
26
 
27
         $currency_code = $model->currency_code ?? Currency::getDefaultCurrencyCode();
27
         $currency_code = $model->currency_code ?? Currency::getDefaultCurrencyCode();
28
 
28
 
29
-        if (!$currency_code) {
29
+        if (! $currency_code) {
30
             throw new UnexpectedValueException('Currency code is not set');
30
             throw new UnexpectedValueException('Currency code is not set');
31
         }
31
         }
32
 
32
 

+ 36
- 0
app/Console/Commands/CacheData.php Vedi File

1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use App\Utilities\ModelCacheManager;
6
+use Illuminate\Console\Command;
7
+
8
+class CacheData extends Command
9
+{
10
+    /**
11
+     * The name and signature of the console command.
12
+     *
13
+     * @var string
14
+     */
15
+    protected $signature = 'cache:data';
16
+
17
+    /**
18
+     * The console command description.
19
+     *
20
+     * @var string
21
+     */
22
+    protected $description = 'Cache data from CSV files into the database.';
23
+
24
+    /**
25
+     * Execute the console command.
26
+     */
27
+    public function handle(): void
28
+    {
29
+        // ModelCacheManager::cacheData(resource_path('data/countries.csv'), 'countries');
30
+        ModelCacheManager::cacheData(resource_path('data/currencies.csv'), 'currencies');
31
+        // ModelCacheManager::cacheData(resource_path('data/states.csv'), 'states');
32
+        // ModelCacheManager::cacheData(resource_path('data/cities.csv'), 'cities');
33
+
34
+        $this->info('Data cached successfully.');
35
+    }
36
+}

+ 35
- 0
app/Console/Commands/ClearLog.php Vedi File

1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use Illuminate\Console\Command;
6
+
7
+class ClearLog extends Command
8
+{
9
+    /**
10
+     * The name and signature of the console command.
11
+     *
12
+     * @var string
13
+     */
14
+    protected $signature = 'clear:log';
15
+
16
+    /**
17
+     * The console command description.
18
+     *
19
+     * @var string
20
+     */
21
+    protected $description = 'Clear the log file.';
22
+
23
+    /**
24
+     * Execute the console command.
25
+     */
26
+    public function handle(): void
27
+    {
28
+        $logFile = storage_path('logs/laravel.log');
29
+        if (file_exists($logFile)) {
30
+            unlink($logFile);
31
+        }
32
+
33
+        $this->info('Log file cleared successfully.');
34
+    }
35
+}

+ 71
- 0
app/Console/Commands/ConvertTimezones.php Vedi File

1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use Illuminate\Console\Command;
6
+
7
+class ConvertTimezones extends Command
8
+{
9
+    /**
10
+     * The name and signature of the console command.
11
+     *
12
+     * @var string
13
+     */
14
+    protected $signature = 'convert:timezones';
15
+
16
+    /**
17
+     * The console command description.
18
+     *
19
+     * @var string
20
+     */
21
+    protected $description = 'Converts countries csv to generate a timezones csv file';
22
+
23
+    /**
24
+     * Execute the console command.
25
+     */
26
+    public function handle(): int
27
+    {
28
+        $sourcePath = resource_path('data/countries.csv');
29
+        $destinationPath = resource_path('data/timezones.csv');
30
+
31
+        $source = fopen($sourcePath, 'rb');
32
+        $destination = fopen($destinationPath, 'wb');
33
+
34
+        fputcsv($destination, ['id', 'country_id', 'country_code', 'name', 'gmt_offset', 'gmt_offset_name', 'abbreviation', 'tz_name']);
35
+
36
+        $idCounter = 1;
37
+
38
+        $headers = fgetcsv($source);
39
+
40
+        while (($row = fgetcsv($source)) !== false) {
41
+            $rowAssoc = array_combine($headers, $row);
42
+            $countryId = $rowAssoc['id'];
43
+            $countryCode = $rowAssoc['iso_code_2'];
44
+            $timezonesJson = $rowAssoc['timezones'];
45
+
46
+            $timezonesArray = json_decode($timezonesJson, true);
47
+
48
+            foreach ($timezonesArray as $timezone) {
49
+                $newRow = [
50
+                    $idCounter++,
51
+                    $countryId,
52
+                    $countryCode,
53
+                    $timezone['zoneName'],
54
+                    $timezone['gmtOffset'],
55
+                    $timezone['gmtOffsetName'],
56
+                    $timezone['abbreviation'],
57
+                    $timezone['tzName'],
58
+                ];
59
+
60
+                fputcsv($destination, $newRow);
61
+            }
62
+        }
63
+
64
+        fclose($source);
65
+        fclose($destination);
66
+
67
+        $this->info('Timezones csv file generated successfully.');
68
+
69
+        return 0;
70
+    }
71
+}

+ 71
- 0
app/Console/Commands/SortCsv.php Vedi File

1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use Illuminate\Console\Command;
6
+
7
+class SortCsv extends Command
8
+{
9
+    /**
10
+     * The name and signature of the console command.
11
+     *
12
+     * @var string
13
+     */
14
+    protected $signature = 'sort:csv';
15
+
16
+    /**
17
+     * The console command description.
18
+     *
19
+     * @var string
20
+     */
21
+    protected $description = 'Sort the cities CSV file by country code and state code';
22
+
23
+    /**
24
+     * Execute the console command.
25
+     */
26
+    public function handle(): void
27
+    {
28
+        $inputPath = resource_path('data/cities.csv');
29
+        $outputPath = resource_path('data/cities-sorted.csv');
30
+
31
+        $fileInput = fopen($inputPath, 'rb');
32
+        $fileOutput = fopen($outputPath, 'wb');
33
+
34
+        // Write header to output file
35
+        if (($header = fgetcsv($fileInput, 1000, ',')) !== false) {
36
+            fputcsv($fileOutput, $header);
37
+        }
38
+
39
+        $buffer = [];
40
+        while (($row = fgetcsv($fileInput, 1000, ',')) !== false) {
41
+            $buffer[] = array_combine($header, $row);
42
+
43
+            // When buffer reaches some size, sort and write to file
44
+            if (count($buffer) >= 10000) {  // Adjust this number based on your available memory
45
+                $this->sortAndWriteBuffer($buffer, $fileOutput);
46
+                $buffer = [];
47
+            }
48
+        }
49
+
50
+        // Sort and write any remaining rows
51
+        $this->sortAndWriteBuffer($buffer, $fileOutput);
52
+
53
+        fclose($fileInput);
54
+        fclose($fileOutput);
55
+    }
56
+
57
+    protected function sortAndWriteBuffer(array $buffer, $fileOutput): void
58
+    {
59
+        usort($buffer, static function ($a, $b) {
60
+            if ($a['country_code'] === $b['country_code']) {
61
+                return (int) $a['state_id'] - (int) $b['state_id'];
62
+            }
63
+
64
+            return strcmp($a['country_code'], $b['country_code']);
65
+        });
66
+
67
+        foreach ($buffer as $row) {
68
+            fputcsv($fileOutput, $row);
69
+        }
70
+    }
71
+}

+ 1
- 1
app/Console/Kernel.php Vedi File

20
      */
20
      */
21
     protected function commands(): void
21
     protected function commands(): void
22
     {
22
     {
23
-        $this->load(__DIR__.'/Commands');
23
+        $this->load(__DIR__ . '/Commands');
24
 
24
 
25
         require base_path('routes/console.php');
25
         require base_path('routes/console.php');
26
     }
26
     }

+ 3
- 5
app/Enums/ContactType.php Vedi File

3
 namespace App\Enums;
3
 namespace App\Enums;
4
 
4
 
5
 use Filament\Support\Colors\Color;
5
 use Filament\Support\Colors\Color;
6
-use Filament\Support\Contracts\HasColor;
7
-use Filament\Support\Contracts\HasIcon;
8
-use Filament\Support\Contracts\HasLabel;
6
+use Filament\Support\Contracts\{HasColor, HasIcon, HasLabel};
9
 
7
 
10
-enum ContactType: string implements HasLabel, HasColor, HasIcon
8
+enum ContactType: string implements HasColor, HasIcon, HasLabel
11
 {
9
 {
12
     case Employee = 'employee';
10
     case Employee = 'employee';
13
     case Customer = 'customer';
11
     case Customer = 'customer';
19
         return $this->name;
17
         return $this->name;
20
     }
18
     }
21
 
19
 
22
-    public function getColor(): string|array|null
20
+    public function getColor(): string | array | null
23
     {
21
     {
24
         return match ($this) {
22
         return match ($this) {
25
             self::Employee => Color::Green,
23
             self::Employee => Color::Green,

+ 3
- 5
app/Enums/DiscountType.php Vedi File

2
 
2
 
3
 namespace App\Enums;
3
 namespace App\Enums;
4
 
4
 
5
-use Filament\Support\Contracts\HasColor;
6
-use Filament\Support\Contracts\HasIcon;
7
-use Filament\Support\Contracts\HasLabel;
5
+use Filament\Support\Contracts\{HasColor, HasIcon, HasLabel};
8
 
6
 
9
-enum DiscountType: string implements HasLabel, HasColor, HasIcon
7
+enum DiscountType: string implements HasColor, HasIcon, HasLabel
10
 {
8
 {
11
     case Sales = 'sales';
9
     case Sales = 'sales';
12
     case Purchase = 'purchase';
10
     case Purchase = 'purchase';
17
         return $this->name;
15
         return $this->name;
18
     }
16
     }
19
 
17
 
20
-    public function getColor(): string|array|null
18
+    public function getColor(): string | array | null
21
     {
19
     {
22
         return match ($this) {
20
         return match ($this) {
23
             self::Sales => 'success',
21
             self::Sales => 'success',

+ 2
- 3
app/Enums/DocumentType.php Vedi File

2
 
2
 
3
 namespace App\Enums;
3
 namespace App\Enums;
4
 
4
 
5
-use Filament\Support\Contracts\HasIcon;
6
-use Filament\Support\Contracts\HasLabel;
5
+use Filament\Support\Contracts\{HasIcon, HasLabel};
7
 
6
 
8
-enum DocumentType: string implements HasLabel, HasIcon
7
+enum DocumentType: string implements HasIcon, HasLabel
9
 {
8
 {
10
     case Invoice = 'invoice';
9
     case Invoice = 'invoice';
11
     case Bill = 'bill';
10
     case Bill = 'bill';

+ 0
- 1
app/Enums/EntityType.php Vedi File

26
             self::Nonprofit => 'Nonprofit',
26
             self::Nonprofit => 'Nonprofit',
27
         };
27
         };
28
     }
28
     }
29
-
30
 }
29
 }

+ 1
- 1
app/Enums/PrimaryColor.php Vedi File

37
 
37
 
38
     public const DEFAULT = self::Indigo->value;
38
     public const DEFAULT = self::Indigo->value;
39
 
39
 
40
-    public function getColor(): string|array|null
40
+    public function getColor(): string | array | null
41
     {
41
     {
42
         return match ($this) {
42
         return match ($this) {
43
             self::Slate => Color::Slate,
43
             self::Slate => Color::Slate,

+ 5
- 1
app/Enums/RecordsPerPage.php Vedi File

17
     public const DEFAULT = self::Ten->value;
17
     public const DEFAULT = self::Ten->value;
18
 
18
 
19
     public const FIVE = self::Five->value;
19
     public const FIVE = self::Five->value;
20
+
20
     public const TEN = self::Ten->value;
21
     public const TEN = self::Ten->value;
22
+
21
     public const TWENTY_FIVE = self::TwentyFive->value;
23
     public const TWENTY_FIVE = self::TwentyFive->value;
24
+
22
     public const FIFTY = self::Fifty->value;
25
     public const FIFTY = self::Fifty->value;
26
+
23
     public const ONE_HUNDRED = self::OneHundred->value;
27
     public const ONE_HUNDRED = self::OneHundred->value;
24
 
28
 
25
     public function getLabel(): ?string
29
     public function getLabel(): ?string
26
     {
30
     {
27
-        return (string)$this->value;
31
+        return (string) $this->value;
28
     }
32
     }
29
 }
33
 }

+ 4
- 6
app/Enums/TaxType.php Vedi File

2
 
2
 
3
 namespace App\Enums;
3
 namespace App\Enums;
4
 
4
 
5
-use Filament\Support\Contracts\HasColor;
6
-use Filament\Support\Contracts\HasIcon;
7
-use Filament\Support\Contracts\HasLabel;
5
+use Filament\Support\Contracts\{HasColor, HasIcon, HasLabel};
8
 
6
 
9
-enum TaxType: string implements HasLabel, HasColor, HasIcon
7
+enum TaxType: string implements HasColor, HasIcon, HasLabel
10
 {
8
 {
11
     case Sales = 'sales';
9
     case Sales = 'sales';
12
     case Purchase = 'purchase';
10
     case Purchase = 'purchase';
14
 
12
 
15
     public function getLabel(): ?string
13
     public function getLabel(): ?string
16
     {
14
     {
17
-        return$this->name;
15
+        return $this->name;
18
     }
16
     }
19
 
17
 
20
-    public function getColor(): string|array|null
18
+    public function getColor(): string | array | null
21
     {
19
     {
22
         return match ($this) {
20
         return match ($this) {
23
             self::Sales => 'success',
21
             self::Sales => 'success',

+ 3
- 1
app/Events/CompanyDefaultEvent.php Vedi File

9
 
9
 
10
 class CompanyDefaultEvent
10
 class CompanyDefaultEvent
11
 {
11
 {
12
-    use Dispatchable, InteractsWithSockets, SerializesModels;
12
+    use Dispatchable;
13
+    use InteractsWithSockets;
14
+    use SerializesModels;
13
 
15
 
14
     public Model $model;
16
     public Model $model;
15
 
17
 

+ 4
- 5
app/Events/CompanyDefaultUpdated.php Vedi File

2
 
2
 
3
 namespace App\Events;
3
 namespace App\Events;
4
 
4
 
5
-use Illuminate\Broadcasting\Channel;
6
 use Illuminate\Broadcasting\InteractsWithSockets;
5
 use Illuminate\Broadcasting\InteractsWithSockets;
7
-use Illuminate\Broadcasting\PresenceChannel;
8
-use Illuminate\Broadcasting\PrivateChannel;
9
-use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
10
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Foundation\Events\Dispatchable;
7
 use Illuminate\Foundation\Events\Dispatchable;
12
 use Illuminate\Queue\SerializesModels;
8
 use Illuminate\Queue\SerializesModels;
13
 
9
 
14
 class CompanyDefaultUpdated
10
 class CompanyDefaultUpdated
15
 {
11
 {
16
-    use Dispatchable, InteractsWithSockets, SerializesModels;
12
+    use Dispatchable;
13
+    use InteractsWithSockets;
14
+    use SerializesModels;
17
 
15
 
18
     public Model $record;
16
     public Model $record;
17
+
19
     public array $data;
18
     public array $data;
20
 
19
 
21
     /**
20
     /**

+ 5
- 3
app/Events/CompanyGenerated.php Vedi File

2
 
2
 
3
 namespace App\Events;
3
 namespace App\Events;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Foundation\Events\Dispatchable;
6
 use Illuminate\Foundation\Events\Dispatchable;
8
 use Illuminate\Queue\SerializesModels;
7
 use Illuminate\Queue\SerializesModels;
9
 
8
 
10
 class CompanyGenerated
9
 class CompanyGenerated
11
 {
10
 {
12
-    use Dispatchable, SerializesModels;
11
+    use Dispatchable;
12
+    use SerializesModels;
13
 
13
 
14
     public User $user;
14
     public User $user;
15
+
15
     public Company $company;
16
     public Company $company;
17
+
16
     public string $country;
18
     public string $country;
17
 
19
 
18
     /**
20
     /**

+ 0
- 1
app/Events/UpdateCompanyDefault.php Vedi File

4
 
4
 
5
 class UpdateCompanyDefault
5
 class UpdateCompanyDefault
6
 {
6
 {
7
-
8
 }
7
 }

+ 25
- 0
app/Faker/PhoneNumber.php Vedi File

1
+<?php
2
+
3
+namespace App\Faker;
4
+
5
+use App\Models\Locale\Country;
6
+use Faker\Provider\PhoneNumber as BasePhoneNumber;
7
+
8
+class PhoneNumber extends BasePhoneNumber
9
+{
10
+    public function phoneNumberForCountryCode(string $countryCode): string
11
+    {
12
+        $phoneCode = Country::where('iso_code_2', $countryCode)->first()->phone_code;
13
+
14
+        $filteredFormats = array_filter(
15
+            static::$e164Formats,
16
+            static fn ($format) => str_starts_with($format, "+{$phoneCode}")
17
+        );
18
+
19
+        if (empty($filteredFormats)) {
20
+            return $this->e164PhoneNumber();
21
+        }
22
+
23
+        return self::numerify($this->generator->parse($this->generator->randomElement($filteredFormats)));
24
+    }
25
+}

+ 16
- 0
app/Faker/State.php Vedi File

1
+<?php
2
+
3
+namespace App\Faker;
4
+
5
+use App\Models\Locale\State as StateModel;
6
+use Faker\Provider\Base;
7
+
8
+class State extends Base
9
+{
10
+    public function state(string $countryCode, string $column = 'id'): mixed
11
+    {
12
+        $state = StateModel::where('country_code', $countryCode)->inRandomOrder()->first();
13
+
14
+        return $state?->{$column};
15
+    }
16
+}

+ 4
- 6
app/Filament/Company/Pages/CreateCompany.php Vedi File

4
 
4
 
5
 use App\Enums\EntityType;
5
 use App\Enums\EntityType;
6
 use App\Events\CompanyGenerated;
6
 use App\Events\CompanyGenerated;
7
-use App\Models\Setting\CompanyProfile;
8
-use Filament\Forms\Components\Select;
9
-use Filament\Forms\Components\TextInput;
7
+use App\Models\Locale\Country;
8
+use Filament\Forms\Components\{Select, TextInput};
10
 use Filament\Forms\Form;
9
 use Filament\Forms\Form;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
12
-use Illuminate\Support\Facades\Auth;
13
-use Illuminate\Support\Facades\Gate;
11
+use Illuminate\Support\Facades\{Auth, Gate};
14
 use Wallo\FilamentCompanies\Events\AddingCompany;
12
 use Wallo\FilamentCompanies\Events\AddingCompany;
15
 use Wallo\FilamentCompanies\FilamentCompanies;
13
 use Wallo\FilamentCompanies\FilamentCompanies;
16
 use Wallo\FilamentCompanies\Pages\Company\CreateCompany as FilamentCreateCompany;
14
 use Wallo\FilamentCompanies\Pages\Company\CreateCompany as FilamentCreateCompany;
39
                     ->label('Country')
37
                     ->label('Country')
40
                     ->native(false)
38
                     ->native(false)
41
                     ->searchable()
39
                     ->searchable()
42
-                    ->options(CompanyProfile::getAvailableCountryOptions())
40
+                    ->options(Country::getAvailableCountryOptions())
43
                     ->required(),
41
                     ->required(),
44
             ])
42
             ])
45
             ->model(FilamentCompanies::companyModel())
43
             ->model(FilamentCompanies::companyModel())

+ 17
- 23
app/Filament/Company/Pages/Setting/Appearance.php Vedi File

2
 
2
 
3
 namespace App\Filament\Company\Pages\Setting;
3
 namespace App\Filament\Company\Pages\Setting;
4
 
4
 
5
-use App\Enums\Font;
6
-use App\Enums\MaxContentWidth;
7
-use App\Enums\ModalWidth;
8
-use App\Enums\PrimaryColor;
9
-use App\Enums\RecordsPerPage;
10
-use App\Enums\TableSortDirection;
5
+use App\Enums\{Font, MaxContentWidth, ModalWidth, PrimaryColor, RecordsPerPage, TableSortDirection};
11
 use App\Models\Setting\Appearance as AppearanceModel;
6
 use App\Models\Setting\Appearance as AppearanceModel;
12
-use Filament\Actions\Action;
13
-use Filament\Actions\ActionGroup;
14
-use Filament\Forms\Components\Component;
15
-use Filament\Forms\Components\Section;
16
-use Filament\Forms\Components\Select;
7
+use Filament\Actions\{Action, ActionGroup};
8
+use Filament\Forms\Components\{Component, Section, Select};
17
 use Filament\Forms\Form;
9
 use Filament\Forms\Form;
18
 use Filament\Notifications\Notification;
10
 use Filament\Notifications\Notification;
19
 use Filament\Pages\Concerns\InteractsWithFormActions;
11
 use Filament\Pages\Concerns\InteractsWithFormActions;
22
 use Illuminate\Auth\Access\AuthorizationException;
14
 use Illuminate\Auth\Access\AuthorizationException;
23
 use Illuminate\Database\Eloquent\Model;
15
 use Illuminate\Database\Eloquent\Model;
24
 use Livewire\Attributes\Locked;
16
 use Livewire\Attributes\Locked;
25
-use Wallo\FilamentSelectify\Components\ButtonGroup;
26
-use Wallo\FilamentSelectify\Components\ToggleButton;
17
+use Wallo\FilamentSelectify\Components\{ButtonGroup, ToggleButton};
18
+
27
 use function Filament\authorize;
19
 use function Filament\authorize;
28
 
20
 
29
 /**
21
 /**
146
                     ->allowHtml()
138
                     ->allowHtml()
147
                     ->selectablePlaceholder(false)
139
                     ->selectablePlaceholder(false)
148
                     ->rule('required')
140
                     ->rule('required')
149
-                    ->options(collect(PrimaryColor::cases())
150
-                        ->mapWithKeys(static fn ($case) => [
151
-                            $case->value => "<span class='flex items-center gap-x-4'>
141
+                    ->options(
142
+                        collect(PrimaryColor::cases())
143
+                            ->mapWithKeys(static fn ($case) => [
144
+                                $case->value => "<span class='flex items-center gap-x-4'>
152
                                 <span class='rounded-full w-4 h-4' style='background:rgb(" . $case->getColor()[600] . ")'></span>
145
                                 <span class='rounded-full w-4 h-4' style='background:rgb(" . $case->getColor()[600] . ")'></span>
153
-                                <span>" . str($case->value)->title() . "</span>
154
-                                </span>"
155
-                        ]),
146
+                                <span>" . str($case->value)->title() . '</span>
147
+                                </span>',
148
+                            ]),
156
                     ),
149
                     ),
157
                 Select::make('font')
150
                 Select::make('font')
158
                     ->label('Font')
151
                     ->label('Font')
160
                     ->selectablePlaceholder(false)
153
                     ->selectablePlaceholder(false)
161
                     ->rule('required')
154
                     ->rule('required')
162
                     ->allowHtml()
155
                     ->allowHtml()
163
-                    ->options(collect(Font::cases())
164
-                        ->mapWithKeys(static fn ($case) => [
165
-                            $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>"
166
-                        ]),
156
+                    ->options(
157
+                        collect(Font::cases())
158
+                            ->mapWithKeys(static fn ($case) => [
159
+                                $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>",
160
+                            ]),
167
                     ),
161
                     ),
168
             ])->columns();
162
             ])->columns();
169
     }
163
     }

+ 3
- 5
app/Filament/Company/Pages/Setting/CompanyDefault.php Vedi File

4
 
4
 
5
 use App\Events\CompanyDefaultUpdated;
5
 use App\Events\CompanyDefaultUpdated;
6
 use App\Models\Setting\CompanyDefault as CompanyDefaultModel;
6
 use App\Models\Setting\CompanyDefault as CompanyDefaultModel;
7
-use Filament\Actions\Action;
8
-use Filament\Actions\ActionGroup;
9
-use Filament\Forms\Components\Component;
10
-use Filament\Forms\Components\Section;
11
-use Filament\Forms\Components\Select;
7
+use Filament\Actions\{Action, ActionGroup};
8
+use Filament\Forms\Components\{Component, Section, Select};
12
 use Filament\Forms\Form;
9
 use Filament\Forms\Form;
13
 use Filament\Notifications\Notification;
10
 use Filament\Notifications\Notification;
14
 use Filament\Pages\Concerns\InteractsWithFormActions;
11
 use Filament\Pages\Concerns\InteractsWithFormActions;
17
 use Illuminate\Auth\Access\AuthorizationException;
14
 use Illuminate\Auth\Access\AuthorizationException;
18
 use Illuminate\Database\Eloquent\Model;
15
 use Illuminate\Database\Eloquent\Model;
19
 use Livewire\Attributes\Locked;
16
 use Livewire\Attributes\Locked;
17
+
20
 use function Filament\authorize;
18
 use function Filament\authorize;
21
 
19
 
22
 /**
20
 /**

+ 18
- 18
app/Filament/Company/Pages/Setting/CompanyProfile.php Vedi File

3
 namespace App\Filament\Company\Pages\Setting;
3
 namespace App\Filament\Company\Pages\Setting;
4
 
4
 
5
 use App\Enums\EntityType;
5
 use App\Enums\EntityType;
6
-use Filament\Actions\Action;
7
-use Filament\Actions\ActionGroup;
8
-use Filament\Forms\Components\Component;
9
-use Filament\Forms\Components\DatePicker;
10
-use Filament\Forms\Components\FileUpload;
11
-use Filament\Forms\Components\Group;
12
-use Filament\Forms\Components\Section;
13
-use Filament\Forms\Components\Select;
14
-use Filament\Forms\Components\TextInput;
15
-use Filament\Forms\Form;
16
-use Filament\Forms\Get;
6
+use App\Models\Locale\{City, Country, State, Timezone};
7
+use App\Models\Setting\CompanyProfile as CompanyProfileModel;
8
+use Filament\Actions\{Action, ActionGroup};
9
+use Filament\Forms\Components\{Component, DatePicker, FileUpload, Group, Section, Select, TextInput};
10
+use Filament\Forms\{Form, Get, Set};
17
 use Filament\Notifications\Notification;
11
 use Filament\Notifications\Notification;
18
 use Filament\Pages\Concerns\InteractsWithFormActions;
12
 use Filament\Pages\Concerns\InteractsWithFormActions;
19
 use Filament\Pages\Page;
13
 use Filament\Pages\Page;
20
-use App\Models\Setting\CompanyProfile as CompanyProfileModel;
21
 use Filament\Support\Exceptions\Halt;
14
 use Filament\Support\Exceptions\Halt;
22
 use Illuminate\Auth\Access\AuthorizationException;
15
 use Illuminate\Auth\Access\AuthorizationException;
23
 use Illuminate\Database\Eloquent\Model;
16
 use Illuminate\Database\Eloquent\Model;
24
 use Illuminate\Support\Facades\Auth;
17
 use Illuminate\Support\Facades\Auth;
25
 use Livewire\Attributes\Locked;
18
 use Livewire\Attributes\Locked;
26
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
19
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
20
+
27
 use function Filament\authorize;
21
 use function Filament\authorize;
28
 
22
 
29
 /**
23
 /**
171
                             ->label('Phone Number')
165
                             ->label('Phone Number')
172
                             ->tel()
166
                             ->tel()
173
                             ->nullable(),
167
                             ->nullable(),
174
-                    ])->columns(1)
168
+                    ])->columns(1),
175
             ])->columns();
169
             ])->columns();
176
     }
170
     }
177
 
171
 
184
                     ->native(false)
178
                     ->native(false)
185
                     ->live()
179
                     ->live()
186
                     ->searchable()
180
                     ->searchable()
187
-                    ->options(CompanyProfileModel::getAvailableCountryOptions())
181
+                    ->options(Country::getAvailableCountryOptions())
182
+                    ->afterStateUpdated(static function (Set $set) {
183
+                        $set('state_id', null);
184
+                        $set('timezone', null);
185
+                        $set('city_id', null);
186
+                    })
188
                     ->required(),
187
                     ->required(),
189
-                Select::make('state')
188
+                Select::make('state_id')
190
                     ->label('State / Province')
189
                     ->label('State / Province')
191
                     ->searchable()
190
                     ->searchable()
192
-                    ->options(static fn (Get $get) => CompanyProfileModel::getStateOptions($get('country')))
191
+                    ->live()
192
+                    ->options(static fn (Get $get) => State::getStateOptions($get('country')))
193
                     ->nullable(),
193
                     ->nullable(),
194
                 Select::make('timezone')
194
                 Select::make('timezone')
195
                     ->label('Timezone')
195
                     ->label('Timezone')
196
                     ->searchable()
196
                     ->searchable()
197
-                    ->options(static fn (Get $get) => CompanyProfileModel::getTimezoneOptions($get('country')))
197
+                    ->options(static fn (Get $get) => Timezone::getTimezoneOptions($get('country')))
198
                     ->nullable(),
198
                     ->nullable(),
199
                 TextInput::make('address')
199
                 TextInput::make('address')
200
                     ->label('Street Address')
200
                     ->label('Street Address')
203
                 Select::make('city_id')
203
                 Select::make('city_id')
204
                     ->label('City / Town')
204
                     ->label('City / Town')
205
                     ->searchable()
205
                     ->searchable()
206
-                    ->options(static fn (Get $get) => CompanyProfileModel::getCityOptions($get('country'), $get('state')))
206
+                    ->options(static fn (Get $get) => City::getCityOptions($get('country'), $get('state_id')))
207
                     ->nullable(),
207
                     ->nullable(),
208
                 TextInput::make('zip_code')
208
                 TextInput::make('zip_code')
209
                     ->label('Zip Code')
209
                     ->label('Zip Code')

+ 10
- 22
app/Filament/Company/Pages/Setting/Invoice.php Vedi File

2
 
2
 
3
 namespace App\Filament\Company\Pages\Setting;
3
 namespace App\Filament\Company\Pages\Setting;
4
 
4
 
5
-use App\Enums\DocumentType;
6
-use App\Enums\Font;
7
-use App\Enums\PaymentTerms;
8
-use App\Enums\Template;
5
+use App\Enums\{DocumentType, Font, PaymentTerms, Template};
9
 use App\Models\Setting\DocumentDefault as InvoiceModel;
6
 use App\Models\Setting\DocumentDefault as InvoiceModel;
10
-use Filament\Actions\Action;
11
-use Filament\Actions\ActionGroup;
12
-use Filament\Forms\Components\Checkbox;
13
-use Filament\Forms\Components\ColorPicker;
14
-use Filament\Forms\Components\Component;
15
-use Filament\Forms\Components\FileUpload;
16
-use Filament\Forms\Components\Group;
17
-use Filament\Forms\Components\Section;
18
-use Filament\Forms\Components\Select;
19
-use Filament\Forms\Components\Textarea;
20
-use Filament\Forms\Components\TextInput;
21
-use Filament\Forms\Components\ViewField;
22
-use Filament\Forms\Form;
23
-use Filament\Forms\Get;
7
+use Filament\Actions\{Action, ActionGroup};
8
+use Filament\Forms\Components\{Checkbox, ColorPicker, Component, FileUpload, Group, Section, Select, TextInput, Textarea, ViewField};
9
+use Filament\Forms\{Form, Get};
24
 use Filament\Notifications\Notification;
10
 use Filament\Notifications\Notification;
25
 use Filament\Pages\Concerns\InteractsWithFormActions;
11
 use Filament\Pages\Concerns\InteractsWithFormActions;
26
 use Filament\Pages\Page;
12
 use Filament\Pages\Page;
29
 use Illuminate\Database\Eloquent\Model;
15
 use Illuminate\Database\Eloquent\Model;
30
 use Illuminate\Support\Facades\Auth;
16
 use Illuminate\Support\Facades\Auth;
31
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
17
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
18
+
32
 use function Filament\authorize;
19
 use function Filament\authorize;
33
 
20
 
34
 /**
21
 /**
234
                             ->selectablePlaceholder(false)
221
                             ->selectablePlaceholder(false)
235
                             ->rule('required')
222
                             ->rule('required')
236
                             ->allowHtml()
223
                             ->allowHtml()
237
-                            ->options(collect(Font::cases())
238
-                                ->mapWithKeys(static fn ($case) => [
239
-                                    $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>"
240
-                                ]),
224
+                            ->options(
225
+                                collect(Font::cases())
226
+                                    ->mapWithKeys(static fn ($case) => [
227
+                                        $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>",
228
+                                    ]),
241
                             ),
229
                             ),
242
                         Select::make('template')
230
                         Select::make('template')
243
                             ->label('Template')
231
                             ->label('Template')

+ 5
- 9
app/Filament/Company/Resources/Banking/AccountResource.php Vedi File

4
 
4
 
5
 use App\Actions\OptionAction\CreateCurrency;
5
 use App\Actions\OptionAction\CreateCurrency;
6
 use App\Filament\Company\Resources\Banking\AccountResource\Pages;
6
 use App\Filament\Company\Resources\Banking\AccountResource\Pages;
7
-use App\Filament\Company\Resources\Banking\AccountResource\RelationManagers;
8
 use App\Models\Banking\Account;
7
 use App\Models\Banking\Account;
9
 use App\Models\Setting\Currency;
8
 use App\Models\Setting\Currency;
10
 use App\Services\CurrencyService;
9
 use App\Services\CurrencyService;
11
 use App\Utilities\CurrencyConverter;
10
 use App\Utilities\CurrencyConverter;
12
-use Filament\Forms;
13
 use Filament\Forms\Form;
11
 use Filament\Forms\Form;
14
 use Filament\Notifications\Notification;
12
 use Filament\Notifications\Notification;
15
 use Filament\Resources\Resource;
13
 use Filament\Resources\Resource;
16
-use Filament\Tables;
17
 use Filament\Tables\Table;
14
 use Filament\Tables\Table;
18
-use Illuminate\Database\Eloquent\SoftDeletingScope;
19
-use Illuminate\Support\Facades\Auth;
20
-use Illuminate\Support\Facades\DB;
15
+use Filament\{Forms, Tables};
16
+use Illuminate\Support\Facades\{Auth, DB};
21
 use Illuminate\Validation\Rules\Unique;
17
 use Illuminate\Validation\Rules\Unique;
22
 use Wallo\FilamentSelectify\Components\ToggleButton;
18
 use Wallo\FilamentSelectify\Components\ToggleButton;
23
 
19
 
134
                                 Forms\Components\TextInput::make('opening_balance')
130
                                 Forms\Components\TextInput::make('opening_balance')
135
                                     ->label('Opening Balance')
131
                                     ->label('Opening Balance')
136
                                     ->required()
132
                                     ->required()
137
-                                    ->currency(static fn (Forms\Get $get) => $get('currency_code'))
133
+                                    ->currency(static fn (Forms\Get $get) => $get('currency_code')),
138
                             ])->columns(),
134
                             ])->columns(),
139
                         Forms\Components\Tabs::make('Account Specifications')
135
                         Forms\Components\Tabs::make('Account Specifications')
140
                             ->tabs([
136
                             ->tabs([
282
                             if ($cachedExchangeRate !== $oldExchangeRate) {
278
                             if ($cachedExchangeRate !== $oldExchangeRate) {
283
 
279
 
284
                                 $scale = 10 ** $record->currency->precision;
280
                                 $scale = 10 ** $record->currency->precision;
285
-                                $cleanedBalance = (int)filter_var($record->opening_balance, FILTER_SANITIZE_NUMBER_INT);
281
+                                $cleanedBalance = (int) filter_var($record->opening_balance, FILTER_SANITIZE_NUMBER_INT);
286
 
282
 
287
                                 $newBalance = ($cachedExchangeRate / $oldExchangeRate) * $cleanedBalance;
283
                                 $newBalance = ($cachedExchangeRate / $oldExchangeRate) * $cleanedBalance;
288
-                                $newBalanceInt = (int)round($newBalance, $scale);
284
+                                $newBalanceInt = (int) round($newBalance, $scale);
289
 
285
 
290
                                 $record->opening_balance = money($newBalanceInt, $record->currency_code)->getValue();
286
                                 $record->opening_balance = money($newBalanceInt, $record->currency_code)->getValue();
291
                                 $record->currency->rate = $cachedExchangeRate;
287
                                 $record->currency->rate = $cachedExchangeRate;

+ 2
- 3
app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php Vedi File

5
 use App\Filament\Company\Resources\Banking\AccountResource;
5
 use App\Filament\Company\Resources\Banking\AccountResource;
6
 use App\Models\Banking\Account;
6
 use App\Models\Banking\Account;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
-use Filament\Actions;
9
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
10
 use Filament\Support\Exceptions\Halt;
9
 use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
24
 
23
 
25
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
26
     {
25
     {
27
-        $data['enabled'] = (bool)$data['enabled'];
26
+        $data['enabled'] = (bool) $data['enabled'];
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
36
     {
35
     {
37
         $user = Auth::user();
36
         $user = Auth::user();
38
 
37
 
39
-        if (!$user) {
38
+        if (! $user) {
40
             throw new Halt('No authenticated user found.');
39
             throw new Halt('No authenticated user found.');
41
         }
40
         }
42
 
41
 

+ 3
- 3
app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php Vedi File

32
 
32
 
33
     protected function mutateFormDataBeforeSave(array $data): array
33
     protected function mutateFormDataBeforeSave(array $data): array
34
     {
34
     {
35
-        $data['enabled'] = (bool)$data['enabled'];
35
+        $data['enabled'] = (bool) $data['enabled'];
36
 
36
 
37
         return $data;
37
         return $data;
38
     }
38
     }
40
     /**
40
     /**
41
      * @throws Halt
41
      * @throws Halt
42
      */
42
      */
43
-    protected function handleRecordUpdate(Account|Model $record, array $data): Model|Account
43
+    protected function handleRecordUpdate(Account | Model $record, array $data): Model | Account
44
     {
44
     {
45
         $user = Auth::user();
45
         $user = Auth::user();
46
 
46
 
47
-        if (!$user) {
47
+        if (! $user) {
48
             throw new Halt('No authenticated user found.');
48
             throw new Halt('No authenticated user found.');
49
         }
49
         }
50
 
50
 

+ 2
- 3
app/Filament/Company/Resources/Core/DepartmentResource.php Vedi File

4
 
4
 
5
 use App\Filament\Company\Resources\Core\DepartmentResource\Pages;
5
 use App\Filament\Company\Resources\Core\DepartmentResource\Pages;
6
 use App\Models\Core\Department;
6
 use App\Models\Core\Department;
7
-use Filament\Forms;
8
 use Filament\Forms\Form;
7
 use Filament\Forms\Form;
9
 use Filament\Resources\Resource;
8
 use Filament\Resources\Resource;
10
-use Filament\Tables;
11
 use Filament\Tables\Table;
9
 use Filament\Tables\Table;
10
+use Filament\{Forms, Tables};
12
 
11
 
13
 class DepartmentResource extends Resource
12
 class DepartmentResource extends Resource
14
 {
13
 {
49
                                     ->label('Description')
48
                                     ->label('Description')
50
                                     ->autosize()
49
                                     ->autosize()
51
                                     ->nullable(),
50
                                     ->nullable(),
52
-                        ])->columns(1),
51
+                            ])->columns(1),
53
                     ])->columns(),
52
                     ])->columns(),
54
             ]);
53
             ]);
55
     }
54
     }

+ 8
- 8
app/Filament/Company/Resources/Setting/CategoryResource.php Vedi File

7
 use App\Models\Setting\Category;
7
 use App\Models\Setting\Category;
8
 use Closure;
8
 use Closure;
9
 use Exception;
9
 use Exception;
10
-use Filament\Forms;
11
 use Filament\Forms\Form;
10
 use Filament\Forms\Form;
12
 use Filament\Notifications\Notification;
11
 use Filament\Notifications\Notification;
13
 use Filament\Resources\Resource;
12
 use Filament\Resources\Resource;
14
-use Filament\Tables;
15
 use Filament\Tables\Table;
13
 use Filament\Tables\Table;
14
+use Filament\{Forms, Tables};
16
 use Illuminate\Database\Eloquent\Collection;
15
 use Illuminate\Database\Eloquent\Collection;
17
 use Wallo\FilamentSelectify\Components\ToggleButton;
16
 use Wallo\FilamentSelectify\Components\ToggleButton;
18
 
17
 
40
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
39
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
41
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
40
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
42
                                     $existingCategory = Category::where('company_id', auth()->user()->currentCompany->id)
41
                                     $existingCategory = Category::where('company_id', auth()->user()->currentCompany->id)
43
-                                                                ->where('name', $value)
44
-                                                                ->where('type', $get('type'))
45
-                                                                ->first();
42
+                                        ->where('name', $value)
43
+                                        ->where('type', $get('type'))
44
+                                        ->first();
46
 
45
 
47
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
46
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
48
                                         $type = ucwords($get('type'));
47
                                         $type = ucwords($get('type'));
125
                                     ->danger()
124
                                     ->danger()
126
                                     ->title('Action Denied')
125
                                     ->title('Action Denied')
127
                                     ->body(static function () use ($defaultCategoryNames) {
126
                                     ->body(static function () use ($defaultCategoryNames) {
128
-                                        $message = __('The following categories are currently set as your default and cannot be deleted. Please set a different category as your default before attempting to delete these ones.') . "<br><br>";
129
-                                        $message .= implode("<br>", array_map(static function ($name) {
130
-                                            return "&bull; " . $name;
127
+                                        $message = __('The following categories are currently set as your default and cannot be deleted. Please set a different category as your default before attempting to delete these ones.') . '<br><br>';
128
+                                        $message .= implode('<br>', array_map(static function ($name) {
129
+                                            return '&bull; ' . $name;
131
                                         }, $defaultCategoryNames));
130
                                         }, $defaultCategoryNames));
131
+
132
                                         return $message;
132
                                         return $message;
133
                                     })
133
                                     })
134
                                     ->persistent()
134
                                     ->persistent()

+ 2
- 2
app/Filament/Company/Resources/Setting/CategoryResource/Pages/CreateCategory.php Vedi File

22
 
22
 
23
     protected function mutateFormDataBeforeCreate(array $data): array
23
     protected function mutateFormDataBeforeCreate(array $data): array
24
     {
24
     {
25
-        $data['enabled'] = (bool)$data['enabled'];
25
+        $data['enabled'] = (bool) $data['enabled'];
26
 
26
 
27
         return $data;
27
         return $data;
28
     }
28
     }
34
     {
34
     {
35
         $user = auth()->user();
35
         $user = auth()->user();
36
 
36
 
37
-        if (!$user) {
37
+        if (! $user) {
38
             throw new Halt('No authenticated user found');
38
             throw new Halt('No authenticated user found');
39
         }
39
         }
40
 
40
 

+ 2
- 2
app/Filament/Company/Resources/Setting/CategoryResource/Pages/EditCategory.php Vedi File

29
 
29
 
30
     protected function mutateFormDataBeforeSave(array $data): array
30
     protected function mutateFormDataBeforeSave(array $data): array
31
     {
31
     {
32
-        $data['enabled'] = (bool)$data['enabled'];
32
+        $data['enabled'] = (bool) $data['enabled'];
33
 
33
 
34
         return $data;
34
         return $data;
35
     }
35
     }
41
     {
41
     {
42
         $user = auth()->user();
42
         $user = auth()->user();
43
 
43
 
44
-        if (!$user) {
44
+        if (! $user) {
45
             throw new Halt('No authenticated user found');
45
             throw new Halt('No authenticated user found');
46
         }
46
         }
47
 
47
 

+ 63
- 60
app/Filament/Company/Resources/Setting/CurrencyResource.php Vedi File

7
 use App\Models\Setting\Currency;
7
 use App\Models\Setting\Currency;
8
 use App\Services\CurrencyService;
8
 use App\Services\CurrencyService;
9
 use App\Traits\ChecksForeignKeyConstraints;
9
 use App\Traits\ChecksForeignKeyConstraints;
10
-use Filament\Forms;
11
 use Filament\Forms\Form;
10
 use Filament\Forms\Form;
12
 use Filament\Notifications\Notification;
11
 use Filament\Notifications\Notification;
13
 use Filament\Resources\Resource;
12
 use Filament\Resources\Resource;
14
 use Filament\Support\Colors\Color;
13
 use Filament\Support\Colors\Color;
15
-use Filament\Tables;
16
 use Filament\Tables\Table;
14
 use Filament\Tables\Table;
15
+use Filament\{Forms, Tables};
17
 use Illuminate\Database\Eloquent\Collection;
16
 use Illuminate\Database\Eloquent\Collection;
18
 use Wallo\FilamentSelectify\Components\ToggleButton;
17
 use Wallo\FilamentSelectify\Components\ToggleButton;
19
 
18
 
36
                 Forms\Components\Section::make('General')
35
                 Forms\Components\Section::make('General')
37
                     ->schema([
36
                     ->schema([
38
                         Forms\Components\Select::make('code')
37
                         Forms\Components\Select::make('code')
39
-                        ->label('Code')
40
-                        ->options(Currency::getAvailableCurrencyCodes())
41
-                        ->searchable()
42
-                        ->placeholder('Select a currency code...')
43
-                        ->live()
44
-                        ->required()
45
-                        ->hidden(static fn (Forms\Get $get): bool => $get('enabled'))
46
-                        ->afterStateUpdated(static function (Forms\Set $set, $state) {
47
-                            if ($state === null) {
48
-                                return;
49
-                            }
38
+                            ->label('Code')
39
+                            ->options(Currency::getAvailableCurrencyCodes())
40
+                            ->searchable()
41
+                            ->placeholder('Select a currency code...')
42
+                            ->live()
43
+                            ->required()
44
+                            ->hidden(static fn (Forms\Get $get): bool => $get('enabled'))
45
+                            ->afterStateUpdated(static function (Forms\Set $set, $state) {
46
+                                if ($state === null) {
47
+                                    return;
48
+                                }
50
 
49
 
51
-                            $code = $state;
50
+                                $code = $state;
52
 
51
 
53
-                            $allCurrencies = Currency::getAllCurrencies();
52
+                                $allCurrencies = Currency::getAllCurrencies();
54
 
53
 
55
-                            $selectedCurrencyCode = $allCurrencies[$code] ?? [];
54
+                                $selectedCurrencyCode = $allCurrencies[$code] ?? [];
56
 
55
 
57
-                            $currencyService = app(CurrencyService::class);
58
-                            $defaultCurrencyCode = Currency::getDefaultCurrencyCode();
59
-                            $rate = 1;
56
+                                $currencyService = app(CurrencyService::class);
57
+                                $defaultCurrencyCode = Currency::getDefaultCurrencyCode();
58
+                                $rate = 1;
60
 
59
 
61
-                            if ($defaultCurrencyCode !== null) {
62
-                                $rate = $currencyService->getCachedExchangeRate($defaultCurrencyCode, $code);
63
-                            }
60
+                                if ($defaultCurrencyCode !== null) {
61
+                                    $rate = $currencyService->getCachedExchangeRate($defaultCurrencyCode, $code);
62
+                                }
64
 
63
 
65
-                            $set('name', $selectedCurrencyCode['name'] ?? '');
66
-                            $set('rate', $rate);
67
-                            $set('precision', $selectedCurrencyCode['precision'] ?? '');
68
-                            $set('symbol', $selectedCurrencyCode['symbol'] ?? '');
69
-                            $set('symbol_first', $selectedCurrencyCode['symbol_first'] ?? '');
70
-                            $set('decimal_mark', $selectedCurrencyCode['decimal_mark'] ?? '');
71
-                            $set('thousands_separator', $selectedCurrencyCode['thousands_separator'] ?? '');
72
-                        }),
64
+                                $set('name', $selectedCurrencyCode['name'] ?? '');
65
+                                $set('rate', $rate);
66
+                                $set('precision', $selectedCurrencyCode['precision'] ?? '');
67
+                                $set('symbol', $selectedCurrencyCode['symbol'] ?? '');
68
+                                $set('symbol_first', $selectedCurrencyCode['symbol_first'] ?? '');
69
+                                $set('decimal_mark', $selectedCurrencyCode['decimal_mark'] ?? '');
70
+                                $set('thousands_separator', $selectedCurrencyCode['thousands_separator'] ?? '');
71
+                            }),
73
                         Forms\Components\TextInput::make('code')
72
                         Forms\Components\TextInput::make('code')
74
                             ->label('Code')
73
                             ->label('Code')
75
-                            ->hidden(static fn (Forms\Get $get): bool => !$get('enabled'))
74
+                            ->hidden(static fn (Forms\Get $get): bool => ! $get('enabled'))
76
                             ->disabled(static fn (Forms\Get $get): bool => $get('enabled'))
75
                             ->disabled(static fn (Forms\Get $get): bool => $get('enabled'))
77
                             ->required(),
76
                             ->required(),
78
                         Forms\Components\TextInput::make('name')
77
                         Forms\Components\TextInput::make('name')
122
                                 if ($enabled) {
121
                                 if ($enabled) {
123
                                     $rate = 1;
122
                                     $rate = 1;
124
                                 } else {
123
                                 } else {
124
+                                    if ($code === null) {
125
+                                        return;
126
+                                    }
127
+
125
                                     $defaultCurrencyCode = Currency::getDefaultCurrencyCode();
128
                                     $defaultCurrencyCode = Currency::getDefaultCurrencyCode();
126
                                     $rate = $defaultCurrencyCode ? $currencyService->getCachedExchangeRate($defaultCurrencyCode, $code) : 1;
129
                                     $rate = $defaultCurrencyCode ? $currencyService->getCachedExchangeRate($defaultCurrencyCode, $code) : 1;
127
                                 }
130
                                 }
195
             ->bulkActions([
198
             ->bulkActions([
196
                 Tables\Actions\BulkActionGroup::make([
199
                 Tables\Actions\BulkActionGroup::make([
197
                     Tables\Actions\DeleteBulkAction::make()
200
                     Tables\Actions\DeleteBulkAction::make()
198
-                    ->before(static function (Tables\Actions\DeleteBulkAction $action, Collection $records) {
199
-                        foreach ($records as $record) {
200
-                            $defaultCurrency = $record->enabled;
201
-                            $modelsToCheck = [
202
-                                Account::class,
203
-                            ];
204
-
205
-                            $isUsed = self::isForeignKeyUsed('currency_code', $record->code, $modelsToCheck);
206
-
207
-                            if ($defaultCurrency) {
208
-                                Notification::make()
209
-                                    ->danger()
210
-                                    ->title('Action Denied')
211
-                                    ->body(__('The :name currency is currently set as the default currency and cannot be deleted. Please set a different currency as your default before attempting to delete this one.', ['name' => $record->name]))
212
-                                    ->persistent()
213
-                                    ->send();
214
-
215
-                                $action->cancel();
216
-                            } elseif ($isUsed) {
217
-                                Notification::make()
218
-                                    ->danger()
219
-                                    ->title('Action Denied')
220
-                                    ->body(__('The :name currency is currently in use by one or more accounts and cannot be deleted. Please remove this currency from all accounts before attempting to delete it.', ['name' => $record->name]))
221
-                                    ->persistent()
222
-                                    ->send();
223
-
224
-                                $action->cancel();
201
+                        ->before(static function (Tables\Actions\DeleteBulkAction $action, Collection $records) {
202
+                            foreach ($records as $record) {
203
+                                $defaultCurrency = $record->enabled;
204
+                                $modelsToCheck = [
205
+                                    Account::class,
206
+                                ];
207
+
208
+                                $isUsed = self::isForeignKeyUsed('currency_code', $record->code, $modelsToCheck);
209
+
210
+                                if ($defaultCurrency) {
211
+                                    Notification::make()
212
+                                        ->danger()
213
+                                        ->title('Action Denied')
214
+                                        ->body(__('The :name currency is currently set as the default currency and cannot be deleted. Please set a different currency as your default before attempting to delete this one.', ['name' => $record->name]))
215
+                                        ->persistent()
216
+                                        ->send();
217
+
218
+                                    $action->cancel();
219
+                                } elseif ($isUsed) {
220
+                                    Notification::make()
221
+                                        ->danger()
222
+                                        ->title('Action Denied')
223
+                                        ->body(__('The :name currency is currently in use by one or more accounts and cannot be deleted. Please remove this currency from all accounts before attempting to delete it.', ['name' => $record->name]))
224
+                                        ->persistent()
225
+                                        ->send();
226
+
227
+                                    $action->cancel();
228
+                                }
225
                             }
229
                             }
226
-                        }
227
-                    }),
230
+                        }),
228
                 ]),
231
                 ]),
229
             ])
232
             ])
230
             ->emptyStateActions([
233
             ->emptyStateActions([

+ 2
- 3
app/Filament/Company/Resources/Setting/CurrencyResource/Pages/CreateCurrency.php Vedi File

5
 use App\Filament\Company\Resources\Setting\CurrencyResource;
5
 use App\Filament\Company\Resources\Setting\CurrencyResource;
6
 use App\Models\Setting\Currency;
6
 use App\Models\Setting\Currency;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
-use Filament\Actions;
9
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
10
 use Filament\Support\Exceptions\Halt;
9
 use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
24
 
23
 
25
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
26
     {
25
     {
27
-        $data['enabled'] = (bool)$data['enabled'];
26
+        $data['enabled'] = (bool) $data['enabled'];
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
36
     {
35
     {
37
         $user = Auth::user();
36
         $user = Auth::user();
38
 
37
 
39
-        if (!$user) {
38
+        if (! $user) {
40
             throw new Halt('No authenticated user found');
39
             throw new Halt('No authenticated user found');
41
         }
40
         }
42
 
41
 

+ 2
- 2
app/Filament/Company/Resources/Setting/CurrencyResource/Pages/EditCurrency.php Vedi File

30
 
30
 
31
     protected function mutateFormDataBeforeSave(array $data): array
31
     protected function mutateFormDataBeforeSave(array $data): array
32
     {
32
     {
33
-        $data['enabled'] = (bool)$data['enabled'];
33
+        $data['enabled'] = (bool) $data['enabled'];
34
 
34
 
35
         return $data;
35
         return $data;
36
     }
36
     }
42
     {
42
     {
43
         $user = Auth::user();
43
         $user = Auth::user();
44
 
44
 
45
-        if (!$user) {
45
+        if (! $user) {
46
             throw new Halt('No authenticated user found');
46
             throw new Halt('No authenticated user found');
47
         }
47
         }
48
 
48
 

+ 11
- 18
app/Filament/Company/Resources/Setting/DiscountResource.php Vedi File

2
 
2
 
3
 namespace App\Filament\Company\Resources\Setting;
3
 namespace App\Filament\Company\Resources\Setting;
4
 
4
 
5
-use App\Enums\DiscountComputation;
6
-use App\Enums\DiscountScope;
7
-use App\Enums\DiscountType;
5
+use App\Enums\{DiscountComputation, DiscountScope, DiscountType};
8
 use App\Filament\Company\Resources\Setting\DiscountResource\Pages;
6
 use App\Filament\Company\Resources\Setting\DiscountResource\Pages;
9
-use App\Filament\Company\Resources\Setting\DiscountResource\RelationManagers;
10
-use App\Models\Setting\Category;
11
 use App\Models\Setting\Discount;
7
 use App\Models\Setting\Discount;
12
 use Closure;
8
 use Closure;
13
-use Filament\Forms;
14
 use Filament\Forms\Form;
9
 use Filament\Forms\Form;
15
 use Filament\Resources\Resource;
10
 use Filament\Resources\Resource;
16
-use Filament\Tables;
17
 use Filament\Tables\Table;
11
 use Filament\Tables\Table;
18
-use Illuminate\Database\Eloquent\Builder;
19
-use Illuminate\Database\Eloquent\SoftDeletingScope;
12
+use Filament\{Forms, Tables};
20
 use Wallo\FilamentSelectify\Components\ToggleButton;
13
 use Wallo\FilamentSelectify\Components\ToggleButton;
21
 
14
 
22
 class DiscountResource extends Resource
15
 class DiscountResource extends Resource
43
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
36
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
44
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
37
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
45
                                     $existingCategory = Discount::where('company_id', auth()->user()->currentCompany->id)
38
                                     $existingCategory = Discount::where('company_id', auth()->user()->currentCompany->id)
46
-                                                                ->where('name', $value)
47
-                                                                ->where('type', $get('type'))
48
-                                                                ->first();
39
+                                        ->where('name', $value)
40
+                                        ->where('type', $get('type'))
41
+                                        ->first();
49
 
42
 
50
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
43
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
51
                                         $type = $get('type')->getLabel();
44
                                         $type = $get('type')->getLabel();
88
                         Forms\Components\DateTimePicker::make('start_date')
81
                         Forms\Components\DateTimePicker::make('start_date')
89
                             ->label('Start Date')
82
                             ->label('Start Date')
90
                             ->native(false)
83
                             ->native(false)
91
-                            ->minDate(static function ($context, Discount|null $record = null) {
84
+                            ->minDate(static function ($context, ?Discount $record = null) {
92
                                 if ($context === 'create') {
85
                                 if ($context === 'create') {
93
                                     return today()->addDay();
86
                                     return today()->addDay();
94
                                 }
87
                                 }
95
 
88
 
96
                                 return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date;
89
                                 return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date;
97
                             })
90
                             })
98
-                            ->maxDate(static function (callable $get, Discount|null $record = null) {
91
+                            ->maxDate(static function (callable $get, ?Discount $record = null) {
99
                                 $end_date = $get('end_date') ?? $record?->end_date;
92
                                 $end_date = $get('end_date') ?? $record?->end_date;
100
 
93
 
101
                                 return $end_date ?: today()->addYear();
94
                                 return $end_date ?: today()->addYear();
104
                             ->displayFormat('F d, Y H:i')
97
                             ->displayFormat('F d, Y H:i')
105
                             ->seconds(false)
98
                             ->seconds(false)
106
                             ->live()
99
                             ->live()
107
-                            ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false)
100
+                            ->disabled(static fn ($context, ?Discount $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false)
108
                             ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
101
                             ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
109
                         Forms\Components\DateTimePicker::make('end_date')
102
                         Forms\Components\DateTimePicker::make('end_date')
110
                             ->label('End Date')
103
                             ->label('End Date')
111
                             ->native(false)
104
                             ->native(false)
112
                             ->live()
105
                             ->live()
113
-                            ->minDate(static function (callable $get, Discount|null $record = null) {
106
+                            ->minDate(static function (callable $get, ?Discount $record = null) {
114
                                 $start_date = $get('start_date') ?? $record?->start_date;
107
                                 $start_date = $get('start_date') ?? $record?->start_date;
115
 
108
 
116
                                 return $start_date ?: today()->addDay();
109
                                 return $start_date ?: today()->addDay();
121
                             ->seconds(false),
114
                             ->seconds(false),
122
                         ToggleButton::make('enabled')
115
                         ToggleButton::make('enabled')
123
                             ->label('Default'),
116
                             ->label('Default'),
124
-                ])->columns(),
117
+                    ])->columns(),
125
             ]);
118
             ]);
126
     }
119
     }
127
 
120
 
159
                 Tables\Columns\TextColumn::make('end_date')
152
                 Tables\Columns\TextColumn::make('end_date')
160
                     ->label('End Date')
153
                     ->label('End Date')
161
                     ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A')
154
                     ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A')
162
-                    ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
155
+                    ->color(static fn (Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
163
                     ->searchable()
156
                     ->searchable()
164
                     ->sortable(),
157
                     ->sortable(),
165
             ])
158
             ])

+ 2
- 3
app/Filament/Company/Resources/Setting/DiscountResource/Pages/CreateDiscount.php Vedi File

5
 use App\Filament\Company\Resources\Setting\DiscountResource;
5
 use App\Filament\Company\Resources\Setting\DiscountResource;
6
 use App\Models\Setting\Discount;
6
 use App\Models\Setting\Discount;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
-use Filament\Actions;
9
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
10
 use Filament\Support\Exceptions\Halt;
9
 use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
23
 
22
 
24
     protected function mutateFormDataBeforeCreate(array $data): array
23
     protected function mutateFormDataBeforeCreate(array $data): array
25
     {
24
     {
26
-        $data['enabled'] = (bool)$data['enabled'];
25
+        $data['enabled'] = (bool) $data['enabled'];
27
 
26
 
28
         return $data;
27
         return $data;
29
     }
28
     }
35
     {
34
     {
36
         $user = auth()->user();
35
         $user = auth()->user();
37
 
36
 
38
-        if (!$user) {
37
+        if (! $user) {
39
             throw new Halt('No authenticated user found');
38
             throw new Halt('No authenticated user found');
40
         }
39
         }
41
 
40
 

+ 2
- 2
app/Filament/Company/Resources/Setting/DiscountResource/Pages/EditDiscount.php Vedi File

29
 
29
 
30
     protected function mutateFormDataBeforeSave(array $data): array
30
     protected function mutateFormDataBeforeSave(array $data): array
31
     {
31
     {
32
-        $data['enabled'] = (bool)$data['enabled'];
32
+        $data['enabled'] = (bool) $data['enabled'];
33
 
33
 
34
         return $data;
34
         return $data;
35
     }
35
     }
41
     {
41
     {
42
         $user = auth()->user();
42
         $user = auth()->user();
43
 
43
 
44
-        if (!$user) {
44
+        if (! $user) {
45
             throw new Halt('No authenticated user found');
45
             throw new Halt('No authenticated user found');
46
         }
46
         }
47
 
47
 

+ 9
- 15
app/Filament/Company/Resources/Setting/TaxResource.php Vedi File

2
 
2
 
3
 namespace App\Filament\Company\Resources\Setting;
3
 namespace App\Filament\Company\Resources\Setting;
4
 
4
 
5
-use App\Enums\TaxComputation;
6
-use App\Enums\TaxScope;
7
-use App\Enums\TaxType;
5
+use App\Enums\{TaxComputation, TaxScope, TaxType};
8
 use App\Filament\Company\Resources\Setting\TaxResource\Pages;
6
 use App\Filament\Company\Resources\Setting\TaxResource\Pages;
9
-use App\Filament\Company\Resources\Setting\TaxResource\RelationManagers;
10
-use App\Models\Setting\Category;
11
 use App\Models\Setting\Tax;
7
 use App\Models\Setting\Tax;
12
 use Closure;
8
 use Closure;
13
-use Filament\Forms;
14
 use Filament\Forms\Form;
9
 use Filament\Forms\Form;
15
 use Filament\Notifications\Notification;
10
 use Filament\Notifications\Notification;
16
 use Filament\Resources\Resource;
11
 use Filament\Resources\Resource;
17
-use Filament\Tables;
18
 use Filament\Tables\Table;
12
 use Filament\Tables\Table;
19
-use Illuminate\Database\Eloquent\Builder;
13
+use Filament\{Forms, Tables};
20
 use Illuminate\Database\Eloquent\Collection;
14
 use Illuminate\Database\Eloquent\Collection;
21
-use Illuminate\Database\Eloquent\SoftDeletingScope;
22
 use Wallo\FilamentSelectify\Components\ToggleButton;
15
 use Wallo\FilamentSelectify\Components\ToggleButton;
23
 
16
 
24
 class TaxResource extends Resource
17
 class TaxResource extends Resource
45
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
38
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
46
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
39
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
47
                                     $existingCategory = Tax::where('company_id', auth()->user()->currentCompany->id)
40
                                     $existingCategory = Tax::where('company_id', auth()->user()->currentCompany->id)
48
-                                                                ->where('name', $value)
49
-                                                                ->where('type', $get('type'))
50
-                                                                ->first();
41
+                                        ->where('name', $value)
42
+                                        ->where('type', $get('type'))
43
+                                        ->first();
51
 
44
 
52
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
45
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
53
                                         $type = $get('type')->getLabel();
46
                                         $type = $get('type')->getLabel();
154
                                     ->danger()
147
                                     ->danger()
155
                                     ->title('Action Denied')
148
                                     ->title('Action Denied')
156
                                     ->body(static function () use ($defaultTaxNames) {
149
                                     ->body(static function () use ($defaultTaxNames) {
157
-                                        $message = __('The following taxes are currently set as your default and cannot be deleted. Please set a different tax as your default before attempting to delete these ones.') . "<br><br>";
158
-                                        $message .= implode("<br>", array_map(static function ($name) {
159
-                                            return "&bull; " . $name;
150
+                                        $message = __('The following taxes are currently set as your default and cannot be deleted. Please set a different tax as your default before attempting to delete these ones.') . '<br><br>';
151
+                                        $message .= implode('<br>', array_map(static function ($name) {
152
+                                            return '&bull; ' . $name;
160
                                         }, $defaultTaxNames));
153
                                         }, $defaultTaxNames));
154
+
161
                                         return $message;
155
                                         return $message;
162
                                     })
156
                                     })
163
                                     ->persistent()
157
                                     ->persistent()

+ 2
- 3
app/Filament/Company/Resources/Setting/TaxResource/Pages/CreateTax.php Vedi File

5
 use App\Filament\Company\Resources\Setting\TaxResource;
5
 use App\Filament\Company\Resources\Setting\TaxResource;
6
 use App\Models\Setting\Tax;
6
 use App\Models\Setting\Tax;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
-use Filament\Actions;
9
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
10
 use Filament\Support\Exceptions\Halt;
9
 use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
23
 
22
 
24
     protected function mutateFormDataBeforeCreate(array $data): array
23
     protected function mutateFormDataBeforeCreate(array $data): array
25
     {
24
     {
26
-        $data['enabled'] = (bool)$data['enabled'];
25
+        $data['enabled'] = (bool) $data['enabled'];
27
 
26
 
28
         return $data;
27
         return $data;
29
     }
28
     }
35
     {
34
     {
36
         $user = auth()->user();
35
         $user = auth()->user();
37
 
36
 
38
-        if (!$user) {
37
+        if (! $user) {
39
             throw new Halt('No authenticated user found');
38
             throw new Halt('No authenticated user found');
40
         }
39
         }
41
 
40
 

+ 2
- 2
app/Filament/Company/Resources/Setting/TaxResource/Pages/EditTax.php Vedi File

29
 
29
 
30
     protected function mutateFormDataBeforeSave(array $data): array
30
     protected function mutateFormDataBeforeSave(array $data): array
31
     {
31
     {
32
-        $data['enabled'] = (bool)$data['enabled'];
32
+        $data['enabled'] = (bool) $data['enabled'];
33
 
33
 
34
         return $data;
34
         return $data;
35
     }
35
     }
41
     {
41
     {
42
         $user = auth()->user();
42
         $user = auth()->user();
43
 
43
 
44
-        if (!$user) {
44
+        if (! $user) {
45
             throw new Halt('No authenticated user found');
45
             throw new Halt('No authenticated user found');
46
         }
46
         }
47
 
47
 

+ 0
- 119
app/Helpers/City.php Vedi File

1
-<?php
2
-
3
-namespace App\Helpers;
4
-
5
-use ArrayAccess;
6
-
7
-class City implements ArrayAccess
8
-{
9
-    protected array $data;
10
-
11
-    public function __construct($data)
12
-    {
13
-        $this->setData($data);
14
-    }
15
-
16
-    /**
17
-     * Set the city data array.
18
-     */
19
-    public function setData($data): static
20
-    {
21
-        $this->data = $data;
22
-
23
-        return $this;
24
-    }
25
-
26
-    /**
27
-     * Get the city data array.
28
-     */
29
-    public function getData(): ?array
30
-    {
31
-        return $this->data;
32
-    }
33
-
34
-    /**
35
-     * Set a single city data array value.
36
-     */
37
-    public function set($key, $value): static
38
-    {
39
-        $this->data[$key] = $value;
40
-
41
-        return $this;
42
-    }
43
-
44
-    /**
45
-     * Get a single city data array value.
46
-     */
47
-    public function get($key): mixed
48
-    {
49
-        return $this->data[$key] ?? null;
50
-    }
51
-
52
-    /**
53
-     * Check if an offset exists in the data array.
54
-     */
55
-    public function offsetExists($offset): bool
56
-    {
57
-        return isset($this->data[$offset]);
58
-    }
59
-
60
-    /**
61
-     * Get an offset from the data array.
62
-     */
63
-    public function offsetGet($offset): mixed
64
-    {
65
-        return $this->data[$offset] ?? null;
66
-    }
67
-
68
-    /**
69
-     * Set an offset in the data array.
70
-     */
71
-    public function offsetSet($offset, $value): void
72
-    {
73
-        if ($offset === null) {
74
-            $this->data[] = $value;
75
-        } else {
76
-            $this->data[$offset] = $value;
77
-        }
78
-    }
79
-
80
-    /**
81
-     * Unset an offset in the data array.
82
-     */
83
-    public function offsetUnset($offset): void
84
-    {
85
-        unset($this->data[$offset]);
86
-    }
87
-
88
-    /**
89
-     * Get the city ID.
90
-     */
91
-    public function getId(): ?int
92
-    {
93
-        return $this->get('id');
94
-    }
95
-
96
-    /**
97
-     * Get the city name.
98
-     */
99
-    public function getName(): ?string
100
-    {
101
-        return $this->get('name');
102
-    }
103
-
104
-    /**
105
-     * Get the city latitude.
106
-     */
107
-    public function getLatitude(): ?string
108
-    {
109
-        return $this->get('latitude');
110
-    }
111
-
112
-    /**
113
-     * Get the city longitude.
114
-     */
115
-    public function getLongitude(): ?string
116
-    {
117
-        return $this->get('longitude');
118
-    }
119
-}

+ 0
- 294
app/Helpers/Country.php Vedi File

1
-<?php
2
-
3
-namespace App\Helpers;
4
-
5
-use ArrayAccess;
6
-use Illuminate\Support\Collection;
7
-
8
-class Country implements ArrayAccess
9
-{
10
-    /**
11
-     * The country data array.
12
-     */
13
-    protected array $data;
14
-
15
-    /**
16
-     * Create a new country instance.
17
-     */
18
-    public function __construct($data)
19
-    {
20
-        $this->setData($data);
21
-    }
22
-
23
-    /**
24
-     * Set the country data array.
25
-     */
26
-    public function setData($data): static
27
-    {
28
-        if (is_array($data)) {
29
-            $this->data = $data;
30
-        } elseif ($data instanceof self) {
31
-            $this->data = $data->getData();
32
-        } else {
33
-            $this->data = [];
34
-        }
35
-
36
-        return $this;
37
-    }
38
-
39
-    /**
40
-     * Get the country data array.
41
-     */
42
-    public function getData(): ?array
43
-    {
44
-        return $this->data;
45
-    }
46
-
47
-    /**
48
-     * Set a single country data array value.
49
-     */
50
-    public function set($key, $value): static
51
-    {
52
-        $this->data[$key] = $value;
53
-
54
-        return $this;
55
-    }
56
-
57
-    /**
58
-     * Get a single country data array value.
59
-     */
60
-    public function get($key): mixed
61
-    {
62
-        return $this->data[$key] ?? null;
63
-    }
64
-
65
-    /**
66
-     * Check if an offset exists in the data array.
67
-     */
68
-    public function offsetExists($offset): bool
69
-    {
70
-        return isset($this->data[$offset]);
71
-    }
72
-
73
-    /**
74
-     * Get an offset from the data array.
75
-     */
76
-    public function offsetGet($offset): mixed
77
-    {
78
-        return $this->data[$offset] ?? null;
79
-    }
80
-
81
-    /**
82
-     * Set an offset in the data array.
83
-     */
84
-    public function offsetSet($offset, $value): void
85
-    {
86
-        if ($offset === null) {
87
-            $this->data[] = $value;
88
-        } else {
89
-            $this->data[$offset] = $value;
90
-        }
91
-    }
92
-
93
-    /**
94
-     * Unset an offset in the data array.
95
-     */
96
-    public function offsetUnset($offset): void
97
-    {
98
-        unset($this->data[$offset]);
99
-    }
100
-
101
-    /**
102
-     * Get the country id.
103
-     */
104
-    public function getId(): ?int
105
-    {
106
-        return $this->get('id');
107
-    }
108
-
109
-    /**
110
-     * Get the country name.
111
-     */
112
-    public function getName(): ?string
113
-    {
114
-        return $this->get('name');
115
-    }
116
-
117
-    /**
118
-     * Get the country iso2.
119
-     */
120
-    public function getIso2(): ?string
121
-    {
122
-        return $this->get('iso2');
123
-    }
124
-
125
-    /**
126
-     * Get the country iso3.
127
-     */
128
-    public function getIso3(): ?string
129
-    {
130
-        return $this->get('iso3');
131
-    }
132
-
133
-    /**
134
-     * Get the country numeric code.
135
-     */
136
-    public function getNumericCode(): ?string
137
-    {
138
-        return $this->get('numeric_code');
139
-    }
140
-
141
-    /**
142
-     * Get the country phone code.
143
-     */
144
-    public function getPhoneCode(): ?string
145
-    {
146
-        return $this->get('phone_code');
147
-    }
148
-
149
-    /**
150
-     * Get the country capital.
151
-     */
152
-    public function getCapital(): ?string
153
-    {
154
-        return $this->get('capital');
155
-    }
156
-
157
-    /**
158
-     * Get the country currency code.
159
-     */
160
-    public function getCurrency(): ?string
161
-    {
162
-        return $this->get('currency');
163
-    }
164
-
165
-    /**
166
-     * Get the country currency name.
167
-     */
168
-    public function getCurrencyName(): ?string
169
-    {
170
-        return $this->get('currency_name');
171
-    }
172
-
173
-    /**
174
-     * Get the country currency symbol.
175
-     */
176
-    public function getCurrencySymbol(): ?string
177
-    {
178
-        return $this->get('currency_symbol');
179
-    }
180
-
181
-    /**
182
-     * Get the country tld.
183
-     */
184
-    public function getTld(): ?string
185
-    {
186
-        return $this->get('tld');
187
-    }
188
-
189
-    /**
190
-     * Get the country native name.
191
-     */
192
-    public function getNative(): ?string
193
-    {
194
-        return $this->get('native');
195
-    }
196
-
197
-    /**
198
-     * Get the country region.
199
-     */
200
-    public function getRegion(): ?string
201
-    {
202
-        return $this->get('region');
203
-    }
204
-
205
-    /**
206
-     * Get the country region id.
207
-     */
208
-    public function getRegionId(): ?int
209
-    {
210
-        return $this->get('region_id');
211
-    }
212
-
213
-    /**
214
-     * Get the country subregion.
215
-     */
216
-    public function getSubregion(): ?string
217
-    {
218
-        return $this->get('subregion');
219
-    }
220
-
221
-    /**
222
-     * Get the country subregion id.
223
-     */
224
-    public function getSubregionId(): ?int
225
-    {
226
-        return $this->get('subregion_id');
227
-    }
228
-
229
-    /**
230
-     * Get the country nationality.
231
-     */
232
-    public function getNationality(): ?string
233
-    {
234
-        return $this->get('nationality');
235
-    }
236
-
237
-    /**
238
-     * Get the country timezones.
239
-     */
240
-    public function getTimezones(): Collection
241
-    {
242
-        return collect($this->get('timezones') ?? []);
243
-    }
244
-
245
-    /**
246
-     * Get the country translations.
247
-     */
248
-    public function getTranslations(): Collection
249
-    {
250
-        return collect($this->get('translations') ?? []);
251
-    }
252
-
253
-    /**
254
-     * Get the country latitude.
255
-     */
256
-    public function getLatitude(): ?string
257
-    {
258
-        return $this->get('latitude');
259
-    }
260
-
261
-    /**
262
-     * Get the country longitude.
263
-     */
264
-    public function getLongitude(): ?string
265
-    {
266
-        return $this->get('longitude');
267
-    }
268
-
269
-    /**
270
-     * Get the country flag emoji.
271
-     */
272
-    public function getEmoji(): ?string
273
-    {
274
-        return $this->get('emoji');
275
-    }
276
-
277
-    /**
278
-     * Get the country flag unicode.
279
-     */
280
-    public function getEmojiU(): ?string
281
-    {
282
-        return $this->get('emojiU');
283
-    }
284
-
285
-    /**
286
-     * Get the country states.
287
-     */
288
-    public function getStates(): ?array
289
-    {
290
-        $countryCode = $this->getIso2();
291
-
292
-        return LocationDataLoader::getAllStates($countryCode, false)->all();
293
-    }
294
-}

+ 0
- 123
app/Helpers/LocationDataLoader.php Vedi File

1
-<?php
2
-
3
-namespace App\Helpers;
4
-
5
-use Illuminate\Support\Collection;
6
-use Illuminate\Support\Facades\Cache;
7
-use Illuminate\Support\Facades\Log;
8
-
9
-class LocationDataLoader
10
-{
11
-    protected static ?array $countries = null;
12
-    protected static ?array $states = null;
13
-    protected static ?array $cities = null;
14
-
15
-    public static function loadData(string $type): void
16
-    {
17
-        // Try to get data from cache first.
18
-        static::${$type} = Cache::remember("location_data_{$type}", now()->addMinutes(30), static function () use ($type) {
19
-            $csvPath = resource_path("data/{$type}.csv");
20
-            $data = [];
21
-
22
-            try {
23
-                $handle = fopen($csvPath, 'rb');
24
-
25
-                // Get the header of the CSV file
26
-                $header = fgetcsv($handle);
27
-
28
-                // Read each line of the CSV
29
-                while (($row = fgetcsv($handle)) !== false) {
30
-                    $data[] = array_combine($header, $row);
31
-                }
32
-
33
-                fclose($handle);
34
-                return $data;
35
-            } catch (\Exception $e) {
36
-                Log::error("CSV reading failed for {$type}: {$e->getMessage()}");
37
-                return [];
38
-            }
39
-        });
40
-    }
41
-
42
-    public static function getCountry($countryCode, $hydrate = true)
43
-    {
44
-        static::loadData('countries');
45
-        $countryCode = strtoupper($countryCode);
46
-        $country = collect(static::$countries)->firstWhere('iso2', $countryCode);
47
-
48
-        return $hydrate ? new Country($country) : $country;
49
-    }
50
-
51
-    public static function getAllCountries($hydrate = true): Collection
52
-    {
53
-        static::loadData('countries');
54
-        $countries = collect(static::$countries);
55
-
56
-        return $hydrate ? $countries->map(static fn ($country) => new Country($country)) : $countries;
57
-    }
58
-
59
-
60
-    public static function getState($countryCode, $stateCode, $hydrate = true)
61
-    {
62
-        static::loadData('states');
63
-        $countryCode = strtoupper($countryCode);
64
-        $stateCode = strtoupper($stateCode);
65
-
66
-        $state = collect(static::$states)->first(static function ($item) use ($countryCode, $stateCode) {
67
-            return $item['country_code'] === $countryCode && $item['state_code'] === $stateCode;
68
-        });
69
-
70
-        if ($state) {
71
-            return $hydrate ? new State($state) : $state;
72
-        }
73
-
74
-        return null;
75
-    }
76
-
77
-
78
-    public static function getAllStates($countryCode, $hydrate = true): Collection
79
-    {
80
-        static::loadData('states');
81
-        $countryCode = strtoupper($countryCode);
82
-        $states = collect(static::$states)->where('country_code', $countryCode);
83
-
84
-        if ($states->isEmpty()) {
85
-            return collect();
86
-        }
87
-
88
-        if ($hydrate) {
89
-            return $states->map(static fn ($state) => new State($state));
90
-        }
91
-
92
-        return $states;
93
-    }
94
-
95
-    public static function getCity($cityId, $hydrate = true)
96
-    {
97
-        static::loadData('cities');
98
-        $city = collect(static::$cities)->firstWhere('id', $cityId);
99
-
100
-        if ($city) {
101
-            return $hydrate ? new City($city) : $city;
102
-        }
103
-
104
-        return null;
105
-    }
106
-
107
-    public static function getAllCities($countryCode, $stateCode, $hydrate = true): Collection
108
-    {
109
-        static::loadData('cities');
110
-
111
-        // Filter cities based on country and state codes
112
-        $filteredCities = collect(static::$cities)
113
-            ->where('country_code', strtoupper($countryCode))
114
-            ->where('state_code', strtoupper($stateCode));
115
-
116
-        if ($filteredCities->isEmpty()) {
117
-            return collect();
118
-        }
119
-
120
-        return $hydrate ? $filteredCities->map(static fn ($city) => new City($city)) : $filteredCities;
121
-    }
122
-
123
-}

+ 0
- 131
app/Helpers/State.php Vedi File

1
-<?php
2
-
3
-namespace App\Helpers;
4
-
5
-use ArrayAccess;
6
-
7
-class State implements ArrayAccess
8
-{
9
-    /**
10
-     * The state data array.
11
-     */
12
-    protected array $data;
13
-
14
-    /**
15
-     * Create a new state instance.
16
-     */
17
-    public function __construct($data)
18
-    {
19
-        $this->setData($data);
20
-    }
21
-
22
-    /**
23
-     * Set the state data array.
24
-     */
25
-    public function setData($data): static
26
-    {
27
-        $this->data = $data;
28
-
29
-        return $this;
30
-    }
31
-
32
-    /**
33
-     * Get the state data array.
34
-     */
35
-    public function getData(): ?array
36
-    {
37
-        return $this->data;
38
-    }
39
-
40
-    /**
41
-     * Set a single state data array value.
42
-     */
43
-    public function set($key, $value): static
44
-    {
45
-        $this->data[$key] = $value;
46
-
47
-        return $this;
48
-    }
49
-
50
-    /**
51
-     * Get a single state data array value.
52
-     */
53
-    public function get($key): mixed
54
-    {
55
-        return $this->data[$key] ?? null;
56
-    }
57
-
58
-    /**
59
-     * Check if an offset exists in the data array.
60
-     */
61
-    public function offsetExists($offset): bool
62
-    {
63
-        return isset($this->data[$offset]);
64
-    }
65
-
66
-    /**
67
-     * Get an offset from the data array.
68
-     */
69
-    public function offsetGet($offset): mixed
70
-    {
71
-        return $this->data[$offset] ?? null;
72
-    }
73
-
74
-    /**
75
-     * Set an offset in the data array.
76
-     */
77
-    public function offsetSet($offset, $value): void
78
-    {
79
-        if ($offset === null) {
80
-            $this->data[] = $value;
81
-        } else {
82
-            $this->data[$offset] = $value;
83
-        }
84
-    }
85
-
86
-    /**
87
-     * Unset an offset in the data array.
88
-     */
89
-    public function offsetUnset($offset): void
90
-    {
91
-        unset($this->data[$offset]);
92
-    }
93
-
94
-    public function getId(): ?int
95
-    {
96
-        return $this->get('id');
97
-    }
98
-
99
-    public function getName(): ?string
100
-    {
101
-        return $this->get('name');
102
-    }
103
-
104
-    public function getStateCode(): ?string
105
-    {
106
-        return $this->get('state_code');
107
-    }
108
-
109
-    public function getLatitude(): ?string
110
-    {
111
-        return $this->get('latitude');
112
-    }
113
-
114
-    public function getLongitude(): ?string
115
-    {
116
-        return $this->get('longitude');
117
-    }
118
-
119
-    public function getType(): ?string
120
-    {
121
-        return $this->get('type');
122
-    }
123
-
124
-    public function getCities(): ?array
125
-    {
126
-        $countryCode = $this->get('country_code');
127
-        $stateCode = $this->get('state_code');
128
-
129
-        return LocationDataLoader::getAllCities($countryCode, $stateCode, false)->all();
130
-    }
131
-}

+ 0
- 46
app/Helpers/helpers.php Vedi File

1
-<?php
2
-
3
-use App\Helpers\LocationDataLoader;
4
-use Illuminate\Support\Collection;
5
-
6
-if (!function_exists('country')) {
7
-    function country($countryCode, $hydrate = true)
8
-    {
9
-        return LocationDataLoader::getCountry($countryCode, $hydrate);
10
-    }
11
-}
12
-
13
-if (!function_exists('countries')) {
14
-    function countries($hydrate = true): Collection
15
-    {
16
-        return LocationDataLoader::getAllCountries($hydrate);
17
-    }
18
-}
19
-
20
-if (!function_exists('state')) {
21
-    function state($stateCode, $hydrate = true)
22
-    {
23
-        return LocationDataLoader::getState($stateCode, $hydrate);
24
-    }
25
-}
26
-
27
-if (!function_exists('states')) {
28
-    function states($countryCode, $hydrate = true): Collection
29
-    {
30
-        return LocationDataLoader::getAllStates($countryCode, $hydrate);
31
-    }
32
-}
33
-
34
-if (!function_exists('city')) {
35
-    function city($cityId, $hydrate = true)
36
-    {
37
-        return LocationDataLoader::getCity($cityId, $hydrate);
38
-    }
39
-}
40
-
41
-if (!function_exists('cities')) {
42
-    function cities($countryCode, $stateCode, $hydrate = true): Collection
43
-    {
44
-        return LocationDataLoader::getAllCities($countryCode, $stateCode, $hydrate);
45
-    }
46
-}

+ 2
- 1
app/Http/Controllers/Controller.php Vedi File

8
 
8
 
9
 class Controller extends BaseController
9
 class Controller extends BaseController
10
 {
10
 {
11
-    use AuthorizesRequests, ValidatesRequests;
11
+    use AuthorizesRequests;
12
+    use ValidatesRequests;
12
 }
13
 }

+ 1
- 1
app/Http/Kernel.php Vedi File

40
 
40
 
41
         'api' => [
41
         'api' => [
42
             // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
42
             // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
43
-            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
43
+            \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
44
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
44
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
45
         ],
45
         ],
46
     ];
46
     ];

+ 1
- 1
app/Http/Middleware/ApplyCurrentCompanyScope.php Vedi File

11
     /**
11
     /**
12
      * Handle an incoming request.
12
      * Handle an incoming request.
13
      *
13
      *
14
-     * @param Closure(Request): (Response) $next
14
+     * @param  Closure(Request): (Response)  $next
15
      */
15
      */
16
     public function handle(Request $request, Closure $next): Response
16
     public function handle(Request $request, Closure $next): Response
17
     {
17
     {

+ 1
- 1
app/Interfaces/Utility/DocumentNumber.php Vedi File

6
 
6
 
7
 interface DocumentNumber
7
 interface DocumentNumber
8
 {
8
 {
9
-    public function getNextNumber(?Model $model, ?string $type, int|string $number, string $prefix, int|string $digits, bool|null $padded = true): string;
9
+    public function getNextNumber(?Model $model, ?string $type, int | string $number, string $prefix, int | string $digits, ?bool $padded = true): string;
10
 
10
 
11
     public function incrementNumber(Model $model, string $type): void;
11
     public function incrementNumber(Model $model, string $type): void;
12
 }
12
 }

+ 2
- 7
app/Listeners/ConfigureCompanyDefault.php Vedi File

2
 
2
 
3
 namespace App\Listeners;
3
 namespace App\Listeners;
4
 
4
 
5
-use App\Enums\Font;
6
-use App\Enums\MaxContentWidth;
7
-use App\Enums\ModalWidth;
8
-use App\Enums\PrimaryColor;
9
-use App\Enums\RecordsPerPage;
10
-use App\Enums\TableSortDirection;
5
+use App\Enums\{Font, MaxContentWidth, ModalWidth, PrimaryColor, RecordsPerPage, TableSortDirection};
11
 use App\Models\Company;
6
 use App\Models\Company;
12
 use Filament\Actions\MountableAction;
7
 use Filament\Actions\MountableAction;
13
 use Filament\Events\TenantSet;
8
 use Filament\Events\TenantSet;
56
             ->font($defaultFont)
51
             ->font($defaultFont)
57
             ->brandName($company->name)
52
             ->brandName($company->name)
58
             ->topNavigation($hasTopNavigation)
53
             ->topNavigation($hasTopNavigation)
59
-            ->sidebarCollapsibleOnDesktop(!$hasTopNavigation)
54
+            ->sidebarCollapsibleOnDesktop(! $hasTopNavigation)
60
             ->maxContentWidth($maxContentWidth);
55
             ->maxContentWidth($maxContentWidth);
61
     }
56
     }
62
 }
57
 }

+ 2
- 4
app/Listeners/CreateCompanyDefaults.php Vedi File

3
 namespace App\Listeners;
3
 namespace App\Listeners;
4
 
4
 
5
 use App\Events\CompanyGenerated;
5
 use App\Events\CompanyGenerated;
6
+use App\Models\Locale\Country;
6
 use App\Services\CompanyDefaultService;
7
 use App\Services\CompanyDefaultService;
7
 
8
 
8
 class CreateCompanyDefaults
9
 class CreateCompanyDefaults
23
         $company = $event->company;
24
         $company = $event->company;
24
         $countryCode = $event->country;
25
         $countryCode = $event->country;
25
 
26
 
26
-        $currencyId = country($countryCode)?->getCurrency();
27
-
28
-        $currencyData = currency($currencyId);
29
-        $currencyCode = $currencyData->getCurrency();
27
+        $currencyCode = Country::where('iso_code_2', $countryCode)->pluck('currency_code')->first();
30
 
28
 
31
         $user = $company->owner;
29
         $user = $company->owner;
32
 
30
 

+ 0
- 2
app/Listeners/SyncAssociatedModels.php Vedi File

4
 
4
 
5
 use App\Events\CompanyDefaultUpdated;
5
 use App\Events\CompanyDefaultUpdated;
6
 use App\Models\Setting\CompanyDefault;
6
 use App\Models\Setting\CompanyDefault;
7
-use Illuminate\Contracts\Queue\ShouldQueue;
8
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
7
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
-use Illuminate\Queue\InteractsWithQueue;
10
 use Illuminate\Support\Facades\DB;
8
 use Illuminate\Support\Facades\DB;
11
 
9
 
12
 class SyncAssociatedModels
10
 class SyncAssociatedModels

+ 3
- 6
app/Listeners/SyncWithCompanyDefaults.php Vedi File

2
 
2
 
3
 namespace App\Listeners;
3
 namespace App\Listeners;
4
 
4
 
5
-use App\Enums\CategoryType;
6
-use App\Enums\DiscountType;
7
-use App\Enums\TaxType;
5
+use App\Enums\{CategoryType, DiscountType, TaxType};
8
 use App\Events\CompanyDefaultEvent;
6
 use App\Events\CompanyDefaultEvent;
9
 use App\Models\Setting\CompanyDefault;
7
 use App\Models\Setting\CompanyDefault;
10
 use Illuminate\Support\Facades\DB;
8
 use Illuminate\Support\Facades\DB;
33
     {
31
     {
34
         $model = $event->model;
32
         $model = $event->model;
35
 
33
 
36
-        if (!$model->getAttribute('enabled') || !auth()->check() || !auth()->user()->currentCompany) {
34
+        if (! $model->getAttribute('enabled') || ! auth()->check() || ! auth()->user()->currentCompany) {
37
             return;
35
             return;
38
         }
36
         }
39
 
37
 
40
         $companyId = auth()->user()->currentCompany->id;
38
         $companyId = auth()->user()->currentCompany->id;
41
 
39
 
42
-        if (!$companyId) {
40
+        if (! $companyId) {
43
             return;
41
             return;
44
         }
42
         }
45
 
43
 
90
             $type === CategoryType::Expense => $default->expense_category_id = $key,
88
             $type === CategoryType::Expense => $default->expense_category_id = $key,
91
         };
89
         };
92
     }
90
     }
93
-
94
 }
91
 }

+ 6
- 5
app/Models/Banking/Account.php Vedi File

4
 
4
 
5
 use App\Casts\MoneyCast;
5
 use App\Casts\MoneyCast;
6
 use App\Models\Setting\Currency;
6
 use App\Models\Setting\Currency;
7
-use App\Traits\Blamable;
8
-use App\Traits\CompanyOwned;
7
+use App\Traits\{Blamable, CompanyOwned};
9
 use Database\Factories\Banking\AccountFactory;
8
 use Database\Factories\Banking\AccountFactory;
10
-use Illuminate\Database\Eloquent\Factories\Factory;
11
-use Illuminate\Database\Eloquent\Factories\HasFactory;
9
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
12
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
13
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
14
 use Spatie\Tags\HasTags;
12
 use Spatie\Tags\HasTags;
16
 
14
 
17
 class Account extends Model
15
 class Account extends Model
18
 {
16
 {
19
-    use Blamable, CompanyOwned, HasTags, HasFactory;
17
+    use Blamable;
18
+    use CompanyOwned;
19
+    use HasFactory;
20
+    use HasTags;
20
 
21
 
21
     protected $table = 'accounts';
22
     protected $table = 'accounts';
22
 
23
 

+ 7
- 9
app/Models/Common/Contact.php Vedi File

5
 use App\Enums\ContactType;
5
 use App\Enums\ContactType;
6
 use App\Models\Core\Department;
6
 use App\Models\Core\Department;
7
 use App\Models\Setting\Currency;
7
 use App\Models\Setting\Currency;
8
-use App\Traits\Blamable;
9
-use App\Traits\CompanyOwned;
8
+use App\Traits\{Blamable, CompanyOwned};
10
 use Database\Factories\Common\ContactFactory;
9
 use Database\Factories\Common\ContactFactory;
11
-use Illuminate\Database\Eloquent\Factories\Factory;
12
-use Illuminate\Database\Eloquent\Factories\HasFactory;
10
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
13
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Database\Eloquent\Model;
14
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
15
-use Illuminate\Database\Eloquent\Relations\HasMany;
16
-use Illuminate\Database\Eloquent\Relations\HasOne;
12
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany, HasOne};
17
 use Wallo\FilamentCompanies\FilamentCompanies;
13
 use Wallo\FilamentCompanies\FilamentCompanies;
18
 
14
 
19
 class Contact extends Model
15
 class Contact extends Model
20
 {
16
 {
21
-    use Blamable, CompanyOwned, HasFactory;
17
+    use Blamable;
18
+    use CompanyOwned;
19
+    use HasFactory;
22
 
20
 
23
     protected $table = 'contacts';
21
     protected $table = 'contacts';
24
 
22
 
30
         'address',
28
         'address',
31
         'city_id',
29
         'city_id',
32
         'zip_code',
30
         'zip_code',
33
-        'state',
31
+        'state_id',
34
         'country',
32
         'country',
35
         'timezone',
33
         'timezone',
36
         'language',
34
         'language',

+ 8
- 18
app/Models/Company.php Vedi File

6
 use App\Models\Banking\Account;
6
 use App\Models\Banking\Account;
7
 use App\Models\Common\Contact;
7
 use App\Models\Common\Contact;
8
 use App\Models\Core\Department;
8
 use App\Models\Core\Department;
9
-use App\Models\Setting\Appearance;
10
-use App\Models\Setting\Category;
11
-use App\Models\Setting\CompanyDefault;
12
-use App\Models\Setting\CompanyProfile;
13
-use App\Models\Setting\Currency;
14
-use App\Models\Setting\Discount;
15
-use App\Models\Setting\DocumentDefault;
16
-use App\Models\Setting\Tax;
9
+use App\Models\Setting\{Appearance, Category, CompanyDefault, CompanyProfile, Currency, Discount, DocumentDefault, Tax};
17
 use Filament\Models\Contracts\HasAvatar;
10
 use Filament\Models\Contracts\HasAvatar;
18
 use Illuminate\Database\Eloquent\Factories\HasFactory;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
19
-use Illuminate\Database\Eloquent\Relations\HasMany;
20
-use Illuminate\Database\Eloquent\Relations\HasOne;
12
+use Illuminate\Database\Eloquent\Relations\{HasMany, HasOne};
21
 use Wallo\FilamentCompanies\Company as FilamentCompaniesCompany;
13
 use Wallo\FilamentCompanies\Company as FilamentCompaniesCompany;
22
-use Wallo\FilamentCompanies\Events\CompanyCreated;
23
-use Wallo\FilamentCompanies\Events\CompanyDeleted;
24
-use Wallo\FilamentCompanies\Events\CompanyUpdated;
14
+use Wallo\FilamentCompanies\Events\{CompanyCreated, CompanyDeleted, CompanyUpdated};
25
 
15
 
26
 class Company extends FilamentCompaniesCompany implements HasAvatar
16
 class Company extends FilamentCompaniesCompany implements HasAvatar
27
 {
17
 {
28
     use HasFactory;
18
     use HasFactory;
29
 
19
 
30
-    public function getFilamentAvatarUrl(): string
31
-    {
32
-        return $this->owner->profile_photo_url;
33
-    }
34
-
35
     /**
20
     /**
36
      * The attributes that should be cast.
21
      * The attributes that should be cast.
37
      *
22
      *
62
         'deleted' => CompanyDeleted::class,
47
         'deleted' => CompanyDeleted::class,
63
     ];
48
     ];
64
 
49
 
50
+    public function getFilamentAvatarUrl(): string
51
+    {
52
+        return $this->owner->profile_photo_url;
53
+    }
54
+
65
     public function accounts(): HasMany
55
     public function accounts(): HasMany
66
     {
56
     {
67
         return $this->hasMany(Account::class, 'company_id');
57
         return $this->hasMany(Account::class, 'company_id');

+ 1
- 3
app/Models/ConnectedAccount.php Vedi File

4
 
4
 
5
 use Illuminate\Database\Eloquent\Concerns\HasTimestamps;
5
 use Illuminate\Database\Eloquent\Concerns\HasTimestamps;
6
 use Wallo\FilamentCompanies\ConnectedAccount as SocialiteConnectedAccount;
6
 use Wallo\FilamentCompanies\ConnectedAccount as SocialiteConnectedAccount;
7
-use Wallo\FilamentCompanies\Events\ConnectedAccountCreated;
8
-use Wallo\FilamentCompanies\Events\ConnectedAccountDeleted;
9
-use Wallo\FilamentCompanies\Events\ConnectedAccountUpdated;
7
+use Wallo\FilamentCompanies\Events\{ConnectedAccountCreated, ConnectedAccountDeleted, ConnectedAccountUpdated};
10
 
8
 
11
 class ConnectedAccount extends SocialiteConnectedAccount
9
 class ConnectedAccount extends SocialiteConnectedAccount
12
 {
10
 {

+ 6
- 8
app/Models/Core/Department.php Vedi File

3
 namespace App\Models\Core;
3
 namespace App\Models\Core;
4
 
4
 
5
 use App\Models\Common\Contact;
5
 use App\Models\Common\Contact;
6
-use App\Traits\Blamable;
7
-use App\Traits\CompanyOwned;
6
+use App\Traits\{Blamable, CompanyOwned};
8
 use Database\Factories\Core\DepartmentFactory;
7
 use Database\Factories\Core\DepartmentFactory;
9
-use Illuminate\Database\Eloquent\Factories\Factory;
10
-use Illuminate\Database\Eloquent\Factories\HasFactory;
8
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
11
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Model;
12
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
13
-use Illuminate\Database\Eloquent\Relations\HasMany;
10
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany};
14
 use Wallo\FilamentCompanies\FilamentCompanies;
11
 use Wallo\FilamentCompanies\FilamentCompanies;
15
 
12
 
16
 class Department extends Model
13
 class Department extends Model
17
 {
14
 {
18
-    use Blamable, CompanyOwned, HasFactory;
15
+    use Blamable;
16
+    use CompanyOwned;
17
+    use HasFactory;
19
 
18
 
20
     protected $table = 'departments';
19
     protected $table = 'departments';
21
 
20
 
39
         return $this->belongsTo(Contact::class, 'manager_id');
38
         return $this->belongsTo(Contact::class, 'manager_id');
40
     }
39
     }
41
 
40
 
42
-
43
     public function parent(): BelongsTo
41
     public function parent(): BelongsTo
44
     {
42
     {
45
         return $this->belongsTo(self::class, 'parent_id');
43
         return $this->belongsTo(self::class, 'parent_id');

+ 2
- 4
app/Models/Employeeship.php Vedi File

4
 
4
 
5
 use App\Models\Common\Contact;
5
 use App\Models\Common\Contact;
6
 use App\Models\Core\Department;
6
 use App\Models\Core\Department;
7
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
8
-use Illuminate\Database\Eloquent\Relations\HasMany;
9
-use Wallo\FilamentCompanies\Employeeship as FilamentCompaniesEmployeeship;
10
-use Wallo\FilamentCompanies\FilamentCompanies;
7
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany};
8
+use Wallo\FilamentCompanies\{Employeeship as FilamentCompaniesEmployeeship, FilamentCompanies};
11
 
9
 
12
 class Employeeship extends FilamentCompaniesEmployeeship
10
 class Employeeship extends FilamentCompaniesEmployeeship
13
 {
11
 {

+ 61
- 0
app/Models/Locale/City.php Vedi File

1
+<?php
2
+
3
+namespace App\Models\Locale;
4
+
5
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
+use Illuminate\Support\Collection;
7
+use Squire\Model;
8
+
9
+/**
10
+ * @property int $id
11
+ * @property string $name
12
+ * @property int $state_id
13
+ * @property string $state_code
14
+ * @property int $country_id
15
+ * @property string $country_code
16
+ * @property float $latitude
17
+ * @property float $longitude
18
+ */
19
+class City extends Model
20
+{
21
+    public static array $schema = [
22
+        'id' => 'integer',
23
+        'name' => 'string',
24
+        'state_id' => 'integer',
25
+        'state_code' => 'string',
26
+        'country_id' => 'integer',
27
+        'country_code' => 'string',
28
+        'latitude' => 'float',
29
+        'longitude' => 'float',
30
+    ];
31
+
32
+    public static function getCitiesByCountryAndState(?string $countryCode, ?string $stateId): Collection
33
+    {
34
+        if ($stateId === null || $countryCode === null) {
35
+            return collect();
36
+        }
37
+
38
+        return self::query()->where('country_code', $countryCode)
39
+            ->where('state_id', $stateId)
40
+            ->get();
41
+    }
42
+
43
+    public static function getCityOptions(?string $countryCode = null, ?string $stateId = null): Collection
44
+    {
45
+        if ($countryCode === null || $stateId === null) {
46
+            return collect();
47
+        }
48
+
49
+        return self::getCitiesByCountryAndState($countryCode, $stateId)->pluck('name', 'id');
50
+    }
51
+
52
+    public function state(): BelongsTo
53
+    {
54
+        return $this->belongsTo(State::class, 'state_id', 'id');
55
+    }
56
+
57
+    public function country(): BelongsTo
58
+    {
59
+        return $this->belongsTo(Country::class, 'country_id', 'id');
60
+    }
61
+}

+ 78
- 0
app/Models/Locale/Country.php Vedi File

1
+<?php
2
+
3
+namespace App\Models\Locale;
4
+
5
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany};
6
+use Illuminate\Support\Collection;
7
+use Squire\Model;
8
+
9
+/**
10
+ * @property int $id
11
+ * @property string $name
12
+ * @property string $iso_code_3
13
+ * @property string $iso_code_2
14
+ * @property int $numeric_code
15
+ * @property string $phone_code
16
+ * @property string $capital
17
+ * @property string $currency_code
18
+ * @property string $native_name
19
+ * @property string $nationality
20
+ * @property float $latitude
21
+ * @property float $longitude
22
+ * @property string $flag
23
+ */
24
+class Country extends Model
25
+{
26
+    public static array $schema = [
27
+        'id' => 'integer',
28
+        'name' => 'string',
29
+        'iso_code_3' => 'string',
30
+        'iso_code_2' => 'string',
31
+        'numeric_code' => 'integer',
32
+        'phone_code' => 'string',
33
+        'capital' => 'string',
34
+        'currency_code' => 'string',
35
+        'native_name' => 'string',
36
+        'nationality' => 'string',
37
+        'latitude' => 'float',
38
+        'longitude' => 'float',
39
+        'flag' => 'string',
40
+    ];
41
+
42
+    public function currency(): BelongsTo
43
+    {
44
+        return $this->belongsTo(Currency::class, 'currency_code', 'code');
45
+    }
46
+
47
+    public function states(): HasMany
48
+    {
49
+        return $this->hasMany(State::class, 'country_id', 'id');
50
+    }
51
+
52
+    public function cities(): HasMany
53
+    {
54
+        return $this->hasMany(City::class, 'country_id', 'id');
55
+    }
56
+
57
+    public function timezones(): HasMany
58
+    {
59
+        return $this->hasMany(Timezone::class, 'country_id', 'id');
60
+    }
61
+
62
+    public static function findByIsoCode2(string $code): ?self
63
+    {
64
+        return self::where('iso_code_2', $code)->first();
65
+    }
66
+
67
+    public static function getAllCountryCodes(): Collection
68
+    {
69
+        return self::all()->pluck('iso_code_2');
70
+    }
71
+
72
+    public static function getAvailableCountryOptions(): array
73
+    {
74
+        return self::all()->mapWithKeys(static function ($country): array {
75
+            return [$country->iso_code_2 => $country->name . ' ' . $country->flag];
76
+        })->toArray();
77
+    }
78
+}

+ 172
- 0
app/Models/Locale/Currency.php Vedi File

1
+<?php
2
+
3
+namespace App\Models\Locale;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+use Illuminate\Database\Eloquent\Relations\HasMany;
7
+use Illuminate\Support\Collection;
8
+use Illuminate\Support\Facades\Cache;
9
+
10
+class Currency extends Model
11
+{
12
+    protected $table = 'currencies';
13
+
14
+    protected $guarded = [];
15
+
16
+    protected $casts = [
17
+        'code' => 'string',
18
+        'name' => 'string',
19
+        'symbol' => 'string',
20
+        'precision' => 'int',
21
+        'decimal_mark' => 'string',
22
+        'thousands_separator' => 'string',
23
+        'symbol_first' => 'bool',
24
+        'subunit' => 'int',
25
+    ];
26
+
27
+    public function countries(): HasMany
28
+    {
29
+        return $this->hasMany(Country::class, 'currency_code', 'code');
30
+    }
31
+
32
+    public static function allCached(): Collection
33
+    {
34
+        return collect(Cache::get('currencies') ?? []);
35
+    }
36
+
37
+    // To find a currency by its code
38
+    public static function findByCode(string $code): ?self
39
+    {
40
+        return self::allCached()->firstWhere('code', $code);
41
+    }
42
+
43
+    // To find a currency by its name
44
+    public static function findByName(string $name): ?self
45
+    {
46
+        return self::allCached()->firstWhere('name', $name);
47
+    }
48
+
49
+    // Get currency name by its code
50
+    public static function getNameByCode(string $code): ?string
51
+    {
52
+        $currency = self::findByCode($code);
53
+
54
+        return $currency->name ?? null;
55
+    }
56
+
57
+    // Get currency code by its name
58
+    public static function getCodeByName(string $name): ?string
59
+    {
60
+        $currency = self::findByName($name);
61
+
62
+        return $currency->code ?? null;
63
+    }
64
+
65
+    // Get currency symbol by its code
66
+    public static function getSymbolByCode(string $code): ?string
67
+    {
68
+        $currency = self::findByCode($code);
69
+
70
+        return $currency->symbol ?? null;
71
+    }
72
+
73
+    // Get currency symbol by its name
74
+    public static function getSymbolByName(string $name): ?string
75
+    {
76
+        $currency = self::findByName($name);
77
+
78
+        return $currency->symbol ?? null;
79
+    }
80
+
81
+    // Get currency precision by its code
82
+    public static function getPrecisionByCode(string $code): ?int
83
+    {
84
+        $currency = self::findByCode($code);
85
+
86
+        return $currency->precision ?? null;
87
+    }
88
+
89
+    // Get currency precision by its name
90
+    public static function getPrecisionByName(string $name): ?int
91
+    {
92
+        $currency = self::findByName($name);
93
+
94
+        return $currency->precision ?? null;
95
+    }
96
+
97
+    // Get currency decimal mark by its code
98
+    public static function getDecimalMarkByCode(string $code): ?string
99
+    {
100
+        $currency = self::findByCode($code);
101
+
102
+        return $currency->decimal_mark ?? null;
103
+    }
104
+
105
+    // Get currency decimal mark by its name
106
+    public static function getDecimalMarkByName(string $name): ?string
107
+    {
108
+        $currency = self::findByName($name);
109
+
110
+        return $currency->decimal_mark ?? null;
111
+    }
112
+
113
+    // Get currency thousands separator by its code
114
+    public static function getThousandsSeparatorByCode(string $code): ?string
115
+    {
116
+        $currency = self::findByCode($code);
117
+
118
+        return $currency->thousands_separator ?? null;
119
+    }
120
+
121
+    // Get currency thousands separator by its name
122
+    public static function getThousandsSeparatorByName(string $name): ?string
123
+    {
124
+        $currency = self::findByName($name);
125
+
126
+        return $currency->thousands_separator ?? null;
127
+    }
128
+
129
+    // Get currency symbol first by its code
130
+    public static function getSymbolFirstByCode(string $code): ?bool
131
+    {
132
+        $currency = self::findByCode($code);
133
+
134
+        return $currency->symbol_first ?? null;
135
+    }
136
+
137
+    // Get currency symbol first by its name
138
+    public static function getSymbolFirstByName(string $name): ?bool
139
+    {
140
+        $currency = self::findByName($name);
141
+
142
+        return $currency->symbol_first ?? null;
143
+    }
144
+
145
+    // Get currency subunit by its code
146
+    public static function getSubunitByCode(string $code): ?int
147
+    {
148
+        $currency = self::findByCode($code);
149
+
150
+        return $currency->subunit ?? null;
151
+    }
152
+
153
+    // Get currency subunit by its name
154
+    public static function getSubunitByName(string $name): ?int
155
+    {
156
+        $currency = self::findByName($name);
157
+
158
+        return $currency->subunit ?? null;
159
+    }
160
+
161
+    // Get all currency codes
162
+    public static function getAllCodes(): Collection
163
+    {
164
+        return self::allCached()->pluck('code');
165
+    }
166
+
167
+    // Get all currency names
168
+    public static function getAllNames(): Collection
169
+    {
170
+        return self::allCached()->pluck('name');
171
+    }
172
+}

+ 50
- 0
app/Models/Locale/State.php Vedi File

1
+<?php
2
+
3
+namespace App\Models\Locale;
4
+
5
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany};
6
+use Illuminate\Support\Collection;
7
+use Squire\Model;
8
+
9
+/**
10
+ * @property int $id
11
+ * @property string $name
12
+ * @property int $country_id
13
+ * @property string $country_code
14
+ * @property string $country_name
15
+ * @property string $state_code
16
+ * @property float $latitude
17
+ * @property float $longitude
18
+ */
19
+class State extends Model
20
+{
21
+    public static array $schema = [
22
+        'id' => 'integer',
23
+        'name' => 'string',
24
+        'country_id' => 'integer',
25
+        'country_code' => 'string',
26
+        'country_name' => 'string',
27
+        'state_code' => 'string',
28
+        'latitude' => 'float',
29
+        'longitude' => 'float',
30
+    ];
31
+
32
+    public static function getStateOptions(?string $code = null): Collection
33
+    {
34
+        if ($code === null) {
35
+            return collect();
36
+        }
37
+
38
+        return self::where('country_code', $code)->get()->pluck('name', 'id');
39
+    }
40
+
41
+    public function country(): BelongsTo
42
+    {
43
+        return $this->belongsTo(Country::class, 'country_id', 'id');
44
+    }
45
+
46
+    public function cities(): HasMany
47
+    {
48
+        return $this->hasMany(City::class, 'state_id', 'id');
49
+    }
50
+}

+ 68
- 0
app/Models/Locale/Timezone.php Vedi File

1
+<?php
2
+
3
+namespace App\Models\Locale;
4
+
5
+use DateTime;
6
+use DateTimeZone;
7
+use Exception;
8
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
+use Squire\Model;
10
+
11
+/**
12
+ * @property int $id
13
+ * @property int $country_id
14
+ * @property string $country_code
15
+ * @property string $name
16
+ * @property int $gmt_offset
17
+ * @property string $gmt_offset_name
18
+ * @property string $abbreviation
19
+ * @property string $tz_name
20
+ */
21
+class Timezone extends Model
22
+{
23
+    public static array $schema = [
24
+        'id' => 'integer',
25
+        'country_id' => 'integer',
26
+        'country_code' => 'string',
27
+        'name' => 'string',
28
+        'gmt_offset' => 'integer',
29
+        'gmt_offset_name' => 'string',
30
+        'abbreviation' => 'string',
31
+        'tz_name' => 'string',
32
+    ];
33
+
34
+    public function country(): BelongsTo
35
+    {
36
+        return $this->belongsTo(Country::class, 'country_id');
37
+    }
38
+
39
+    public static function getTimezoneOptions(?string $countryCode = null): array
40
+    {
41
+        if (empty($countryCode)) {
42
+            return [];
43
+        }
44
+
45
+        $timezones = self::where('country_code', $countryCode)->get();
46
+
47
+        if ($timezones->isEmpty()) {
48
+            return [];
49
+        }
50
+
51
+        return $timezones
52
+            ->mapWithKeys(static function ($timezone) {
53
+                $localTime = self::getLocalTime($timezone->name); // Adjust this as per your column name
54
+                $cityName = str_replace('_', ' ', last(explode('/', $timezone->name))); // Adjust this as per your column name
55
+
56
+                return [$timezone->name => "{$cityName} ({$timezone->abbreviation}) {$localTime}"];
57
+            })
58
+            ->toArray();
59
+    }
60
+
61
+    /**
62
+     * @throws Exception
63
+     */
64
+    public static function getLocalTime(string $timezone): string
65
+    {
66
+        return (new DateTime('now', new DateTimeZone($timezone)))->format('g:i A');
67
+    }
68
+}

+ 6
- 11
app/Models/Setting/Appearance.php Vedi File

2
 
2
 
3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
-use App\Enums\Font;
6
-use App\Enums\MaxContentWidth;
7
-use App\Enums\ModalWidth;
8
-use App\Enums\PrimaryColor;
9
-use App\Enums\RecordsPerPage;
10
-use App\Enums\TableSortDirection;
11
-use App\Traits\Blamable;
12
-use App\Traits\CompanyOwned;
5
+use App\Enums\{Font, MaxContentWidth, ModalWidth, PrimaryColor, RecordsPerPage, TableSortDirection};
6
+use App\Traits\{Blamable, CompanyOwned};
13
 use Database\Factories\Setting\AppearanceFactory;
7
 use Database\Factories\Setting\AppearanceFactory;
14
-use Illuminate\Database\Eloquent\Factories\Factory;
15
-use Illuminate\Database\Eloquent\Factories\HasFactory;
8
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
16
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Model;
17
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
10
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
18
 use Wallo\FilamentCompanies\FilamentCompanies;
11
 use Wallo\FilamentCompanies\FilamentCompanies;
19
 
12
 
20
 class Appearance extends Model
13
 class Appearance extends Model
21
 {
14
 {
22
-    use Blamable, CompanyOwned, HasFactory;
15
+    use Blamable;
16
+    use CompanyOwned;
17
+    use HasFactory;
23
 
18
 
24
     protected $table = 'appearances';
19
     protected $table = 'appearances';
25
 
20
 

+ 7
- 8
app/Models/Setting/Category.php Vedi File

3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
 use App\Enums\CategoryType;
5
 use App\Enums\CategoryType;
6
-use App\Traits\Blamable;
7
-use App\Traits\CompanyOwned;
8
-use App\Traits\SyncsWithCompanyDefaults;
6
+use App\Traits\{Blamable, CompanyOwned, SyncsWithCompanyDefaults};
9
 use Database\Factories\Setting\CategoryFactory;
7
 use Database\Factories\Setting\CategoryFactory;
10
-use Illuminate\Database\Eloquent\Factories\Factory;
11
-use Illuminate\Database\Eloquent\Factories\HasFactory;
8
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
12
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Model;
13
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
14
-use Illuminate\Database\Eloquent\Relations\HasOne;
10
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasOne};
15
 use Wallo\FilamentCompanies\FilamentCompanies;
11
 use Wallo\FilamentCompanies\FilamentCompanies;
16
 
12
 
17
 class Category extends Model
13
 class Category extends Model
18
 {
14
 {
19
-    use Blamable, CompanyOwned, SyncsWithCompanyDefaults, HasFactory;
15
+    use Blamable;
16
+    use CompanyOwned;
17
+    use HasFactory;
18
+    use SyncsWithCompanyDefaults;
20
 
19
 
21
     protected $table = 'categories';
20
     protected $table = 'categories';
22
 
21
 

+ 6
- 14
app/Models/Setting/CompanyDefault.php Vedi File

2
 
2
 
3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
-use App\Enums\CategoryType;
6
-use App\Enums\DiscountType;
7
-use App\Enums\Font;
8
-use App\Enums\MaxContentWidth;
9
-use App\Enums\ModalWidth;
10
-use App\Enums\PrimaryColor;
11
-use App\Enums\RecordsPerPage;
12
-use App\Enums\TableSortDirection;
13
-use App\Enums\TaxType;
5
+use App\Enums\{CategoryType, DiscountType, TaxType};
14
 use App\Models\Banking\Account;
6
 use App\Models\Banking\Account;
15
-use App\Traits\Blamable;
16
-use App\Traits\CompanyOwned;
7
+use App\Traits\{Blamable, CompanyOwned};
17
 use Database\Factories\Setting\CompanyDefaultFactory;
8
 use Database\Factories\Setting\CompanyDefaultFactory;
18
-use Illuminate\Database\Eloquent\Factories\Factory;
19
-use Illuminate\Database\Eloquent\Factories\HasFactory;
9
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
20
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
21
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
22
 use Wallo\FilamentCompanies\FilamentCompanies;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
23
 
13
 
24
 class CompanyDefault extends Model
14
 class CompanyDefault extends Model
25
 {
15
 {
26
-    use Blamable, CompanyOwned, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
27
 
19
 
28
     protected $table = 'company_defaults';
20
     protected $table = 'company_defaults';
29
 
21
 

+ 8
- 98
app/Models/Setting/CompanyProfile.php Vedi File

3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
 use App\Enums\EntityType;
5
 use App\Enums\EntityType;
6
-use App\Traits\Blamable;
7
-use App\Traits\CompanyOwned;
6
+use App\Models\Locale\Country;
7
+use App\Traits\{Blamable, CompanyOwned};
8
 use Database\Factories\Setting\CompanyProfileFactory;
8
 use Database\Factories\Setting\CompanyProfileFactory;
9
-use DateTime;
10
-use DateTimeZone;
11
-use Exception;
12
-use Illuminate\Database\Eloquent\Factories\Factory;
13
-use Illuminate\Database\Eloquent\Factories\HasFactory;
9
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
14
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
15
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
16
-use Squire\Models\Timezone;
17
 use Wallo\FilamentCompanies\FilamentCompanies;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
18
 
13
 
19
 class CompanyProfile extends Model
14
 class CompanyProfile extends Model
20
 {
15
 {
21
-    use Blamable, CompanyOwned, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
22
 
19
 
23
     protected $table = 'company_profiles';
20
     protected $table = 'company_profiles';
24
 
21
 
28
         'address',
25
         'address',
29
         'city_id',
26
         'city_id',
30
         'zip_code',
27
         'zip_code',
31
-        'state',
28
+        'state_id',
32
         'country',
29
         'country',
33
         'timezone',
30
         'timezone',
34
         'phone_number',
31
         'phone_number',
62
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
59
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
63
     }
60
     }
64
 
61
 
65
-
66
     public function getCountryName(): string
62
     public function getCountryName(): string
67
     {
63
     {
68
-        return country($this->country)?->getName();
69
-    }
70
-
71
-    public static function getAvailableCountryCodes(): array
72
-    {
73
-        return countries()->pluck('iso2')->toArray();
74
-    }
75
-
76
-    public static function getAvailableCountryOptions(): array
77
-    {
78
-        $countries = countries();
79
-
80
-        return $countries->mapWithKeys(static function ($country): array {
81
-            return [$country['iso2'] => $country['name'] . ' ' . $country['emoji']];
82
-        })->toArray();
83
-    }
84
-
85
-    public static function getAvailableCountryNames(): array
86
-    {
87
-        return countries()->pluck('name')->toArray();
88
-    }
89
-
90
-    public static function getAvailableCountryEmojis(): array
91
-    {
92
-        return countries()->pluck('emoji')->toArray();
93
-    }
94
-
95
-    public static function getStateOptions(?string $countryCode = null): array
96
-    {
97
-        if (empty($countryCode)) {
98
-            return [];
99
-        }
100
-
101
-        $states = states($countryCode);
102
-
103
-        return $states->mapWithKeys(static function ($state): array {
104
-            return [$state['state_code'] => $state['name']];
105
-        })->toArray();
106
-    }
107
-
108
-    public static function getCityOptions(?string $countryCode = null, ?string $stateCode = null): array
109
-    {
110
-        if (empty($countryCode) || empty($stateCode)) {
111
-            return [];
112
-        }
113
-
114
-        $cities = cities($countryCode, $stateCode);
115
-
116
-        return $cities->mapWithKeys(static function ($city): array {
117
-            return [$city['id'] => $city['name']];
118
-        })->toArray();
119
-    }
120
-
121
-    public static function getTimezoneOptions(?string $countryCode = null): array
122
-    {
123
-        if (empty($countryCode)) {
124
-            return [];
125
-        }
126
-
127
-        // convert countryCode to lowercase
128
-        $countryCode = strtolower($countryCode);
129
-
130
-        $timezones = Timezone::where('country_id', $countryCode)->get();
131
-
132
-        if (!$timezones->isEmpty()) {
133
-            return $timezones->mapWithKeys(static function ($timezone): array {
134
-                $localTime = self::getLocalTime($timezone->code);
135
-                $parts = explode('/', $timezone->code);
136
-                $cityName = str_replace('_', ' ', end($parts));
137
-                $offsetInSeconds = $timezone->getOffset(now());
138
-                $hours = floor($offsetInSeconds / 3600);
139
-                $minutes = floor(($offsetInSeconds / 60) % 60);
140
-                $gmtOffsetName = sprintf("UTC%+d:%02d", $hours, $minutes);
141
-
142
-                return [$timezone->code => $cityName . ' (' . $gmtOffsetName . ') ' . $localTime];
143
-            })->toArray();
144
-        }
145
-
146
-        return [];
147
-    }
148
-
149
-    /**
150
-     * @throws Exception
151
-     */
152
-    public static function getLocalTime(string $timezone): string
153
-    {
154
-        return (new DateTime('now', new DateTimeZone($timezone)))->format('g:i A');
64
+        return Country::findByIsoCode2($this->country)?->name ?? '';
155
     }
65
     }
156
 
66
 
157
     protected static function newFactory(): Factory
67
     protected static function newFactory(): Factory

+ 9
- 11
app/Models/Setting/Currency.php Vedi File

5
 use Akaunting\Money\Currency as ISOCurrencies;
5
 use Akaunting\Money\Currency as ISOCurrencies;
6
 use App\Casts\RateCast;
6
 use App\Casts\RateCast;
7
 use App\Models\Banking\Account;
7
 use App\Models\Banking\Account;
8
-use App\Traits\Blamable;
9
-use App\Traits\CompanyOwned;
10
-use App\Traits\SyncsWithCompanyDefaults;
8
+use App\Traits\{Blamable, CompanyOwned, SyncsWithCompanyDefaults};
11
 use Database\Factories\Setting\CurrencyFactory;
9
 use Database\Factories\Setting\CurrencyFactory;
12
-use Illuminate\Database\Eloquent\Factories\Factory;
13
-use Illuminate\Database\Eloquent\Factories\HasFactory;
10
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
14
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Database\Eloquent\Model;
15
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
16
-use Illuminate\Database\Eloquent\Relations\HasMany;
17
-use Illuminate\Database\Eloquent\Relations\HasOne;
12
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany, HasOne};
18
 use Illuminate\Support\Facades\DB;
13
 use Illuminate\Support\Facades\DB;
19
 use Wallo\FilamentCompanies\FilamentCompanies;
14
 use Wallo\FilamentCompanies\FilamentCompanies;
20
 
15
 
21
 class Currency extends Model
16
 class Currency extends Model
22
 {
17
 {
23
-    use Blamable, CompanyOwned, SyncsWithCompanyDefaults, HasFactory;
18
+    use Blamable;
19
+    use CompanyOwned;
20
+    use HasFactory;
21
+    use SyncsWithCompanyDefaults;
24
 
22
 
25
     protected $table = 'currencies';
23
     protected $table = 'currencies';
26
 
24
 
89
         return ISOCurrencies::getCurrencies();
87
         return ISOCurrencies::getCurrencies();
90
     }
88
     }
91
 
89
 
92
-    public static function getDefaultCurrencyCode(): string|null
90
+    public static function getDefaultCurrencyCode(): ?string
93
     {
91
     {
94
         $defaultCurrency = static::query()
92
         $defaultCurrency = static::query()
95
             ->where('enabled', true)
93
             ->where('enabled', true)
116
 
114
 
117
         $scale = 10 ** $precision;
115
         $scale = 10 ** $precision;
118
 
116
 
119
-        $cleanBalance = (int)filter_var($balance, FILTER_SANITIZE_NUMBER_INT);
117
+        $cleanBalance = (int) filter_var($balance, FILTER_SANITIZE_NUMBER_INT);
120
 
118
 
121
         return round(($cleanBalance * $newRate * $scale) / ($oldRate * $scale));
119
         return round(($cleanBalance * $newRate * $scale) / ($oldRate * $scale));
122
     }
120
     }

+ 8
- 11
app/Models/Setting/Discount.php Vedi File

3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
 use App\Casts\RateCast;
5
 use App\Casts\RateCast;
6
-use App\Enums\DiscountComputation;
7
-use App\Enums\DiscountScope;
8
-use App\Enums\DiscountType;
9
-use App\Traits\Blamable;
10
-use App\Traits\CompanyOwned;
11
-use App\Traits\SyncsWithCompanyDefaults;
6
+use App\Enums\{DiscountComputation, DiscountScope, DiscountType};
7
+use App\Traits\{Blamable, CompanyOwned, SyncsWithCompanyDefaults};
12
 use Database\Factories\Setting\DiscountFactory;
8
 use Database\Factories\Setting\DiscountFactory;
13
-use Illuminate\Database\Eloquent\Factories\Factory;
14
-use Illuminate\Database\Eloquent\Factories\HasFactory;
9
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
15
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
16
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
17
-use Illuminate\Database\Eloquent\Relations\HasOne;
11
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasOne};
18
 use Wallo\FilamentCompanies\FilamentCompanies;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
19
 
13
 
20
 class Discount extends Model
14
 class Discount extends Model
21
 {
15
 {
22
-    use Blamable, CompanyOwned, SyncsWithCompanyDefaults, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
19
+    use SyncsWithCompanyDefaults;
23
 
20
 
24
     protected $table = 'discounts';
21
     protected $table = 'discounts';
25
 
22
 

+ 11
- 21
app/Models/Setting/DocumentDefault.php Vedi File

3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
 use App\Casts\TrimLeadingZeroCast;
5
 use App\Casts\TrimLeadingZeroCast;
6
-use App\Enums\DocumentAmountColumn;
7
-use App\Enums\DocumentItemColumn;
8
-use App\Enums\DocumentPriceColumn;
9
-use App\Enums\DocumentType;
10
-use App\Enums\DocumentUnitColumn;
11
-use App\Enums\Font;
12
-use App\Enums\PaymentTerms;
13
-use App\Enums\Template;
14
-use App\Traits\Blamable;
15
-use App\Traits\CompanyOwned;
6
+use App\Enums\{DocumentType, Font, PaymentTerms, Template};
7
+use App\Traits\{Blamable, CompanyOwned};
16
 use Database\Factories\Setting\DocumentDefaultFactory;
8
 use Database\Factories\Setting\DocumentDefaultFactory;
17
-use Illuminate\Database\Eloquent\Builder;
18
 use Illuminate\Database\Eloquent\Casts\AsArrayObject;
9
 use Illuminate\Database\Eloquent\Casts\AsArrayObject;
19
-use Illuminate\Database\Eloquent\Factories\Factory;
20
-use Illuminate\Database\Eloquent\Factories\HasFactory;
21
-use Illuminate\Database\Eloquent\Model;
10
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
22
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
12
+use Illuminate\Database\Eloquent\{Builder, Model};
23
 use Wallo\FilamentCompanies\FilamentCompanies;
13
 use Wallo\FilamentCompanies\FilamentCompanies;
24
 
14
 
25
 class DocumentDefault extends Model
15
 class DocumentDefault extends Model
26
 {
16
 {
27
-    use Blamable, CompanyOwned, HasFactory;
17
+    use Blamable;
18
+    use CompanyOwned;
19
+    use HasFactory;
28
 
20
 
29
     protected $table = 'document_defaults';
21
     protected $table = 'document_defaults';
30
 
22
 
79
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
71
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
80
     }
72
     }
81
 
73
 
82
-    public function scopeType(Builder $query, string|DocumentType $type): Builder
74
+    public function scopeType(Builder $query, string | DocumentType $type): Builder
83
     {
75
     {
84
         return $query->where($this->qualifyColumn('type'), $type);
76
         return $query->where($this->qualifyColumn('type'), $type);
85
     }
77
     }
99
         return array_combine(range(1, 20), range(1, 20));
91
         return array_combine(range(1, 20), range(1, 20));
100
     }
92
     }
101
 
93
 
102
-    public static function getNumberNext(?bool $padded = null, ?bool $format = null, ?string $prefix = null, int|string|null $digits = null, int|string|null $next = null, ?string $type = null): string
94
+    public static function getNumberNext(?bool $padded = null, ?bool $format = null, ?string $prefix = null, int | string | null $digits = null, int | string | null $next = null, ?string $type = null): string
103
     {
95
     {
104
         $initializeAttributes = new static;
96
         $initializeAttributes = new static;
105
 
97
 
116
         return $number_next;
108
         return $number_next;
117
     }
109
     }
118
 
110
 
119
-    public function initializeAttributes(?string $prefix, int|string|null $digits, int|string|null $next, ?string $type): array
111
+    public function initializeAttributes(?string $prefix, int | string | null $digits, int | string | null $next, ?string $type): array
120
     {
112
     {
121
         $number_prefix = $prefix ?? $this->getAttributeFromArray('number_prefix');
113
         $number_prefix = $prefix ?? $this->getAttributeFromArray('number_prefix');
122
         $number_digits = $digits ?? $this->getAttributeFromArray('number_digits');
114
         $number_digits = $digits ?? $this->getAttributeFromArray('number_digits');
133
         return [$number_prefix, $number_digits, $number_next];
125
         return [$number_prefix, $number_digits, $number_next];
134
     }
126
     }
135
 
127
 
136
-
137
-
138
     public static function getAttributesByType(?string $type): array
128
     public static function getAttributesByType(?string $type): array
139
     {
129
     {
140
         $model = new static;
130
         $model = new static;
147
      * Get the next number with padding for dynamic display purposes.
137
      * Get the next number with padding for dynamic display purposes.
148
      * Even if number_next is a string, it will be cast to an integer.
138
      * Even if number_next is a string, it will be cast to an integer.
149
      */
139
      */
150
-    public static function getPaddedNumberNext(int|string|null $number_next, int|string|null $number_digits): string
140
+    public static function getPaddedNumberNext(int | string | null $number_next, int | string | null $number_digits): string
151
     {
141
     {
152
         return str_pad($number_next, $number_digits, '0', STR_PAD_LEFT);
142
         return str_pad($number_next, $number_digits, '0', STR_PAD_LEFT);
153
     }
143
     }

+ 8
- 11
app/Models/Setting/Tax.php Vedi File

3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
 use App\Casts\RateCast;
5
 use App\Casts\RateCast;
6
-use App\Enums\TaxComputation;
7
-use App\Enums\TaxScope;
8
-use App\Enums\TaxType;
9
-use App\Traits\Blamable;
10
-use App\Traits\CompanyOwned;
11
-use App\Traits\SyncsWithCompanyDefaults;
6
+use App\Enums\{TaxComputation, TaxScope, TaxType};
7
+use App\Traits\{Blamable, CompanyOwned, SyncsWithCompanyDefaults};
12
 use Database\Factories\Setting\TaxFactory;
8
 use Database\Factories\Setting\TaxFactory;
13
-use Illuminate\Database\Eloquent\Factories\Factory;
14
-use Illuminate\Database\Eloquent\Factories\HasFactory;
9
+use Illuminate\Database\Eloquent\Factories\{Factory, HasFactory};
15
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
16
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
17
-use Illuminate\Database\Eloquent\Relations\HasOne;
11
+use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasOne};
18
 use Wallo\FilamentCompanies\FilamentCompanies;
12
 use Wallo\FilamentCompanies\FilamentCompanies;
19
 
13
 
20
 class Tax extends Model
14
 class Tax extends Model
21
 {
15
 {
22
-    use Blamable, CompanyOwned, SyncsWithCompanyDefaults, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
19
+    use SyncsWithCompanyDefaults;
23
 
20
 
24
     protected $table = 'taxes';
21
     protected $table = 'taxes';
25
 
22
 

+ 35
- 41
app/Models/User.php Vedi File

3
 namespace App\Models;
3
 namespace App\Models;
4
 
4
 
5
 use App\Models\Core\Department;
5
 use App\Models\Core\Department;
6
-use Filament\Models\Contracts\FilamentUser;
7
-use Filament\Models\Contracts\HasAvatar;
8
-use Filament\Models\Contracts\HasDefaultTenant;
9
-use Filament\Models\Contracts\HasTenants;
6
+use Filament\Models\Contracts\{FilamentUser, HasAvatar, HasDefaultTenant, HasTenants};
10
 use Filament\Panel;
7
 use Filament\Panel;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
8
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Model;
15
 use Illuminate\Notifications\Notifiable;
12
 use Illuminate\Notifications\Notifiable;
16
 use Illuminate\Support\Collection;
13
 use Illuminate\Support\Collection;
17
 use Laravel\Sanctum\HasApiTokens;
14
 use Laravel\Sanctum\HasApiTokens;
18
-use Wallo\FilamentCompanies\HasCompanies;
19
-use Wallo\FilamentCompanies\HasConnectedAccounts;
20
-use Wallo\FilamentCompanies\HasProfilePhoto;
21
-use Wallo\FilamentCompanies\SetsProfilePhotoFromUrl;
15
+use Wallo\FilamentCompanies\{HasCompanies, HasConnectedAccounts, HasProfilePhoto, SetsProfilePhotoFromUrl};
22
 
16
 
23
 /** @property Company $currentCompany */
17
 /** @property Company $currentCompany */
24
-class User extends Authenticatable implements FilamentUser, HasAvatar, HasTenants, HasDefaultTenant
18
+class User extends Authenticatable implements FilamentUser, HasAvatar, HasDefaultTenant, HasTenants
25
 {
19
 {
26
     use HasApiTokens;
20
     use HasApiTokens;
27
-    use HasFactory;
28
-    use HasProfilePhoto;
29
     use HasCompanies;
21
     use HasCompanies;
30
     use HasConnectedAccounts;
22
     use HasConnectedAccounts;
23
+    use HasFactory;
24
+    use HasProfilePhoto;
31
     use Notifiable;
25
     use Notifiable;
32
     use SetsProfilePhotoFromUrl;
26
     use SetsProfilePhotoFromUrl;
33
 
27
 
34
-    public function canAccessPanel(Panel $panel): bool
35
-    {
36
-        return true;
37
-    }
38
-
39
-    public function getTenants(Panel $panel): array|Collection
40
-    {
41
-        return $this->allCompanies();
42
-    }
43
-
44
-    public function canAccessTenant(Model $tenant): bool
45
-    {
46
-        return $this->belongsToCompany($tenant);
47
-    }
48
-
49
-    public function getDefaultTenant(Panel $panel): ?Model
50
-    {
51
-        return $this->currentCompany;
52
-    }
53
-
54
-    public function getFilamentAvatarUrl(): string
55
-    {
56
-        return $this->profile_photo_url;
57
-    }
58
-
59
-    public function managers(): HasMany
60
-    {
61
-        return $this->hasMany(Department::class, 'manager_id');
62
-    }
63
-
64
     /**
28
     /**
65
      * The attributes that are mass assignable.
29
      * The attributes that are mass assignable.
66
      *
30
      *
97
     protected $appends = [
61
     protected $appends = [
98
         'profile_photo_url',
62
         'profile_photo_url',
99
     ];
63
     ];
64
+
65
+    public function canAccessPanel(Panel $panel): bool
66
+    {
67
+        return true;
68
+    }
69
+
70
+    public function getTenants(Panel $panel): array | Collection
71
+    {
72
+        return $this->allCompanies();
73
+    }
74
+
75
+    public function canAccessTenant(Model $tenant): bool
76
+    {
77
+        return $this->belongsToCompany($tenant);
78
+    }
79
+
80
+    public function getDefaultTenant(Panel $panel): ?Model
81
+    {
82
+        return $this->currentCompany;
83
+    }
84
+
85
+    public function getFilamentAvatarUrl(): string
86
+    {
87
+        return $this->profile_photo_url;
88
+    }
89
+
90
+    public function managers(): HasMany
91
+    {
92
+        return $this->hasMany(Department::class, 'manager_id');
93
+    }
100
 }
94
 }

+ 1
- 2
app/Policies/CompanyPolicy.php Vedi File

2
 
2
 
3
 namespace App\Policies;
3
 namespace App\Policies;
4
 
4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7
 use Illuminate\Auth\Access\HandlesAuthorization;
6
 use Illuminate\Auth\Access\HandlesAuthorization;
8
 
7
 
9
 class CompanyPolicy
8
 class CompanyPolicy

+ 1
- 2
app/Policies/ConnectedAccountPolicy.php Vedi File

2
 
2
 
3
 namespace App\Policies;
3
 namespace App\Policies;
4
 
4
 
5
-use App\Models\ConnectedAccount;
6
-use App\Models\User;
5
+use App\Models\{ConnectedAccount, User};
7
 use Illuminate\Auth\Access\HandlesAuthorization;
6
 use Illuminate\Auth\Access\HandlesAuthorization;
8
 
7
 
9
 class ConnectedAccountPolicy
8
 class ConnectedAccountPolicy

+ 6
- 11
app/Providers/AppServiceProvider.php Vedi File

4
 
4
 
5
 use App\Enums\PrimaryColor;
5
 use App\Enums\PrimaryColor;
6
 use Closure;
6
 use Closure;
7
-use Filament\Forms\Components\Field;
8
-use Filament\Forms\Components\Select;
9
-use Filament\Forms\Components\TextInput;
10
-use Filament\Forms\Get;
7
+use Filament\Forms\Components\{Select, TextInput};
11
 use Filament\Notifications\Livewire\Notifications;
8
 use Filament\Notifications\Livewire\Notifications;
12
 use Filament\Support\Enums\Alignment;
9
 use Filament\Support\Enums\Alignment;
13
 use Filament\Support\RawJs;
10
 use Filament\Support\RawJs;
14
-use Filament\Tables\Actions\Action;
15
 use Filament\Tables\Columns\TextColumn;
11
 use Filament\Tables\Columns\TextColumn;
16
-use Illuminate\Support\ServiceProvider;
17
-use Illuminate\Support\Str;
12
+use Illuminate\Support\{ServiceProvider, Str};
18
 
13
 
19
 class AppServiceProvider extends ServiceProvider
14
 class AppServiceProvider extends ServiceProvider
20
 {
15
 {
33
     {
28
     {
34
         Notifications::alignment(Alignment::Center);
29
         Notifications::alignment(Alignment::Center);
35
 
30
 
36
-        TextColumn::macro('currency', function (string|Closure|null $currency = null, bool|null $convert = null): static {
31
+        TextColumn::macro('currency', function (string | Closure | null $currency = null, ?bool $convert = null): static {
37
             $this->formatStateUsing(static function (TextColumn $column, $state) use ($currency, $convert): ?string {
32
             $this->formatStateUsing(static function (TextColumn $column, $state) use ($currency, $convert): ?string {
38
                 if (blank($state)) {
33
                 if (blank($state)) {
39
                     return null;
34
                     return null;
48
             return $this;
43
             return $this;
49
         });
44
         });
50
 
45
 
51
-        TextInput::macro('currency', function (string|Closure|null $currency = null): static {
46
+        TextInput::macro('currency', function (string | Closure | null $currency = null): static {
52
             $this->extraAttributes(['wire:key' => Str::random()])
47
             $this->extraAttributes(['wire:key' => Str::random()])
53
                 ->prefix(static function (TextInput $component) use ($currency) {
48
                 ->prefix(static function (TextInput $component) use ($currency) {
54
                     $currency = $component->evaluate($currency);
49
                     $currency = $component->evaluate($currency);
66
                     $thousands_separator = currency($currency)->getThousandsSeparator();
61
                     $thousands_separator = currency($currency)->getThousandsSeparator();
67
                     $precision = currency($currency)->getPrecision();
62
                     $precision = currency($currency)->getPrecision();
68
 
63
 
69
-                    $jsCode = "\$money(\$input, '" . $decimal_mark . "', '" . $thousands_separator . "', " . $precision . ");";
64
+                    $jsCode = "\$money(\$input, '" . $decimal_mark . "', '" . $thousands_separator . "', " . $precision . ');';
70
 
65
 
71
                     return RawJs::make($jsCode);
66
                     return RawJs::make($jsCode);
72
                 });
67
                 });
74
             return $this;
69
             return $this;
75
         });
70
         });
76
 
71
 
77
-        Select::macro('color', function (string|Closure|null $color = null): static {
72
+        Select::macro('color', function (string | Closure | null $color = null): static {
78
             $this->options(
73
             $this->options(
79
                 collect(PrimaryColor::caseValues())
74
                 collect(PrimaryColor::caseValues())
80
                     ->mapWithKeys(static function ($color) {
75
                     ->mapWithKeys(static function ($color) {

+ 2
- 7
app/Providers/EventServiceProvider.php Vedi File

2
 
2
 
3
 namespace App\Providers;
3
 namespace App\Providers;
4
 
4
 
5
-use App\Events\CompanyDefaultEvent;
6
-use App\Events\CompanyDefaultUpdated;
7
-use App\Events\CompanyGenerated;
8
-use App\Listeners\ConfigureCompanyDefault;
9
-use App\Listeners\CreateCompanyDefaults;
10
-use App\Listeners\SyncAssociatedModels;
11
-use App\Listeners\SyncWithCompanyDefaults;
5
+use App\Events\{CompanyDefaultEvent, CompanyDefaultUpdated, CompanyGenerated};
6
+use App\Listeners\{ConfigureCompanyDefault, CreateCompanyDefaults, SyncAssociatedModels, SyncWithCompanyDefaults};
12
 use Filament\Events\TenantSet;
7
 use Filament\Events\TenantSet;
13
 use Illuminate\Auth\Events\Registered;
8
 use Illuminate\Auth\Events\Registered;
14
 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
9
 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;

+ 32
- 0
app/Providers/Faker/FakerServiceProvider.php Vedi File

1
+<?php
2
+
3
+namespace App\Providers\Faker;
4
+
5
+use App\Faker\{PhoneNumber, State};
6
+use Faker\{Factory, Generator};
7
+use Illuminate\Support\ServiceProvider;
8
+
9
+class FakerServiceProvider extends ServiceProvider
10
+{
11
+    /**
12
+     * Register services.
13
+     */
14
+    public function register(): void
15
+    {
16
+        $this->app->singleton(Generator::class, static function () {
17
+            $faker = Factory::create();
18
+            $faker->addProvider(new PhoneNumber($faker));
19
+            $faker->addProvider(new State($faker));
20
+
21
+            return $faker;
22
+        });
23
+    }
24
+
25
+    /**
26
+     * Bootstrap services.
27
+     */
28
+    public function boot(): void
29
+    {
30
+        //
31
+    }
32
+}

+ 4
- 11
app/Providers/Filament/AdminPanelProvider.php Vedi File

2
 
2
 
3
 namespace App\Providers\Filament;
3
 namespace App\Providers\Filament;
4
 
4
 
5
-use Filament\Http\Middleware\Authenticate;
6
-use Filament\Http\Middleware\DisableBladeIconComponents;
7
-use Filament\Http\Middleware\DispatchServingFilamentEvent;
8
-use Filament\Pages;
9
-use Filament\Panel;
10
-use Filament\PanelProvider;
5
+use Filament\Http\Middleware\{Authenticate, DisableBladeIconComponents, DispatchServingFilamentEvent};
11
 use Filament\Support\Colors\Color;
6
 use Filament\Support\Colors\Color;
12
-use Filament\Widgets;
13
-use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
14
-use Illuminate\Cookie\Middleware\EncryptCookies;
7
+use Filament\{Pages, Panel, PanelProvider, Widgets};
8
+use Illuminate\Cookie\Middleware\{AddQueuedCookiesToResponse, EncryptCookies};
15
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
9
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
16
 use Illuminate\Routing\Middleware\SubstituteBindings;
10
 use Illuminate\Routing\Middleware\SubstituteBindings;
17
-use Illuminate\Session\Middleware\AuthenticateSession;
18
-use Illuminate\Session\Middleware\StartSession;
11
+use Illuminate\Session\Middleware\{AuthenticateSession, StartSession};
19
 use Illuminate\View\Middleware\ShareErrorsFromSession;
12
 use Illuminate\View\Middleware\ShareErrorsFromSession;
20
 
13
 
21
 class AdminPanelProvider extends PanelProvider
14
 class AdminPanelProvider extends PanelProvider

+ 6
- 14
app/Providers/Filament/UserPanelProvider.php Vedi File

3
 namespace App\Providers\Filament;
3
 namespace App\Providers\Filament;
4
 
4
 
5
 use App\Http\Middleware\Authenticate;
5
 use App\Http\Middleware\Authenticate;
6
-use Filament\Http\Middleware\DisableBladeIconComponents;
7
-use Filament\Http\Middleware\DispatchServingFilamentEvent;
8
-use Filament\Navigation\MenuItem;
9
-use Filament\Navigation\NavigationItem;
10
-use Filament\Pages;
11
-use Filament\Panel;
12
-use Filament\PanelProvider;
6
+use Filament\Http\Middleware\{DisableBladeIconComponents, DispatchServingFilamentEvent};
7
+use Filament\Navigation\{MenuItem, NavigationItem};
13
 use Filament\Support\Colors\Color;
8
 use Filament\Support\Colors\Color;
14
-use Filament\Widgets;
15
-use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
16
-use Illuminate\Cookie\Middleware\EncryptCookies;
9
+use Filament\{Pages, Panel, PanelProvider, Widgets};
10
+use Illuminate\Cookie\Middleware\{AddQueuedCookiesToResponse, EncryptCookies};
17
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
11
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
18
 use Illuminate\Routing\Middleware\SubstituteBindings;
12
 use Illuminate\Routing\Middleware\SubstituteBindings;
19
-use Illuminate\Session\Middleware\AuthenticateSession;
20
-use Illuminate\Session\Middleware\StartSession;
13
+use Illuminate\Session\Middleware\{AuthenticateSession, StartSession};
21
 use Illuminate\Support\Facades\Auth;
14
 use Illuminate\Support\Facades\Auth;
22
 use Illuminate\View\Middleware\ShareErrorsFromSession;
15
 use Illuminate\View\Middleware\ShareErrorsFromSession;
23
-use Wallo\FilamentCompanies\Pages\User\PersonalAccessTokens;
24
-use Wallo\FilamentCompanies\Pages\User\Profile;
16
+use Wallo\FilamentCompanies\Pages\User\{PersonalAccessTokens, Profile};
25
 
17
 
26
 class UserPanelProvider extends PanelProvider
18
 class UserPanelProvider extends PanelProvider
27
 {
19
 {

+ 11
- 35
app/Providers/FilamentCompaniesServiceProvider.php Vedi File

2
 
2
 
3
 namespace App\Providers;
3
 namespace App\Providers;
4
 
4
 
5
-use App\Actions\FilamentCompanies\AddCompanyEmployee;
6
-use App\Actions\FilamentCompanies\CreateConnectedAccount;
7
-use App\Actions\FilamentCompanies\CreateNewUser;
8
-use App\Actions\FilamentCompanies\CreateUserFromProvider;
9
-use App\Actions\FilamentCompanies\DeleteCompany;
10
-use App\Actions\FilamentCompanies\DeleteUser;
11
-use App\Actions\FilamentCompanies\HandleInvalidState;
12
-use App\Actions\FilamentCompanies\InviteCompanyEmployee;
13
-use App\Actions\FilamentCompanies\RemoveCompanyEmployee;
14
-use App\Actions\FilamentCompanies\ResolveSocialiteUser;
15
-use App\Actions\FilamentCompanies\SetUserPassword;
16
-use App\Actions\FilamentCompanies\UpdateCompanyName;
17
-use App\Actions\FilamentCompanies\UpdateConnectedAccount;
18
-use App\Actions\FilamentCompanies\UpdateUserPassword;
19
-use App\Actions\FilamentCompanies\UpdateUserProfileInformation;
5
+use App\Actions\FilamentCompanies\{AddCompanyEmployee, CreateConnectedAccount, CreateNewUser, CreateUserFromProvider, DeleteCompany, DeleteUser, HandleInvalidState, InviteCompanyEmployee, RemoveCompanyEmployee, ResolveSocialiteUser, SetUserPassword, UpdateCompanyName, UpdateConnectedAccount, UpdateUserPassword, UpdateUserProfileInformation};
20
 use App\Filament\Company\Pages\CreateCompany;
6
 use App\Filament\Company\Pages\CreateCompany;
21
-use Illuminate\Support\Facades\Auth;
22
-use Wallo\FilamentCompanies\Actions\GenerateRedirectForProvider;
23
-use Wallo\FilamentCompanies\Pages\Auth\Login;
24
-use Wallo\FilamentCompanies\Pages\Company\CompanySettings;
25
-use Filament\Navigation\MenuItem;
26
-use Wallo\FilamentCompanies\Pages\Auth\Register;
27
 use App\Models\Company;
7
 use App\Models\Company;
28
-use Filament\Http\Middleware\Authenticate;
29
-use Filament\Http\Middleware\DisableBladeIconComponents;
30
-use Filament\Http\Middleware\DispatchServingFilamentEvent;
31
-use Filament\Pages;
32
-use Filament\Panel;
33
-use Filament\PanelProvider;
8
+use Filament\Http\Middleware\{Authenticate, DisableBladeIconComponents, DispatchServingFilamentEvent};
9
+use Filament\Navigation\MenuItem;
34
 use Filament\Support\Colors\Color;
10
 use Filament\Support\Colors\Color;
35
-use Filament\Widgets;
36
-use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
37
-use Illuminate\Cookie\Middleware\EncryptCookies;
11
+use Filament\{Pages, Panel, PanelProvider, Widgets};
12
+use Illuminate\Cookie\Middleware\{AddQueuedCookiesToResponse, EncryptCookies};
38
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
13
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
39
 use Illuminate\Routing\Middleware\SubstituteBindings;
14
 use Illuminate\Routing\Middleware\SubstituteBindings;
40
-use Illuminate\Session\Middleware\AuthenticateSession;
41
-use Illuminate\Session\Middleware\StartSession;
15
+use Illuminate\Session\Middleware\{AuthenticateSession, StartSession};
16
+use Illuminate\Support\Facades\Auth;
42
 use Illuminate\View\Middleware\ShareErrorsFromSession;
17
 use Illuminate\View\Middleware\ShareErrorsFromSession;
43
-use Wallo\FilamentCompanies\FilamentCompanies;
18
+use Wallo\FilamentCompanies\Actions\GenerateRedirectForProvider;
19
+use Wallo\FilamentCompanies\Pages\Auth\{Login, Register};
20
+use Wallo\FilamentCompanies\Pages\Company\CompanySettings;
44
 use Wallo\FilamentCompanies\Pages\User\Profile;
21
 use Wallo\FilamentCompanies\Pages\User\Profile;
45
-use Wallo\FilamentCompanies\Providers;
46
-use Wallo\FilamentCompanies\Socialite;
22
+use Wallo\FilamentCompanies\{FilamentCompanies, Providers, Socialite};
47
 
23
 
48
 class FilamentCompaniesServiceProvider extends PanelProvider
24
 class FilamentCompaniesServiceProvider extends PanelProvider
49
 {
25
 {

+ 1
- 2
app/Providers/RouteServiceProvider.php Vedi File

5
 use Illuminate\Cache\RateLimiting\Limit;
5
 use Illuminate\Cache\RateLimiting\Limit;
6
 use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
6
 use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
7
 use Illuminate\Http\Request;
7
 use Illuminate\Http\Request;
8
-use Illuminate\Support\Facades\RateLimiter;
9
-use Illuminate\Support\Facades\Route;
8
+use Illuminate\Support\Facades\{RateLimiter, Route};
10
 
9
 
11
 class RouteServiceProvider extends ServiceProvider
10
 class RouteServiceProvider extends ServiceProvider
12
 {
11
 {

+ 23
- 0
app/Providers/SquireServiceProvider.php Vedi File

1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use App\Models\Locale\{City, Country, State, Timezone};
6
+use Illuminate\Support\ServiceProvider;
7
+use Squire\Repository;
8
+
9
+class SquireServiceProvider extends ServiceProvider
10
+{
11
+    public function register(): void
12
+    {
13
+
14
+    }
15
+
16
+    public function boot(): void
17
+    {
18
+        Repository::registerSource(Country::class, 'en', resource_path('data/countries.csv'));
19
+        Repository::registerSource(State::class, 'en', resource_path('data/states.csv'));
20
+        Repository::registerSource(City::class, 'en', resource_path('data/cities.csv'));
21
+        Repository::registerSource(Timezone::class, 'en', resource_path('data/timezones.csv'));
22
+    }
23
+}

+ 1
- 3
app/Scopes/CurrentCompanyScope.php Vedi File

2
 
2
 
3
 namespace App\Scopes;
3
 namespace App\Scopes;
4
 
4
 
5
-use Illuminate\Database\Eloquent\Builder;
6
-use Illuminate\Database\Eloquent\Model;
7
-use Illuminate\Database\Eloquent\Scope;
5
+use Illuminate\Database\Eloquent\{Builder, Model, Scope};
8
 use Illuminate\Support\Facades\Auth;
6
 use Illuminate\Support\Facades\Auth;
9
 
7
 
10
 class CurrentCompanyScope implements Scope
8
 class CurrentCompanyScope implements Scope

+ 4
- 12
app/Services/CompanyDefaultService.php Vedi File

3
 namespace App\Services;
3
 namespace App\Services;
4
 
4
 
5
 use App\Enums\CategoryType;
5
 use App\Enums\CategoryType;
6
-use App\Models\Company;
7
-use App\Models\Setting\Appearance;
8
-use App\Models\Setting\Category;
9
-use App\Models\Setting\CompanyDefault;
10
-use App\Models\Setting\Currency;
11
-use App\Models\Setting\Discount;
12
-use App\Models\Setting\DocumentDefault;
13
-use App\Models\Setting\Tax;
14
-use App\Models\User;
6
+use App\Models\Setting\{Appearance, Category, CompanyDefault, Currency, Discount, DocumentDefault, Tax};
7
+use App\Models\{Company, User};
15
 use Illuminate\Support\Facades\DB;
8
 use Illuminate\Support\Facades\DB;
16
 
9
 
17
 class CompanyDefaultService
10
 class CompanyDefaultService
64
 
57
 
65
         foreach ($shuffledCategories as $category) {
58
         foreach ($shuffledCategories as $category) {
66
             $enabled = false;
59
             $enabled = false;
67
-            if (!$incomeEnabled && $category['type'] === CategoryType::Income->value) {
60
+            if (! $incomeEnabled && $category['type'] === CategoryType::Income->value) {
68
                 $enabled = $incomeEnabled = true;
61
                 $enabled = $incomeEnabled = true;
69
-            } elseif (!$expenseEnabled && $category['type'] === CategoryType::Expense->value) {
62
+            } elseif (! $expenseEnabled && $category['type'] === CategoryType::Expense->value) {
70
                 $enabled = $expenseEnabled = true;
63
                 $enabled = $expenseEnabled = true;
71
             }
64
             }
72
 
65
 
160
             'updated_by' => $user->id,
153
             'updated_by' => $user->id,
161
         ]);
154
         ]);
162
     }
155
     }
163
-
164
 }
156
 }

+ 0
- 0
app/Services/CurrencyService.php Vedi File


Dato che sono stati cambiati molti file in questo diff, alcuni di essi non verranno mostrati

Loading…
Annulla
Salva