Browse Source

refactor

3.x
Andrew Wallo 11 months ago
parent
commit
102fc13820
45 changed files with 451 additions and 480 deletions
  1. 16
    0
      app/Enums/Accounting/AdjustmentCategory.php
  2. 2
    4
      app/Enums/Accounting/AdjustmentComputation.php
  3. 2
    4
      app/Enums/Accounting/AdjustmentScope.php
  4. 2
    7
      app/Enums/Accounting/AdjustmentType.php
  5. 0
    16
      app/Enums/Setting/DiscountScope.php
  6. 0
    39
      app/Enums/Setting/DiscountType.php
  7. 0
    19
      app/Enums/Setting/TaxComputation.php
  8. 1
    1
      app/Filament/Company/Clusters/Settings/Pages/CompanyDefault.php
  9. 0
    4
      app/Listeners/SyncAssociatedModels.php
  10. 0
    29
      app/Listeners/SyncWithCompanyDefaults.php
  11. 5
    0
      app/Models/Accounting/Account.php
  12. 69
    0
      app/Models/Accounting/Adjustment.php
  13. 2
    2
      app/Models/Accounting/Document.php
  14. 2
    2
      app/Models/Accounting/DocumentLineItem.php
  15. 2
    2
      app/Models/Banking/Payment.php
  16. 2
    2
      app/Models/Common/Client.php
  17. 1
    1
      app/Models/Common/Offering.php
  18. 2
    2
      app/Models/Common/Vendor.php
  19. 5
    12
      app/Models/Company.php
  20. 0
    30
      app/Models/Setting/CompanyDefault.php
  21. 8
    2
      app/Models/Setting/Discount.php
  22. 8
    2
      app/Models/Setting/Tax.php
  23. 35
    0
      app/Services/ChartOfAccountsService.php
  24. 6
    6
      composer.lock
  25. 47
    6
      config/chart-of-accounts.php
  26. 57
    0
      database/factories/Accounting/AccountFactory.php
  27. 120
    0
      database/factories/Accounting/AdjustmentFactory.php
  28. 2
    2
      database/factories/Accounting/DocumentFactory.php
  29. 2
    2
      database/factories/Accounting/DocumentLineItemFactory.php
  30. 6
    0
      database/factories/Accounting/TransactionFactory.php
  31. 2
    2
      database/factories/Banking/PaymentFactory.php
  32. 2
    2
      database/factories/Common/ClientFactory.php
  33. 2
    2
      database/factories/Common/OfferingFactory.php
  34. 2
    2
      database/factories/Common/VendorFactory.php
  35. 0
    50
      database/factories/Setting/CompanyDefaultFactory.php
  36. 0
    68
      database/factories/Setting/DiscountFactory.php
  37. 0
    62
      database/factories/Setting/TaxFactory.php
  38. 4
    3
      database/migrations/2023_09_03_100000_create_accounting_tables.php
  39. 0
    41
      database/migrations/2023_09_08_011045_create_taxes_table.php
  40. 0
    4
      database/migrations/2023_09_08_040159_create_company_defaults_table.php
  41. 4
    8
      database/migrations/2023_09_12_014413_create_appearances_table.php
  42. 3
    6
      database/migrations/2023_09_12_032057_create_document_defaults_table.php
  43. 4
    8
      database/migrations/2023_10_11_210415_create_localizations_table.php
  44. 7
    9
      database/migrations/2024_11_14_230753_create_adjustments_table.php
  45. 17
    17
      package-lock.json

+ 16
- 0
app/Enums/Accounting/AdjustmentCategory.php View File

1
+<?php
2
+
3
+namespace App\Enums\Accounting;
4
+
5
+use Filament\Support\Contracts\HasLabel;
6
+
7
+enum AdjustmentCategory: string implements HasLabel
8
+{
9
+    case Tax = 'tax';
10
+    case Discount = 'discount';
11
+
12
+    public function getLabel(): ?string
13
+    {
14
+        return $this->name;
15
+    }
16
+}

app/Enums/Setting/DiscountComputation.php → app/Enums/Accounting/AdjustmentComputation.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Enums\Setting;
3
+namespace App\Enums\Accounting;
4
 
4
 
5
 use Filament\Support\Contracts\HasLabel;
5
 use Filament\Support\Contracts\HasLabel;
6
 
6
 
