Bläddra i källkod

add pint and refactor

3.x
wallo 2 år sedan
förälder
incheckning
8fd4f2778e
100 ändrade filer med 1147 tillägg och 1404 borttagningar
  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 Visa fil

@@ -2,16 +2,13 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 6
 use Closure;
8 7
 use Illuminate\Auth\Access\AuthorizationException;
9 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 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 12
 use Wallo\FilamentCompanies\FilamentCompanies;
16 13
 use Wallo\FilamentCompanies\Rules\Role;
17 14
 
@@ -22,7 +19,7 @@ class AddCompanyEmployee implements AddsCompanyEmployees
22 19
      *
23 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 24
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
28 25
 
@@ -33,7 +30,8 @@ class AddCompanyEmployee implements AddsCompanyEmployees
33 30
         AddingCompanyEmployee::dispatch($company, $newCompanyEmployee);
34 31
 
35 32
         $company->users()->attach(
36
-            $newCompanyEmployee, ['role' => $role]
33
+            $newCompanyEmployee,
34
+            ['role' => $role]
37 35
         );
38 36
 
39 37
         CompanyEmployeeAdded::dispatch($company, $newCompanyEmployee);

+ 2
- 4
app/Actions/FilamentCompanies/CreateCompany.php Visa fil

@@ -2,11 +2,9 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 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 8
 use Wallo\FilamentCompanies\Contracts\CreatesCompanies;
11 9
 use Wallo\FilamentCompanies\Events\AddingCompany;
12 10
 use Wallo\FilamentCompanies\FilamentCompanies;

+ 1
- 2
app/Actions/FilamentCompanies/CreateConnectedAccount.php Visa fil

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

+ 3
- 6
app/Actions/FilamentCompanies/CreateNewUser.php Visa fil

@@ -2,11 +2,8 @@
2 2
 
3 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 7
 use Wallo\FilamentCompanies\Contracts\CreatesNewUsers;
11 8
 use Wallo\FilamentCompanies\Features;
12 9
 
@@ -44,7 +41,7 @@ class CreateNewUser implements CreatesNewUsers
44 41
     {
45 42
         $user->ownedCompanies()->save(Company::forceCreate([
46 43
             'user_id' => $user->id,
47
-            'name' => explode(' ', $user->name, 2)[0]."'s Company",
44
+            'name' => explode(' ', $user->name, 2)[0] . "'s Company",
48 45
             'personal_company' => true,
49 46
         ]));
50 47
     }

+ 4
- 7
app/Actions/FilamentCompanies/CreateUserFromProvider.php Visa fil

@@ -2,14 +2,11 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 6
 use Illuminate\Support\Facades\DB;
8 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 11
 class CreateUserFromProvider implements CreatesUserFromProvider
