Andrew Wallo 5 months ago
parent
commit
e73f465016

+ 9
- 2
database/factories/Accounting/BillFactory.php View File

8
 use App\Models\Accounting\DocumentLineItem;
8
 use App\Models\Accounting\DocumentLineItem;
9
 use App\Models\Banking\BankAccount;
9
 use App\Models\Banking\BankAccount;
10
 use App\Models\Common\Vendor;
10
 use App\Models\Common\Vendor;
11
+use App\Models\Company;
11
 use App\Models\Setting\DocumentDefault;
12
 use App\Models\Setting\DocumentDefault;
12
 use App\Utilities\Currency\CurrencyConverter;
13
 use App\Utilities\Currency\CurrencyConverter;
13
 use Illuminate\Database\Eloquent\Factories\Factory;
14
 use Illuminate\Database\Eloquent\Factories\Factory;
42
 
43
 
43
         return [
44
         return [
44
             'company_id' => 1,
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
             'bill_number' => $this->faker->unique()->numerify('BILL-####'),
47
             'bill_number' => $this->faker->unique()->numerify('BILL-####'),
47
             'order_number' => $this->faker->unique()->numerify('PO-####'),
48
             'order_number' => $this->faker->unique()->numerify('PO-####'),
48
             'date' => $billDate,
49
             'date' => $billDate,
49
             'due_date' => Carbon::parse($billDate)->addDays($dueDays),
50
             'due_date' => Carbon::parse($billDate)->addDays($dueDays),
50
             'status' => BillStatus::Open,
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
             'notes' => $this->faker->sentence,
59
             'notes' => $this->faker->sentence,
53
             'created_by' => 1,
60
             'created_by' => 1,
54
             'updated_by' => 1,
61
             'updated_by' => 1,

+ 3
- 0
database/factories/Accounting/DocumentLineItemFactory.php View File

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

+ 9
- 2
database/factories/Accounting/EstimateFactory.php View File

6
 use App\Models\Accounting\DocumentLineItem;
6
 use App\Models\Accounting\DocumentLineItem;
7
 use App\Models\Accounting\Estimate;
7
 use App\Models\Accounting\Estimate;
8
 use App\Models\Common\Client;
8
 use App\Models\Common\Client;
9
+use App\Models\Company;
9
 use App\Models\Setting\DocumentDefault;
10
 use App\Models\Setting\DocumentDefault;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Support\Carbon;
12
 use Illuminate\Support\Carbon;
31
 
32
 
32
         return [
33
         return [
33
             'company_id' => 1,
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
             'header' => 'Estimate',
36
             'header' => 'Estimate',
36
             'subheader' => 'Estimate',
37
             'subheader' => 'Estimate',
37
             'estimate_number' => $this->faker->unique()->numerify('EST-####'),
38
             'estimate_number' => $this->faker->unique()->numerify('EST-####'),
39
             'date' => $estimateDate,
40
             'date' => $estimateDate,
40
             'expiration_date' => Carbon::parse($estimateDate)->addDays($this->faker->numberBetween(14, 30)),
41
             'expiration_date' => Carbon::parse($estimateDate)->addDays($this->faker->numberBetween(14, 30)),
41
             'status' => EstimateStatus::Draft,
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
             'terms' => $this->faker->sentence,
50
             'terms' => $this->faker->sentence,
44
             'footer' => $this->faker->sentence,
51
             'footer' => $this->faker->sentence,
45
             'created_by' => 1,
52
             'created_by' => 1,

+ 9
- 2
database/factories/Accounting/InvoiceFactory.php View File

8
 use App\Models\Accounting\Invoice;
8
 use App\Models\Accounting\Invoice;
9
 use App\Models\Banking\BankAccount;
9
 use App\Models\Banking\BankAccount;
10
 use App\Models\Common\Client;
10
 use App\Models\Common\Client;
11
+use App\Models\Company;
11
 use App\Models\Setting\DocumentDefault;
12
 use App\Models\Setting\DocumentDefault;
12
 use App\Utilities\Currency\CurrencyConverter;
13
 use App\Utilities\Currency\CurrencyConverter;
13
 use Illuminate\Database\Eloquent\Factories\Factory;
14
 use Illuminate\Database\Eloquent\Factories\Factory;
34
 
35
 
35
         return [
36
         return [
36
             'company_id' => 1,
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
             'header' => 'Invoice',
39
             'header' => 'Invoice',
39
             'subheader' => 'Invoice',
40
             'subheader' => 'Invoice',
40
             'invoice_number' => $this->faker->unique()->numerify('INV-####'),
41
             'invoice_number' => $this->faker->unique()->numerify('INV-####'),
42
             'date' => $invoiceDate,
43
             'date' => $invoiceDate,
43
             'due_date' => Carbon::parse($invoiceDate)->addDays($this->faker->numberBetween(14, 60)),
44
             'due_date' => Carbon::parse($invoiceDate)->addDays($this->faker->numberBetween(14, 60)),
44
             'status' => InvoiceStatus::Draft,
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
             'terms' => $this->faker->sentence,
53
             'terms' => $this->faker->sentence,
47
             'footer' => $this->faker->sentence,
54
             'footer' => $this->faker->sentence,
48
             'created_by' => 1,
55
             'created_by' => 1,

+ 9
- 2
database/factories/Accounting/RecurringInvoiceFactory.php View File

13
 use App\Models\Accounting\DocumentLineItem;
13
 use App\Models\Accounting\DocumentLineItem;
14
 use App\Models\Accounting\RecurringInvoice;
14
 use App\Models\Accounting\RecurringInvoice;
15
 use App\Models\Common\Client;
15
 use App\Models\Common\Client;
16
+use App\Models\Company;
16
 use Illuminate\Database\Eloquent\Factories\Factory;
17
 use Illuminate\Database\Eloquent\Factories\Factory;
17
 use Illuminate\Support\Carbon;
18
 use Illuminate\Support\Carbon;
18
 
19
 
35
     {
36
     {
36
         return [
37
         return [
37
             'company_id' => 1,
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
             'header' => 'Invoice',
40
             'header' => 'Invoice',
40
             'subheader' => 'Invoice',
41
             'subheader' => 'Invoice',
41
             'order_number' => $this->faker->unique()->numerify('ORD-####'),
42
             'order_number' => $this->faker->unique()->numerify('ORD-####'),
42
             'payment_terms' => PaymentTerms::Net30,
43
             'payment_terms' => PaymentTerms::Net30,
43
             'status' => RecurringInvoiceStatus::Draft,
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
             'terms' => $this->faker->sentence,
52
             'terms' => $this->faker->sentence,
46
             'footer' => $this->faker->sentence,
53
             'footer' => $this->faker->sentence,
47
             'created_by' => 1,
54
             'created_by' => 1,

+ 11
- 0
database/factories/Common/AddressFactory.php View File

4
 
4
 
5
 use App\Enums\Common\AddressType;
5
 use App\Enums\Common\AddressType;
6
 use App\Models\Common\Address;
6
 use App\Models\Common\Address;
7
+use Database\Factories\Concerns\HasParentRelationship;
7
 use Illuminate\Database\Eloquent\Factories\Factory;
8
 use Illuminate\Database\Eloquent\Factories\Factory;
8
 
9
 
9
 /**
10
 /**
11
  */
12
  */
12
 class AddressFactory extends Factory
13
 class AddressFactory extends Factory
13
 {
14
 {
15
+    use HasParentRelationship;
16
+
14
     /**
17
     /**
15
      * The name of the factory's corresponding model.
18
      * The name of the factory's corresponding model.
16
      */
19
      */
60
             'type' => AddressType::General,
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 View File

5
 use App\Models\Common\Address;
5
 use App\Models\Common\Address;
6
 use App\Models\Common\Client;
6
 use App\Models\Common\Client;
7
 use App\Models\Common\Contact;
7
 use App\Models\Common\Contact;
8
+use App\Models\Company;
8
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 
10
 
10
 /**
11
 /**
27
         return [
28
         return [
28
             'company_id' => 1,
29
             'company_id' => 1,
29
             'name' => $this->faker->company,
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
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
32
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
32
             'website' => $this->faker->url,
33
             'website' => $this->faker->url,
33
             'notes' => $this->faker->sentence,
34
             'notes' => $this->faker->sentence,
38
 
39
 
39
     public function withContacts(int $count = 1): self
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
     public function withPrimaryContact(): self
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
     public function withAddresses(): self
58
     public function withAddresses(): self
50
     {
59
     {
51
         return $this
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 View File

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

+ 4
- 3
database/factories/Common/VendorFactory.php View File

7
 use App\Models\Common\Address;
7
 use App\Models\Common\Address;
8
 use App\Models\Common\Contact;
8
 use App\Models\Common\Contact;
9
 use App\Models\Common\Vendor;
9
 use App\Models\Common\Vendor;
10
+use App\Models\Company;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 
12
 
12
 /**
13
 /**
39
             'ein' => function (array $attributes) {
40
             'ein' => function (array $attributes) {
40
                 return $attributes['contractor_type'] === ContractorType::Business ? $this->faker->numerify(str_repeat('#', 9)) : null;
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
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
44
             'account_number' => $this->faker->unique()->numerify(str_repeat('#', 12)),
44
             'website' => $this->faker->url,
45
             'website' => $this->faker->url,
45
             'notes' => $this->faker->sentence,
46
             'notes' => $this->faker->sentence,
80
 
81
 
81
     public function withContact(): self
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
     public function withAddress(): self
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 View File

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
      * Set up default settings for the company after creation.
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
             $countryCode = $company->profile->address->country_code;
58
             $countryCode = $company->profile->address->country_code;
56
             $companyDefaultService = app(CompanyDefaultService::class);
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
 
78
 
76
     public function withClients(int $count = 10): self
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
     public function withVendors(int $count = 10): self
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
     public function withOfferings(int $count = 10): self
109
     public function withOfferings(int $count = 10): self

+ 19
- 0
database/factories/Concerns/HasParentRelationship.php View File

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 View File

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 View File

2
 
2
 
3
 namespace Database\Seeders;
3
 namespace Database\Seeders;
4
 
4
 
5
+use App\Models\Company;
5
 use App\Models\User;
6
 use App\Models\User;
6
 use Database\Factories\CompanyFactory;
7
 use Database\Factories\CompanyFactory;
7
 use Illuminate\Database\Seeder;
8
 use Illuminate\Database\Seeder;
14
     public function run(): void
15
     public function run(): void
15
     {
16
     {
16
         // Create a single admin user and their personal company
17
         // Create a single admin user and their personal company
17
-        User::factory()
18
+        $user = User::factory()
18
             ->withPersonalCompany(function (CompanyFactory $factory) {
19
             ->withPersonalCompany(function (CompanyFactory $factory) {
19
                 return $factory
20
                 return $factory
20
                     ->state([
21
                     ->state([
35
                 'password' => bcrypt('password'),
36
                 'password' => bcrypt('password'),
36
                 'current_company_id' => 1,  // Assuming this will be the ID of the created company
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
 }

Loading…
Cancel
Save