7
-enum DiscountComputation: string implements HasLabel
7
+enum AdjustmentComputation: string implements HasLabel
8
 {
8
 {
9
     case Percentage = 'percentage';
9
     case Percentage = 'percentage';
10
     case Fixed = 'fixed';
10
     case Fixed = 'fixed';
11
 
11
 
12
-    public const DEFAULT = self::Percentage->value;
13
-
14
     public function getLabel(): ?string
12
     public function getLabel(): ?string
15
     {
13
     {
16
         return translate($this->name);
14
         return translate($this->name);

app/Enums/Setting/TaxScope.php → app/Enums/Accounting/AdjustmentScope.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Enums\Setting;
3
+namespace App\Enums\Accounting;
4
 
4
 
5
-use Filament\Support\Contracts\HasLabel;
6
-
7
-enum TaxScope: string implements HasLabel
5
+enum AdjustmentScope: string
8
 {
6
 {
9
     case Product = 'product';
7
     case Product = 'product';
10
     case Service = 'service';
8
     case Service = 'service';

app/Enums/Setting/TaxType.php → app/Enums/Accounting/AdjustmentType.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Enums\Setting;
3
+namespace App\Enums\Accounting;
4
 
4
 
5
 use Filament\Support\Contracts\HasColor;
5
 use Filament\Support\Contracts\HasColor;
6
 use Filament\Support\Contracts\HasIcon;
6
 use Filament\Support\Contracts\HasIcon;
7
 use Filament\Support\Contracts\HasLabel;
7
 use Filament\Support\Contracts\HasLabel;
8
 
8
 
9
-enum TaxType: string implements HasColor, HasIcon, HasLabel
9
+enum AdjustmentType: string implements HasColor, HasIcon, HasLabel
10
 {
10
 {
11
     case Sales = 'sales';
11
     case Sales = 'sales';
12
     case Purchase = 'purchase';
12
     case Purchase = 'purchase';
13
-    case None = 'none';
14
-
15
-    public const DEFAULT = self::Sales->value;
16
 
13
 
17
     public function getLabel(): ?string
14
     public function getLabel(): ?string
18
     {
15
     {
24
         return match ($this) {
21
         return match ($this) {
25
             self::Sales => 'success',
22
             self::Sales => 'success',
26
             self::Purchase => 'warning',
23
             self::Purchase => 'warning',
27
-            self::None => 'gray',
28
         };
24
         };
29
     }
25
     }
30
 
26
 
33
         return match ($this) {
29
         return match ($this) {
34
             self::Sales => 'heroicon-o-currency-dollar',
30
             self::Sales => 'heroicon-o-currency-dollar',
35
             self::Purchase => 'heroicon-o-shopping-bag',
31
             self::Purchase => 'heroicon-o-shopping-bag',
36
-            self::None => 'heroicon-o-x-circle',
37
         };
32
         };
38
     }
33
     }
39
 }
34
 }

+ 0
- 16
app/Enums/Setting/DiscountScope.php View File

1
-<?php
2
-
3
-namespace App\Enums\Setting;
4
-
5
-use Filament\Support\Contracts\HasLabel;
6
-
7
-enum DiscountScope: string implements HasLabel
8
-{
9
-    case Product = 'product';
10
-    case Service = 'service';
11
-
12
-    public function getLabel(): ?string
13
-    {
14
-        return translate($this->name);
15
-    }
16
-}

+ 0
- 39
app/Enums/Setting/DiscountType.php View File

1
-<?php
2
-
3
-namespace App\Enums\Setting;
4
-
5
-use Filament\Support\Contracts\HasColor;
6
-use Filament\Support\Contracts\HasIcon;
7
-use Filament\Support\Contracts\HasLabel;
8
-
9
-enum DiscountType: string implements HasColor, HasIcon, HasLabel
10
-{
11
-    case Sales = 'sales';
12
-    case Purchase = 'purchase';
13
-    case None = 'none';
14
-
15
-    public const DEFAULT = self::Sales->value;
16
-
17
-    public function getLabel(): ?string
18
-    {
19
-        return translate($this->name);
20
-    }
21
-
22
-    public function getColor(): string | array | null
23
-    {
24
-        return match ($this) {
25
-            self::Sales => 'success',
26
-            self::Purchase => 'warning',
27
-            self::None => 'gray',
28
-        };
29
-    }
30
-
31
-    public function getIcon(): ?string
32
-    {
33
-        return match ($this) {
34
-            self::Sales => 'heroicon-o-currency-dollar',
35
-            self::Purchase => 'heroicon-o-shopping-bag',
36
-            self::None => 'heroicon-o-x-circle',
37
-        };
38
-    }
39
-}

+ 0
- 19
app/Enums/Setting/TaxComputation.php View File

1
-<?php
2
-
3
-namespace App\Enums\Setting;
4
-
5
-use Filament\Support\Contracts\HasLabel;
6
-
7
-enum TaxComputation: string implements HasLabel
8
-{
9
-    case Fixed = 'fixed';
10
-    case Percentage = 'percentage';
11
-    case Compound = 'compound';
12
-
13
-    public const DEFAULT = self::Percentage->value;
14
-
15
-    public function getLabel(): ?string
16
-    {
17
-        return translate($this->name);
18
-    }
19
-}

+ 1
- 1
app/Filament/Company/Clusters/Settings/Pages/CompanyDefault.php View File

108
         return $form
108
         return $form
109
             ->schema([
109
             ->schema([
110
                 $this->getGeneralSection(),
110
                 $this->getGeneralSection(),
111
-                $this->getModifiersSection(),
111
+                // $this->getModifiersSection(),
112
             ])
112
             ])
113
             ->model($this->record)
113
             ->model($this->record)
114
             ->statePath('data')
114
             ->statePath('data')

+ 0
- 4
app/Listeners/SyncAssociatedModels.php View File

40
 
40
 
41
         $keyToMethodMap = [
41
         $keyToMethodMap = [
42
             'bank_account_id' => 'bankAccount',
42
             'bank_account_id' => 'bankAccount',
43
-            'sales_tax_id' => 'salesTax',
44
-            'purchase_tax_id' => 'purchaseTax',
45
-            'sales_discount_id' => 'salesDiscount',
46
-            'purchase_discount_id' => 'purchaseDiscount',
47
         ];
43
         ];
48
 
44
 
49
         foreach ($diff as $key => $value) {
45
         foreach ($diff as $key => $value) {

+ 0
- 29
app/Listeners/SyncWithCompanyDefaults.php View File

2
 
2
 
3
 namespace App\Listeners;
3
 namespace App\Listeners;
4
 
4
 
5
-use App\Enums\Setting\DiscountType;
6
-use App\Enums\Setting\TaxType;
7
 use App\Events\CompanyDefaultEvent;
5
 use App\Events\CompanyDefaultEvent;
8
 use App\Models\Setting\CompanyDefault;
6
 use App\Models\Setting\CompanyDefault;
9
 use Illuminate\Support\Facades\DB;
7
 use Illuminate\Support\Facades\DB;
48
     private function updateCompanyDefaults($model, $companyId): void
46
     private function updateCompanyDefaults($model, $companyId): void
49
     {
47
     {
50
         $modelName = class_basename($model);
48
         $modelName = class_basename($model);
51
-        $type = $model->getAttribute('type');
52
 
49
 
53
         $default = CompanyDefault::firstOrNew([
50
         $default = CompanyDefault::firstOrNew([
54
             'company_id' => $companyId,
51
             'company_id' => $companyId,
55
         ]);
52
         ]);
56
 
53
 
57
         match ($modelName) {
54
         match ($modelName) {
58
-            'Discount' => $this->handleDiscount($default, $type, $model->getKey()),
59
-            'Tax' => $this->handleTax($default, $type, $model->getKey()),
60
             'Currency' => $default->currency_code = $model->getAttribute('code'),
55
             'Currency' => $default->currency_code = $model->getAttribute('code'),
61
             'BankAccount' => $default->bank_account_id = $model->getKey(),
56
             'BankAccount' => $default->bank_account_id = $model->getKey(),
62
             default => null,
57
             default => null,
64
 
59
 
65
         $default->save();
60
         $default->save();
66
     }
61
     }
67
-
68
-    private function handleDiscount($default, $type, $key): void
69
-    {
70
-        if (! in_array($type, [DiscountType::Sales, DiscountType::Purchase], true)) {
71
-            return;
72
-        }
73
-
74
-        match (true) {
75
-            $type === DiscountType::Sales => $default->sales_discount_id = $key,
76
-            $type === DiscountType::Purchase => $default->purchase_discount_id = $key,
77
-        };
78
-    }
79
-
80
-    private function handleTax($default, $type, $key): void
81
-    {
82
-        if (! in_array($type, [TaxType::Sales, TaxType::Purchase], true)) {
83
-            return;
84
-        }
85
-
86
-        match (true) {
87
-            $type === TaxType::Sales => $default->sales_tax_id = $key,
88
-            $type === TaxType::Purchase => $default->purchase_tax_id = $key,
89
-        };
90
-    }
91
 }
62
 }

+ 5
- 0
app/Models/Accounting/Account.php View File

79
         return $this->hasOne(BankAccount::class, 'account_id');
79
         return $this->hasOne(BankAccount::class, 'account_id');
80
     }
80
     }
81
 
81
 
82
+    public function adjustment(): HasOne
83
+    {
84
+        return $this->hasOne(Adjustment::class, 'account_id');
85
+    }
86
+
82
     public function getLastTransactionDate(): ?string
87
     public function getLastTransactionDate(): ?string
83
     {
88
     {
84
         $lastJournalEntryTransaction = $this->journalEntries()
89
         $lastJournalEntryTransaction = $this->journalEntries()

+ 69
- 0
app/Models/Accounting/Adjustment.php View File

1
+<?php
2
+
3
+namespace App\Models\Accounting;
4
+
5
+use App\Casts\RateCast;
6
+use App\Concerns\Blamable;
7
+use App\Concerns\CompanyOwned;
8
+use App\Concerns\HasDefault;
9
+use App\Enums\Accounting\AdjustmentCategory;
10
+use App\Enums\Accounting\AdjustmentComputation;
11
+use App\Enums\Accounting\AdjustmentScope;
12
+use App\Enums\Accounting\AdjustmentType;
13
+use Database\Factories\Accounting\AdjustmentFactory;
14
+use Illuminate\Database\Eloquent\Factories\Factory;
15
+use Illuminate\Database\Eloquent\Factories\HasFactory;
16
+use Illuminate\Database\Eloquent\Model;
17
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
18
+use Illuminate\Database\Eloquent\Relations\MorphTo;
19
+
20
+class Adjustment extends Model
21
+{
22
+    use Blamable;
23
+    use CompanyOwned;
24
+    use HasDefault;
25
+    use HasFactory;
26
+
27
+    protected $table = 'adjustments';
28
+
29
+    protected $fillable = [
30
+        'company_id',
31
+        'account_id',
32
+        'category',
33
+        'type',
34
+        'rate',
35
+        'computation',
36
+        'scope',
37
+        'start_date',
38
+        'end_date',
39
+        'enabled',
40
+        'created_by',
41
+        'updated_by',
42
+    ];
43
+
44
+    protected $casts = [
45
+        'category' => AdjustmentCategory::class,
46
+        'type' => AdjustmentType::class,
47
+        'rate' => RateCast::class,
48
+        'computation' => AdjustmentComputation::class,
49
+        'scope' => AdjustmentScope::class,
50
+        'start_date' => 'datetime',
51
+        'end_date' => 'datetime',
52
+        'enabled' => 'boolean',
53
+    ];
54
+
55
+    public function account(): BelongsTo
56
+    {
57
+        return $this->belongsTo(Account::class, 'account_id');
58
+    }
59
+
60
+    public function adjustmentables(): MorphTo
61
+    {
62
+        return $this->morphTo();
63
+    }
64
+
65
+    protected static function newFactory(): Factory
66
+    {
67
+        return AdjustmentFactory::new();
68
+    }
69
+}

app/Models/Document.php → app/Models/Accounting/Document.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Accounting;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
 
7
 
8
 class Document extends Model
8
 class Document extends Model
9
 {
9
 {
10
-    /** @use HasFactory<\Database\Factories\DocumentFactory> */
10
+    /** @use HasFactory<\Database\Factories\Accounting\DocumentFactory> */
11
     use HasFactory;
11
     use HasFactory;
12
 }
12
 }

app/Models/DocumentLineItem.php → app/Models/Accounting/DocumentLineItem.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Accounting;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
 
7
 
8
 class DocumentLineItem extends Model
8
 class DocumentLineItem extends Model
9
 {
9
 {
10
-    /** @use HasFactory<\Database\Factories\DocumentLineItemFactory> */
10
+    /** @use HasFactory<\Database\Factories\Accounting\DocumentLineItemFactory> */
11
     use HasFactory;
11
     use HasFactory;
12
 }
12
 }

app/Models/Payment.php → app/Models/Banking/Payment.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Banking;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
 
7
 
8
 class Payment extends Model
8
 class Payment extends Model
9
 {
9
 {
10
-    /** @use HasFactory<\Database\Factories\PaymentFactory> */
10
+    /** @use HasFactory<\Database\Factories\Banking\PaymentFactory> */
11
     use HasFactory;
11
     use HasFactory;
12
 }
12
 }

app/Models/Client.php → app/Models/Common/Client.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Common;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
 
7
 
8
 class Client extends Model
8
 class Client extends Model
9
 {
9
 {
10
-    /** @use HasFactory<\Database\Factories\ClientFactory> */
10
+    /** @use HasFactory<\Database\Factories\Common\ClientFactory> */
11
     use HasFactory;
11
     use HasFactory;
12
 }
12
 }

app/Models/Offering.php → app/Models/Common/Offering.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Common;
4
 
4
 
5
 use App\Concerns\CompanyOwned;
5
 use App\Concerns\CompanyOwned;
6
 use App\Models\Accounting\Account;
6
 use App\Models\Accounting\Account;

app/Models/Vendor.php → app/Models/Common/Vendor.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace App\Models;
3
+namespace App\Models\Common;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
 
7
 
8
 class Vendor extends Model
8
 class Vendor extends Model
9
 {
9
 {
10
-    /** @use HasFactory<\Database\Factories\VendorFactory> */
10
+    /** @use HasFactory<\Database\Factories\Common\VendorFactory> */
11
     use HasFactory;
11
     use HasFactory;
12
 }
12
 }

+ 5
- 12
app/Models/Company.php View File

12
 use App\Models\Setting\CompanyDefault;
12
 use App\Models\Setting\CompanyDefault;
13
 use App\Models\Setting\CompanyProfile;
13
 use App\Models\Setting\CompanyProfile;
14
 use App\Models\Setting\Currency;
14
 use App\Models\Setting\Currency;
15
-use App\Models\Setting\Discount;
16
 use App\Models\Setting\DocumentDefault;
15
 use App\Models\Setting\DocumentDefault;
17
 use App\Models\Setting\Localization;
16
 use App\Models\Setting\Localization;
18
-use App\Models\Setting\Tax;
19
 use Filament\Models\Contracts\HasAvatar;
17
 use Filament\Models\Contracts\HasAvatar;
20
 use Illuminate\Database\Eloquent\Factories\HasFactory;
18
 use Illuminate\Database\Eloquent\Factories\HasFactory;
21
 use Illuminate\Database\Eloquent\Relations\HasMany;
19
 use Illuminate\Database\Eloquent\Relations\HasMany;
74
         return $this->hasMany(Accounting\Account::class, 'company_id');
72
         return $this->hasMany(Accounting\Account::class, 'company_id');
75
     }
73
     }
76
 
74
 
75
+    public function adjustments(): HasMany
76
+    {
77
+        return $this->hasMany(Accounting\Adjustment::class, 'company_id');
78
+    }
79
+
77
     public function bankAccounts(): HasMany
80
     public function bankAccounts(): HasMany
78
     {
81
     {
79
         return $this->hasMany(BankAccount::class, 'company_id');
82
         return $this->hasMany(BankAccount::class, 'company_id');
122
         return $this->hasMany(Department::class, 'company_id');
125
         return $this->hasMany(Department::class, 'company_id');
123
     }
126
     }
124
 
127
 
125
-    public function discounts(): HasMany
126
-    {
127
-        return $this->hasMany(Discount::class, 'company_id');
128
-    }
129
-
130
     public function locale(): HasOne
128
     public function locale(): HasOne
131
     {
129
     {
132
         return $this->hasOne(Localization::class, 'company_id');
130
         return $this->hasOne(Localization::class, 'company_id');
137
         return $this->hasOne(CompanyProfile::class, 'company_id');
135
         return $this->hasOne(CompanyProfile::class, 'company_id');
138
     }
136
     }
139
 
137
 
140
-    public function taxes(): HasMany
141
-    {
142
-        return $this->hasMany(Tax::class, 'company_id');
143
-    }
144
-
145
     public function transactions(): HasMany
138
     public function transactions(): HasMany
146
     {
139
     {
147
         return $this->hasMany(Accounting\Transaction::class, 'company_id');
140
         return $this->hasMany(Accounting\Transaction::class, 'company_id');

+ 0
- 30
app/Models/Setting/CompanyDefault.php View File

4
 
4
 
5
 use App\Concerns\Blamable;
5
 use App\Concerns\Blamable;
6
 use App\Concerns\CompanyOwned;
6
 use App\Concerns\CompanyOwned;
7
-use App\Enums\Setting\DiscountType;
8
-use App\Enums\Setting\TaxType;
9
 use App\Models\Banking\BankAccount;
7
 use App\Models\Banking\BankAccount;
10
 use Database\Factories\Setting\CompanyDefaultFactory;
8
 use Database\Factories\Setting\CompanyDefaultFactory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
25
         'company_id',
23
         'company_id',
26
         'bank_account_id',
24
         'bank_account_id',
27
         'currency_code',
25
         'currency_code',
28
-        'sales_tax_id',
29
-        'purchase_tax_id',
30
-        'sales_discount_id',
31
-        'purchase_discount_id',
32
         'created_by',
26
         'created_by',
33
         'updated_by',
27
         'updated_by',
34
     ];
28
     ];
43
         return $this->belongsTo(Currency::class, 'currency_code', 'code');
37
         return $this->belongsTo(Currency::class, 'currency_code', 'code');
44
     }
38
     }
45
 
39
 
46
-    public function salesTax(): BelongsTo
47
-    {
48
-        return $this->belongsTo(Tax::class, 'sales_tax_id', 'id')
49
-            ->where('type', TaxType::Sales);
50
-    }
51
-
52
-    public function purchaseTax(): BelongsTo
53
-    {
54
-        return $this->belongsTo(Tax::class, 'purchase_tax_id', 'id')
55
-            ->where('type', TaxType::Purchase);
56
-    }
57
-
58
-    public function salesDiscount(): BelongsTo
59
-    {
60
-        return $this->belongsTo(Discount::class, 'sales_discount_id', 'id')
61
-            ->where('type', DiscountType::Sales);
62
-    }
63
-
64
-    public function purchaseDiscount(): BelongsTo
65
-    {
66
-        return $this->belongsTo(Discount::class, 'purchase_discount_id', 'id')
67
-            ->where('type', DiscountType::Purchase);
68
-    }
69
-
70
     protected static function newFactory(): Factory
40
     protected static function newFactory(): Factory
71
     {
41
     {
72
         return CompanyDefaultFactory::new();
42
         return CompanyDefaultFactory::new();

+ 8
- 2
app/Models/Setting/Discount.php View File

10
 use App\Enums\Setting\DiscountComputation;
10
 use App\Enums\Setting\DiscountComputation;
11
 use App\Enums\Setting\DiscountScope;
11
 use App\Enums\Setting\DiscountScope;
12
 use App\Enums\Setting\DiscountType;
12
 use App\Enums\Setting\DiscountType;
13
+use App\Models\Accounting\Account;
13
 use Database\Factories\Setting\DiscountFactory;
14
 use Database\Factories\Setting\DiscountFactory;
14
 use Illuminate\Database\Eloquent\Factories\Factory;
15
 use Illuminate\Database\Eloquent\Factories\Factory;
15
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 use Illuminate\Database\Eloquent\Model;
17
 use Illuminate\Database\Eloquent\Model;
18
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
17
 use Illuminate\Database\Eloquent\Relations\HasOne;
19
 use Illuminate\Database\Eloquent\Relations\HasOne;
18
 use Illuminate\Database\Eloquent\Relations\MorphTo;
20
 use Illuminate\Database\Eloquent\Relations\MorphTo;
19
 
21
 
29
 
31
 
30
     protected $fillable = [
32
     protected $fillable = [
31
         'company_id',
33
         'company_id',
32
-        'name',
33
-        'description',
34
+        'account_id',
34
         'rate',
35
         'rate',
35
         'computation',
36
         'computation',
36
         'type',
37
         'type',
54
 
55
 
55
     protected ?string $evaluatedDefault = 'type';
56
     protected ?string $evaluatedDefault = 'type';
56
 
57
 
58
+    public function account(): BelongsTo
59
+    {
60
+        return $this->belongsTo(Account::class, 'account_id');
61
+    }
62
+
57
     public function defaultSalesDiscount(): HasOne
63
     public function defaultSalesDiscount(): HasOne
58
     {
64
     {
59
         return $this->hasOne(CompanyDefault::class, 'sales_discount_id');
65
         return $this->hasOne(CompanyDefault::class, 'sales_discount_id');

+ 8
- 2
app/Models/Setting/Tax.php View File

10
 use App\Enums\Setting\TaxComputation;
10
 use App\Enums\Setting\TaxComputation;
11
 use App\Enums\Setting\TaxScope;
11
 use App\Enums\Setting\TaxScope;
12
 use App\Enums\Setting\TaxType;
12
 use App\Enums\Setting\TaxType;
13
+use App\Models\Accounting\Account;
13
 use Database\Factories\Setting\TaxFactory;
14
 use Database\Factories\Setting\TaxFactory;
14
 use Illuminate\Database\Eloquent\Factories\Factory;
15
 use Illuminate\Database\Eloquent\Factories\Factory;
15
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 use Illuminate\Database\Eloquent\Model;
17
 use Illuminate\Database\Eloquent\Model;
18
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
17
 use Illuminate\Database\Eloquent\Relations\HasOne;
19
 use Illuminate\Database\Eloquent\Relations\HasOne;
18
 use Illuminate\Database\Eloquent\Relations\MorphTo;
20
 use Illuminate\Database\Eloquent\Relations\MorphTo;
19
 
21
 
29
 
31
 
30
     protected $fillable = [
32
     protected $fillable = [
31
         'company_id',
33
         'company_id',
32
-        'name',
33
-        'description',
34
+        'account_id',
34
         'rate',
35
         'rate',
35
         'computation',
36
         'computation',
36
         'type',
37
         'type',
50
 
51
 
51
     protected ?string $evaluatedDefault = 'type';
52
     protected ?string $evaluatedDefault = 'type';
52
 
53
 
54
+    public function account(): BelongsTo
55
+    {
56
+        return $this->belongsTo(Account::class, 'account_id');
57
+    }
58
+
53
     public function defaultSalesTax(): HasOne
59
     public function defaultSalesTax(): HasOne
54
     {
60
     {
55
         return $this->hasOne(CompanyDefault::class, 'sales_tax_id');
61
         return $this->hasOne(CompanyDefault::class, 'sales_tax_id');

+ 35
- 0
app/Services/ChartOfAccountsService.php View File

5
 use App\Enums\Accounting\AccountType;
5
 use App\Enums\Accounting\AccountType;
6
 use App\Enums\Banking\BankAccountType;
6
 use App\Enums\Banking\BankAccountType;
7
 use App\Models\Accounting\AccountSubtype;
7
 use App\Models\Accounting\AccountSubtype;
8
+use App\Models\Accounting\Adjustment;
8
 use App\Models\Banking\BankAccount;
9
 use App\Models\Banking\BankAccount;
9
 use App\Models\Company;
10
 use App\Models\Company;
10
 use App\Utilities\Currency\CurrencyAccessor;
11
 use App\Utilities\Currency\CurrencyAccessor;
77
                     $bankAccount->account()->associate($account);
78
                     $bankAccount->account()->associate($account);
78
                     $bankAccount->saveQuietly();
79
                     $bankAccount->saveQuietly();
79
                 }
80
                 }
81
+
82
+                if (isset($subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type'])) {
83
+                    $adjustment = $this->createAdjustmentForAccount($company, $subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type']);
84
+
85
+                    // Associate the Adjustment with the Account
86
+                    $adjustment->account()->associate($account);
87
+                    $adjustment->saveQuietly();
88
+                }
80
             }
89
             }
81
         }
90
         }
82
     }
91
     }
92
             'updated_by' => $company->owner->id,
101
             'updated_by' => $company->owner->id,
93
         ]);
102
         ]);
94
     }
103
     }