15 12
 {
@@ -65,7 +62,7 @@ class CreateUserFromProvider implements CreatesUserFromProvider
65 62
     {
66 63
         $user->ownedCompanies()->save(Company::forceCreate([
67 64
             'user_id' => $user->id,
68
-            'name' => explode(' ', $user->name, 2)[0]."'s Company",
65
+            'name' => explode(' ', $user->name, 2)[0] . "'s Company",
69 66
             'personal_company' => true,
70 67
         ]));
71 68
     }

+ 2
- 4
app/Actions/FilamentCompanies/DeleteUser.php Visa fil

@@ -2,11 +2,9 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 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 9
 class DeleteUser implements DeletesUsers
12 10
 {

+ 1
- 1
app/Actions/FilamentCompanies/HandleInvalidState.php Visa fil

@@ -11,7 +11,7 @@ class HandleInvalidState implements HandlesInvalidState
11 11
     /**
12 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 16
         if ($callback) {
17 17
             return $callback($exception);

+ 3
- 6
app/Actions/FilamentCompanies/InviteCompanyEmployee.php Visa fil

@@ -2,14 +2,11 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 6
 use Closure;
8 7
 use Illuminate\Auth\Access\AuthorizationException;
9 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 10
 use Illuminate\Validation\Rule;
14 11
 use Wallo\FilamentCompanies\Contracts\InvitesCompanyEmployees;
15 12
 use Wallo\FilamentCompanies\Events\InvitingCompanyEmployee;
@@ -24,7 +21,7 @@ class InviteCompanyEmployee implements InvitesCompanyEmployees
24 21
      *
25 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 26
         Gate::forUser($user)->authorize('addCompanyEmployee', $company);
30 27
 

+ 1
- 2
app/Actions/FilamentCompanies/RemoveCompanyEmployee.php Visa fil

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

+ 1
- 1
app/Actions/FilamentCompanies/ResolveSocialiteUser.php Visa fil

@@ -17,7 +17,7 @@ class ResolveSocialiteUser implements ResolvesSocialiteUsers
17 17
         $user = Socialite::driver($provider)->user();
18 18
 
19 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 23
         return $user;

+ 1
- 2
app/Actions/FilamentCompanies/SetUserPassword.php Visa fil

@@ -3,8 +3,7 @@
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5 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 7
 use Wallo\FilamentCompanies\Contracts\SetsUserPasswords;
9 8
 
10 9
 class SetUserPassword implements SetsUserPasswords

+ 2
- 4
app/Actions/FilamentCompanies/UpdateCompanyName.php Visa fil

@@ -2,11 +2,9 @@
2 2
 
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5
-use App\Models\Company;
6
-use App\Models\User;
5
+use App\Models\{Company, User};
7 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 8
 use Wallo\FilamentCompanies\Contracts\UpdatesCompanyNames;
11 9
 
12 10
 class UpdateCompanyName implements UpdatesCompanyNames

+ 1
- 2
app/Actions/FilamentCompanies/UpdateUserPassword.php Visa fil

@@ -3,8 +3,7 @@
3 3
 namespace App\Actions\FilamentCompanies;
4 4
 
5 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 7
 use Wallo\FilamentCompanies\Contracts\UpdatesUserPasswords;
9 8
 
10 9
 class UpdateUserPassword implements UpdatesUserPasswords

+ 1
- 1
app/Actions/OptionAction/CreateCurrency.php Visa fil

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

+ 1
- 1
app/Casts/MoneyCast.php Visa fil

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

+ 36
- 0
app/Console/Commands/CacheData.php Visa fil

@@ -0,0 +1,36 @@
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 Visa fil

@@ -0,0 +1,35 @@
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 Visa fil

@@ -0,0 +1,71 @@
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 Visa fil

@@ -0,0 +1,71 @@
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 Visa fil

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

+ 3
- 5
app/Enums/ContactType.php Visa fil

@@ -3,11 +3,9 @@
3 3
 namespace App\Enums;
4 4
 
5 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 10
     case Employee = 'employee';
13 11
     case Customer = 'customer';
@@ -19,7 +17,7 @@ enum ContactType: string implements HasLabel, HasColor, HasIcon
19 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 22
         return match ($this) {
25 23
             self::Employee => Color::Green,

+ 3
- 5
app/Enums/DiscountType.php Visa fil

@@ -2,11 +2,9 @@
2 2
 
3 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 9
     case Sales = 'sales';
12 10
     case Purchase = 'purchase';
@@ -17,7 +15,7 @@ enum DiscountType: string implements HasLabel, HasColor, HasIcon
17 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 20
         return match ($this) {
23 21
             self::Sales => 'success',

+ 2
- 3
app/Enums/DocumentType.php Visa fil

@@ -2,10 +2,9 @@
2 2
 
3 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 9
     case Invoice = 'invoice';
11 10
     case Bill = 'bill';

+ 0
- 1
app/Enums/EntityType.php Visa fil

@@ -26,5 +26,4 @@ enum EntityType: string implements HasLabel
26 26
             self::Nonprofit => 'Nonprofit',
27 27
         };
28 28
     }
29
-
30 29
 }

+ 1
- 1
app/Enums/PrimaryColor.php Visa fil

@@ -37,7 +37,7 @@ enum PrimaryColor: string implements HasColor
37 37
 
38 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 42
         return match ($this) {
43 43
             self::Slate => Color::Slate,

+ 5
- 1
app/Enums/RecordsPerPage.php Visa fil

@@ -17,13 +17,17 @@ enum RecordsPerPage: int implements HasLabel
17 17
     public const DEFAULT = self::Ten->value;
18 18
 
19 19
     public const FIVE = self::Five->value;
20
+
20 21
     public const TEN = self::Ten->value;
22
+
21 23
     public const TWENTY_FIVE = self::TwentyFive->value;
24
+
22 25
     public const FIFTY = self::Fifty->value;
26
+
23 27
     public const ONE_HUNDRED = self::OneHundred->value;
24 28
 
25 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 Visa fil

@@ -2,11 +2,9 @@
2 2
 
3 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 9
     case Sales = 'sales';
12 10
     case Purchase = 'purchase';
@@ -14,10 +12,10 @@ enum TaxType: string implements HasLabel, HasColor, HasIcon
14 12
 
15 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 20
         return match ($this) {
23 21
             self::Sales => 'success',

+ 3
- 1
app/Events/CompanyDefaultEvent.php Visa fil

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

+ 4
- 5
app/Events/CompanyDefaultUpdated.php Visa fil

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

+ 5
- 3
app/Events/CompanyGenerated.php Visa fil

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

+ 0
- 1
app/Events/UpdateCompanyDefault.php Visa fil

@@ -4,5 +4,4 @@ namespace App\Events;
4 4
 
5 5
 class UpdateCompanyDefault
6 6
 {
7
-
8 7
 }

+ 25
- 0
app/Faker/PhoneNumber.php Visa fil

@@ -0,0 +1,25 @@
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 Visa fil

@@ -0,0 +1,16 @@
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 Visa fil

@@ -4,13 +4,11 @@ namespace App\Filament\Company\Pages;
4 4
 
5 5
 use App\Enums\EntityType;
6 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 9
 use Filament\Forms\Form;
11 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 12
 use Wallo\FilamentCompanies\Events\AddingCompany;
15 13
 use Wallo\FilamentCompanies\FilamentCompanies;
16 14
 use Wallo\FilamentCompanies\Pages\Company\CreateCompany as FilamentCreateCompany;
@@ -39,7 +37,7 @@ class CreateCompany extends FilamentCreateCompany
39 37
                     ->label('Country')
40 38
                     ->native(false)
41 39
                     ->searchable()
42
-                    ->options(CompanyProfile::getAvailableCountryOptions())
40
+                    ->options(Country::getAvailableCountryOptions())
43 41
                     ->required(),
44 42
             ])
45 43
             ->model(FilamentCompanies::companyModel())

+ 17
- 23
app/Filament/Company/Pages/Setting/Appearance.php Visa fil

@@ -2,18 +2,10 @@
2 2
 
3 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 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 9
 use Filament\Forms\Form;
18 10
 use Filament\Notifications\Notification;
19 11
 use Filament\Pages\Concerns\InteractsWithFormActions;
@@ -22,8 +14,8 @@ use Filament\Support\Exceptions\Halt;
22 14
 use Illuminate\Auth\Access\AuthorizationException;
23 15
 use Illuminate\Database\Eloquent\Model;
24 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 19
 use function Filament\authorize;
28 20
 
29 21
 /**
@@ -146,13 +138,14 @@ class Appearance extends Page
146 138
                     ->allowHtml()
147 139
                     ->selectablePlaceholder(false)
148 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 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 150
                 Select::make('font')
158 151
                     ->label('Font')
@@ -160,10 +153,11 @@ class Appearance extends Page
160 153
                     ->selectablePlaceholder(false)
161 154
                     ->rule('required')
162 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 162
             ])->columns();
169 163
     }

+ 3
- 5
app/Filament/Company/Pages/Setting/CompanyDefault.php Visa fil

@@ -4,11 +4,8 @@ namespace App\Filament\Company\Pages\Setting;
4 4
 
5 5
 use App\Events\CompanyDefaultUpdated;
6 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 9
 use Filament\Forms\Form;
13 10
 use Filament\Notifications\Notification;
14 11
 use Filament\Pages\Concerns\InteractsWithFormActions;
@@ -17,6 +14,7 @@ use Filament\Support\Exceptions\Halt;
17 14
 use Illuminate\Auth\Access\AuthorizationException;
18 15
 use Illuminate\Database\Eloquent\Model;
19 16
 use Livewire\Attributes\Locked;
17
+
20 18
 use function Filament\authorize;
21 19
 
22 20
 /**

+ 18
- 18
app/Filament/Company/Pages/Setting/CompanyProfile.php Visa fil

@@ -3,27 +3,21 @@
3 3
 namespace App\Filament\Company\Pages\Setting;
4 4
 
5 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 11
 use Filament\Notifications\Notification;
18 12
 use Filament\Pages\Concerns\InteractsWithFormActions;
19 13
 use Filament\Pages\Page;
20
-use App\Models\Setting\CompanyProfile as CompanyProfileModel;
21 14
 use Filament\Support\Exceptions\Halt;
22 15
 use Illuminate\Auth\Access\AuthorizationException;
23 16
 use Illuminate\Database\Eloquent\Model;
24 17
 use Illuminate\Support\Facades\Auth;
25 18
 use Livewire\Attributes\Locked;
26 19
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
20
+
27 21
 use function Filament\authorize;
28 22
 
29 23
 /**
@@ -171,7 +165,7 @@ class CompanyProfile extends Page
171 165
                             ->label('Phone Number')
172 166
                             ->tel()
173 167
                             ->nullable(),
174
-                    ])->columns(1)
168
+                    ])->columns(1),
175 169
             ])->columns();
176 170
     }
177 171
 
@@ -184,17 +178,23 @@ class CompanyProfile extends Page
184 178
                     ->native(false)
185 179
                     ->live()
186 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 187
                     ->required(),
189
-                Select::make('state')
188
+                Select::make('state_id')
190 189
                     ->label('State / Province')
191 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 193
                     ->nullable(),
194 194
                 Select::make('timezone')
195 195
                     ->label('Timezone')
196 196
                     ->searchable()
197
-                    ->options(static fn (Get $get) => CompanyProfileModel::getTimezoneOptions($get('country')))
197
+                    ->options(static fn (Get $get) => Timezone::getTimezoneOptions($get('country')))
198 198
                     ->nullable(),
199 199
                 TextInput::make('address')
200 200
                     ->label('Street Address')
@@ -203,7 +203,7 @@ class CompanyProfile extends Page
203 203
                 Select::make('city_id')
204 204
                     ->label('City / Town')
205 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 207
                     ->nullable(),
208 208
                 TextInput::make('zip_code')
209 209
                     ->label('Zip Code')

+ 10
- 22
app/Filament/Company/Pages/Setting/Invoice.php Visa fil

@@ -2,25 +2,11 @@
2 2
 
3 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 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 10
 use Filament\Notifications\Notification;
25 11
 use Filament\Pages\Concerns\InteractsWithFormActions;
26 12
 use Filament\Pages\Page;
@@ -29,6 +15,7 @@ use Illuminate\Auth\Access\AuthorizationException;
29 15
 use Illuminate\Database\Eloquent\Model;
30 16
 use Illuminate\Support\Facades\Auth;
31 17
 use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
18
+
32 19
 use function Filament\authorize;
33 20
 
34 21
 /**
@@ -234,10 +221,11 @@ class Invoice extends Page
234 221
                             ->selectablePlaceholder(false)
235 222
                             ->rule('required')
236 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 230
                         Select::make('template')
243 231
                             ->label('Template')

+ 5
- 9
app/Filament/Company/Resources/Banking/AccountResource.php Visa fil

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

+ 2
- 3
app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php Visa fil

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

+ 3
- 3
app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php Visa fil

@@ -32,7 +32,7 @@ class EditAccount extends EditRecord
32 32
 
33 33
     protected function mutateFormDataBeforeSave(array $data): array
34 34
     {
35
-        $data['enabled'] = (bool)$data['enabled'];
35
+        $data['enabled'] = (bool) $data['enabled'];
36 36
 
37 37
         return $data;
38 38
     }
@@ -40,11 +40,11 @@ class EditAccount extends EditRecord
40 40
     /**
41 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 45
         $user = Auth::user();
46 46
 
47
-        if (!$user) {
47
+        if (! $user) {
48 48
             throw new Halt('No authenticated user found.');
49 49
         }
50 50
 

+ 2
- 3
app/Filament/Company/Resources/Core/DepartmentResource.php Visa fil

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

+ 8
- 8
app/Filament/Company/Resources/Setting/CategoryResource.php Visa fil

@@ -7,12 +7,11 @@ use App\Filament\Company\Resources\Setting\CategoryResource\Pages;
7 7
 use App\Models\Setting\Category;
8 8
 use Closure;
9 9
 use Exception;
10
-use Filament\Forms;
11 10
 use Filament\Forms\Form;
12 11
 use Filament\Notifications\Notification;
13 12
 use Filament\Resources\Resource;
14
-use Filament\Tables;
15 13
 use Filament\Tables\Table;
14
+use Filament\{Forms, Tables};
16 15
 use Illuminate\Database\Eloquent\Collection;
17 16
 use Wallo\FilamentSelectify\Components\ToggleButton;
18 17
 
@@ -40,9 +39,9 @@ class CategoryResource extends Resource
40 39
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
41 40
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
42 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 46
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
48 47
                                         $type = ucwords($get('type'));
@@ -125,10 +124,11 @@ class CategoryResource extends Resource
125 124
                                     ->danger()
126 125
                                     ->title('Action Denied')
127 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 130
                                         }, $defaultCategoryNames));
131
+
132 132
                                         return $message;
133 133
                                     })
134 134
                                     ->persistent()

+ 2
- 2
app/Filament/Company/Resources/Setting/CategoryResource/Pages/CreateCategory.php Visa fil

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

+ 2
- 2
app/Filament/Company/Resources/Setting/CategoryResource/Pages/EditCategory.php Visa fil

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

+ 63
- 60
app/Filament/Company/Resources/Setting/CurrencyResource.php Visa fil

@@ -7,13 +7,12 @@ use App\Models\Banking\Account;
7 7
 use App\Models\Setting\Currency;
8 8
 use App\Services\CurrencyService;
9 9
 use App\Traits\ChecksForeignKeyConstraints;
10
-use Filament\Forms;
11 10
 use Filament\Forms\Form;
12 11
 use Filament\Notifications\Notification;
13 12
 use Filament\Resources\Resource;
14 13
 use Filament\Support\Colors\Color;
15
-use Filament\Tables;
16 14
 use Filament\Tables\Table;
15
+use Filament\{Forms, Tables};
17 16
 use Illuminate\Database\Eloquent\Collection;
18 17
 use Wallo\FilamentSelectify\Components\ToggleButton;
19 18
 
@@ -36,43 +35,43 @@ class CurrencyResource extends Resource
36 35
                 Forms\Components\Section::make('General')
37 36
                     ->schema([
38 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 72
                         Forms\Components\TextInput::make('code')
74 73
                             ->label('Code')
75
-                            ->hidden(static fn (Forms\Get $get): bool => !$get('enabled'))
74
+                            ->hidden(static fn (Forms\Get $get): bool => ! $get('enabled'))
76 75
                             ->disabled(static fn (Forms\Get $get): bool => $get('enabled'))
77 76
                             ->required(),
78 77
                         Forms\Components\TextInput::make('name')
@@ -122,6 +121,10 @@ class CurrencyResource extends Resource
122 121
                                 if ($enabled) {
123 122
                                     $rate = 1;
124 123
                                 } else {
124
+                                    if ($code === null) {
125
+                                        return;
126
+                                    }
127
+
125 128
                                     $defaultCurrencyCode = Currency::getDefaultCurrencyCode();
126 129
                                     $rate = $defaultCurrencyCode ? $currencyService->getCachedExchangeRate($defaultCurrencyCode, $code) : 1;
127 130
                                 }
@@ -195,36 +198,36 @@ class CurrencyResource extends Resource
195 198
             ->bulkActions([
196 199
                 Tables\Actions\BulkActionGroup::make([
197 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 233
             ->emptyStateActions([

+ 2
- 3
app/Filament/Company/Resources/Setting/CurrencyResource/Pages/CreateCurrency.php Visa fil

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

+ 2
- 2
app/Filament/Company/Resources/Setting/CurrencyResource/Pages/EditCurrency.php Visa fil

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

+ 11
- 18
app/Filament/Company/Resources/Setting/DiscountResource.php Visa fil

@@ -2,21 +2,14 @@
2 2
 
3 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 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 7
 use App\Models\Setting\Discount;
12 8
 use Closure;
13
-use Filament\Forms;
14 9
 use Filament\Forms\Form;
15 10
 use Filament\Resources\Resource;
16
-use Filament\Tables;
17 11
 use Filament\Tables\Table;
18
-use Illuminate\Database\Eloquent\Builder;
19
-use Illuminate\Database\Eloquent\SoftDeletingScope;
12
+use Filament\{Forms, Tables};
20 13
 use Wallo\FilamentSelectify\Components\ToggleButton;
21 14
 
22 15
 class DiscountResource extends Resource
@@ -43,9 +36,9 @@ class DiscountResource extends Resource
43 36
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
44 37
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
45 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 43
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
51 44
                                         $type = $get('type')->getLabel();
@@ -88,14 +81,14 @@ class DiscountResource extends Resource
88 81
                         Forms\Components\DateTimePicker::make('start_date')
89 82
                             ->label('Start Date')
90 83
                             ->native(false)
91
-                            ->minDate(static function ($context, Discount|null $record = null) {
84
+                            ->minDate(static function ($context, ?Discount $record = null) {
92 85
                                 if ($context === 'create') {
93 86
                                     return today()->addDay();
94 87
                                 }
95 88
 
96 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 92
                                 $end_date = $get('end_date') ?? $record?->end_date;
100 93
 
101 94
                                 return $end_date ?: today()->addYear();
@@ -104,13 +97,13 @@ class DiscountResource extends Resource
104 97
                             ->displayFormat('F d, Y H:i')
105 98
                             ->seconds(false)
106 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 101
                             ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
109 102
                         Forms\Components\DateTimePicker::make('end_date')
110 103
                             ->label('End Date')
111 104
                             ->native(false)
112 105
                             ->live()
113
-                            ->minDate(static function (callable $get, Discount|null $record = null) {
106
+                            ->minDate(static function (callable $get, ?Discount $record = null) {
114 107
                                 $start_date = $get('start_date') ?? $record?->start_date;
115 108
 
116 109
                                 return $start_date ?: today()->addDay();
@@ -121,7 +114,7 @@ class DiscountResource extends Resource
121 114
                             ->seconds(false),
122 115
                         ToggleButton::make('enabled')
123 116
                             ->label('Default'),
124
-                ])->columns(),
117
+                    ])->columns(),
125 118
             ]);
126 119
     }
127 120
 
@@ -159,7 +152,7 @@ class DiscountResource extends Resource
159 152
                 Tables\Columns\TextColumn::make('end_date')
160 153
                     ->label('End Date')
161 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 156
                     ->searchable()
164 157
                     ->sortable(),
165 158
             ])

+ 2
- 3
app/Filament/Company/Resources/Setting/DiscountResource/Pages/CreateDiscount.php Visa fil

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

+ 2
- 2
app/Filament/Company/Resources/Setting/DiscountResource/Pages/EditDiscount.php Visa fil

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

+ 9
- 15
app/Filament/Company/Resources/Setting/TaxResource.php Visa fil

@@ -2,23 +2,16 @@
2 2
 
3 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 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 7
 use App\Models\Setting\Tax;
12 8
 use Closure;
13
-use Filament\Forms;
14 9
 use Filament\Forms\Form;
15 10
 use Filament\Notifications\Notification;
16 11
 use Filament\Resources\Resource;
17
-use Filament\Tables;
18 12
 use Filament\Tables\Table;
19
-use Illuminate\Database\Eloquent\Builder;
13
+use Filament\{Forms, Tables};
20 14
 use Illuminate\Database\Eloquent\Collection;
21
-use Illuminate\Database\Eloquent\SoftDeletingScope;
22 15
 use Wallo\FilamentSelectify\Components\ToggleButton;
23 16
 
24 17
 class TaxResource extends Resource
@@ -45,9 +38,9 @@ class TaxResource extends Resource
45 38
                             ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
46 39
                                 return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
47 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 45
                                     if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
53 46
                                         $type = $get('type')->getLabel();
@@ -154,10 +147,11 @@ class TaxResource extends Resource
154 147
                                     ->danger()
155 148
                                     ->title('Action Denied')
156 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 153
                                         }, $defaultTaxNames));
154
+
161 155
                                         return $message;
162 156
                                     })
163 157
                                     ->persistent()

+ 2
- 3
app/Filament/Company/Resources/Setting/TaxResource/Pages/CreateTax.php Visa fil

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

+ 2
- 2
app/Filament/Company/Resources/Setting/TaxResource/Pages/EditTax.php Visa fil

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

+ 0
- 119
app/Helpers/City.php Visa fil

@@ -1,119 +0,0 @@
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 Visa fil

@@ -1,294 +0,0 @@
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 Visa fil

@@ -1,123 +0,0 @@
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 Visa fil

@@ -1,131 +0,0 @@
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 Visa fil

@@ -1,46 +0,0 @@
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 Visa fil

@@ -8,5 +8,6 @@ use Illuminate\Routing\Controller as BaseController;
8 8
 
9 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 Visa fil

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

+ 1
- 1
app/Http/Middleware/ApplyCurrentCompanyScope.php Visa fil

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

+ 1
- 1
app/Interfaces/Utility/DocumentNumber.php Visa fil

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
6 6
 
7 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 11
     public function incrementNumber(Model $model, string $type): void;
12 12
 }

+ 2
- 7
app/Listeners/ConfigureCompanyDefault.php Visa fil

@@ -2,12 +2,7 @@
2 2
 
3 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 6
 use App\Models\Company;
12 7
 use Filament\Actions\MountableAction;
13 8
 use Filament\Events\TenantSet;
@@ -56,7 +51,7 @@ class ConfigureCompanyDefault
56 51
             ->font($defaultFont)
57 52
             ->brandName($company->name)
58 53
             ->topNavigation($hasTopNavigation)
59
-            ->sidebarCollapsibleOnDesktop(!$hasTopNavigation)
54
+            ->sidebarCollapsibleOnDesktop(! $hasTopNavigation)
60 55
             ->maxContentWidth($maxContentWidth);
61 56
     }
62 57
 }

+ 2
- 4
app/Listeners/CreateCompanyDefaults.php Visa fil

@@ -3,6 +3,7 @@
3 3
 namespace App\Listeners;
4 4
 
5 5
 use App\Events\CompanyGenerated;
6
+use App\Models\Locale\Country;
6 7
 use App\Services\CompanyDefaultService;
7 8
 
8 9
 class CreateCompanyDefaults
@@ -23,10 +24,7 @@ class CreateCompanyDefaults
23 24
         $company = $event->company;
24 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 29
         $user = $company->owner;
32 30
 

+ 0
- 2
app/Listeners/SyncAssociatedModels.php Visa fil

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

+ 3
- 6
app/Listeners/SyncWithCompanyDefaults.php Visa fil

@@ -2,9 +2,7 @@
2 2
 
3 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 6
 use App\Events\CompanyDefaultEvent;
9 7
 use App\Models\Setting\CompanyDefault;
10 8
 use Illuminate\Support\Facades\DB;
@@ -33,13 +31,13 @@ class SyncWithCompanyDefaults
33 31
     {
34 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 35
             return;
38 36
         }
39 37
 
40 38
         $companyId = auth()->user()->currentCompany->id;
41 39
 
42
-        if (!$companyId) {
40
+        if (! $companyId) {
43 41
             return;
44 42
         }
45 43
 
@@ -90,5 +88,4 @@ class SyncWithCompanyDefaults
90 88
             $type === CategoryType::Expense => $default->expense_category_id = $key,
91 89
         };
92 90
     }
93
-
94 91
 }

+ 6
- 5
app/Models/Banking/Account.php Visa fil

@@ -4,11 +4,9 @@ namespace App\Models\Banking;
4 4
 
5 5
 use App\Casts\MoneyCast;
6 6
 use App\Models\Setting\Currency;
7
-use App\Traits\Blamable;
8
-use App\Traits\CompanyOwned;
7
+use App\Traits\{Blamable, CompanyOwned};
9 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 10
 use Illuminate\Database\Eloquent\Model;
13 11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
14 12
 use Spatie\Tags\HasTags;
@@ -16,7 +14,10 @@ use Wallo\FilamentCompanies\FilamentCompanies;
16 14
 
17 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 22
     protected $table = 'accounts';
22 23
 

+ 7
- 9
app/Models/Common/Contact.php Visa fil

@@ -5,20 +5,18 @@ namespace App\Models\Common;
5 5
 use App\Enums\ContactType;
6 6
 use App\Models\Core\Department;
7 7
 use App\Models\Setting\Currency;
8
-use App\Traits\Blamable;
9
-use App\Traits\CompanyOwned;
8
+use App\Traits\{Blamable, CompanyOwned};
10 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 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 13
 use Wallo\FilamentCompanies\FilamentCompanies;
18 14
 
19 15
 class Contact extends Model
20 16
 {
21
-    use Blamable, CompanyOwned, HasFactory;
17
+    use Blamable;
18
+    use CompanyOwned;
19
+    use HasFactory;
22 20
 
23 21
     protected $table = 'contacts';
24 22
 
@@ -30,7 +28,7 @@ class Contact extends Model
30 28
         'address',
31 29
         'city_id',
32 30
         'zip_code',
33
-        'state',
31
+        'state_id',
34 32
         'country',
35 33
         'timezone',
36 34
         'language',

+ 8
- 18
app/Models/Company.php Visa fil

@@ -6,32 +6,17 @@ use App\Enums\DocumentType;
6 6
 use App\Models\Banking\Account;
7 7
 use App\Models\Common\Contact;
8 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 10
 use Filament\Models\Contracts\HasAvatar;
18 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 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 16
 class Company extends FilamentCompaniesCompany implements HasAvatar
27 17
 {
28 18
     use HasFactory;
29 19
 
30
-    public function getFilamentAvatarUrl(): string
31
-    {
32
-        return $this->owner->profile_photo_url;
33
-    }
34
-
35 20
     /**
36 21
      * The attributes that should be cast.
37 22
      *
@@ -62,6 +47,11 @@ class Company extends FilamentCompaniesCompany implements HasAvatar
62 47
         'deleted' => CompanyDeleted::class,
63 48
     ];
64 49
 
50
+    public function getFilamentAvatarUrl(): string
51
+    {
52
+        return $this->owner->profile_photo_url;
53
+    }
54
+
65 55
     public function accounts(): HasMany
66 56
     {
67 57
         return $this->hasMany(Account::class, 'company_id');

+ 1
- 3
app/Models/ConnectedAccount.php Visa fil

@@ -4,9 +4,7 @@ namespace App\Models;
4 4
 
5 5
 use Illuminate\Database\Eloquent\Concerns\HasTimestamps;
6 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 9
 class ConnectedAccount extends SocialiteConnectedAccount
12 10
 {

+ 6
- 8
app/Models/Core/Department.php Visa fil

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

+ 2
- 4
app/Models/Employeeship.php Visa fil

@@ -4,10 +4,8 @@ namespace App\Models;
4 4
 
5 5
 use App\Models\Common\Contact;
6 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 10
 class Employeeship extends FilamentCompaniesEmployeeship
13 11
 {

+ 61
- 0
app/Models/Locale/City.php Visa fil

@@ -0,0 +1,61 @@
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 Visa fil

@@ -0,0 +1,78 @@
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 Visa fil

@@ -0,0 +1,172 @@
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 Visa fil

@@ -0,0 +1,50 @@
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 Visa fil

@@ -0,0 +1,68 @@
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 Visa fil

@@ -2,24 +2,19 @@
2 2
 
3 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 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 9
 use Illuminate\Database\Eloquent\Model;
17 10
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
18 11
 use Wallo\FilamentCompanies\FilamentCompanies;
19 12
 
20 13
 class Appearance extends Model
21 14
 {
22
-    use Blamable, CompanyOwned, HasFactory;
15
+    use Blamable;
16
+    use CompanyOwned;
17
+    use HasFactory;
23 18
 
24 19
     protected $table = 'appearances';
25 20
 

+ 7
- 8
app/Models/Setting/Category.php Visa fil

@@ -3,20 +3,19 @@
3 3
 namespace App\Models\Setting;
4 4
 
5 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 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 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 11
 use Wallo\FilamentCompanies\FilamentCompanies;
16 12
 
17 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 20
     protected $table = 'categories';
22 21
 

+ 6
- 14
app/Models/Setting/CompanyDefault.php Visa fil

@@ -2,28 +2,20 @@
2 2
 
3 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 6
 use App\Models\Banking\Account;
15
-use App\Traits\Blamable;
16
-use App\Traits\CompanyOwned;
7
+use App\Traits\{Blamable, CompanyOwned};
17 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 10
 use Illuminate\Database\Eloquent\Model;
21 11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
22 12
 use Wallo\FilamentCompanies\FilamentCompanies;
23 13
 
24 14
 class CompanyDefault extends Model
25 15
 {
26
-    use Blamable, CompanyOwned, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
27 19
 
28 20
     protected $table = 'company_defaults';
29 21
 

+ 8
- 98
app/Models/Setting/CompanyProfile.php Visa fil

@@ -3,22 +3,19 @@
3 3
 namespace App\Models\Setting;
4 4
 
5 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 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 10
 use Illuminate\Database\Eloquent\Model;
15 11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
16
-use Squire\Models\Timezone;
17 12
 use Wallo\FilamentCompanies\FilamentCompanies;
18 13
 
19 14
 class CompanyProfile extends Model
20 15
 {
21
-    use Blamable, CompanyOwned, HasFactory;
16
+    use Blamable;
17
+    use CompanyOwned;
18
+    use HasFactory;
22 19
 
23 20
     protected $table = 'company_profiles';
24 21
 
@@ -28,7 +25,7 @@ class CompanyProfile extends Model
28 25
         'address',
29 26
         'city_id',
30 27
         'zip_code',
31
-        'state',
28
+        'state_id',
32 29
         'country',
33 30
         'timezone',
34 31
         'phone_number',
@@ -62,96 +59,9 @@ class CompanyProfile extends Model
62 59
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
63 60
     }
64 61
 
65
-
66 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 67
     protected static function newFactory(): Factory

+ 9
- 11
app/Models/Setting/Currency.php Visa fil

@@ -5,22 +5,20 @@ namespace App\Models\Setting;
5 5
 use Akaunting\Money\Currency as ISOCurrencies;
6 6
 use App\Casts\RateCast;
7 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 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 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 13
 use Illuminate\Support\Facades\DB;
19 14
 use Wallo\FilamentCompanies\FilamentCompanies;
20 15
 
21 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 23
     protected $table = 'currencies';
26 24
 
@@ -89,7 +87,7 @@ class Currency extends Model
89 87
         return ISOCurrencies::getCurrencies();
90 88
     }
91 89
 
92
-    public static function getDefaultCurrencyCode(): string|null
90
+    public static function getDefaultCurrencyCode(): ?string
93 91
     {
94 92
         $defaultCurrency = static::query()
95 93
             ->where('enabled', true)
@@ -116,7 +114,7 @@ class Currency extends Model
116 114
 
117 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 119
         return round(($cleanBalance * $newRate * $scale) / ($oldRate * $scale));
122 120
     }

+ 8
- 11
app/Models/Setting/Discount.php Visa fil

@@ -3,23 +3,20 @@
3 3
 namespace App\Models\Setting;
4 4
 
5 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 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 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 12
 use Wallo\FilamentCompanies\FilamentCompanies;
19 13
 
20 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 21
     protected $table = 'discounts';
25 22
 

+ 11
- 21
app/Models/Setting/DocumentDefault.php Visa fil

@@ -3,28 +3,20 @@
3 3
 namespace App\Models\Setting;
4 4
 
5 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 8
 use Database\Factories\Setting\DocumentDefaultFactory;
17
-use Illuminate\Database\Eloquent\Builder;
18 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 11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
12
+use Illuminate\Database\Eloquent\{Builder, Model};
23 13
 use Wallo\FilamentCompanies\FilamentCompanies;
24 14
 
25 15
 class DocumentDefault extends Model
26 16
 {
27
-    use Blamable, CompanyOwned, HasFactory;
17
+    use Blamable;
18
+    use CompanyOwned;
19
+    use HasFactory;
28 20
 
29 21
     protected $table = 'document_defaults';
30 22
 
@@ -79,7 +71,7 @@ class DocumentDefault extends Model
79 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 76
         return $query->where($this->qualifyColumn('type'), $type);
85 77
     }
@@ -99,7 +91,7 @@ class DocumentDefault extends Model
99 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 96
         $initializeAttributes = new static;
105 97
 
@@ -116,7 +108,7 @@ class DocumentDefault extends Model
116 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 113
         $number_prefix = $prefix ?? $this->getAttributeFromArray('number_prefix');
122 114
         $number_digits = $digits ?? $this->getAttributeFromArray('number_digits');
@@ -133,8 +125,6 @@ class DocumentDefault extends Model
133 125
         return [$number_prefix, $number_digits, $number_next];
134 126
     }
135 127
 
136
-
137
-
138 128
     public static function getAttributesByType(?string $type): array
139 129
     {
140 130
         $model = new static;
@@ -147,7 +137,7 @@ class DocumentDefault extends Model
147 137
      * Get the next number with padding for dynamic display purposes.
148 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 142
         return str_pad($number_next, $number_digits, '0', STR_PAD_LEFT);
153 143
     }

+ 8
- 11
app/Models/Setting/Tax.php Visa fil

@@ -3,23 +3,20 @@
3 3
 namespace App\Models\Setting;
4 4
 
5 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 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 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 12
 use Wallo\FilamentCompanies\FilamentCompanies;
19 13
 
20 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 21
     protected $table = 'taxes';
25 22
 

+ 35
- 41
app/Models/User.php Visa fil

@@ -3,10 +3,7 @@
3 3
 namespace App\Models;
4 4
 
5 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 7
 use Filament\Panel;
11 8
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12 9
 use Illuminate\Database\Eloquent\Model;
@@ -15,52 +12,19 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
15 12
 use Illuminate\Notifications\Notifiable;
16 13
 use Illuminate\Support\Collection;
17 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 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 20
     use HasApiTokens;
27
-    use HasFactory;
28
-    use HasProfilePhoto;
29 21
     use HasCompanies;
30 22
     use HasConnectedAccounts;
23
+    use HasFactory;
24
+    use HasProfilePhoto;
31 25
     use Notifiable;
32 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 29
      * The attributes that are mass assignable.
66 30
      *
@@ -97,4 +61,34 @@ class User extends Authenticatable implements FilamentUser, HasAvatar, HasTenant
97 61
     protected $appends = [
98 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 Visa fil

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

+ 1
- 2
app/Policies/ConnectedAccountPolicy.php Visa fil

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

+ 6
- 11
app/Providers/AppServiceProvider.php Visa fil

@@ -4,17 +4,12 @@ namespace App\Providers;
4 4
 
5 5
 use App\Enums\PrimaryColor;
6 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 8
 use Filament\Notifications\Livewire\Notifications;
12 9
 use Filament\Support\Enums\Alignment;
13 10
 use Filament\Support\RawJs;
14
-use Filament\Tables\Actions\Action;
15 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 14
 class AppServiceProvider extends ServiceProvider
20 15
 {
@@ -33,7 +28,7 @@ class AppServiceProvider extends ServiceProvider
33 28
     {
34 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 32
             $this->formatStateUsing(static function (TextColumn $column, $state) use ($currency, $convert): ?string {
38 33
                 if (blank($state)) {
39 34
                     return null;
@@ -48,7 +43,7 @@ class AppServiceProvider extends ServiceProvider
48 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 47
             $this->extraAttributes(['wire:key' => Str::random()])
53 48
                 ->prefix(static function (TextInput $component) use ($currency) {
54 49
                     $currency = $component->evaluate($currency);
@@ -66,7 +61,7 @@ class AppServiceProvider extends ServiceProvider
66 61
                     $thousands_separator = currency($currency)->getThousandsSeparator();
67 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 66
                     return RawJs::make($jsCode);
72 67
                 });
@@ -74,7 +69,7 @@ class AppServiceProvider extends ServiceProvider
74 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 73
             $this->options(
79 74
                 collect(PrimaryColor::caseValues())
80 75
                     ->mapWithKeys(static function ($color) {

+ 2
- 7
app/Providers/EventServiceProvider.php Visa fil

@@ -2,13 +2,8 @@
2 2
 
3 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 7
 use Filament\Events\TenantSet;
13 8
 use Illuminate\Auth\Events\Registered;
14 9
 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;

+ 32
- 0
app/Providers/Faker/FakerServiceProvider.php Visa fil

@@ -0,0 +1,32 @@
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 Visa fil

@@ -2,20 +2,13 @@
2 2
 
3 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 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 9
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
16 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 12
 use Illuminate\View\Middleware\ShareErrorsFromSession;
20 13
 
21 14
 class AdminPanelProvider extends PanelProvider

+ 6
- 14
app/Providers/Filament/UserPanelProvider.php Visa fil

@@ -3,25 +3,17 @@
3 3
 namespace App\Providers\Filament;
4 4
 
5 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 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 11
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
18 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 14
 use Illuminate\Support\Facades\Auth;
22 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 18
 class UserPanelProvider extends PanelProvider
27 19
 {

+ 11
- 35
app/Providers/FilamentCompaniesServiceProvider.php Visa fil

@@ -2,48 +2,24 @@
2 2
 
3 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 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 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 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 13
 use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
39 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 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 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 24
 class FilamentCompaniesServiceProvider extends PanelProvider
49 25
 {

+ 1
- 2
app/Providers/RouteServiceProvider.php Visa fil

@@ -5,8 +5,7 @@ namespace App\Providers;
5 5
 use Illuminate\Cache\RateLimiting\Limit;
6 6
 use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
7 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 10
 class RouteServiceProvider extends ServiceProvider
12 11
 {

+ 23
- 0
app/Providers/SquireServiceProvider.php Visa fil

@@ -0,0 +1,23 @@
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 Visa fil

@@ -2,9 +2,7 @@
2 2
 
3 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 6
 use Illuminate\Support\Facades\Auth;
9 7
 
10 8
 class CurrentCompanyScope implements Scope

+ 4
- 12
app/Services/CompanyDefaultService.php Visa fil

@@ -3,15 +3,8 @@
3 3
 namespace App\Services;
4 4
 
5 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 8
 use Illuminate\Support\Facades\DB;
16 9
 
17 10
 class CompanyDefaultService
@@ -64,9 +57,9 @@ class CompanyDefaultService
64 57
 
65 58
         foreach ($shuffledCategories as $category) {
66 59
             $enabled = false;
67
-            if (!$incomeEnabled && $category['type'] === CategoryType::Income->value) {
60
+            if (! $incomeEnabled && $category['type'] === CategoryType::Income->value) {
68 61
                 $enabled = $incomeEnabled = true;
69
-            } elseif (!$expenseEnabled && $category['type'] === CategoryType::Expense->value) {
62
+            } elseif (! $expenseEnabled && $category['type'] === CategoryType::Expense->value) {
70 63
                 $enabled = $expenseEnabled = true;
71 64
             }
72 65
 
@@ -160,5 +153,4 @@ class CompanyDefaultService
160 153
             'updated_by' => $user->id,
161 154
         ]);
162 155
     }
163
-
164 156
 }

+ 0
- 0
app/Services/CurrencyService.php Visa fil


Vissa filer visades inte eftersom för många filer har ändrats

Laddar…
Avbryt
Spara