| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 | 
							- <?php
 - 
 - namespace App\Filament\Company\Resources\Sales;
 - 
 - use App\Filament\Company\Resources\Sales\ClientResource\Pages;
 - use App\Filament\Forms\Components\AddressFields;
 - use App\Filament\Forms\Components\CreateCurrencySelect;
 - use App\Filament\Forms\Components\CustomSection;
 - use App\Filament\Forms\Components\PhoneBuilder;
 - use App\Filament\Tables\Columns;
 - use App\Models\Common\Address;
 - use App\Models\Common\Client;
 - use App\Utilities\Currency\CurrencyConverter;
 - use Filament\Forms;
 - use Filament\Forms\Form;
 - use Filament\Forms\Get;
 - use Filament\Forms\Set;
 - use Filament\Resources\Resource;
 - use Filament\Tables;
 - use Filament\Tables\Table;
 - use Illuminate\Database\Eloquent\Builder;
 - 
 - class ClientResource extends Resource
 - {
 -     protected static ?string $model = Client::class;
 - 
 -     public static function form(Form $form): Form
 -     {
 -         return $form
 -             ->schema([
 -                 Forms\Components\Section::make('General Information')
 -                     ->schema([
 -                         Forms\Components\Group::make()
 -                             ->columns()
 -                             ->schema([
 -                                 Forms\Components\TextInput::make('name')
 -                                     ->label('Client name')
 -                                     ->required()
 -                                     ->maxLength(255),
 -                                 Forms\Components\TextInput::make('account_number')
 -                                     ->maxLength(255)
 -                                     ->columnStart(1),
 -                                 Forms\Components\TextInput::make('website')
 -                                     ->maxLength(255),
 -                                 Forms\Components\Textarea::make('notes')
 -                                     ->columnSpanFull(),
 -                             ]),
 -                         CustomSection::make('Primary Contact')
 -                             ->relationship('primaryContact')
 -                             ->contained(false)
 -                             ->schema([
 -                                 Forms\Components\Hidden::make('is_primary')
 -                                     ->default(true),
 -                                 Forms\Components\TextInput::make('first_name')
 -                                     ->label('First name')
 -                                     ->required()
 -                                     ->maxLength(255),
 -                                 Forms\Components\TextInput::make('last_name')
 -                                     ->label('Last name')
 -                                     ->required()
 -                                     ->maxLength(255),
 -                                 Forms\Components\TextInput::make('email')
 -                                     ->label('Email')
 -                                     ->required()
 -                                     ->email()
 -                                     ->columnSpanFull()
 -                                     ->maxLength(255),
 -                                 PhoneBuilder::make('phones')
 -                                     ->hiddenLabel()
 -                                     ->blockLabels(false)
 -                                     ->default([
 -                                         ['type' => 'primary'],
 -                                     ])
 -                                     ->columnSpanFull()
 -                                     ->blocks([
 -                                         Forms\Components\Builder\Block::make('primary')
 -                                             ->schema([
 -                                                 Forms\Components\TextInput::make('number')
 -                                                     ->label('Phone')
 -                                                     ->required()
 -                                                     ->maxLength(15),
 -                                             ])->maxItems(1),
 -                                         Forms\Components\Builder\Block::make('mobile')
 -                                             ->schema([
 -                                                 Forms\Components\TextInput::make('number')
 -                                                     ->label('Mobile')
 -                                                     ->required()
 -                                                     ->maxLength(15),
 -                                             ])->maxItems(1),
 -                                         Forms\Components\Builder\Block::make('toll_free')
 -                                             ->schema([
 -                                                 Forms\Components\TextInput::make('number')
 -                                                     ->label('Toll free')
 -                                                     ->required()
 -                                                     ->maxLength(15),
 -                                             ])->maxItems(1),
 -                                         Forms\Components\Builder\Block::make('fax')
 -                                             ->schema([
 -                                                 Forms\Components\TextInput::make('number')
 -                                                     ->label('Fax')
 -                                                     ->live()
 -                                                     ->maxLength(15),
 -                                             ])->maxItems(1),
 -                                     ])
 -                                     ->deletable(fn (PhoneBuilder $builder) => $builder->getItemsCount() > 1)
 -                                     ->reorderable(false)
 -                                     ->blockNumbers(false)
 -                                     ->addActionLabel('Add Phone'),
 -                             ])->columns(),
 -                         Forms\Components\Repeater::make('secondaryContacts')
 -                             ->relationship()
 -                             ->hiddenLabel()
 -                             ->extraAttributes([
 -                                 'class' => 'uncontained',
 -                             ])
 -                             ->columns()
 -                             ->defaultItems(0)
 -                             ->maxItems(3)
 -                             ->itemLabel(function (Forms\Components\Repeater $component, array $state): ?string {
 -                                 if ($component->getItemsCount() === 1) {
 -                                     return 'Secondary Contact';
 -                                 }
 - 
 -                                 $firstName = $state['first_name'] ?? null;
 -                                 $lastName = $state['last_name'] ?? null;
 - 
 -                                 if ($firstName && $lastName) {
 -                                     return "{$firstName} {$lastName}";
 -                                 }
 - 
 -                                 if ($firstName) {
 -                                     return $firstName;
 -                                 }
 - 
 -                                 return 'Secondary Contact';
 -                             })
 -                             ->addActionLabel('Add Contact')
 -                             ->schema([
 -                                 Forms\Components\TextInput::make('first_name')
 -                                     ->label('First name')
 -                                     ->required()
 -                                     ->live(onBlur: true)
 -                                     ->maxLength(255),
 -                                 Forms\Components\TextInput::make('last_name')
 -                                     ->label('Last name')
 -                                     ->required()
 -                                     ->live(onBlur: true)
 -                                     ->maxLength(255),
 -                                 Forms\Components\TextInput::make('email')
 -                                     ->label('Email')
 -                                     ->required()
 -                                     ->email()
 -                                     ->maxLength(255),
 -                                 PhoneBuilder::make('phones')
 -                                     ->hiddenLabel()
 -                                     ->blockLabels(false)
 -                                     ->default([
 -                                         ['type' => 'primary'],
 -                                     ])
 -                                     ->blocks([
 -                                         Forms\Components\Builder\Block::make('primary')
 -                                             ->schema([
 -                                                 Forms\Components\TextInput::make('number')
 -                                                     ->label('Phone')
 -                                                     ->required()
 -                                                     ->maxLength(255),
 -                                             ])->maxItems(1),
 -                                     ])
 -                                     ->addable(false)
 -                                     ->deletable(false)
 -                                     ->reorderable(false)
 -                                     ->blockNumbers(false),
 -                             ]),
 -                     ])->columns(1),
 -                 Forms\Components\Section::make('Billing')
 -                     ->schema([
 -                         CreateCurrencySelect::make('currency_code'),
 -                         CustomSection::make('Billing Address')
 -                             ->relationship('billingAddress')
 -                             ->saveRelationshipsUsing(null)
 -                             ->dehydrated(true)
 -                             ->contained(false)
 -                             ->schema([
 -                                 Forms\Components\Hidden::make('type')
 -                                     ->default('billing'),
 -                                 AddressFields::make(),
 -                             ])->columns(),
 -                     ])
 -                     ->columns(1),
 -                 Forms\Components\Section::make('Shipping')
 -                     ->relationship('shippingAddress')
 -                     ->saveRelationshipsUsing(null)
 -                     ->dehydrated(true)
 -                     ->schema([
 -                         Forms\Components\Hidden::make('type')
 -                             ->default('shipping'),
 -                         Forms\Components\TextInput::make('recipient')
 -                             ->label('Recipient')
 -                             ->required()
 -                             ->maxLength(255),
 -                         Forms\Components\TextInput::make('phone')
 -                             ->label('Phone')
 -                             ->required()
 -                             ->maxLength(255),
 -                         CustomSection::make('Shipping Address')
 -                             ->contained(false)
 -                             ->schema([
 -                                 Forms\Components\Checkbox::make('same_as_billing')
 -                                     ->label('Same as billing address')
 -                                     ->live()
 -                                     ->afterStateHydrated(function (?Address $record, Forms\Components\Checkbox $component) {
 -                                         if (! $record || $record->parent_address_id) {
 -                                             return $component->state(true);
 -                                         }
 - 
 -                                         return $component->state(false);
 -                                     })
 -                                     ->afterStateUpdated(static function (Get $get, Set $set, $state) {
 -                                         if ($state) {
 -                                             return;
 -                                         }
 - 
 -                                         $billingAddress = $get('../billingAddress');
 - 
 -                                         $fieldsToSync = [
 -                                             'address_line_1',
 -                                             'address_line_2',
 -                                             'country_code',
 -                                             'state_id',
 -                                             'city',
 -                                             'postal_code',
 -                                         ];
 - 
 -                                         foreach ($fieldsToSync as $field) {
 -                                             $set($field, $billingAddress[$field]);
 -                                         }
 -                                     })
 -                                     ->columnSpanFull(),
 -                                 AddressFields::make()
 -                                     ->visible(static fn (Get $get) => ! $get('same_as_billing')),
 -                                 Forms\Components\Textarea::make('notes')
 -                                     ->label('Delivery instructions')
 -                                     ->maxLength(255)
 -                                     ->columnSpanFull(),
 -                             ])->columns(),
 -                     ])->columns(),
 -             ]);
 -     }
 - 
 -     public static function table(Table $table): Table
 -     {
 -         return $table
 -             ->columns([
 -                 Columns::id(),
 -                 Tables\Columns\TextColumn::make('name')
 -                     ->searchable()
 -                     ->sortable()
 -                     ->description(static fn (Client $client) => $client->primaryContact->full_name),
 -                 Tables\Columns\TextColumn::make('primaryContact.email')
 -                     ->label('Email')
 -                     ->searchable()
 -                     ->toggleable(),
 -                 Tables\Columns\TextColumn::make('primaryContact.phones')
 -                     ->label('Phone')
 -                     ->toggleable()
 -                     ->state(static fn (Client $client) => $client->primaryContact->first_available_phone),
 -                 Tables\Columns\TextColumn::make('billingAddress.address_string')
 -                     ->label('Billing address')
 -                     ->searchable()
 -                     ->toggleable(isToggledHiddenByDefault: true)
 -                     ->listWithLineBreaks(),
 -                 Tables\Columns\TextColumn::make('balance')
 -                     ->label('Balance')
 -                     ->getStateUsing(function (Client $client) {
 -                         return $client->invoices()
 -                             ->unpaid()
 -                             ->get()
 -                             ->sumMoneyInDefaultCurrency('amount_due');
 -                     })
 -                     ->coloredDescription(function (Client $client) {
 -                         $overdue = $client->invoices()
 -                             ->overdue()
 -                             ->get()
 -                             ->sumMoneyInDefaultCurrency('amount_due');
 - 
 -                         if ($overdue <= 0) {
 -                             return null;
 -                         }
 - 
 -                         $formattedOverdue = CurrencyConverter::formatCentsToMoney($overdue);
 - 
 -                         return "Overdue: {$formattedOverdue}";
 -                     })
 -                     ->sortable(query: function (Builder $query, string $direction) {
 -                         return $query
 -                             ->withSum(['invoices' => fn (Builder $query) => $query->unpaid()], 'amount_due')
 -                             ->orderBy('invoices_sum_amount_due', $direction);
 -                     })
 -                     ->currency(convert: false)
 -                     ->alignEnd(),
 -             ])
 -             ->filters([
 -                 //
 -             ])
 -             ->actions([
 -                 Tables\Actions\ActionGroup::make([
 -                     Tables\Actions\ActionGroup::make([
 -                         Tables\Actions\EditAction::make(),
 -                         Tables\Actions\ViewAction::make(),
 -                     ])->dropdown(false),
 -                     Tables\Actions\DeleteAction::make(),
 -                 ]),
 -             ])
 -             ->bulkActions([
 -                 Tables\Actions\BulkActionGroup::make([
 -                     Tables\Actions\DeleteBulkAction::make(),
 -                 ]),
 -             ]);
 -     }
 - 
 -     public static function getRelations(): array
 -     {
 -         return [
 -             //
 -         ];
 -     }
 - 
 -     public static function getPages(): array
 -     {
 -         return [
 -             'index' => Pages\ListClients::route('/'),
 -             'create' => Pages\CreateClient::route('/create'),
 -             'view' => Pages\ViewClient::route('/{record}'),
 -             'edit' => Pages\EditClient::route('/{record}/edit'),
 -         ];
 -     }
 - }
 
 
  |