104
+
105
+    private function createAdjustmentForAccount(Company $company, string $category, string $type): Adjustment
106
+    {
107
+        $noDefaultAdjustmentType = $company->adjustments()->where('category', $category)
108
+            ->where('type', $type)
109
+            ->where('enabled', true)
110
+            ->doesntExist();
111
+
112
+        $defaultRate = match ([$category, $type]) {
113
+            ['tax', 'sales'] => 8,          // Default 8% for Sales Tax
114
+            ['tax', 'purchase'] => 8,       // Default 8% for Purchase Tax
115
+            ['discount', 'sales'] => 5,     // Default 5% for Sales Discount
116
+            ['discount', 'purchase'] => 5,  // Default 5% for Purchase Discount
117
+            default => 0,                   // Default to 0 if unspecified
118
+        };
119
+
120
+        return $company->adjustments()->createQuietly([
121
+            'category' => $category,
122
+            'type' => $type,
123
+            'rate' => $defaultRate,
124
+            'computation' => 'percentage',
125
+            'enabled' => $noDefaultAdjustmentType,
126
+            'created_by' => $company->owner->id,
127
+            'updated_by' => $company->owner->id,
128
+        ]);
129
+    }
95
 }
130
 }

+ 6
- 6
composer.lock View File

497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.326.0",
500
+            "version": "3.327.0",
501
             "source": {
501
             "source": {
502
                 "type": "git",
502
                 "type": "git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "5420284de9aad84e375fa8012cefd834bebfd623"
504
+                "reference": "ba4a7ac2544de61b33f693c461f8b09c0353298f"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5420284de9aad84e375fa8012cefd834bebfd623",
509
-                "reference": "5420284de9aad84e375fa8012cefd834bebfd623",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ba4a7ac2544de61b33f693c461f8b09c0353298f",
509
+                "reference": "ba4a7ac2544de61b33f693c461f8b09c0353298f",
510
                 "shasum": ""
510
                 "shasum": ""
511
             },
511
             },
