Andrew Wallo 5ヶ月前
コミット
e73f465016

+ 9
- 2
database/factories/Accounting/BillFactory.php ファイルの表示

@@ -8,6 +8,7 @@ use App\Models\Accounting\Bill;
8 8
 use App\Models\Accounting\DocumentLineItem;
9 9
 use App\Models\Banking\BankAccount;
10 10
 use App\Models\Common\Vendor;
11
+use App\Models\Company;
11 12
 use App\Models\Setting\DocumentDefault;
12 13
 use App\Utilities\Currency\CurrencyConverter;
13 14
 use Illuminate\Database\Eloquent\Factories\Factory;
@@ -42,13 +43,19 @@ class BillFactory extends Factory
42 43
 
43 44
         return [
44 45
             'company_id' => 1,
45
-            'vendor_id' => Vendor::inRandomOrder()->value('id'),
46
+            'vendor_id' => fn (array $attributes) => Vendor::where('company_id', $attributes['company_id'])->inRandomOrder()->value('id'),
46 47
             'bill_number' => $this->faker->unique()->numerify('BILL-####'),
47 48
             'order_number' => $this->faker->unique()->numerify('PO-####'),
48 49
             'date' => $billDate,
49 50
             'due_date' => Carbon::parse($billDate)->addDays($dueDays),
50 51
             'status' => BillStatus::Open,
51
-            'currency_code' => 'USD',
52
+            'currency_code' => function (array $attributes) {
53
+                $vendor = Vendor::find($attributes['vendor_id']);
54
+
55
+                return $vendor->currency_code ??
56
+                    Company::find($attributes['company_id'])->default->currency_code ??
57
+                    'USD';
58
+            },
52 59
             'notes' => $this->faker->sentence,
53 60
             'created_by' => 1,
54 61
             'updated_by' => 1,

+ 3
- 0
database/factories/Accounting/DocumentLineItemFactory.php ファイルの表示

@@ -42,6 +42,7 @@ class DocumentLineItemFactory extends Factory
42 42
     {
43 43
         return $this
44 44
             ->for($invoice, 'documentable')
45
+            ->for($invoice->company, 'company')
45 46
             ->state(function (array $attributes) {
46 47
                 $offering = Offering::where('sellable', true)
47 48
                     ->inRandomOrder()
@@ -76,6 +77,7 @@ class DocumentLineItemFactory extends Factory
76 77
     {
77 78
         return $this
78 79
             ->for($estimate, 'documentable')
80
+            ->for($estimate->company, 'company')
79 81
             ->state(function (array $attributes) {
80 82
                 $offering = Offering::where('sellable', true)
81 83
                     ->inRandomOrder()
@@ -110,6 +112,7 @@ class DocumentLineItemFactory extends Factory
110 112
     {
111 113
         return $this
112 114
             ->for($bill, 'documentable')
115
+            ->for($bill->company, 'company')
113 116
             ->state(function (array $attributes) {
114 117
                 $offering = Offering::where('purchasable', true)
115 118
                     ->inRandomOrder()

+ 9
- 2
database/factories/Accounting/EstimateFactory.php ファイルの表示

@@ -6,6 +6,7 @@ use App\Enums\Accounting\EstimateStatus;
6 6
 use App\Models\Accounting\DocumentLineItem;
7 7
 use App\Models\Accounting\Estimate;
8 8
 use App\Models\Common\Client;
9
+use App\Models\Company;
9 10
 use App\Models\Setting\DocumentDefault;
10 11
 use Illuminate\Database\Eloquent\Factories\Factory;
11 12
 use Illuminate\Support\Carbon;
@@ -31,7 +32,7 @@ class EstimateFactory extends Factory
31 32
 
32 33
         return [
33 34
             'company_id' => 1,
34
-            'client_id' => Client::inRandomOrder()->value('id'),
35
+            'client_id' => fn (array $attributes) => Client::where('company_id', $attributes['company_id'])->inRandomOrder()->value('id'),
35 36
             'header' => 'Estimate',
36 37
             'subheader' => 'Estimate',
37 38
             'estimate_number' => $this->faker->unique()->numerify('EST-####'),
@@ -39,7 +40,13 @@ class EstimateFactory extends Factory
39 40
             'date' => $estimateDate,
40 41
             'expiration_date' => Carbon::parse($estimateDate)->addDays($this->faker->numberBetween(14, 30)),
41 42
             'status' => EstimateStatus::Draft,
42
-            'currency_code' => 'USD',
43
+            'currency_code' => function (array $attributes) {
44
+                $client = Client::find($attributes['client_id']);
45
+
46
+                return $client->currency_code ??
47
+                    Company::find($attributes['company_id'])->default->currency_code ??
48
+                    'USD';
49
+            },
43 50
             'terms' => $this->faker->sentence,
44 51
             'footer' => $this->faker->sentence,
45 52
             'created_by' => 1,

+ 9
- 2
database/factories/Accounting/InvoiceFactory.php ファイルの表示

@@ -8,6 +8,7 @@ use App\Models\Accounting\DocumentLineItem;
8 8
 use App\Models\Accounting\Invoice;
9 9
 use App\Models\Banking\BankAccount;
10 10
 use App\Models\Common\Client;
11
+use App\Models\Company;
11 12
 use App\Models\Setting\DocumentDefault;
12 13
 use App\Utilities\Currency\CurrencyConverter;
13 14
 use Illuminate\Database\Eloquent\Factories\Factory;
@@ -34,7 +35,7 @@ class InvoiceFactory extends Factory
34 35
 
35 36
         return [
36 37
             'company_id' => 1,
37
-            'client_id' => Client::inRandomOrder()->value('id'),
38
+            'client_id' => fn (array $attributes) => Client::where('company_id', $attributes['company_id'])->inRandomOrder()->value('id'),
38 39
             'header' => 'Invoice',
39 40
             'subheader' => 'Invoice',
40 41
             'invoice_number' => $this->faker->unique()->numerify('INV-####'),
@@ -42,7 +43,13 @@ class InvoiceFactory extends Factory
42 43
             'date' => $invoiceDate,
43 44
             'due_date' => Carbon::parse($invoiceDate)->addDays($this->faker->numberBetween(14, 60)),
44 45
             'status' => InvoiceStatus::Draft,
45
-            'currency_code' => 'USD',
46
+            'currency_code' => function (array $attributes) {
47
+                $client = Client::find($attributes['client_id']);
48
+
49
+                return $client->currency_code ??
50
+                    Company::find($attributes['company_id'])->default->currency_code ??
51
+                    'USD';
52
+            },
46 53
             'terms' => $this->faker->sentence,
47 54
             'footer' => $this->faker->sentence,
48 55
             'created_by' => 1,

+ 9
- 2
database/factories/Accounting/RecurringInvoiceFactory.php ファイルの表示

@@ -13,6 +13,7 @@ use App\Enums\Setting\PaymentTerms;
13 13
 use App\Models\Accounting\DocumentLineItem;
14 14
 use App\Models\Accounting\RecurringInvoice;
15 15
 use App\Models\Common\Client;
16
+use App\Models\Company;
16 17
 use Illuminate\Database\Eloquent\Factories\Factory;
17 18
 use Illuminate\Support\Carbon;
18 19
 
@@ -35,13 +36,19 @@ class RecurringInvoiceFactory extends Factory
35 36
     {
36 37
         return [
37 38
             'company_id' => 1,
38
-            'client_id' => Client::inRandomOrder()->value('id'),
39
+            'client_id' => fn (array $attributes) => Client::where('company_id', $attributes['company_id'])->inRandomOrder()->value('id'),
39 40
             'header' => 'Invoice',
40 41
             'subheader' => 'Invoice',
41 42
             'order_number' => $this->faker->unique()->numerify('ORD-####'),
42 43
             'payment_terms' => PaymentTerms::Net30,
43 44
             'status' => RecurringInvoiceStatus::Draft,
44
-            'currency_code' => 'USD',
45
+            'currency_code' => function (array $attributes) {
46
+                $client = Client::find($attributes['client_id']);
47
+
48
+                return $client->currency_code ??
49
+                    Company::find($attributes['company_id'])->default->currency_code ??
50
+                    'USD';
51
+            },
45 52
             'terms' => $this->faker->sentence,
46 53
             'footer' => $this->faker->sentence,
47 54
             'created_by' => 1,

+ 11
- 0
database/factories/Common/AddressFactory.php ファイルの表示

@@ -4,6 +4,7 @@ namespace Database\Factories\Common;
4 4
 
5 5
 use App\Enums\Common\AddressType;
6 6
 use App\Models\Common\Address;
7
+use Database\Factories\Concerns\HasParentRelationship;
7 8
 use Illuminate\Database\Eloquent\Factories\Factory;
8 9
 
9 10
 /**
@@ -11,6 +12,8 @@ use Illuminate\Database\Eloquent\Factories\Factory;
11 12
  */
12 13
 class AddressFactory extends Factory
13 14
 {
15
+    use HasParentRelationship;
16
+
14 17
     /**
15 18
      * The name of the factory's corresponding model.
16 19
      */
@@ -60,4 +63,12 @@ class AddressFactory extends Factory
60 63
             'type' => AddressType::General,
61 64
         ]);
62 65
     }
66
+
67
+    public function forCountry(string $countryCode): self
68
+    {
69
+        return $this->state([
70
+            'state_id' => $this->faker->state($countryCode),
71
+            'country_code' => $countryCode,
72
+        ]);
73
+    }
63 74
 }

+ 14
- 5
database/factories/Common/ClientFactory.php ファイルの表示

@@ -5,6 +5,7 @@ namespace Database\Factories\Common;
5 5
 use App\Models\Common\Address;
6 6
 use App\Models\Common\Client;
7 7
 use App\Models\Common\Contact;
8
+use App\Models\Company;
8 9
 use Illuminate\Database\Eloquent\Factories\Factory;
9 10
 
10 11
 /**
@@ -27,7 +28,7 @@ class ClientFactory extends Factory
27 28
         return [
28 29
             'company_id' => 1,
29 30
             'name' => $this->faker->company,
30
-            'currency_code' => 'USD',
31
+            'currency_code' => fn (array $attributes) => Company::find($attributes['company_id'])->default->currency_code ?? 'USD',
31 32
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
32 33
             'website' => $this->faker->url,
33 34
             'notes' => $this->faker->sentence,
@@ -38,18 +39,26 @@ class ClientFactory extends Factory
38 39
 
39 40
     public function withContacts(int $count = 1): self
40 41
     {
41
-        return $this->has(Contact::factory()->count($count));
42
+        return $this->has(
43
+            Contact::factory()
44
+                ->count($count)
45
+                ->useParentCompany()
46
+        );
42 47
     }
43 48
 
44 49
     public function withPrimaryContact(): self
45 50
     {
46
-        return $this->has(Contact::factory()->primary());
51
+        return $this->has(
52
+            Contact::factory()
53
+                ->primary()
54
+                ->useParentCompany()
55
+        );
47 56
     }
48 57
 
49 58
     public function withAddresses(): self
50 59
     {
51 60
         return $this
52
-            ->has(Address::factory()->billing())
53
-            ->has(Address::factory()->shipping());
61
+            ->has(Address::factory()->billing()->useParentCompany())
62
+            ->has(Address::factory()->shipping()->useParentCompany());
54 63
     }
55 64
 }

+ 3
- 0
database/factories/Common/ContactFactory.php ファイルの表示

@@ -3,6 +3,7 @@
3 3
 namespace Database\Factories\Common;
4 4
 
5 5
 use App\Models\Common\Contact;
6
+use Database\Factories\Concerns\HasParentRelationship;
6 7
 use Illuminate\Database\Eloquent\Factories\Factory;
7 8
 
8 9
 /**
@@ -10,6 +11,8 @@ use Illuminate\Database\Eloquent\Factories\Factory;
10 11
  */
11 12
 class ContactFactory extends Factory
12 13
 {
14
+    use HasParentRelationship;
15
+
13 16
     /**
14 17
      * The name of the factory's corresponding model.
15 18
      */

+ 4
- 3
database/factories/Common/VendorFactory.php ファイルの表示

@@ -7,6 +7,7 @@ use App\Enums\Common\VendorType;
7 7
 use App\Models\Common\Address;
8 8
 use App\Models\Common\Contact;
9 9
 use App\Models\Common\Vendor;
10
+use App\Models\Company;
10 11
 use Illuminate\Database\Eloquent\Factories\Factory;
11 12
 
12 13
 /**
@@ -39,7 +40,7 @@ class VendorFactory extends Factory
39 40
             'ein' => function (array $attributes) {
40 41
                 return $attributes['contractor_type'] === ContractorType::Business ? $this->faker->numerify(str_repeat('#', 9)) : null;
41 42
             },
42
-            'currency_code' => 'USD',
43
+            'currency_code' => fn (array $attributes) => Company::find($attributes['company_id'])->default->currency_code ?? 'USD',
43 44
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
44 45
             'website' => $this->faker->url,
45 46
             'notes' => $this->faker->sentence,
@@ -80,11 +81,11 @@ class VendorFactory extends Factory
80 81
 
81 82
     public function withContact(): self
82 83
     {
83
-        return $this->has(Contact::factory()->primary());
84
+        return $this->has(Contact::factory()->primary()->useParentCompany());
84 85
     }
85 86
 
86 87
     public function withAddress(): self
87 88
     {
88
-        return $this->has(Address::factory()->general());
89
+        return $this->has(Address::factory()->general()->useParentCompany());
89 90
     }
90 91
 }

+ 31
- 8
database/factories/CompanyFactory.php ファイルの表示

@@ -39,22 +39,25 @@ class CompanyFactory extends Factory
39 39
         ];
40 40
     }
41 41
 
42
-    public function withCompanyProfile(): self
42
+    public function withCompanyProfile(?string $countryCode = null): self
43 43
     {
44
-        return $this->afterCreating(function (Company $company) {
45
-            CompanyProfile::factory()->forCompany($company)->withAddress()->create();
44
+        return $this->afterCreating(function (Company $company) use ($countryCode) {
45
+            CompanyProfile::factory()
46
+                ->forCompany($company)
47
+                ->withAddress($countryCode)
48
+                ->create();
46 49
         });
47 50
     }
48 51
 
49 52
     /**
50 53
      * Set up default settings for the company after creation.
51 54
      */
52
-    public function withCompanyDefaults(): self
55
+    public function withCompanyDefaults(string $currencyCode = 'USD', string $locale = 'en'): self
53 56
     {
54
-        return $this->afterCreating(function (Company $company) {
57
+        return $this->afterCreating(function (Company $company) use ($currencyCode, $locale) {
55 58
             $countryCode = $company->profile->address->country_code;
56 59
             $companyDefaultService = app(CompanyDefaultService::class);
57
-            $companyDefaultService->createCompanyDefaults($company, $company->owner, 'USD', $countryCode, 'en');
60
+            $companyDefaultService->createCompanyDefaults($company, $company->owner, $currencyCode, $countryCode, $locale);
58 61
         });
59 62
     }
60 63
 
@@ -75,12 +78,32 @@ class CompanyFactory extends Factory
75 78
 
76 79
     public function withClients(int $count = 10): self
77 80
     {
78
-        return $this->has(Client::factory()->count($count)->withPrimaryContact()->withAddresses());
81
+        return $this->afterCreating(function (Company $company) use ($count) {
82
+            Client::factory()
83
+                ->count($count)
84
+                ->withPrimaryContact()
85
+                ->withAddresses()
86
+                ->create([
87
+                    'company_id' => $company->id,
88
+                    'created_by' => $company->user_id,
89
+                    'updated_by' => $company->user_id,
90
+                ]);
91
+        });
79 92
     }
80 93
 
81 94
     public function withVendors(int $count = 10): self
82 95
     {
83
-        return $this->has(Vendor::factory()->count($count)->withContact()->withAddress());
96
+        return $this->afterCreating(function (Company $company) use ($count) {
97
+            Vendor::factory()
98
+                ->count($count)
99
+                ->withContact()
100
+                ->withAddress()
101
+                ->create([
102
+                    'company_id' => $company->id,
103
+                    'created_by' => $company->user_id,
104
+                    'updated_by' => $company->user_id,
105
+                ]);
106
+        });
84 107
     }
85 108
 
86 109
     public function withOfferings(int $count = 10): self

+ 19
- 0
database/factories/Concerns/HasParentRelationship.php ファイルの表示

@@ -0,0 +1,19 @@
1
+<?php
2
+
3
+namespace Database\Factories\Concerns;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+trait HasParentRelationship
8
+{
9
+    public function useParentCompany(): self
10
+    {
11
+        return $this->state(function (array $attributes, Model $parent) {
12
+            return [
13
+                'company_id' => $parent->company_id,
14
+                'created_by' => $parent->created_by ?? 1,
15
+                'updated_by' => $parent->updated_by ?? 1,
16
+            ];
17
+        });
18
+    }
19
+}

+ 9
- 2
database/factories/Setting/CompanyProfileFactory.php ファイルの表示

@@ -42,8 +42,15 @@ class CompanyProfileFactory extends Factory
42 42
         ]);
43 43
     }
44 44
 
45
-    public function withAddress(): self
45
+    public function withAddress(?string $countryCode = null): self
46 46
     {
47
-        return $this->has(Address::factory()->general());
47
+        return $this->has(
48
+            Address::factory()
49
+                ->general()
50
+                ->when($countryCode, function (Factory $factory) use ($countryCode) {
51
+                    return $factory->forCountry($countryCode);
52
+                })
53
+                ->useParentCompany()
54
+        );
48 55
     }
49 56
 }

+ 29
- 1
database/seeders/DatabaseSeeder.php ファイルの表示

@@ -2,6 +2,7 @@
2 2
 
3 3
 namespace Database\Seeders;
4 4
 
5
+use App\Models\Company;
5 6
 use App\Models\User;
6 7
 use Database\Factories\CompanyFactory;
7 8
 use Illuminate\Database\Seeder;
@@ -14,7 +15,7 @@ class DatabaseSeeder extends Seeder
14 15
     public function run(): void
15 16
     {
16 17
         // Create a single admin user and their personal company
17
-        User::factory()
18
+        $user = User::factory()
18 19
             ->withPersonalCompany(function (CompanyFactory $factory) {
19 20
                 return $factory
20 21
                     ->state([
@@ -35,5 +36,32 @@ class DatabaseSeeder extends Seeder
35 36
                 'password' => bcrypt('password'),
36 37
                 'current_company_id' => 1,  // Assuming this will be the ID of the created company
37 38
             ]);
39
+
40
+        $additionalCompanies = [
41
+            ['name' => 'European Retail GmbH', 'country' => 'DE', 'currency' => 'EUR', 'locale' => 'de'],
42
+            ['name' => 'UK Services Ltd', 'country' => 'GB', 'currency' => 'GBP', 'locale' => 'en'],
43
+            ['name' => 'Canadian Manufacturing Inc', 'country' => 'CA', 'currency' => 'CAD', 'locale' => 'en'],
44
+            ['name' => 'Australian Hospitality Pty', 'country' => 'AU', 'currency' => 'AUD', 'locale' => 'en'],
45
+        ];
46
+
47
+        foreach ($additionalCompanies as $companyData) {
48
+            Company::factory()
49
+                ->state([
50
+                    'name' => $companyData['name'],
51
+                    'user_id' => $user->id,
52
+                    'personal_company' => false,
53
+                ])
54
+                ->withCompanyProfile($companyData['country'])
55
+                ->withCompanyDefaults($companyData['currency'], $companyData['locale'])
56
+                ->withTransactions(100)
57
+                ->withOfferings()
58
+                ->withClients()
59
+                ->withVendors()
60
+                ->withInvoices(20)
61
+                ->withRecurringInvoices()
62
+                ->withEstimates(15)
63
+                ->withBills(15)
64
+                ->create();
65
+        }
38 66
     }
39 67
 }

読み込み中…
キャンセル
保存