| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 | 
							- <?php
 - 
 - namespace App\Models\Common;
 - 
 - use App\Concerns\Blamable;
 - use App\Concerns\CompanyOwned;
 - use App\Enums\Common\AddressType;
 - use App\Models\Accounting\Estimate;
 - use App\Models\Accounting\Invoice;
 - use App\Models\Accounting\RecurringInvoice;
 - use App\Models\Accounting\Transaction;
 - use App\Models\Setting\Currency;
 - use Illuminate\Database\Eloquent\Factories\HasFactory;
 - use Illuminate\Database\Eloquent\Model;
 - use Illuminate\Database\Eloquent\Relations\BelongsTo;
 - use Illuminate\Database\Eloquent\Relations\HasMany;
 - use Illuminate\Database\Eloquent\Relations\MorphMany;
 - use Illuminate\Database\Eloquent\Relations\MorphOne;
 - 
 - class Client extends Model
 - {
 -     use Blamable;
 -     use CompanyOwned;
 -     use HasFactory;
 - 
 -     protected $table = 'clients';
 - 
 -     protected $fillable = [
 -         'company_id',
 -         'name',
 -         'currency_code',
 -         'account_number',
 -         'website',
 -         'notes',
 -         'created_by',
 -         'updated_by',
 -     ];
 - 
 -     public static function createWithRelations(array $data): self
 -     {
 -         /** @var Client $client */
 -         $client = self::create($data);
 - 
 -         if (isset($data['primaryContact'], $data['primaryContact']['first_name'])) {
 -             $client->primaryContact()->create([
 -                 'is_primary' => true,
 -                 'first_name' => $data['primaryContact']['first_name'],
 -                 'last_name' => $data['primaryContact']['last_name'],
 -                 'email' => $data['primaryContact']['email'],
 -                 'phones' => $data['primaryContact']['phones'] ?? [],
 -             ]);
 -         }
 - 
 -         if (isset($data['secondaryContacts'])) {
 -             foreach ($data['secondaryContacts'] as $contactData) {
 -                 if (isset($contactData['first_name'])) {
 -                     $client->secondaryContacts()->create([
 -                         'is_primary' => false,
 -                         'first_name' => $contactData['first_name'],
 -                         'last_name' => $contactData['last_name'],
 -                         'email' => $contactData['email'],
 -                         'phones' => $contactData['phones'] ?? [],
 -                     ]);
 -                 }
 -             }
 -         }
 - 
 -         if (isset($data['billingAddress'], $data['billingAddress']['address_line_1'])) {
 -             $client->billingAddress()->create([
 -                 'type' => AddressType::Billing,
 -                 'address_line_1' => $data['billingAddress']['address_line_1'],
 -                 'address_line_2' => $data['billingAddress']['address_line_2'] ?? null,
 -                 'country_code' => $data['billingAddress']['country_code'] ?? null,
 -                 'state_id' => $data['billingAddress']['state_id'] ?? null,
 -                 'city' => $data['billingAddress']['city'] ?? null,
 -                 'postal_code' => $data['billingAddress']['postal_code'] ?? null,
 -             ]);
 -         }
 - 
 -         if (isset($data['shippingAddress'])) {
 -             $shippingData = $data['shippingAddress'];
 -             $shippingAddress = [
 -                 'type' => AddressType::Shipping,
 -                 'recipient' => $shippingData['recipient'] ?? null,
 -                 'phone' => $shippingData['phone'] ?? null,
 -                 'notes' => $shippingData['notes'] ?? null,
 -             ];
 - 
 -             if ($shippingData['same_as_billing'] ?? false) {
 -                 $billingAddress = $client->billingAddress;
 -                 if ($billingAddress) {
 -                     $shippingAddress = [
 -                         ...$shippingAddress,
 -                         'parent_address_id' => $billingAddress->id,
 -                         'address_line_1' => $billingAddress->address_line_1,
 -                         'address_line_2' => $billingAddress->address_line_2,
 -                         'country_code' => $billingAddress->country_code,
 -                         'state_id' => $billingAddress->state_id,
 -                         'city' => $billingAddress->city,
 -                         'postal_code' => $billingAddress->postal_code,
 -                     ];
 -                     $client->shippingAddress()->create($shippingAddress);
 -                 }
 -             } elseif (isset($shippingData['address_line_1'])) {
 -                 $shippingAddress = [
 -                     ...$shippingAddress,
 -                     'address_line_1' => $shippingData['address_line_1'],
 -                     'address_line_2' => $shippingData['address_line_2'] ?? null,
 -                     'country_code' => $shippingData['country_code'] ?? null,
 -                     'state_id' => $shippingData['state_id'] ?? null,
 -                     'city' => $shippingData['city'] ?? null,
 -                     'postal_code' => $shippingData['postal_code'] ?? null,
 -                 ];
 - 
 -                 $client->shippingAddress()->create($shippingAddress);
 -             }
 -         }
 - 
 -         return $client;
 -     }
 - 
 -     public function updateWithRelations(array $data): self
 -     {
 -         $this->update($data);
 - 
 -         if (isset($data['primaryContact'], $data['primaryContact']['first_name'])) {
 -             $this->primaryContact()->updateOrCreate(
 -                 ['is_primary' => true],
 -                 [
 -                     'first_name' => $data['primaryContact']['first_name'],
 -                     'last_name' => $data['primaryContact']['last_name'],
 -                     'email' => $data['primaryContact']['email'],
 -                     'phones' => $data['primaryContact']['phones'] ?? [],
 -                 ]
 -             );
 -         }
 - 
 -         if (isset($data['secondaryContacts'])) {
 -             // Delete removed contacts
 -             $existingIds = collect($data['secondaryContacts'])->pluck('id')->filter()->all();
 -             $this->secondaryContacts()->whereNotIn('id', $existingIds)->delete();
 - 
 -             // Update or create contacts
 -             foreach ($data['secondaryContacts'] as $contactData) {
 -                 if (isset($contactData['first_name'])) {
 -                     $this->secondaryContacts()->updateOrCreate(
 -                         ['id' => $contactData['id'] ?? null],
 -                         [
 -                             'is_primary' => false,
 -                             'first_name' => $contactData['first_name'],
 -                             'last_name' => $contactData['last_name'],
 -                             'email' => $contactData['email'],
 -                             'phones' => $contactData['phones'] ?? [],
 -                         ]
 -                     );
 -                 }
 -             }
 -         }
 - 
 -         if (isset($data['billingAddress'], $data['billingAddress']['address_line_1'])) {
 -             $this->billingAddress()->updateOrCreate(
 -                 ['type' => AddressType::Billing],
 -                 [
 -                     'address_line_1' => $data['billingAddress']['address_line_1'],
 -                     'address_line_2' => $data['billingAddress']['address_line_2'] ?? null,
 -                     'country_code' => $data['billingAddress']['country_code'] ?? null,
 -                     'state_id' => $data['billingAddress']['state_id'] ?? null,
 -                     'city' => $data['billingAddress']['city'] ?? null,
 -                     'postal_code' => $data['billingAddress']['postal_code'] ?? null,
 -                 ]
 -             );
 -         }
 - 
 -         if (isset($data['shippingAddress'])) {
 -             $shippingData = $data['shippingAddress'];
 - 
 -             if ($shippingData['same_as_billing'] ?? false) {
 -                 $billingAddress = $this->billingAddress;
 -                 if ($billingAddress) {
 -                     $shippingAddress = [
 -                         'type' => AddressType::Shipping,
 -                         'recipient' => $shippingData['recipient'] ?? null,
 -                         'phone' => $shippingData['phone'] ?? null,
 -                         'notes' => $shippingData['notes'] ?? null,
 -                         'parent_address_id' => $billingAddress->id,
 -                         'address_line_1' => $billingAddress->address_line_1,
 -                         'address_line_2' => $billingAddress->address_line_2,
 -                         'country_code' => $billingAddress->country_code,
 -                         'state_id' => $billingAddress->state_id,
 -                         'city' => $billingAddress->city,
 -                         'postal_code' => $billingAddress->postal_code,
 -                     ];
 - 
 -                     $this->shippingAddress()->updateOrCreate(
 -                         ['type' => AddressType::Shipping],
 -                         $shippingAddress
 -                     );
 -                 }
 -             } elseif (isset($shippingData['address_line_1'])) {
 -                 $shippingAddress = [
 -                     'type' => AddressType::Shipping,
 -                     'recipient' => $shippingData['recipient'] ?? null,
 -                     'phone' => $shippingData['phone'] ?? null,
 -                     'notes' => $shippingData['notes'] ?? null,
 -                     'parent_address_id' => null,
 -                     'address_line_1' => $shippingData['address_line_1'],
 -                     'address_line_2' => $shippingData['address_line_2'] ?? null,
 -                     'country_code' => $shippingData['country_code'] ?? null,
 -                     'state_id' => $shippingData['state_id'] ?? null,
 -                     'city' => $shippingData['city'] ?? null,
 -                     'postal_code' => $shippingData['postal_code'] ?? null,
 -                 ];
 - 
 -                 $this->shippingAddress()->updateOrCreate(
 -                     ['type' => AddressType::Shipping],
 -                     $shippingAddress
 -                 );
 -             }
 -         }
 - 
 -         return $this;
 -     }
 - 
 -     public function transactions(): MorphMany
 -     {
 -         return $this->morphMany(Transaction::class, 'payeeable');
 -     }
 - 
 -     public function contacts(): MorphMany
 -     {
 -         return $this->morphMany(Contact::class, 'contactable');
 -     }
 - 
 -     public function primaryContact(): MorphOne
 -     {
 -         return $this->morphOne(Contact::class, 'contactable')
 -             ->where('is_primary', true);
 -     }
 - 
 -     public function secondaryContacts(): MorphMany
 -     {
 -         return $this->morphMany(Contact::class, 'contactable')
 -             ->where('is_primary', false);
 -     }
 - 
 -     public function currency(): BelongsTo
 -     {
 -         return $this->belongsTo(Currency::class, 'currency_code', 'code');
 -     }
 - 
 -     public function addresses(): MorphMany
 -     {
 -         return $this->morphMany(Address::class, 'addressable');
 -     }
 - 
 -     public function billingAddress(): MorphOne
 -     {
 -         return $this->morphOne(Address::class, 'addressable')
 -             ->where('type', AddressType::Billing);
 -     }
 - 
 -     public function shippingAddress(): MorphOne
 -     {
 -         return $this->morphOne(Address::class, 'addressable')
 -             ->where('type', AddressType::Shipping);
 -     }
 - 
 -     public function estimates(): HasMany
 -     {
 -         return $this->hasMany(Estimate::class);
 -     }
 - 
 -     public function invoices(): HasMany
 -     {
 -         return $this->hasMany(Invoice::class);
 -     }
 - 
 -     public function recurringInvoices(): HasMany
 -     {
 -         return $this->hasMany(RecurringInvoice::class);
 -     }
 - }
 
 
  |