512
             "require": {
512
             "require": {
589
             "support": {
589
             "support": {
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.326.0"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.327.0"
593
             },
593
             },
594
-            "time": "2024-11-13T19:07:44+00:00"
594
+            "time": "2024-11-14T19:06:19+00:00"
595
         },
595
         },
596
         {
596
         {
597
             "name": "aws/aws-sdk-php-laravel",
597
             "name": "aws/aws-sdk-php-laravel",

+ 47
- 6
config/chart-of-accounts.php View File

118
                 'multi_currency' => false,
118
                 'multi_currency' => false,
119
                 'base_code' => '2100',
119
                 'base_code' => '2100',
120
                 'inverse_cash_flow' => false,
120
                 'inverse_cash_flow' => false,
121
+            ],
122
+            'Sales Taxes' => [
123
+                'description' => 'The amount of money owed to the government for sales tax collected from customers.',
124
+                'multi_currency' => false,
125
+                'base_code' => '2150',
126
+                'inverse_cash_flow' => false,
127
+                'adjustment_category' => 'tax',
128
+                'adjustment_type' => 'sales',
121
                 'accounts' => [
129
                 'accounts' => [
122
-                    'Sales Tax Payable' => [
123
-                        'description' => 'The amount of money owed to the government for sales tax collected from customers.',
130
+                    'Sales Tax' => [
131
+                        'description' => null,
124
                     ],
132
                     ],
125
                 ],
133
                 ],
126
             ],
134
             ],
271
                     'Sales Returns and Allowances' => [
279
                     'Sales Returns and Allowances' => [
272
                         'description' => 'The amount of money returned to customers or deducted from sales due to returned goods or allowances granted.',
280
                         'description' => 'The amount of money returned to customers or deducted from sales due to returned goods or allowances granted.',
273
                     ],
281
                     ],
274
-                    'Sales Discounts' => [
275
-                        'description' => 'The amount of money deducted from sales due to discounts offered to customers for early payment or other reasons.',
282
+                ],
283
+            ],
284
+            'Sales Discounts' => [
285
+                'description' => 'The amount of money deducted from sales due to discounts offered to customers for early payment or other reasons.',
286
+                'multi_currency' => false,
287
+                'base_code' => '4925',
288
+                'inverse_cash_flow' => false,
289
+                'adjustment_category' => 'discount',
290
+                'adjustment_type' => 'sales',
291
+                'accounts' => [
292
+                    'Sales Discount' => [
293
+                        'description' => null,
276
                     ],
294
                     ],
277
                 ],
295
                 ],
278
             ],
296
             ],
412
                 'base_code' => '5600',
430
                 'base_code' => '5600',
413
                 'inverse_cash_flow' => true,
431
                 'inverse_cash_flow' => true,
414
             ],
432
             ],
433
+            'Purchase Taxes' => [
434
+                'description' => 'Taxes paid on purchases of goods or services, such as value-added tax (VAT), goods and services tax (GST), or customs duties.',
435
+                'multi_currency' => false,
436
+                'base_code' => '5650',
437
+                'inverse_cash_flow' => true,
438
+                'adjustment_category' => 'tax',
439
+                'adjustment_type' => 'purchase',
440
+                'accounts' => [
441
+                    'Purchase Tax' => [
442
+                        'description' => null,
443
+                    ],
444
+                ],
445
+            ],
415
             'Other Non-Operating Expense' => [
446
             'Other Non-Operating Expense' => [
416
                 'description' => 'Expenses not related to primary business activities, like losses from asset disposals, legal settlements, restructuring costs, or foreign exchange losses.',
447
                 'description' => 'Expenses not related to primary business activities, like losses from asset disposals, legal settlements, restructuring costs, or foreign exchange losses.',
417
                 'multi_currency' => false,
448
                 'multi_currency' => false,
434
                     'Purchase Returns and Allowances' => [
465
                     'Purchase Returns and Allowances' => [
435
                         'description' => 'The amount of money returned to suppliers or deducted from purchases due to returned goods or allowances granted.',
466
                         'description' => 'The amount of money returned to suppliers or deducted from purchases due to returned goods or allowances granted.',
436
                     ],
467
                     ],
437
-                    'Purchase Discounts' => [
438
-                        'description' => 'The amount of money deducted from purchases due to discounts offered by suppliers for early payment or other reasons.',
468
+                ],
469
+            ],
470
+            'Purchase Discounts' => [
471
+                'description' => 'The amount of money deducted from purchases due to discounts offered by suppliers for early payment or other reasons.',
472
+                'multi_currency' => false,
473
+                'base_code' => '5925',
474
+                'inverse_cash_flow' => true,
475
+                'adjustment_category' => 'discount',
476
+                'adjustment_type' => 'purchase',
477
+                'accounts' => [
478
+                    'Purchase Discount' => [
479
+                        'description' => null,
439
                     ],
480
                     ],
440
                 ],
481
                 ],
441
             ],
482
             ],

+ 57
- 0
database/factories/Accounting/AccountFactory.php View File

6
 use App\Models\Accounting\AccountSubtype;
6
 use App\Models\Accounting\AccountSubtype;
7
 use App\Models\Banking\BankAccount;
7
 use App\Models\Banking\BankAccount;
8
 use App\Models\Setting\Currency;
8
 use App\Models\Setting\Currency;
9
+use App\Utilities\Accounting\AccountCode;
9
 use App\Utilities\Currency\CurrencyAccessor;
10
 use App\Utilities\Currency\CurrencyAccessor;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 
12
 
74
             ]);
75
             ]);
75
         });
76
         });
76
     }
77
     }
78
+
79
+    public function forSalesTax(?string $name = null, ?string $description = null): static
80
+    {
81
+        $accountSubtype = AccountSubtype::where('name', 'Sales Taxes')->first();
82
+
83
+        return $this->state([
84
+            'name' => $name,
85
+            'description' => $description,
86
+            'category' => $accountSubtype->category,
87
+            'type' => $accountSubtype->type,
88
+            'subtype_id' => $accountSubtype->id,
89
+            'code' => AccountCode::generate($accountSubtype),
90
+        ]);
91
+    }
92
+
93
+    public function forPurchaseTax(?string $name = null, ?string $description = null): static
94
+    {
95
+        $accountSubtype = AccountSubtype::where('name', 'Purchase Taxes')->first();
96
+
97
+        return $this->state([
98
+            'name' => $name,
99
+            'description' => $description,
100
+            'category' => $accountSubtype->category,
101
+            'type' => $accountSubtype->type,
102
+            'subtype_id' => $accountSubtype->id,
103
+            'code' => AccountCode::generate($accountSubtype),
104
+        ]);
105
+    }
106
+
107
+    public function forSalesDiscount(?string $name = null, ?string $description = null): static
108
+    {
109
+        $accountSubtype = AccountSubtype::where('name', 'Sales Discounts')->first();
110
+
111
+        return $this->state([
112
+            'name' => $name,
113
+            'description' => $description,
114
+            'category' => $accountSubtype->category,
115
+            'type' => $accountSubtype->type,
116
+            'subtype_id' => $accountSubtype->id,
117
+            'code' => AccountCode::generate($accountSubtype),
118
+        ]);
119
+    }
120
+
121
+    public function forPurchaseDiscount(?string $name = null, ?string $description = null): static
122
+    {
123
+        $accountSubtype = AccountSubtype::where('name', 'Purchase Discounts')->first();
124
+
125
+        return $this->state([
126
+            'name' => $name,
127
+            'description' => $description,
128
+            'category' => $accountSubtype->category,
129
+            'type' => $accountSubtype->type,
130
+            'subtype_id' => $accountSubtype->id,
131
+            'code' => AccountCode::generate($accountSubtype),
132
+        ]);
133
+    }
77
 }
134
 }

+ 120
- 0
database/factories/Accounting/AdjustmentFactory.php View File

1
+<?php
2
+
3
+namespace Database\Factories\Accounting;
4
+
5
+use App\Enums\Accounting\AdjustmentCategory;
6
+use App\Enums\Accounting\AdjustmentComputation;
7
+use App\Enums\Accounting\AdjustmentScope;
8
+use App\Enums\Accounting\AdjustmentType;
9
+use App\Models\Accounting\Account;
10
+use App\Models\Accounting\Adjustment;
11
+use Illuminate\Database\Eloquent\Factories\Factory;
12
+use Illuminate\Support\Carbon;
13
+
14
+/**
15
+ * @extends Factory<Adjustment>
16
+ */
17
+class AdjustmentFactory extends Factory
18
+{
19
+    /**
20
+     * The name of the factory's corresponding model.
21
+     */
22
+    protected $model = Adjustment::class;
23
+
24
+    /**
25
+     * Define the model's default state.
26
+     *
27
+     * @return array<string, mixed>
28
+     */
29
+    public function definition(): array
30
+    {
31
+        $startDate = $this->faker->dateTimeBetween('now', '+1 year');
32
+        $endDate = $this->faker->dateTimeBetween($startDate, Carbon::parse($startDate)->addYear());
33
+        $computation = $this->faker->randomElement(AdjustmentComputation::class);
34
+
35
+        $rate = $computation === AdjustmentComputation::Fixed
36
+            ? $this->faker->numberBetween(5, 100) * 100 // $5 - $100 for fixed amounts
37
+            : $this->faker->numberBetween(3, 25) * 10000; // 3% - 25% for percentages
38
+
39
+        return [
40
+            'rate' => $rate,
41
+            'computation' => $computation,
42
+            'category' => $this->faker->randomElement(AdjustmentCategory::class),
43
+            'type' => $this->faker->randomElement(AdjustmentType::class),
44
+            'scope' => $this->faker->randomElement(AdjustmentScope::class),
45
+            'start_date' => $startDate,
46
+            'end_date' => $endDate,
47
+            'enabled' => false,
48
+        ];
49
+    }
50
+
51
+    public function configure(): static
52
+    {
53
+        return $this->afterCreating(function (Adjustment $adjustment) {
54
+            if ($adjustment->account_id === null) {
55
+                $account = Account::factory()->create();
56
+                $adjustment->account()->associate($account);
57
+            }
58
+        });
59
+    }
60
+
61
+    /**
62
+     * Define a sales tax adjustment.
63
+     */
64
+    public function salesTax(?string $name = null, ?string $description = null): self
65
+    {
66
+        $name = $name ?? 'Sales Tax';
67
+        $account = Account::factory()->forSalesTax($name, $description)->create();
68
+
69
+        return $this->state([
70
+            'category' => AdjustmentCategory::Tax,
71
+            'type' => AdjustmentType::Sales,
72
+            'account_id' => $account->id,
73
+        ]);
74
+    }
75
+
76
+    /**
77
+     * Define a purchase tax adjustment.
78
+     */
79
+    public function purchaseTax(?string $name = null, ?string $description = null): self
80
+    {
81
+        $name = $name ?? 'Purchase Tax';
82
+        $account = Account::factory()->forPurchaseTax($name, $description)->create();
83
+
84
+        return $this->state([
85
+            'category' => AdjustmentCategory::Tax,
86
+            'type' => AdjustmentType::Purchase,
87
+            'account_id' => $account->id,
88
+        ]);
89
+    }
90
+
91
+    /**
92
+     * Define a sales discount adjustment.
93
+     */
94
+    public function salesDiscount(?string $name = null, ?string $description = null): self
95
+    {
96
+        $name = $name ?? 'Sales Discount';
97
+        $account = Account::factory()->forSalesDiscount($name, $description)->create();
98
+
99
+        return $this->state([
100
+            'category' => AdjustmentCategory::Discount,
101
+            'type' => AdjustmentType::Sales,
102
+            'account_id' => $account->id,
103
+        ]);
104
+    }
105
+
106
+    /**
107
+     * Define a purchase discount adjustment.
108
+     */
109
+    public function purchaseDiscount(?string $name = null, ?string $description = null): self
110
+    {
111
+        $name = $name ?? 'Purchase Discount';
112
+        $account = Account::factory()->forPurchaseDiscount($name, $description)->create();
113
+
114
+        return $this->state([
115
+            'category' => AdjustmentCategory::Discount,
116
+            'type' => AdjustmentType::Purchase,
117
+            'account_id' => $account->id,
118
+        ]);
119
+    }
120
+}

database/factories/DocumentFactory.php → database/factories/Accounting/DocumentFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Accounting;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Document>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Accounting\Document>
9
  */
9
  */
10
 class DocumentFactory extends Factory
10
 class DocumentFactory extends Factory
11
 {
11
 {

database/factories/DocumentLineItemFactory.php → database/factories/Accounting/DocumentLineItemFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Accounting;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\DocumentLineItem>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Accounting\DocumentLineItem>
9
  */
9
  */
10
 class DocumentLineItemFactory extends Factory
10
 class DocumentLineItemFactory extends Factory
11
 {
11
 {

+ 6
- 0
database/factories/Accounting/TransactionFactory.php View File

5
 use App\Enums\Accounting\AccountType;
5
 use App\Enums\Accounting\AccountType;
6
 use App\Enums\Accounting\TransactionType;
6
 use App\Enums\Accounting\TransactionType;
7
 use App\Models\Accounting\Account;
7
 use App\Models\Accounting\Account;
8
+use App\Models\Accounting\AccountSubtype;
8
 use App\Models\Accounting\Transaction;
9
 use App\Models\Accounting\Transaction;
9
 use App\Models\Banking\BankAccount;
10
 use App\Models\Banking\BankAccount;
10
 use App\Models\Company;
11
 use App\Models\Company;
69
 
70
 
70
             $accountIdForBankAccount = $bankAccount->account->id;
71
             $accountIdForBankAccount = $bankAccount->account->id;
71
 
72
 
73
+            $excludedSubtypes = AccountSubtype::where('company_id', $company->id)
74
+                ->whereIn('name', ['Sales Taxes', 'Purchase Taxes', 'Sales Discounts', 'Purchase Discounts'])
75
+                ->pluck('id');
76
+
72
             $account = Account::whereIn('type', $associatedAccountTypes)
77
             $account = Account::whereIn('type', $associatedAccountTypes)
73
                 ->where('company_id', $company->id)
78
                 ->where('company_id', $company->id)
79
+                ->whereNotIn('subtype_id', $excludedSubtypes)
74
                 ->whereKeyNot($accountIdForBankAccount)
80
                 ->whereKeyNot($accountIdForBankAccount)
75
                 ->inRandomOrder()
81
                 ->inRandomOrder()
76
                 ->first();
82
                 ->first();

database/factories/PaymentFactory.php → database/factories/Banking/PaymentFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Banking;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Payment>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Banking\Payment>
9
  */
9
  */
10
 class PaymentFactory extends Factory
10
 class PaymentFactory extends Factory
11
 {
11
 {

database/factories/ClientFactory.php → database/factories/Common/ClientFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Common;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Client>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Common\Client>
9
  */
9
  */
10
 class ClientFactory extends Factory
10
 class ClientFactory extends Factory
11
 {
11
 {

database/factories/OfferingFactory.php → database/factories/Common/OfferingFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Common;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Offering>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Common\Offering>
9
  */
9
  */
10
 class OfferingFactory extends Factory
10
 class OfferingFactory extends Factory
11
 {
11
 {

database/factories/VendorFactory.php → database/factories/Common/VendorFactory.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-namespace Database\Factories;
3
+namespace Database\Factories\Common;
4
 
4
 
5
 use Illuminate\Database\Eloquent\Factories\Factory;
5
 use Illuminate\Database\Eloquent\Factories\Factory;
6
 
6
 
7
 /**
7
 /**
8
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Vendor>
8
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Common\Vendor>
9
  */
9
  */
10
 class VendorFactory extends Factory
10
 class VendorFactory extends Factory
11
 {
11
 {

+ 0
- 50
database/factories/Setting/CompanyDefaultFactory.php View File

7
 use App\Models\Setting\Appearance;
7
 use App\Models\Setting\Appearance;
8
 use App\Models\Setting\CompanyDefault;
8
 use App\Models\Setting\CompanyDefault;
9
 use App\Models\Setting\Currency;
9
 use App\Models\Setting\Currency;
10
-use App\Models\Setting\Discount;
11
 use App\Models\Setting\DocumentDefault;
10
 use App\Models\Setting\DocumentDefault;
12
 use App\Models\Setting\Localization;
11
 use App\Models\Setting\Localization;
13
-use App\Models\Setting\Tax;
14
 use App\Models\User;
12
 use App\Models\User;
15
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Database\Eloquent\Factories\Factory;
16
 
14
 
46
         }
44
         }
47
 
45
 
48
         $currency = $this->createCurrency($company, $user, $currencyCode);
46
         $currency = $this->createCurrency($company, $user, $currencyCode);
49
-        $salesTax = $this->createSalesTax($company, $user);
50
-        $purchaseTax = $this->createPurchaseTax($company, $user);
51
-        $salesDiscount = $this->createSalesDiscount($company, $user);
52
-        $purchaseDiscount = $this->createPurchaseDiscount($company, $user);
53
         $this->createAppearance($company, $user);
47
         $this->createAppearance($company, $user);
54
         $this->createDocumentDefaults($company, $user);
48
         $this->createDocumentDefaults($company, $user);
55
         $this->createLocalization($company, $user, $countryCode, $language);
49
         $this->createLocalization($company, $user, $countryCode, $language);
57
         $companyDefaults = [
51
         $companyDefaults = [
58
             'company_id' => $company->id,
52
             'company_id' => $company->id,
59
             'currency_code' => $currency->code,
53
             'currency_code' => $currency->code,
60
-            'sales_tax_id' => $salesTax->id,
61
-            'purchase_tax_id' => $purchaseTax->id,
62
-            'sales_discount_id' => $salesDiscount->id,
63
-            'purchase_discount_id' => $purchaseDiscount->id,
64
             'created_by' => $user->id,
54
             'created_by' => $user->id,
65
             'updated_by' => $user->id,
55
             'updated_by' => $user->id,
66
         ];
56
         ];
78
         ]);
68
         ]);
79
     }
69
     }
80
 
70
 
81
-    private function createSalesTax(Company $company, User $user): Tax
82
-    {
83
-        return Tax::factory()->salesTax()->createQuietly([
84
-            'company_id' => $company->id,
85
-            'enabled' => true,
86
-            'created_by' => $user->id,
87
-            'updated_by' => $user->id,
88
-        ]);
89
-    }
90
-
91
-    private function createPurchaseTax(Company $company, User $user): Tax
92
-    {
93
-        return Tax::factory()->purchaseTax()->createQuietly([
94
-            'company_id' => $company->id,
95
-            'enabled' => true,
96
-            'created_by' => $user->id,
97
-            'updated_by' => $user->id,
98
-        ]);
99
-    }
100
-
101
-    private function createSalesDiscount(Company $company, User $user): Discount
102
-    {
103
-        return Discount::factory()->salesDiscount()->createQuietly([
104
-            'company_id' => $company->id,
105
-            'enabled' => true,
106
-            'created_by' => $user->id,
107
-            'updated_by' => $user->id,
108
-        ]);
109
-    }
110
-
111
-    private function createPurchaseDiscount(Company $company, User $user): Discount
112
-    {
113
-        return Discount::factory()->purchaseDiscount()->createQuietly([
114
-            'company_id' => $company->id,
115
-            'enabled' => true,
116
-            'created_by' => $user->id,
117
-            'updated_by' => $user->id,
118
-        ]);
119
-    }
120
-
121
     private function createAppearance(Company $company, User $user): void
71
     private function createAppearance(Company $company, User $user): void
122
     {
72
     {
123
         Appearance::factory()->createQuietly([
73
         Appearance::factory()->createQuietly([

+ 0
- 68
database/factories/Setting/DiscountFactory.php View File

1
-<?php
2
-
3
-namespace Database\Factories\Setting;
4
-
5
-use App\Enums\Setting\DiscountComputation;
6
-use App\Enums\Setting\DiscountScope;
7
-use App\Enums\Setting\DiscountType;
8
-use App\Models\Setting\Discount;
9
-use Illuminate\Database\Eloquent\Factories\Factory;
10
-use Illuminate\Support\Carbon;
11
-
12
-/**
13
- * @extends Factory<Discount>
14
- */
15
-class DiscountFactory extends Factory
16
-{
17
-    /**
18
-     * The name of the factory's corresponding model.
19
-     */
20
-    protected $model = Discount::class;
21
-
22
-    /**
23
-     * Define the model's default state.
24
-     *
25
-     * @return array<string, mixed>
26
-     */
27
-    public function definition(): array
28
-    {
29
-        $startDate = $this->faker->dateTimeBetween('now', '+1 year');
30
-        $endDate = $this->faker->dateTimeBetween($startDate, Carbon::parse($startDate)->addYear());
31
-
32
-        $computation = $this->faker->randomElement(DiscountComputation::class);
33
-
34
-        if ($computation === DiscountComputation::Fixed) {
35
-            $rate = $this->faker->numberBetween(5, 100) * 100; // $5 - $100
36
-        } else {
37
-            $rate = $this->faker->numberBetween(3, 50) * 10000; // 3% - 50%
38
-        }
39
-
40
-        return [
41
-            'name' => $this->faker->unique()->word,
42
-            'description' => $this->faker->sentence,
43
-            'rate' => $rate,
44
-            'computation' => $computation,
45
-            'type' => $this->faker->randomElement(DiscountType::class),
46
-            'scope' => $this->faker->randomElement(DiscountScope::class),
47
-            'start_date' => $startDate,
48
-            'end_date' => $endDate,
49
-            'enabled' => false,
50
-        ];
51
-    }
52
-
53
-    public function salesDiscount(): self
54
-    {
55
-        return $this->state([
56
-            'name' => 'Summer Sale',
57
-            'type' => DiscountType::Sales,
58
-        ]);
59
-    }
60
-
61
-    public function purchaseDiscount(): self
62
-    {
63
-        return $this->state([
64
-            'name' => 'Bulk Purchase',
65
-            'type' => DiscountType::Purchase,
66
-        ]);
67
-    }
68
-}

+ 0
- 62
database/factories/Setting/TaxFactory.php View File

1
-<?php
2
-
3
-namespace Database\Factories\Setting;
4
-
5
-use App\Enums\Setting\TaxComputation;
6
-use App\Enums\Setting\TaxScope;
7
-use App\Enums\Setting\TaxType;
8
-use App\Models\Setting\Tax;
9
-use Illuminate\Database\Eloquent\Factories\Factory;
10
-
11
-/**
12
- * @extends Factory<Tax>
13
- */
14
-class TaxFactory extends Factory
15
-{
16
-    /**
17
-     * The name of the factory's corresponding model.
18
-     */
19
-    protected $model = Tax::class;
20
-
21
-    /**
22
-     * Define the model's default state.
23
-     *
24
-     * @return array<string, mixed>
25
-     */
26
-    public function definition(): array
27
-    {
28
-        $computation = $this->faker->randomElement(TaxComputation::class);
29
-
30
-        if ($computation === TaxComputation::Fixed) {
31
-            $rate = $this->faker->biasedNumberBetween(1, 10) * 100; // $1 - $10
32
-        } else {
33
-            $rate = $this->faker->biasedNumberBetween(3, 25) * 10000; // 3% - 25%
34
-        }
35
-
36
-        return [
37
-            'name' => $this->faker->unique()->word,
38
-            'description' => $this->faker->sentence,
39
-            'rate' => $rate,
40
-            'computation' => $computation,
41
-            'type' => $this->faker->randomElement(TaxType::class),
42
-            'scope' => $this->faker->randomElement(TaxScope::class),
43
-            'enabled' => false,
44
-        ];
45
-    }
46
-
47
-    public function salesTax(): self
48
-    {
49
-        return $this->state([
50
-            'name' => 'State Sales Tax',
51
-            'type' => TaxType::Sales,
52
-        ]);
53
-    }
54
-
55
-    public function purchaseTax(): self
56
-    {
57
-        return $this->state([
58
-            'name' => 'State Purchase Tax',
59
-            'type' => TaxType::Purchase,
60
-        ]);
61
-    }
62
-}

+ 4
- 3
database/migrations/2023_09_03_100000_create_accounting_tables.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-use App\Enums\Banking\BankAccountType;
4
 use Illuminate\Database\Migrations\Migration;
3
 use Illuminate\Database\Migrations\Migration;
5
 use Illuminate\Database\Schema\Blueprint;
4
 use Illuminate\Database\Schema\Blueprint;
6
 use Illuminate\Support\Facades\Schema;
5
 use Illuminate\Support\Facades\Schema;
61
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
60
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
62
             $table->foreignId('account_id')->nullable()->constrained('accounts')->nullOnDelete();
61
             $table->foreignId('account_id')->nullable()->constrained('accounts')->nullOnDelete();
63
             $table->foreignId('institution_id')->nullable()->constrained('institutions')->nullOnDelete();
62
             $table->foreignId('institution_id')->nullable()->constrained('institutions')->nullOnDelete();
64
-            $table->string('type')->default(BankAccountType::DEFAULT);
63
+            $table->string('type')->default('depository');
65
             $table->string('number', 20)->nullable();
64
             $table->string('number', 20)->nullable();
66
             $table->boolean('enabled')->default(true);
65
             $table->boolean('enabled')->default(true);
67
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
66
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
68
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
67
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
69
             $table->timestamps();
68
             $table->timestamps();
69
+
70
+            $table->unique(['company_id', 'account_id']);
70
         });
71
         });
71
 
72
 
72
         Schema::create('connected_bank_accounts', function (Blueprint $table) {
73
         Schema::create('connected_bank_accounts', function (Blueprint $table) {
82
             $table->double('current_balance')->default(0);
83
             $table->double('current_balance')->default(0);
83
             $table->string('name');
84
             $table->string('name');
84
             $table->string('mask');
85
             $table->string('mask');
85
-            $table->string('type')->default(BankAccountType::DEFAULT);
86
+            $table->string('type')->default('depository');
86
             $table->string('subtype')->nullable();
87
             $table->string('subtype')->nullable();
87
             $table->boolean('import_transactions')->default(false);
88
             $table->boolean('import_transactions')->default(false);
88
             $table->timestamp('last_imported_at')->nullable();
89
             $table->timestamp('last_imported_at')->nullable();

+ 0
- 41
database/migrations/2023_09_08_011045_create_taxes_table.php View File

1
-<?php
2
-
3
-use App\Enums\Setting\TaxComputation;
4
-use App\Enums\Setting\TaxType;
5
-use Illuminate\Database\Migrations\Migration;
6
-use Illuminate\Database\Schema\Blueprint;
7
-use Illuminate\Support\Facades\Schema;
8
-
9
-return new class extends Migration
10
-{
11
-    /**
12
-     * Run the migrations.
13
-     */
14
-    public function up(): void
15
-    {
16
-        Schema::create('taxes', function (Blueprint $table) {
17
-            $table->id();
18
-            $table->foreignId('company_id')->constrained()->cascadeOnDelete();
19
-            $table->string('name')->index();
20
-            $table->string('description')->nullable();
21
-            $table->integer('rate')->default(0);
22
-            $table->string('computation')->default(TaxComputation::DEFAULT);
23
-            $table->string('type')->default(TaxType::DEFAULT);
24
-            $table->string('scope')->nullable();
25
-            $table->boolean('enabled')->default(true);
26
-            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
27
-            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
28
-            $table->timestamps();
29
-
30
-            $table->unique(['company_id', 'name', 'type']);
31
-        });
32
-    }
33
-
34
-    /**
35
-     * Reverse the migrations.
36
-     */
37
-    public function down(): void
38
-    {
39
-        Schema::dropIfExists('taxes');
40
-    }
41
-};

+ 0
- 4
database/migrations/2023_09_08_040159_create_company_defaults_table.php View File

16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
17
             $table->foreignId('bank_account_id')->nullable()->constrained('bank_accounts')->nullOnDelete();
17
             $table->foreignId('bank_account_id')->nullable()->constrained('bank_accounts')->nullOnDelete();
18
             $table->string('currency_code')->nullable();
18
             $table->string('currency_code')->nullable();
19
-            $table->foreignId('sales_tax_id')->nullable()->constrained('taxes')->nullOnDelete();
20
-            $table->foreignId('purchase_tax_id')->nullable()->constrained('taxes')->nullOnDelete();
21
-            $table->foreignId('sales_discount_id')->nullable()->constrained('discounts')->nullOnDelete();
22
-            $table->foreignId('purchase_discount_id')->nullable()->constrained('discounts')->nullOnDelete();
23
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
19
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
24
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
20
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
25
             $table->timestamps();
21
             $table->timestamps();

+ 4
- 8
database/migrations/2023_09_12_014413_create_appearances_table.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-use App\Enums\Setting\Font;
4
-use App\Enums\Setting\PrimaryColor;
5
-use App\Enums\Setting\RecordsPerPage;
6
-use App\Enums\Setting\TableSortDirection;
7
 use Illuminate\Database\Migrations\Migration;
3
 use Illuminate\Database\Migrations\Migration;
8
 use Illuminate\Database\Schema\Blueprint;
4
 use Illuminate\Database\Schema\Blueprint;
9
 use Illuminate\Support\Facades\Schema;
5
 use Illuminate\Support\Facades\Schema;
18
         Schema::create('appearances', function (Blueprint $table) {
14
         Schema::create('appearances', function (Blueprint $table) {
19
             $table->id();
15
             $table->id();
20
             $table->foreignId('company_id')->constrained()->onDelete('cascade');
16
             $table->foreignId('company_id')->constrained()->onDelete('cascade');
21
-            $table->string('primary_color')->default(PrimaryColor::DEFAULT);
22
-            $table->string('font')->default(Font::DEFAULT);
23
-            $table->string('table_sort_direction')->default(TableSortDirection::DEFAULT);
24
-            $table->unsignedTinyInteger('records_per_page')->default(RecordsPerPage::DEFAULT);
17
+            $table->string('primary_color')->default('indigo');
18
+            $table->string('font')->default('inter');
19
+            $table->string('table_sort_direction')->default('asc');
20
+            $table->unsignedTinyInteger('records_per_page')->default(10);
25
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
21
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
26
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
22
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
27
             $table->timestamps();
23
             $table->timestamps();

+ 3
- 6
database/migrations/2023_09_12_032057_create_document_defaults_table.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-use App\Enums\Setting\Font;
4
-use App\Enums\Setting\PaymentTerms;
5
-use App\Enums\Setting\Template;
6
 use Illuminate\Database\Migrations\Migration;
3
 use Illuminate\Database\Migrations\Migration;
7
 use Illuminate\Database\Schema\Blueprint;
4
 use Illuminate\Database\Schema\Blueprint;
8
 use Illuminate\Support\Facades\Schema;
5
 use Illuminate\Support\Facades\Schema;
23
             $table->string('number_prefix')->nullable();
20
             $table->string('number_prefix')->nullable();
24
             $table->unsignedTinyInteger('number_digits')->default(5);
21
             $table->unsignedTinyInteger('number_digits')->default(5);
25
             $table->unsignedBigInteger('number_next')->default(1);
22
             $table->unsignedBigInteger('number_next')->default(1);
26
-            $table->string('payment_terms')->default(PaymentTerms::DEFAULT);
23
+            $table->string('payment_terms')->default('due_upon_receipt');
27
             $table->string('header')->nullable();
24
             $table->string('header')->nullable();
28
             $table->string('subheader')->nullable();
25
             $table->string('subheader')->nullable();
29
             $table->text('terms')->nullable();
26
             $table->text('terms')->nullable();
30
             $table->text('footer')->nullable();
27
             $table->text('footer')->nullable();
31
             $table->string('accent_color')->default('#4F46E5');
28
             $table->string('accent_color')->default('#4F46E5');
32
-            $table->string('font')->default(Font::DEFAULT);
33
-            $table->string('template')->default(Template::DEFAULT);
29
+            $table->string('font')->default('inter');
30
+            $table->string('template')->default('default');
34
             $table->json('item_name')->nullable();
31
             $table->json('item_name')->nullable();
35
             $table->json('unit_name')->nullable();
32
             $table->json('unit_name')->nullable();
36
             $table->json('price_name')->nullable();
33
             $table->json('price_name')->nullable();

+ 4
- 8
database/migrations/2023_10_11_210415_create_localizations_table.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-use App\Enums\Setting\DateFormat;
4
-use App\Enums\Setting\NumberFormat;
5
-use App\Enums\Setting\TimeFormat;
6
-use App\Enums\Setting\WeekStart;
7
 use Illuminate\Database\Migrations\Migration;
3
 use Illuminate\Database\Migrations\Migration;
8
 use Illuminate\Database\Schema\Blueprint;
4
 use Illuminate\Database\Schema\Blueprint;
9
 use Illuminate\Support\Facades\Schema;
5
 use Illuminate\Support\Facades\Schema;
20
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
21
             $table->string('language')->default('en');
17
             $table->string('language')->default('en');
22
             $table->string('timezone')->nullable();
18
             $table->string('timezone')->nullable();
23
-            $table->string('date_format')->default(DateFormat::DEFAULT);
24
-            $table->string('time_format')->default(TimeFormat::DEFAULT);
19
+            $table->string('date_format')->default('M j, Y');
20
+            $table->string('time_format')->default('g:i A');
25
             $table->unsignedTinyInteger('fiscal_year_end_month')->default(12);
21
             $table->unsignedTinyInteger('fiscal_year_end_month')->default(12);
26
             $table->unsignedTinyInteger('fiscal_year_end_day')->default(31);
22
             $table->unsignedTinyInteger('fiscal_year_end_day')->default(31);
27
-            $table->unsignedTinyInteger('week_start')->default(WeekStart::DEFAULT);
28
-            $table->string('number_format')->default(NumberFormat::DEFAULT);
23
+            $table->unsignedTinyInteger('week_start')->default(1);
24
+            $table->string('number_format')->default('comma_dot');
29
             $table->boolean('percent_first')->default(false);
25
             $table->boolean('percent_first')->default(false);
30
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
26
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
31
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
27
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();

database/migrations/2023_09_08_024259_create_discounts_table.php → database/migrations/2024_11_14_230753_create_adjustments_table.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-use App\Enums\Setting\DiscountComputation;
4
-use App\Enums\Setting\DiscountType;
5
 use Illuminate\Database\Migrations\Migration;
3
 use Illuminate\Database\Migrations\Migration;
6
 use Illuminate\Database\Schema\Blueprint;
4
 use Illuminate\Database\Schema\Blueprint;
7
 use Illuminate\Support\Facades\Schema;
5
 use Illuminate\Support\Facades\Schema;
13
      */
11
      */
14
     public function up(): void
12
     public function up(): void
15
     {
13
     {
16
-        Schema::create('discounts', function (Blueprint $table) {
14
+        Schema::create('adjustments', function (Blueprint $table) {
17
             $table->id();
15
             $table->id();
18
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
19
-            $table->string('name')->index();
20
-            $table->string('description')->nullable();
17
+            $table->foreignId('account_id')->nullable()->constrained('accounts')->nullOnDelete();
18
+            $table->string('category')->default('tax');
19
+            $table->string('type')->default('sales');
21
             $table->integer('rate')->default(0);
20
             $table->integer('rate')->default(0);
22
-            $table->string('computation')->default(DiscountComputation::DEFAULT);
23
-            $table->string('type')->default(DiscountType::DEFAULT);
21
+            $table->string('computation')->default('percentage');
24
             $table->string('scope')->nullable();
22
             $table->string('scope')->nullable();
25
             $table->dateTime('start_date')->nullable();
23
             $table->dateTime('start_date')->nullable();
26
             $table->dateTime('end_date')->nullable();
24
             $table->dateTime('end_date')->nullable();
29
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
27
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
30
             $table->timestamps();
28
             $table->timestamps();
31
 
29
 
32
-            $table->unique(['company_id', 'name', 'type']);
30
+            $table->unique(['company_id', 'account_id']);
33
         });
31
         });
34
     }
32
     }
35
 
33
 
38
      */
36
      */
39
     public function down(): void
37
     public function down(): void
40
     {
38
     {
41
-        Schema::dropIfExists('discounts');
39
+        Schema::dropIfExists('adjustments');
42
     }
40
     }
43
 };
41
 };

+ 17
- 17
package-lock.json View File

1187
             "license": "MIT"
1187
             "license": "MIT"
1188
         },
1188
         },
1189
         "node_modules/electron-to-chromium": {
1189
         "node_modules/electron-to-chromium": {
1190
-            "version": "1.5.57",
1191
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz",
1192
-            "integrity": "sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg==",
1190
+            "version": "1.5.59",
1191
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.59.tgz",
1192
+            "integrity": "sha512-faAXB6+gEbC8FsiRdpOXgOe4snP49YwjiXynEB8Mp7sUx80W5eN+BnnBHJ/F7eIeLzs+QBfDD40bJMm97oEFcw==",
1193
             "dev": true,
1193
             "dev": true,
1194
             "license": "ISC"
1194
             "license": "ISC"
1195
         },
1195
         },
2447
             }
2447
             }
2448
         },
2448
         },
2449
         "node_modules/tailwindcss": {
2449
         "node_modules/tailwindcss": {
2450
-            "version": "3.4.14",
2451
-            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz",
2452
-            "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==",
2450
+            "version": "3.4.15",
2451
+            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz",
2452
+            "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==",
2453
             "dev": true,
2453
             "dev": true,
2454
             "license": "MIT",
2454
             "license": "MIT",
2455
             "dependencies": {
2455
             "dependencies": {
2456
                 "@alloc/quick-lru": "^5.2.0",
2456
                 "@alloc/quick-lru": "^5.2.0",
2457
                 "arg": "^5.0.2",
2457
                 "arg": "^5.0.2",
2458
-                "chokidar": "^3.5.3",
2458
+                "chokidar": "^3.6.0",
2459
                 "didyoumean": "^1.2.2",
2459
                 "didyoumean": "^1.2.2",
2460
                 "dlv": "^1.1.3",
2460
                 "dlv": "^1.1.3",
2461
-                "fast-glob": "^3.3.0",
2461
+                "fast-glob": "^3.3.2",
2462
                 "glob-parent": "^6.0.2",
2462
                 "glob-parent": "^6.0.2",
2463
                 "is-glob": "^4.0.3",
2463
                 "is-glob": "^4.0.3",
2464
-                "jiti": "^1.21.0",
2464
+                "jiti": "^1.21.6",
2465
                 "lilconfig": "^2.1.0",
2465
                 "lilconfig": "^2.1.0",
2466
-                "micromatch": "^4.0.5",
2466
+                "micromatch": "^4.0.8",
2467
                 "normalize-path": "^3.0.0",
2467
                 "normalize-path": "^3.0.0",
2468
                 "object-hash": "^3.0.0",
2468
                 "object-hash": "^3.0.0",
2469
-                "picocolors": "^1.0.0",
2470
-                "postcss": "^8.4.23",
2469
+                "picocolors": "^1.1.1",
2470
+                "postcss": "^8.4.47",
2471
                 "postcss-import": "^15.1.0",
2471
                 "postcss-import": "^15.1.0",
2472
                 "postcss-js": "^4.0.1",
2472
                 "postcss-js": "^4.0.1",
2473
-                "postcss-load-config": "^4.0.1",
2474
-                "postcss-nested": "^6.0.1",
2475
-                "postcss-selector-parser": "^6.0.11",
2476
-                "resolve": "^1.22.2",
2477
-                "sucrase": "^3.32.0"
2473
+                "postcss-load-config": "^4.0.2",
2474
+                "postcss-nested": "^6.2.0",
2475
+                "postcss-selector-parser": "^6.1.2",
2476
+                "resolve": "^1.22.8",
2477
+                "sucrase": "^3.35.0"
2478
             },
2478
             },
2479
             "bin": {
2479
             "bin": {
2480
                 "tailwind": "lib/cli.js",
2480
                 "tailwind": "lib/cli.js",

Loading…
Cancel
Save