diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index e6b9960..4c1dd5a 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -20,7 +20,7 @@ protected function schedule(Schedule $schedule): void
*/
protected function commands(): void
{
- $this->load(__DIR__.'/Commands');
+ $this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
diff --git a/app/Enums/ExpenseCategory.php b/app/Enums/ExpenseCategory.php
index f5b3d1a..ec76a0b 100644
--- a/app/Enums/ExpenseCategory.php
+++ b/app/Enums/ExpenseCategory.php
@@ -26,7 +26,7 @@ public function getLabel(): ?string
};
}
- public function getColor(): string | array | null
+ public function getColor(): string|array|null
{
return match ($this) {
self::Vat => 'teal',
diff --git a/app/Enums/LanguageCode.php b/app/Enums/LanguageCode.php
index d647855..5e26183 100644
--- a/app/Enums/LanguageCode.php
+++ b/app/Enums/LanguageCode.php
@@ -18,7 +18,7 @@ public function getLabel(): ?string
};
}
- public function getColor(): string | array | null
+ public function getColor(): string|array|null
{
return match ($this) {
self::DE => 'blue',
diff --git a/app/Enums/OfftimeCategory.php b/app/Enums/OfftimeCategory.php
index a25e14e..8aaea96 100644
--- a/app/Enums/OfftimeCategory.php
+++ b/app/Enums/OfftimeCategory.php
@@ -23,7 +23,7 @@ public function getLabel(): ?string
};
}
- public function getColor(): string | array | null
+ public function getColor(): string|array|null
{
return match ($this) {
self::Vacation => Color::Lime,
diff --git a/app/Enums/PricingUnit.php b/app/Enums/PricingUnit.php
index 1fc2c86..eef2fb9 100644
--- a/app/Enums/PricingUnit.php
+++ b/app/Enums/PricingUnit.php
@@ -20,7 +20,7 @@ public function getLabel(): ?string
};
}
- public function getColor(): string | array | null
+ public function getColor(): string|array|null
{
return match ($this) {
self::Hour => 'blue',
diff --git a/app/Filament/Pages/Auth/EditProfile.php b/app/Filament/Pages/Auth/EditProfile.php
index f7894f6..c1619c4 100644
--- a/app/Filament/Pages/Auth/EditProfile.php
+++ b/app/Filament/Pages/Auth/EditProfile.php
@@ -19,7 +19,7 @@ public function form(Schema $schema): Schema
$this->getPasswordFormComponent(),
$this->getPasswordConfirmationFormComponent(),
$this->getCurrentPasswordFormComponent(),
- ])
+ ]),
]);
}
}
diff --git a/app/Filament/Pages/Dashboard.php b/app/Filament/Pages/Dashboard.php
index 91be8a4..39f970f 100644
--- a/app/Filament/Pages/Dashboard.php
+++ b/app/Filament/Pages/Dashboard.php
@@ -10,7 +10,7 @@
class Dashboard extends BaseDashboard
{
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-chart-pie';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-chart-pie';
public function getColumns(): int|array
{
diff --git a/app/Filament/Pages/Taxes.php b/app/Filament/Pages/Taxes.php
index 053e437..39aa4fd 100644
--- a/app/Filament/Pages/Taxes.php
+++ b/app/Filament/Pages/Taxes.php
@@ -10,7 +10,7 @@ class Taxes extends BaseDashboard
{
protected static string $routePath = 'taxes';
protected static ?string $title = 'Steuern';
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-tax-euro';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-tax-euro';
public function getColumns(): int|array
{
diff --git a/app/Filament/Relations/EstimatesRelationManager.php b/app/Filament/Relations/EstimatesRelationManager.php
index 22e4baa..aaabeb1 100644
--- a/app/Filament/Relations/EstimatesRelationManager.php
+++ b/app/Filament/Relations/EstimatesRelationManager.php
@@ -35,7 +35,7 @@ public function table(Table $table): Table
->label(__('title')),
TextColumn::make('description')
->label(__('description'))
- ->formatStateUsing(fn (string $state): string => nl2br($state))
+ ->formatStateUsing(fn(string $state): string => nl2br($state))
->html(),
TextColumn::make('amount')
->label(trans_choice('hour', 2))
diff --git a/app/Filament/Relations/InvoicesRelationManager.php b/app/Filament/Relations/InvoicesRelationManager.php
index 0a2e2d1..1d4cd79 100644
--- a/app/Filament/Relations/InvoicesRelationManager.php
+++ b/app/Filament/Relations/InvoicesRelationManager.php
@@ -35,35 +35,36 @@ public function table(Table $table): Table
TextColumn::make('title')
->label(__('title'))
->sortable()
- ->description(fn (Invoice $record): string =>
- ($record->invoiced_at ? __('invoicedAt') . ' ' . Carbon::parse($record->invoiced_at)->isoFormat('LL') : '') .
- ($record->paid_at ? ', ' . __('paidAt') . ' ' . Carbon::parse($record->paid_at)->isoFormat('LL') : '')
+ ->description(
+ fn(Invoice $record): string
+ => ($record->invoiced_at ? __('invoicedAt') . ' ' . Carbon::parse($record->invoiced_at)->isoFormat('LL') : '')
+ . ($record->paid_at ? ', ' . __('paidAt') . ' ' . Carbon::parse($record->paid_at)->isoFormat('LL') : ''),
)
- ->tooltip(fn (Invoice $record): ?string => $record->description),
+ ->tooltip(fn(Invoice $record): ?string => $record->description),
TextColumn::make('price')
->label(__('price'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->description(fn (Invoice $record): string => $record->pricing_unit->getLabel()),
+ ->description(fn(Invoice $record): string => $record->pricing_unit->getLabel()),
TextColumn::make('net')
->label(__('net'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Invoice $record): float => $record->net)
- ->description(fn (Invoice $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
+ ->state(fn(Invoice $record): float => $record->net)
+ ->description(fn(Invoice $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
TextColumn::make('total')
->label(__('total'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Invoice $record): float => $record->final)
- ->description(fn (Invoice $record): string => Number::currency($record->vat, 'eur') . ' ' . __('vat')),
+ ->state(fn(Invoice $record): float => $record->final)
+ ->description(fn(Invoice $record): string => Number::currency($record->vat, 'eur') . ' ' . __('vat')),
])
->headerActions([
CreateAction::make()
->icon('tabler-plus')
->label(__('create'))
->schema(InvoiceResource::formFields(6, false))
- ->visible(fn (): bool => $this->getOwnerRecord() instanceof Project)
+ ->visible(fn(): bool => $this->getOwnerRecord() instanceof Project)
->mountUsing(function (Schema $schema) {
$schema->fill();
if ($this->getOwnerRecord() instanceof Project) {
@@ -86,7 +87,7 @@ public function table(Table $table): Table
->slideOver()
->modalWidth(Width::ExtraLarge),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
])
->toolbarActions([
BulkActionGroup::make([
@@ -99,7 +100,7 @@ public function table(Table $table): Table
->icon('tabler-plus')
->label(__('create'))
->schema(InvoiceResource::formFields(6, false))
- ->visible(fn (): bool => $this->getOwnerRecord() instanceof Project)
+ ->visible(fn(): bool => $this->getOwnerRecord() instanceof Project)
->mountUsing(function (Schema $schema) {
$schema->fill();
if ($this->getOwnerRecord() instanceof Project) {
diff --git a/app/Filament/Relations/PositionsRelationManager.php b/app/Filament/Relations/PositionsRelationManager.php
index a97ae0e..29bf29c 100644
--- a/app/Filament/Relations/PositionsRelationManager.php
+++ b/app/Filament/Relations/PositionsRelationManager.php
@@ -33,14 +33,14 @@ public function table(Table $table): Table
->columns([
TextColumn::make('description')
->label(__('description'))
- ->formatStateUsing(fn (string $state): string => nl2br($state))
+ ->formatStateUsing(fn(string $state): string => nl2br($state))
->html(),
TextColumn::make('amount')
->label(trans_choice('hour', 2))
- ->state(fn (Position $record): float => $record->duration)
+ ->state(fn(Position $record): float => $record->duration)
->weight(FontWeight::ExtraBold)
->fontFamily(FontFamily::Mono)
- ->description(fn (Position $record): string => $record->time_range),
+ ->description(fn(Position $record): string => $record->time_range),
ToggleColumn::make('remote')
->label(__('remote')),
])
diff --git a/app/Filament/Relations/ProjectsRelationManager.php b/app/Filament/Relations/ProjectsRelationManager.php
index 2cfdcce..c64e870 100644
--- a/app/Filament/Relations/ProjectsRelationManager.php
+++ b/app/Filament/Relations/ProjectsRelationManager.php
@@ -30,21 +30,22 @@ public function table(Table $table): Table
->label(__('title'))
->searchable()
->sortable()
- ->tooltip(fn (Project $record): ?string => $record->description),
+ ->tooltip(fn(Project $record): ?string => $record->description),
TextColumn::make('date_range')
->label(__('dateRange'))
- ->state(fn (Project $record): string => Carbon::parse($record->start_at)
- ->isoFormat('ll') . ' - ' . ($record->due_at ? Carbon::parse($record->due_at)->isoFormat('ll') : '∞')
+ ->state(
+ fn(Project $record): string => Carbon::parse($record->start_at)
+ ->isoFormat('ll') . ' - ' . ($record->due_at ? Carbon::parse($record->due_at)->isoFormat('ll') : '∞'),
),
TextColumn::make('scope')
->label(__('scope'))
- ->state(fn (Project $record): string => $record->scope_range),
+ ->state(fn(Project $record): string => $record->scope_range),
TextColumn::make('price_per_unit')
->label(__('price'))
- ->state(fn (Project $record): string => $record->price_per_unit),
+ ->state(fn(Project $record): string => $record->price_per_unit),
TextColumn::make('progress')
->label(__('progress'))
- ->state(fn (Project $record): string => $record->hours_with_label),
+ ->state(fn(Project $record): string => $record->hours_with_label),
TextColumn::make('created_at')
->label(__('createdAt'))
->datetime('j. F Y, H:i:s')
@@ -84,7 +85,7 @@ public function table(Table $table): Table
->slideOver()
->modalWidth(Width::Large),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
]);
}
diff --git a/app/Filament/Resources/ClientResource.php b/app/Filament/Resources/ClientResource.php
index 144c7d3..ed3d5ec 100644
--- a/app/Filament/Resources/ClientResource.php
+++ b/app/Filament/Resources/ClientResource.php
@@ -37,7 +37,7 @@
class ClientResource extends Resource
{
protected static ?string $model = Client::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-users';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-users';
protected static ?int $navigationSort = 10;
public static function getNavigationBadge(): ?string
@@ -70,7 +70,7 @@ public static function table(Table $table): Table
->label(__('name'))
->searchable()
->sortable()
- ->description(fn (Client $record): string => $record->full_address)
+ ->description(fn(Client $record): string => $record->full_address)
->wrap(),
TextColumn::make('language')
->label(__('language'))
@@ -80,14 +80,14 @@ public static function table(Table $table): Table
->label(__('net'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Client $record): float => $record->net)
- ->description(fn (Client $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
+ ->state(fn(Client $record): float => $record->net)
+ ->description(fn(Client $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
TextColumn::make('days_to_pay')
->label(__('payment'))
->abbr(__('averagePaymentDuration'), asTooltip: true)
->numeric(1)
->fontFamily(FontFamily::Mono)
- ->state(fn (Client $record): float => $record->avg_payment_delay)
+ ->state(fn(Client $record): float => $record->avg_payment_delay)
->description(trans_choice('day', 2)),
TextColumn::make('created_at')
->label(__('createdAt'))
@@ -107,9 +107,9 @@ public static function table(Table $table): Table
->recordActions(ActionGroup::make([
EditAction::make()->icon('tabler-edit'),
Action::make('kontaktieren')
- ->disabled(fn (Client $record) => !boolval($record->email))
+ ->disabled(fn(Client $record) => !boolval($record->email))
->icon('tabler-mail')
- ->schema(fn (Client $record) => [
+ ->schema(fn(Client $record) => [
TextInput::make('subject')
->label(__('subject'))
->required(),
@@ -118,12 +118,12 @@ public static function table(Table $table): Table
->required()
->default(__("email.template.contact.body", [
'name' => $record->name,
- 'sender' => Setting::get('name')
+ 'sender' => Setting::get('name'),
])),
])
->action(function (Client $record, array $data) {
Mail::to($record->email)->send(
- (new ContactClient(body: $data['content']))->subject($data['subject'])
+ (new ContactClient(body: $data['content']))->subject($data['subject']),
);
})
->slideOver()
diff --git a/app/Filament/Resources/EstimateResource.php b/app/Filament/Resources/EstimateResource.php
index 30d2ceb..b82a9ce 100644
--- a/app/Filament/Resources/EstimateResource.php
+++ b/app/Filament/Resources/EstimateResource.php
@@ -28,7 +28,7 @@
class EstimateResource extends Resource
{
protected static ?string $model = Estimate::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-clock-code';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-clock-code';
protected static ?int $navigationSort = 25;
public static function form(Schema $schema): Schema
@@ -43,12 +43,12 @@ public static function table(Table $table): Table
->columns([
ColorColumn::make('project.client.color')
->label('')
- ->tooltip(fn (Estimate $record): ?string => $record->project?->client?->name),
+ ->tooltip(fn(Estimate $record): ?string => $record->project?->client?->name),
TextColumn::make('title')
->label(__('title'))
->searchable()
->sortable()
- ->description(fn (Estimate $record): string => substr($record->description, 0, 75) . '...'),
+ ->description(fn(Estimate $record): string => substr($record->description, 0, 75) . '...'),
TextColumn::make('amount')
->label(trans_choice('hour', 2))
->numeric()
@@ -73,7 +73,7 @@ public static function table(Table $table): Table
->filters([
SelectFilter::make('project')
->label(trans_choice('project', 1))
- ->relationship('project', 'title')
+ ->relationship('project', 'title'),
])
->recordActions(
ActionGroup::make([
@@ -89,7 +89,7 @@ public static function table(Table $table): Table
->modalWidth(Width::Large),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
diff --git a/app/Filament/Resources/ExpenseResource.php b/app/Filament/Resources/ExpenseResource.php
index 10e9fd7..66e58d2 100644
--- a/app/Filament/Resources/ExpenseResource.php
+++ b/app/Filament/Resources/ExpenseResource.php
@@ -33,7 +33,7 @@
class ExpenseResource extends Resource
{
protected static ?string $model = Expense::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-credit-card';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-credit-card';
protected static ?int $navigationSort = 40;
public static function form(Schema $schema): Schema
@@ -65,8 +65,8 @@ public static function table(Table $table): Table
->label(__('vat'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Expense $record): float => $record->vat)
- ->color(fn (string $state): string => $state == 0 ? 'gray' : 'normal')
+ ->state(fn(Expense $record): float => $record->vat)
+ ->color(fn(string $state): string => $state == 0 ? 'gray' : 'normal')
->sortable(),
TextColumn::make('quantity')
->label(__('quantity'))
@@ -94,7 +94,7 @@ public static function table(Table $table): Table
->filters([
SelectFilter::make('category')
->label(__('category'))
- ->options(ExpenseCategory::options())
+ ->options(ExpenseCategory::options()),
])
->recordActions(
ActionGroup::make([
@@ -110,7 +110,7 @@ public static function table(Table $table): Table
->modalWidth(Width::Large),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
@@ -216,7 +216,7 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->suffixIcon('tabler-receipt-tax')
->columnSpan($columns / 2)
->required()
- ->hidden(fn (Get $get): bool => !$get('taxable')),
+ ->hidden(fn(Get $get): bool => !$get('taxable')),
Textarea::make('description')
->label(__('description'))
->maxLength(65535)
diff --git a/app/Filament/Resources/ExpenseResource/Pages/ListExpenses.php b/app/Filament/Resources/ExpenseResource/Pages/ListExpenses.php
index 886b074..5d753b2 100644
--- a/app/Filament/Resources/ExpenseResource/Pages/ListExpenses.php
+++ b/app/Filament/Resources/ExpenseResource/Pages/ListExpenses.php
@@ -14,28 +14,28 @@ class ListExpenses extends ListRecords
{
protected static string $resource = ExpenseResource::class;
- protected function getHeaderActions(): array
- {
- return [
- CreateAction::make()
- ->icon('tabler-plus')
- ->schema(ExpenseResource::formFields(6, false))
- ->slideOver()
- ->modalWidth(Width::Large),
- ];
- }
-
public function getTabs(): array
{
return [
'deliverables' => Tab::make()
->label(__('deliverables'))
- ->modifyQueryUsing(fn (Builder $query) => $query->whereIn('category', ExpenseCategory::deliverableCategories())),
+ ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('category', ExpenseCategory::deliverableCategories())),
'tax' => Tab::make()
->label(__('taxes'))
- ->modifyQueryUsing(fn (Builder $query) => $query->whereIn('category', ExpenseCategory::taxCategories())),
+ ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('category', ExpenseCategory::taxCategories())),
'all' => Tab::make()
->label(__('all')),
];
}
+
+ protected function getHeaderActions(): array
+ {
+ return [
+ CreateAction::make()
+ ->icon('tabler-plus')
+ ->schema(ExpenseResource::formFields(6, false))
+ ->slideOver()
+ ->modalWidth(Width::Large),
+ ];
+ }
}
diff --git a/app/Filament/Resources/GiftResource.php b/app/Filament/Resources/GiftResource.php
index 052e4ab..122c62d 100644
--- a/app/Filament/Resources/GiftResource.php
+++ b/app/Filament/Resources/GiftResource.php
@@ -27,7 +27,7 @@
class GiftResource extends Resource
{
protected static ?string $model = Gift::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-gift';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-gift';
protected static ?int $navigationSort = 50;
public static function form(Schema $schema): Schema
@@ -51,7 +51,7 @@ public static function table(Table $table): Table
->label(__('name'))
->searchable()
->sortable()
- ->description(fn (Gift $record): string => $record->email ?? ''),
+ ->description(fn(Gift $record): string => $record->email ?? ''),
TextColumn::make('amount')
->label(__('amount'))
->money('eur')
@@ -87,7 +87,7 @@ public static function table(Table $table): Table
->modalWidth(Width::Large),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
diff --git a/app/Filament/Resources/InvoiceResource.php b/app/Filament/Resources/InvoiceResource.php
index 2498ab3..70e5bf8 100644
--- a/app/Filament/Resources/InvoiceResource.php
+++ b/app/Filament/Resources/InvoiceResource.php
@@ -24,7 +24,6 @@
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
-use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Grid;
@@ -45,7 +44,7 @@
class InvoiceResource extends Resource
{
protected static ?string $model = Invoice::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-file-stack';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-file-stack';
protected static ?int $navigationSort = 30;
public static function getNavigationBadge(): ?string
@@ -70,13 +69,13 @@ public static function form(Schema $schema): Schema
->columns(10)
->components([
Section::make()
- ->columnSpan(['lg' => fn (?Invoice $record) => !$record?->project ? 10 : 8])
+ ->columnSpan(['lg' => fn(?Invoice $record) => !$record?->project ? 10 : 8])
->schema(self::formFields(12, false)),
Grid::make()
- ->hidden(fn (?Invoice $record) => !$record?->project)
+ ->hidden(fn(?Invoice $record) => !$record?->project)
->columns(1)
->columnSpan(['lg' => 2])
- ->schema(fn (?Invoice $record) => [
+ ->schema(fn(?Invoice $record) => [
Stat::make('project', '...')
->label(trans_choice('project', 1))
->value($record->project?->progress_percent ?? '-')
@@ -85,7 +84,7 @@ public static function form(Schema $schema): Schema
->label(trans_choice('invoice', 1))
->value($record->hours_formatted)
->description(new HtmlString(
- "$record->positions_formatted
$record->net_formatted " . __('net')
+ "$record->positions_formatted
$record->net_formatted " . __('net'),
)),
]),
]);
@@ -101,31 +100,32 @@ public static function table(Table $table): Table
->label(__('title'))
->searchable()
->sortable()
- ->description(fn (Invoice $record): string => $record->project?->client?->name)
- ->tooltip(fn (Invoice $record): ?string => $record->description),
+ ->description(fn(Invoice $record): string => $record->project?->client?->name)
+ ->tooltip(fn(Invoice $record): ?string => $record->description),
TextColumn::make('price')
->label(__('price'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->description(fn (Invoice $record): string => $record->pricing_unit->getLabel()),
+ ->description(fn(Invoice $record): string => $record->pricing_unit->getLabel()),
TextColumn::make('net')
->label(__('net'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Invoice $record): float => $record->net)
- ->description(fn (Invoice $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
+ ->state(fn(Invoice $record): float => $record->net)
+ ->description(fn(Invoice $record): string => $record->hours . ' ' . trans_choice('hour', $record->hours)),
TextColumn::make('total')
->label(__('total'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->state(fn (Invoice $record): float => $record->final)
- ->description(fn (Invoice $record): string => Number::currency($record->vat, 'eur') . ' ' . __('vat')),
+ ->state(fn(Invoice $record): float => $record->final)
+ ->description(fn(Invoice $record): string => Number::currency($record->vat, 'eur') . ' ' . __('vat')),
TextColumn::make('invoiced_at')
->label(__('invoiceDates'))
->date('j. F Y')
- ->description(fn (Invoice $record): string => $record->paid_at
+ ->description(
+ fn(Invoice $record): string => $record->paid_at
? Carbon::parse($record->paid_at)->isoFormat('LL')
- : ''
+ : '',
),
TextColumn::make('created_at')
->label(__('createdAt'))
@@ -178,7 +178,7 @@ public static function table(Table $table): Table
->label(__('send'))
->icon('tabler-mail-forward')
->hidden(fn(Invoice $record) => $record->status != InvoiceStatus::RUNNING)
- ->url(fn (Invoice $record): string => 'mailto:' . $record->project?->client?->email
+ ->url(fn(Invoice $record): string => 'mailto:' . $record->project?->client?->email
. '?subject=' . rawurlencode(trans_choice('invoice', 1, [], $record->project?->client?->language->value)) . ' ' . $record->current_number
. '&body=' . rawurlencode(__('email.template.invoicing.body.url', ['title' => $record->project?->title], $record->project?->client?->language->value))),
Action::make('issue')
@@ -213,12 +213,12 @@ public static function table(Table $table): Table
->label(__('paymentReminder'))
->icon('tabler-mail-exclamation')
->hidden(fn(Invoice $record) => $record->status != InvoiceStatus::SENT)
- ->url(fn (Invoice $record): string => 'mailto:' . $record->project?->client?->email
+ ->url(fn(Invoice $record): string => 'mailto:' . $record->project?->client?->email
. '?subject=' . rawurlencode(__('paymentReminder') . ' ' . trans_choice('invoice', 1, [], $record->project?->client?->language->value)) . ' ' . $record->final_number
. '&body=' . rawurlencode(__('email.template.paymentReminder.body.url', ['number' => $record->final_number], $record->project?->client?->language->value))),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
@@ -279,7 +279,7 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
Select::make('project_id')
->label(trans_choice('project', 1))
->relationship('project', 'title')
- ->getOptionLabelFromRecordUsing(fn (Project $record) => "{$record->title} ({$record->client->name})")
+ ->getOptionLabelFromRecordUsing(fn(Project $record) => "{$record->title} ({$record->client->name})")
->searchable()
->preload()
->suffixIcon('tabler-package')
@@ -289,12 +289,12 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->label(__('transitory'))
->inline(false)
->hintIcon('tabler-info-circle', __('invoice.onlyTransitory'))
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
Toggle::make('undated')
->label(__('undated'))
->inline(false)
->hintIcon('tabler-info-circle', __('hidePositionsDate'))
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
TextInput::make('title')
->label(__('title'))
->required()
@@ -311,13 +311,13 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->minValue(0.01)
->suffixIcon('tabler-currency-euro')
->required()
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
Select::make('pricing_unit')
->label(__('pricingUnit'))
->options(PricingUnit::class)
->suffixIcon('tabler-clock-2')
->required()
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
TextInput::make('discount')
->label(__('discount'))
->numeric()
@@ -325,7 +325,7 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->minValue(0.01)
->suffixIcon('tabler-currency-euro')
->helperText(__('priceBeforeTax'))
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
TextInput::make('deduction')
->label(__('deduction'))
->numeric()
@@ -333,13 +333,13 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->minValue(0.01)
->suffixIcon('tabler-currency-euro')
->helperText(__('priceAfterTax'))
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
Toggle::make('taxable')
->label(__('taxable'))
->inline(false)
->default(true)
->live()
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
TextInput::make('vat_rate')
->label(__('vatRate'))
->numeric()
@@ -347,18 +347,18 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
->minValue(0.01)
->default(0.19)
->suffixIcon('tabler-receipt-tax')
- ->hidden(fn (Get $get): bool => ! $get('taxable'))
- ->columnSpan($half/2),
+ ->hidden(fn(Get $get): bool => ! $get('taxable'))
+ ->columnSpan($half / 2),
DatePicker::make('invoiced_at')
->label(__('invoicedAt'))
->weekStartsOnMonday()
->suffixIcon('tabler-calendar-up')
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
DatePicker::make('paid_at')
->label(__('paidAt'))
->weekStartsOnMonday()
->suffixIcon('tabler-calendar-down')
- ->columnSpan($half/2),
+ ->columnSpan($half / 2),
];
return $useSection
diff --git a/app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php b/app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php
index add5d45..da224e0 100644
--- a/app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php
+++ b/app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php
@@ -17,6 +17,11 @@ class EditInvoice extends EditRecord
{
protected static string $resource = InvoiceResource::class;
+ public function getFooterWidgetsColumns(): int|array
+ {
+ return 12;
+ }
+
protected function getHeaderActions(): array
{
return [
@@ -40,11 +45,6 @@ protected function getHeaderActions(): array
];
}
- public function getFooterWidgetsColumns(): int|array
- {
- return 12;
- }
-
protected function getFooterWidgets(): array
{
return [
diff --git a/app/Filament/Resources/InvoiceResource/Pages/ListInvoices.php b/app/Filament/Resources/InvoiceResource/Pages/ListInvoices.php
index 206db14..ae156ef 100644
--- a/app/Filament/Resources/InvoiceResource/Pages/ListInvoices.php
+++ b/app/Filament/Resources/InvoiceResource/Pages/ListInvoices.php
@@ -15,17 +15,6 @@ class ListInvoices extends ListRecords
{
protected static string $resource = InvoiceResource::class;
- protected function getHeaderActions(): array
- {
- return [
- CreateAction::make()
- ->icon('tabler-plus')
- ->schema(InvoiceResource::formFields(6, false))
- ->slideOver()
- ->modalWidth(Width::ExtraLarge),
- ];
- }
-
public function getTabs(): array
{
$active = Invoice::active();
@@ -40,19 +29,30 @@ public function getTabs(): array
'active' => Tab::make()
->label(__('inProgress', ['net' => Number::currency($activeNet, 'eur') ]))
->badge($activeCount)
- ->modifyQueryUsing(fn (Builder $query) => $query->active()->orderBy('updated_at', 'desc')),
+ ->modifyQueryUsing(fn(Builder $query) => $query->active()->orderBy('updated_at', 'desc')),
'waiting' => Tab::make()
->label(__('waitingForPayment', ['net' => Number::currency($waitingNet, 'eur') ]))
->badge($waitingCount)
->badgeColor($waitingCount > 0 ? 'warning' : 'gray')
- ->modifyQueryUsing(fn (Builder $query) => $query->waiting()->orderBy('invoiced_at', 'desc')),
+ ->modifyQueryUsing(fn(Builder $query) => $query->waiting()->orderBy('invoiced_at', 'desc')),
'finished' => Tab::make()
->label(__('finished'))
->badge($finishedCount)
->badgeColor('gray')
- ->modifyQueryUsing(fn (Builder $query) => $query->finished()->orderBy('paid_at', 'desc')),
+ ->modifyQueryUsing(fn(Builder $query) => $query->finished()->orderBy('paid_at', 'desc')),
'all' => Tab::make()
->label(__('all')),
];
}
+
+ protected function getHeaderActions(): array
+ {
+ return [
+ CreateAction::make()
+ ->icon('tabler-plus')
+ ->schema(InvoiceResource::formFields(6, false))
+ ->slideOver()
+ ->modalWidth(Width::ExtraLarge),
+ ];
+ }
}
diff --git a/app/Filament/Resources/InvoiceResource/Widgets/ActiveInvoices.php b/app/Filament/Resources/InvoiceResource/Widgets/ActiveInvoices.php
index 598e2a9..50e15d8 100644
--- a/app/Filament/Resources/InvoiceResource/Widgets/ActiveInvoices.php
+++ b/app/Filament/Resources/InvoiceResource/Widgets/ActiveInvoices.php
@@ -14,7 +14,7 @@ class ActiveInvoices extends TableWidget
{
public ?Invoice $record = null;
- protected int | string | array $columnSpan = 6;
+ protected int|string|array $columnSpan = 6;
public function table(Table $table): Table
{
@@ -33,7 +33,7 @@ public function table(Table $table): Table
Action::make('edit')
->label('')
->icon('tabler-edit')
- ->url(fn (Invoice $i): string => InvoiceResource::getUrl('edit', ['record' => $i])),
+ ->url(fn(Invoice $i): string => InvoiceResource::getUrl('edit', ['record' => $i])),
]);
}
}
diff --git a/app/Filament/Resources/InvoiceResource/Widgets/ClientInvoices.php b/app/Filament/Resources/InvoiceResource/Widgets/ClientInvoices.php
index d4fe0bd..57ff653 100644
--- a/app/Filament/Resources/InvoiceResource/Widgets/ClientInvoices.php
+++ b/app/Filament/Resources/InvoiceResource/Widgets/ClientInvoices.php
@@ -14,15 +14,15 @@ class ClientInvoices extends TableWidget
{
public ?Invoice $record = null;
- protected int | string | array $columnSpan = 6;
+ protected int|string|array $columnSpan = 6;
public function table(Table $table): Table
{
return $table
->heading(__('otherInvoices'))
->query(
- Invoice::whereHas('project', fn ($query) => $query->where('client_id', $this->record?->project->client_id))
- ->whereNot('id', $this->record?->id)
+ Invoice::whereHas('project', fn($query) => $query->where('client_id', $this->record?->project->client_id))
+ ->whereNot('id', $this->record?->id),
)
->paginated([8])
->defaultSort('created_at', 'desc')
@@ -39,7 +39,7 @@ public function table(Table $table): Table
Action::make('edit')
->label('')
->icon('tabler-edit')
- ->url(fn (Invoice $i): string => InvoiceResource::getUrl('edit', ['record' => $i])),
+ ->url(fn(Invoice $i): string => InvoiceResource::getUrl('edit', ['record' => $i])),
]);
}
}
diff --git a/app/Filament/Resources/OfftimeResource.php b/app/Filament/Resources/OfftimeResource.php
index f05f7e9..b8bcd92 100644
--- a/app/Filament/Resources/OfftimeResource.php
+++ b/app/Filament/Resources/OfftimeResource.php
@@ -28,7 +28,7 @@
class OfftimeResource extends Resource
{
protected static ?string $model = Offtime::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-beach';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-beach';
protected static ?int $navigationSort = 60;
public static function form(Schema $schema): Schema
@@ -46,7 +46,7 @@ public static function table(Table $table): Table
->sortable(),
TextColumn::make('days')
->label(trans_choice('day', 2))
- ->state(fn (Offtime $record): string => $record->days_count ?? '')
+ ->state(fn(Offtime $record): string => $record->days_count ?? '')
->fontFamily(FontFamily::Mono)
->sortable(),
TextColumn::make('category')
@@ -60,7 +60,7 @@ public static function table(Table $table): Table
])
->filters([
SelectFilter::make('category')
- ->options(OfftimeCategory::options())
+ ->options(OfftimeCategory::options()),
])
->recordActions(
ActionGroup::make([
@@ -76,7 +76,7 @@ public static function table(Table $table): Table
->modalWidth(Width::Large),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
diff --git a/app/Filament/Resources/PositionResource.php b/app/Filament/Resources/PositionResource.php
index 866c1cf..ef3188f 100644
--- a/app/Filament/Resources/PositionResource.php
+++ b/app/Filament/Resources/PositionResource.php
@@ -39,7 +39,7 @@
class PositionResource extends Resource
{
protected static ?string $model = Position::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-list-details';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-list-details';
protected static ?int $navigationSort = 35;
public static function form(Schema $schema): Schema
@@ -53,19 +53,19 @@ public static function table(Table $table): Table
->columns([
ColorColumn::make('invoice.project.client.color')
->label('')
- ->tooltip(fn (Position $record): ?string => $record->invoice?->project?->client?->name),
+ ->tooltip(fn(Position $record): ?string => $record->invoice?->project?->client?->name),
TextColumn::make('description')
->label(__('description'))
->searchable()
- ->tooltip(fn (Position $record): ?string => $record->invoice?->title)
- ->formatStateUsing(fn (string $state): string => nl2br($state))
+ ->tooltip(fn(Position $record): ?string => $record->invoice?->title)
+ ->formatStateUsing(fn(string $state): string => nl2br($state))
->html(),
TextColumn::make('amount')
->label(trans_choice('hour', 2))
- ->state(fn (Position $record): float => $record->duration)
+ ->state(fn(Position $record): float => $record->duration)
->fontFamily(FontFamily::Mono)
->weight(FontWeight::ExtraBold)
- ->description(fn (Position $record): string => $record->time_range),
+ ->description(fn(Position $record): string => $record->time_range),
ToggleColumn::make('remote')
->label(__('remote')),
TextColumn::make('created_at')
@@ -92,7 +92,7 @@ public static function table(Table $table): Table
->preload(),
SelectFilter::make('invoice')
->label(trans_choice('invoice', 1))
- ->relationship('invoice', 'title', fn (Builder $query) => $query->active()->orderByDesc('created_at'))
+ ->relationship('invoice', 'title', fn(Builder $query) => $query->active()->orderByDesc('created_at'))
->searchable()
->preload(),
Filter::make('created_at')
@@ -107,11 +107,11 @@ public static function table(Table $table): Table
return $query
->when(
$data['earliest'],
- fn (Builder $query, $date): Builder => $query->whereDate('started_at', '>=', $date),
+ fn(Builder $query, $date): Builder => $query->whereDate('started_at', '>=', $date),
)
->when(
$data['latest'],
- fn (Builder $query, $date): Builder => $query->whereDate('finished_at', '<=', $date),
+ fn(Builder $query, $date): Builder => $query->whereDate('finished_at', '<=', $date),
);
}),
TernaryFilter::make('remote'),
@@ -131,7 +131,7 @@ public static function table(Table $table): Table
->modalWidth(Width::TwoExtraLarge),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
@@ -206,7 +206,7 @@ public static function formFields(int $columns = 12, bool $useSection = true): a
if ($started >= $finished || !$started->isSameDay($finished)) {
$set(
'finished_at',
- $started->addMinutes($previous->diffInMinutes($finished))->toDateTimeString()
+ $started->addMinutes($previous->diffInMinutes($finished))->toDateTimeString(),
);
}
})
diff --git a/app/Filament/Resources/PositionResource/Widgets/RecentPositionsChart.php b/app/Filament/Resources/PositionResource/Widgets/RecentPositionsChart.php
index 6fa6c85..f8af493 100644
--- a/app/Filament/Resources/PositionResource/Widgets/RecentPositionsChart.php
+++ b/app/Filament/Resources/PositionResource/Widgets/RecentPositionsChart.php
@@ -11,13 +11,13 @@
class RecentPositionsChart extends ChartWidget
{
- protected ?string $maxHeight = '180px';
public ?string $filter = '60';
- public int | string | array $columnSpan = [
+ public int|string|array $columnSpan = [
'sm' => 12,
'xl' => 6,
];
+ protected ?string $maxHeight = '180px';
public function getHeading(): string
{
@@ -33,7 +33,7 @@ protected function getData(): array
{
$labels = [];
$datasets = [];
- $period = CarbonPeriod::create(Carbon::now()->subDays((int)$this->filter), '1 day', 'now');
+ $period = CarbonPeriod::create(Carbon::now()->subDays((int) $this->filter), '1 day', 'now');
foreach ($period as $i => $date) {
// X-Axis labels
$labels[] = $date->isoFormat('dd, D. MMM');
diff --git a/app/Filament/Resources/ProjectResource.php b/app/Filament/Resources/ProjectResource.php
index 266cdef..f1c6a77 100644
--- a/app/Filament/Resources/ProjectResource.php
+++ b/app/Filament/Resources/ProjectResource.php
@@ -37,7 +37,7 @@
class ProjectResource extends Resource
{
protected static ?string $model = Project::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-package';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-package';
protected static ?int $navigationSort = 20;
public static function getNavigationBadge(): ?string
@@ -65,24 +65,26 @@ public static function table(Table $table): Table
->label(__('title'))
->searchable()
->sortable()
- ->description(fn (Project $record): string => $record->client?->name)
- ->tooltip(fn (Project $record): ?string => $record->description),
+ ->description(fn(Project $record): string => $record->client?->name)
+ ->tooltip(fn(Project $record): ?string => $record->description),
TextColumn::make('date_range')
->label(__('dateRange'))
- ->state(fn (Project $record): string => Carbon::parse($record->start_at)
- ->longAbsoluteDiffForHumans(Carbon::parse($record->due_at), 2)
+ ->state(
+ fn(Project $record): string => Carbon::parse($record->start_at)
+ ->longAbsoluteDiffForHumans(Carbon::parse($record->due_at), 2),
)
- ->description(fn (Project $record): string => Carbon::parse($record->start_at)
- ->isoFormat('ll') . ' - ' . ($record->due_at ? Carbon::parse($record->due_at)->isoFormat('ll') : '∞')
+ ->description(
+ fn(Project $record): string => Carbon::parse($record->start_at)
+ ->isoFormat('ll') . ' - ' . ($record->due_at ? Carbon::parse($record->due_at)->isoFormat('ll') : '∞'),
),
TextColumn::make('scope')
->label(__('scope'))
- ->state(fn (Project $record): string => $record->scope_range)
- ->description(fn (Project $record): string => $record->price_per_unit),
+ ->state(fn(Project $record): string => $record->scope_range)
+ ->description(fn(Project $record): string => $record->price_per_unit),
TextColumn::make('progress')
->label(__('progress'))
- ->state(fn (Project $record): string => $record->hours_with_label)
- ->description(fn (Project $record): string => $record->progress_percent),
+ ->state(fn(Project $record): string => $record->hours_with_label)
+ ->description(fn(Project $record): string => $record->progress_percent),
TextColumn::make('created_at')
->label(__('createdAt'))
->datetime('j. F Y, H:i:s')
@@ -122,7 +124,7 @@ public static function table(Table $table): Table
}),
DeleteAction::make()->icon('tabler-trash')->requiresConfirmation(),
])
- ->icon('tabler-dots-vertical')
+ ->icon('tabler-dots-vertical'),
)
->toolbarActions([
BulkActionGroup::make([
diff --git a/app/Filament/Resources/ProjectResource/Pages/ListProjects.php b/app/Filament/Resources/ProjectResource/Pages/ListProjects.php
index 54be1bc..98d4e10 100644
--- a/app/Filament/Resources/ProjectResource/Pages/ListProjects.php
+++ b/app/Filament/Resources/ProjectResource/Pages/ListProjects.php
@@ -14,40 +14,40 @@ class ListProjects extends ListRecords
{
protected static string $resource = ProjectResource::class;
- protected function getHeaderActions(): array
- {
- return [
- CreateAction::make()
- ->icon('tabler-plus')
- ->schema(ProjectResource::formFields(6, false))
- ->slideOver()
- ->modalWidth(Width::Large),
- ];
- }
-
public function getTabs(): array
{
return [
'active' => Tab::make()
->label(__('active'))
->badge(Project::active()->count())
- ->modifyQueryUsing(fn (Builder $query) => $query->active()),
+ ->modifyQueryUsing(fn(Builder $query) => $query->active()),
'upcoming' => Tab::make()
->label(__('upcoming'))
->badge(Project::upcoming()->count())
- ->modifyQueryUsing(fn (Builder $query) => $query->upcoming()),
+ ->modifyQueryUsing(fn(Builder $query) => $query->upcoming()),
'finished' => Tab::make()
->label(__('finished'))
->badge(Project::finished()->count())
->badgeColor('gray')
- ->modifyQueryUsing(fn (Builder $query) => $query->finished()),
+ ->modifyQueryUsing(fn(Builder $query) => $query->finished()),
'aborted' => Tab::make()
->label(__('aborted'))
->badge(Project::aborted()->count())
->badgeColor('gray')
- ->modifyQueryUsing(fn (Builder $query) => $query->aborted()),
+ ->modifyQueryUsing(fn(Builder $query) => $query->aborted()),
'all' => Tab::make()
->label(__('all')),
];
}
+
+ protected function getHeaderActions(): array
+ {
+ return [
+ CreateAction::make()
+ ->icon('tabler-plus')
+ ->schema(ProjectResource::formFields(6, false))
+ ->slideOver()
+ ->modalWidth(Width::Large),
+ ];
+ }
}
diff --git a/app/Filament/Resources/ProjectResource/Widgets/CurrentProjects.php b/app/Filament/Resources/ProjectResource/Widgets/CurrentProjects.php
index b1c499b..8edc762 100644
--- a/app/Filament/Resources/ProjectResource/Widgets/CurrentProjects.php
+++ b/app/Filament/Resources/ProjectResource/Widgets/CurrentProjects.php
@@ -11,7 +11,7 @@ class CurrentProjects extends Widget
protected string $view = 'filament.widgets.current-projects-widget';
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 6,
];
diff --git a/app/Filament/Resources/SettingResource.php b/app/Filament/Resources/SettingResource.php
index be8591e..10c38cb 100644
--- a/app/Filament/Resources/SettingResource.php
+++ b/app/Filament/Resources/SettingResource.php
@@ -12,7 +12,7 @@
class SettingResource extends Resource
{
protected static ?string $model = Setting::class;
- protected static string | \BackedEnum | null $navigationIcon = 'tabler-adjustments';
+ protected static string|\BackedEnum|null $navigationIcon = 'tabler-adjustments';
public static function table(Table $table): Table
{
@@ -21,7 +21,7 @@ public static function table(Table $table): Table
->columns([
TextColumn::make('field')
->label(__('field'))
- ->state(fn (Setting $record): string => "{$record->label} ({$record->field})")
+ ->state(fn(Setting $record): string => "{$record->label} ({$record->field})")
->html(),
TextInputColumn::make('value')
->label(__('value'))
diff --git a/app/Filament/Widgets/ClientHoursChart.php b/app/Filament/Widgets/ClientHoursChart.php
index 5c44911..5198432 100644
--- a/app/Filament/Widgets/ClientHoursChart.php
+++ b/app/Filament/Widgets/ClientHoursChart.php
@@ -13,7 +13,7 @@ class ClientHoursChart extends ChartWidget
protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -49,7 +49,7 @@ protected function getData(): array
$client = Client::find($clientId);
$datasets[] = [
'label' => $client->name,
- 'data' => array_map(fn ($i) => $yearly[$i] ?? 0, array_keys($labels)),
+ 'data' => array_map(fn($i) => $yearly[$i] ?? 0, array_keys($labels)),
'fill' => 'start',
'borderColor' => $client->color,
'backgroundColor' => $client->color . '22',
@@ -58,7 +58,7 @@ protected function getData(): array
return [
'datasets' => $datasets,
- 'labels' => array_map(fn ($year) => (string) $year, $labels),
+ 'labels' => array_map(fn($year) => (string) $year, $labels),
];
}
diff --git a/app/Filament/Widgets/ClientProfitChart.php b/app/Filament/Widgets/ClientProfitChart.php
index 43a77de..86a3f88 100644
--- a/app/Filament/Widgets/ClientProfitChart.php
+++ b/app/Filament/Widgets/ClientProfitChart.php
@@ -13,7 +13,7 @@ class ClientProfitChart extends ChartWidget
protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -49,7 +49,7 @@ protected function getData(): array
$client = Client::find($clientId);
$datasets[] = [
'label' => $client->name,
- 'data' => array_map(fn ($i) => $yearly[$i] ?? 0, array_keys($labels)),
+ 'data' => array_map(fn($i) => $yearly[$i] ?? 0, array_keys($labels)),
'fill' => 'start',
'borderColor' => $client->color,
'backgroundColor' => $client->color . '22',
@@ -58,7 +58,7 @@ protected function getData(): array
return [
'datasets' => $datasets,
- 'labels' => array_map(fn ($year) => (string) $year, $labels),
+ 'labels' => array_map(fn($year) => (string) $year, $labels),
];
}
diff --git a/app/Filament/Widgets/ClientProfitDistributionChart.php b/app/Filament/Widgets/ClientProfitDistributionChart.php
index 64bd82b..8074e1c 100644
--- a/app/Filament/Widgets/ClientProfitDistributionChart.php
+++ b/app/Filament/Widgets/ClientProfitDistributionChart.php
@@ -12,12 +12,12 @@
class ClientProfitDistributionChart extends ChartWidget
{
use HasEmptyStateChart;
+ public ?string $filter = '';
protected ?string $maxHeight = '180px';
- public ?string $filter = '';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -48,8 +48,8 @@ protected function getData(): array
: $obj->net;
}
$sum = array_sum($profit);
- $labels = array_map(fn ($id, $p) => '(' . round($p/$sum*100, 1) . '%) ' . Client::find($id)->name, array_keys($profit), $profit);
- $colors = array_map(fn ($id) => Client::find($id)->color, array_keys($profit));
+ $labels = array_map(fn($id, $p) => '(' . round($p / $sum * 100, 1) . '%) ' . Client::find($id)->name, array_keys($profit), $profit);
+ $colors = array_map(fn($id) => Client::find($id)->color, array_keys($profit));
return [
'datasets' => [
@@ -57,10 +57,10 @@ protected function getData(): array
'data' => array_values($profit),
'borderColor' => $colors,
'backgroundColor' => $colors,
- 'hoverOffset' => 4
+ 'hoverOffset' => 4,
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/GiftSubjectDistributionChart.php b/app/Filament/Widgets/GiftSubjectDistributionChart.php
index c5b231d..78c4724 100644
--- a/app/Filament/Widgets/GiftSubjectDistributionChart.php
+++ b/app/Filament/Widgets/GiftSubjectDistributionChart.php
@@ -11,12 +11,12 @@
class GiftSubjectDistributionChart extends ChartWidget
{
use HasEmptyStateChart;
+ public ?string $filter = 'all';
protected ?string $maxHeight = '180px';
- public ?string $filter = 'all';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -49,8 +49,8 @@ protected function getData(): array
: $obj->amount;
}
$sum = array_sum($amounts);
- $labels = array_map(fn ($subject, $a) => '(' . round($a/$sum*100, 1) . '%) ' . $subject, array_keys($amounts), $amounts);
- $colors = array_map(fn ($subject) => self::colorForSubject($subject), array_keys($amounts));
+ $labels = array_map(fn($subject, $a) => '(' . round($a / $sum * 100, 1) . '%) ' . $subject, array_keys($amounts), $amounts);
+ $colors = array_map(fn($subject) => self::colorForSubject($subject), array_keys($amounts));
return [
'datasets' => [
@@ -58,10 +58,10 @@ protected function getData(): array
'data' => array_values($amounts),
'borderColor' => $colors,
'backgroundColor' => $colors,
- 'hoverOffset' => 4
+ 'hoverOffset' => 4,
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
@@ -75,16 +75,6 @@ protected function getFilters(): ?array
return ['all' => __('all')] + Gift::getYearList();
}
- /**
- * Deterministically derive a color from a subject name, so that
- * the same subject always gets the same slice color across renders.
- */
- private static function colorForSubject(string $subject): string
- {
- $hue = crc32($subject) % 360;
- return "hsl({$hue}, 65%, 55%)";
- }
-
protected function getOptions(): RawJs
{
return RawJs::make(<< 12,
'xl' => 3,
];
@@ -38,19 +38,21 @@ protected function getData(): array
$labels = iterator_to_array($period->map(fn(Carbon $date) => $date->format('Y')));
array_pop($labels);
$period = $period->toArray();
- $count = array_fill(0, count($period)-1, 0);
- $rates = array_fill(0, count($period)-1, 0);
+ $count = array_fill(0, count($period) - 1, 0);
+ $rates = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($invoices as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->paid_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->paid_at)) {
$rates[$i] += $obj->net;
$count[$i] += $obj->hours;
}
}
}
foreach ($rates as $i => $rate) {
- $rates[$i] = $count[$i] != 0 ? round($rate/$count[$i]) : 0;
+ $rates[$i] = $count[$i] != 0 ? round($rate / $count[$i]) : 0;
}
return [
@@ -62,7 +64,7 @@ protected function getData(): array
'barPercentage' => 0.75,
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/MonthlyIncomeChart.php b/app/Filament/Widgets/MonthlyIncomeChart.php
index 71934cc..0a561f4 100644
--- a/app/Filament/Widgets/MonthlyIncomeChart.php
+++ b/app/Filament/Widgets/MonthlyIncomeChart.php
@@ -16,7 +16,7 @@ class MonthlyIncomeChart extends ChartWidget
protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -45,12 +45,14 @@ protected function getData(): array
$labels = iterator_to_array($period->map(fn(Carbon $date) => $date->format('Y')));
array_pop($labels);
$period = $period->toArray();
- $invoiceData = array_fill(0, count($period)-1, 0);
+ $invoiceData = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($invoices as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->paid_at)) {
- $invoiceData[$i] += match($this->filter) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->paid_at)) {
+ $invoiceData[$i] += match ($this->filter) {
'net' => $obj->net,
'gross' => $obj->gross,
};
@@ -59,23 +61,23 @@ protected function getData(): array
if ($this->filter === 'net') {
foreach ($taxes as $obj) {
// Shift yearly income taxes post pays to the year before
- if ($i > 0 && !Str($obj->description)->contains('EStVA') && CarbonPeriod::create($date, $period[$i+1])->contains(Carbon::parse($obj->expended_at))) {
- $invoiceData[$i-1] = round($invoiceData[$i-1] - $obj->net/($i == count($period)-2 ? now()->month : 12), 2);
+ if ($i > 0 && !Str($obj->description)->contains('EStVA') && CarbonPeriod::create($date, $period[$i + 1])->contains(Carbon::parse($obj->expended_at))) {
+ $invoiceData[$i - 1] = round($invoiceData[$i - 1] - $obj->net / ($i == count($period) - 2 ? now()->month : 12), 2);
continue;
}
// Handle income tax advance pays
- if (CarbonPeriod::create($date, $period[$i+1])->contains(Carbon::parse($obj->expended_at))) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains(Carbon::parse($obj->expended_at))) {
$invoiceData[$i] -= $obj->net;
}
}
}
- $invoiceData[$i] = round($invoiceData[$i]/($i == count($period)-2 ? now()->month : 12), 2);
+ $invoiceData[$i] = round($invoiceData[$i] / ($i == count($period) - 2 ? now()->month : 12), 2);
}
return [
'datasets' => [
[
- 'label' => match($this->filter) {
+ 'label' => match ($this->filter) {
'net' => __('netIncome'),
'gross' => __('grossIncome'),
},
@@ -85,7 +87,7 @@ protected function getData(): array
'borderColor' => '#3b82f6',
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/OfftimeChart.php b/app/Filament/Widgets/OfftimeChart.php
index c1997c9..5f38946 100644
--- a/app/Filament/Widgets/OfftimeChart.php
+++ b/app/Filament/Widgets/OfftimeChart.php
@@ -11,11 +11,11 @@
class OfftimeChart extends ChartWidget
{
- protected ?string $maxHeight = '180px';
public ?string $filter = 'y';
+ protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -38,22 +38,24 @@ protected function getData(): array
array_pop($labels);
$period = $period->toArray();
- $weekendData = array_fill(0, count($period)-1, 0);
- $plannedData = array_fill(0, count($period)-1, 0);
- $unplannedData = array_fill(0, count($period)-1, 0);
- $totalData = array_fill(0, count($period)-1, 0);
- $workedData = array_fill(0, count($period)-1, 0);
+ $weekendData = array_fill(0, count($period) - 1, 0);
+ $plannedData = array_fill(0, count($period) - 1, 0);
+ $unplannedData = array_fill(0, count($period) - 1, 0);
+ $totalData = array_fill(0, count($period) - 1, 0);
+ $workedData = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
[$w, $p, $u, $t] = Offtime::daysCountByYear(intval($date->format('Y')));
$weekendData[$i] = $w;
$plannedData[$i] = $p;
$unplannedData[$i] = $u;
$totalData[$i] = $t;
- $workedData[$i] = Position::whereBetween('started_at', [$date, $period[$i+1]])
+ $workedData[$i] = Position::whereBetween('started_at', [$date, $period[$i + 1]])
->get(['started_at'])
- ->map(fn ($obj) => $obj->started_at->format('Y-m-d'))
+ ->map(fn($obj) => $obj->started_at->format('Y-m-d'))
->unique()
->count();
}
@@ -96,7 +98,7 @@ protected function getData(): array
'borderColor' => '#39444b',
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/SalesChart.php b/app/Filament/Widgets/SalesChart.php
index 2178c04..7dc0381 100644
--- a/app/Filament/Widgets/SalesChart.php
+++ b/app/Filament/Widgets/SalesChart.php
@@ -12,11 +12,11 @@
class SalesChart extends ChartWidget
{
- protected ?string $maxHeight = '180px';
public ?string $filter = 'y';
+ protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 5,
];
@@ -45,35 +45,37 @@ protected function getData(): array
->whereIn('category', ExpenseCategory::taxCategories())
->oldest('expended_at')
->get();
- $period = match($this->filter) {
+ $period = match ($this->filter) {
'y' => Carbon::parse($invoices->first()?->paid_at)->startOfYear()->yearsUntil(now()->addYear()),
'q' => Carbon::parse($invoices->first()?->paid_at)->startOfQuarter()->quartersUntil(now()->addQuarter()),
'm' => Carbon::parse($invoices->first()?->paid_at)->startOfMonth()->monthsUntil(now()->addMonth()),
};
- $labels = iterator_to_array($period->map(fn(Carbon $date) => match($this->filter) {
+ $labels = iterator_to_array($period->map(fn(Carbon $date) => match ($this->filter) {
'y' => $date->format('Y'),
'q' => $date->isoFormat('YYYY [Q]Q'),
'm' => $date->isoFormat('YYYY MMM'),
}));
array_pop($labels);
$period = $period->toArray();
- $invoiceData = array_fill(0, count($period)-1, 0);
- $expenseData = array_fill(0, count($period)-1, 0);
- $taxData = array_fill(0, count($period)-1, 0);
+ $invoiceData = array_fill(0, count($period) - 1, 0);
+ $expenseData = array_fill(0, count($period) - 1, 0);
+ $taxData = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($invoices as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->paid_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->paid_at)) {
$invoiceData[$i] += $obj->net;
}
}
foreach ($expenses as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->expended_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->expended_at)) {
$expenseData[$i] += $obj->net;
}
}
foreach ($taxes as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->expended_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->expended_at)) {
$taxData[$i] += $obj->net;
}
}
@@ -103,7 +105,7 @@ protected function getData(): array
'borderColor' => '#f97316',
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/StatsOverview.php b/app/Filament/Widgets/StatsOverview.php
index 404da53..f995558 100644
--- a/app/Filament/Widgets/StatsOverview.php
+++ b/app/Filament/Widgets/StatsOverview.php
@@ -13,7 +13,7 @@
class StatsOverview extends BaseWidget
{
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 12,
];
@@ -21,16 +21,16 @@ class StatsOverview extends BaseWidget
protected function getStats(): array
{
[$revenue, $hours] = $this->getData();
- $previousRevenue = $revenue[count($revenue)-2];
- $revenueStat = Number::currency($revenue[count($revenue)-1], 'eur');
- $revenueDiff = $revenue[count($revenue)-1] - $previousRevenue;
+ $previousRevenue = $revenue[count($revenue) - 2];
+ $revenueStat = Number::currency($revenue[count($revenue) - 1], 'eur');
+ $revenueDiff = $revenue[count($revenue) - 1] - $previousRevenue;
$revenueIncrease = $revenueDiff >= 0;
- $revenueDiffPercent = $previousRevenue ? round(abs($revenueDiff)/$previousRevenue*100) : 0;
- $previousHours = $hours[count($hours)-2];
- $hoursStat = $hours[count($hours)-1];
- $hoursDiff = $hours[count($hours)-1] - $previousHours;
+ $revenueDiffPercent = $previousRevenue ? round(abs($revenueDiff) / $previousRevenue * 100) : 0;
+ $previousHours = $hours[count($hours) - 2];
+ $hoursStat = $hours[count($hours) - 1];
+ $hoursDiff = $hours[count($hours) - 1] - $previousHours;
$hoursIncrease = $hoursDiff >= 0;
- $hoursDiffPercent = $previousHours ? round(abs($hoursDiff)/$previousHours*100) : 0;
+ $hoursDiffPercent = $previousHours ? round(abs($hoursDiff) / $previousHours * 100) : 0;
$vFilament = InstalledVersions::getPrettyVersion('filament/filament');
$vLaravel = InstalledVersions::getPrettyVersion('laravel/framework');
@@ -39,14 +39,14 @@ protected function getStats(): array
Stat::make('weeklyRevenue', $revenueStat)
->label(__('weeklyRevenue'))
->description($revenueDiffPercent . '% ' . ($revenueIncrease ? __('increase') : __('decrease')))
- ->descriptionIcon($revenueIncrease ? 'tabler-trending-up': 'tabler-trending-down')
+ ->descriptionIcon($revenueIncrease ? 'tabler-trending-up' : 'tabler-trending-down')
->chart($revenue)
->color($revenueIncrease ? Color::Blue : Color::Red)
->extraAttributes(['class' => 'font-mono']),
Stat::make('weeklyWorkingHours', Number::format($hoursStat))
->label(__('weeklyWorkingHours'))
->description($hoursDiffPercent . '% ' . ($hoursIncrease ? __('increase') : __('decrease')))
- ->descriptionIcon($hoursIncrease ? 'tabler-trending-up': 'tabler-trending-down')
+ ->descriptionIcon($hoursIncrease ? 'tabler-trending-up' : 'tabler-trending-down')
->chart($hours)
->color($hoursIncrease ? Color::Blue : Color::Red)
->extraAttributes(['class' => 'font-mono']),
@@ -60,12 +60,14 @@ protected function getData(): array
{
$positions = Position::where('started_at', '>', now()->subWeeks(7)->startOfWeek(Carbon::MONDAY))->get();
$period = now()->subWeeks(8)->startOfWeek()->weeksUntil(now()->addWeek()->endOfWeek(Carbon::SUNDAY))->toArray();
- $revenue = array_fill(0, count($period)-1, 0);
- $hours = array_fill(0, count($period)-1, 0);
+ $revenue = array_fill(0, count($period) - 1, 0);
+ $hours = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($positions as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->started_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->started_at)) {
$revenue[$i] += $obj->net;
$hours[$i] += $obj->duration;
}
diff --git a/app/Filament/Widgets/SumGiftsChart.php b/app/Filament/Widgets/SumGiftsChart.php
index 5d37ad7..6a9f503 100644
--- a/app/Filament/Widgets/SumGiftsChart.php
+++ b/app/Filament/Widgets/SumGiftsChart.php
@@ -12,12 +12,12 @@
class SumGiftsChart extends ChartWidget
{
use HasEmptyStateChart;
+ public ?string $filter = 'y';
protected ?string $maxHeight = '180px';
- public ?string $filter = 'y';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -36,23 +36,25 @@ protected function getData(): array
{
$gifts = Gift::oldest('received_at')->get();
$start = $gifts->first()?->received_at;
- $period = match($this->filter) {
+ $period = match ($this->filter) {
'y' => Carbon::parse($start)->startOfYear()->yearsUntil(now()->addYear()),
'q' => Carbon::parse($start)->startOfQuarter()->quartersUntil(now()->addQuarter()),
'm' => Carbon::parse($start)->startOfMonth()->monthsUntil(now()->addMonth()),
};
- $labels = iterator_to_array($period->map(fn(Carbon $date) => match($this->filter) {
+ $labels = iterator_to_array($period->map(fn(Carbon $date) => match ($this->filter) {
'y' => $date->format('Y'),
'q' => $date->isoFormat('YYYY [Q]Q'),
'm' => $date->isoFormat('YYYY MMM'),
}));
array_pop($labels);
$period = $period->toArray();
- $amounts = array_fill(0, count($period)-1, 0);
+ $amounts = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($gifts as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->received_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->received_at)) {
$amounts[$i] += $obj->amount;
}
}
@@ -67,7 +69,7 @@ protected function getData(): array
'barPercentage' => 0.75,
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/SumProductiveHoursChart.php b/app/Filament/Widgets/SumProductiveHoursChart.php
index 1469173..e4efb2a 100644
--- a/app/Filament/Widgets/SumProductiveHoursChart.php
+++ b/app/Filament/Widgets/SumProductiveHoursChart.php
@@ -10,11 +10,11 @@
class SumProductiveHoursChart extends ChartWidget
{
- protected ?string $maxHeight = '180px';
public ?string $filter = 'y';
+ protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -33,23 +33,25 @@ protected function getData(): array
{
$positions = Position::oldest('started_at')->get();
$start = $positions->first()?->started_at;
- $period = match($this->filter) {
+ $period = match ($this->filter) {
'y' => Carbon::parse($start)->startOfYear()->yearsUntil(now()->addYear()),
'q' => Carbon::parse($start)->startOfQuarter()->quartersUntil(now()->addQuarter()),
'm' => Carbon::parse($start)->startOfMonth()->monthsUntil(now()->addMonth()),
};
- $labels = iterator_to_array($period->map(fn(Carbon $date) => match($this->filter) {
+ $labels = iterator_to_array($period->map(fn(Carbon $date) => match ($this->filter) {
'y' => $date->format('Y'),
'q' => $date->isoFormat('YYYY [Q]Q'),
'm' => $date->isoFormat('YYYY MMM'),
}));
array_pop($labels);
$period = $period->toArray();
- $hours = array_fill(0, count($period)-1, 0);
+ $hours = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
foreach ($positions as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->started_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->started_at)) {
$hours[$i] += $obj->duration;
}
}
@@ -65,7 +67,7 @@ protected function getData(): array
'borderColor' => '#3b82f6',
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Filament/Widgets/TaxOverview.php b/app/Filament/Widgets/TaxOverview.php
index f37533b..ef88b1d 100644
--- a/app/Filament/Widgets/TaxOverview.php
+++ b/app/Filament/Widgets/TaxOverview.php
@@ -20,10 +20,10 @@
class TaxOverview extends TableWidget implements HasActions
{
use InteractsWithActions;
+ public ?string $filter = 'm';
- protected int | string | array $columnSpan = 12;
+ protected int|string|array $columnSpan = 12;
protected static int $entryCount = 14;
- public ?string $filter = 'm';
public function lastAdvanceVatAction(): Action
{
@@ -61,18 +61,18 @@ public function table(Table $table): Table
->label(__('netTaxable'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->color(fn (string $state): string => !$state ? 'gray' : 'primary')
+ ->color(fn(string $state): string => !$state ? 'gray' : 'primary')
->alignRight()
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
TextColumn::make('netUntaxable')
->label(__('netUntaxable'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->color(fn (string $state): string => !$state ? 'gray' : 'primary')
+ ->color(fn(string $state): string => !$state ? 'gray' : 'primary')
->alignRight()
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
TextColumn::make('totalNet')
->label(__('netTotal'))
->money('eur')
@@ -80,29 +80,29 @@ public function table(Table $table): Table
->color('gray')
->alignRight()
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
TextColumn::make('vatExpenses')
->label(__('vatExpenses'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->color(fn (string $state): string => !$state ? 'gray' : 'danger')
+ ->color(fn(string $state): string => !$state ? 'gray' : 'danger')
->alignRight()
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
TextColumn::make('totalVat')
->label(__('totalVat'))
->money('eur')
->fontFamily(FontFamily::Mono)
- ->color(fn (string $state): string => !$state ? 'gray' : 'normal')
+ ->color(fn(string $state): string => !$state ? 'gray' : 'normal')
->alignRight()
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
]);
}
public function getTableRecords(): Collection
{
- return match($this->filter) {
+ return match ($this->filter) {
'm' => $this->getMonthData(),
'q' => $this->getQuarterData(),
'y' => $this->getYearData(),
@@ -114,7 +114,7 @@ private function getMonthData(): Collection
$records = [];
$dt = Carbon::today();
- for ($i=0; $i < static::$entryCount; $i++) {
+ for ($i = 0; $i < static::$entryCount; $i++) {
[$netTaxable, $netUntaxable, $vatEarned] = Invoice::ofTime($dt, TimeUnit::MONTH);
[, $vatExpended] = Expense::ofTime($dt, TimeUnit::MONTH);
@@ -139,7 +139,7 @@ private function getQuarterData(): Collection
$records = [];
$dt = Carbon::today();
- for ($i=0; $i < static::$entryCount; $i++) {
+ for ($i = 0; $i < static::$entryCount; $i++) {
[$netTaxable, $netUntaxable, $vatEarned] = Invoice::ofTime($dt, TimeUnit::QUARTER);
[, $vatExpended] = Expense::ofTime($dt, TimeUnit::QUARTER);
@@ -164,7 +164,7 @@ private function getYearData(): Collection
$records = [];
$dt = Carbon::today();
- for ($i=0; $i < static::$entryCount; $i++) {
+ for ($i = 0; $i < static::$entryCount; $i++) {
[$netTaxable, $netUntaxable, $vatEarned] = Invoice::ofTime($dt, TimeUnit::YEAR);
[, $vatExpended] = Expense::ofTime($dt, TimeUnit::YEAR);
diff --git a/app/Filament/Widgets/TaxReturnFormInput.php b/app/Filament/Widgets/TaxReturnFormInput.php
index 366f73c..a3dff70 100644
--- a/app/Filament/Widgets/TaxReturnFormInput.php
+++ b/app/Filament/Widgets/TaxReturnFormInput.php
@@ -16,8 +16,8 @@
class TaxReturnFormInput extends TableWidget
{
- protected int | string | array $columnSpan = 12;
public ?int $filter = null;
+ protected int|string|array $columnSpan = 12;
public function __construct()
{
@@ -37,15 +37,15 @@ public function table(Table $table): Table
TextColumn::make('itr')
->label(__('itr'))
->fontFamily(FontFamily::Mono)
- ->formatStateUsing(fn (?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
+ ->formatStateUsing(fn(?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
TextColumn::make('vr')
->label(__('vr'))
->fontFamily(FontFamily::Mono)
- ->formatStateUsing(fn (?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
+ ->formatStateUsing(fn(?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
TextColumn::make('rsc')
->label(__('rsc'))
->fontFamily(FontFamily::Mono)
- ->formatStateUsing(fn (?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
+ ->formatStateUsing(fn(?string $state) => $state ? __('lineN', ['n' => $state]) : ''),
TextColumn::make('help')
->color('gray')
->label(__('helpText')),
@@ -56,7 +56,7 @@ public function table(Table $table): Table
->alignRight()
->color(fn(array $record) => $record['color'] ?? false)
->copyable()
- ->copyableState(fn (string $state): string => Number::format(floatval($state))),
+ ->copyableState(fn(string $state): string => Number::format(floatval($state))),
]);
}
diff --git a/app/Filament/Widgets/WeeklyHoursChart.php b/app/Filament/Widgets/WeeklyHoursChart.php
index 2d07622..c63cddd 100644
--- a/app/Filament/Widgets/WeeklyHoursChart.php
+++ b/app/Filament/Widgets/WeeklyHoursChart.php
@@ -13,7 +13,7 @@ class WeeklyHoursChart extends ChartWidget
protected ?string $maxHeight = '180px';
protected ?string $pollingInterval = null;
- protected int | string | array $columnSpan = [
+ protected int|string|array $columnSpan = [
'sm' => 12,
'xl' => 4,
];
@@ -35,20 +35,22 @@ protected function getData(): array
$labels = iterator_to_array($period->map(fn(Carbon $date) => $date->format('Y')));
array_pop($labels);
$period = $period->toArray();
- $countWeeks = array_fill(0, count($period)-1, 0);
- $avgWeeklyHours = array_fill(0, count($period)-1, 0);
+ $countWeeks = array_fill(0, count($period) - 1, 0);
+ $avgWeeklyHours = array_fill(0, count($period) - 1, 0);
foreach ($period as $i => $date) {
- if ($i == count($period)-1) break;
+ if ($i == count($period) - 1) {
+ break;
+ }
$weeks = [];
$hours = 0;
foreach ($positions as $obj) {
- if (CarbonPeriod::create($date, $period[$i+1])->contains($obj->started_at)) {
+ if (CarbonPeriod::create($date, $period[$i + 1])->contains($obj->started_at)) {
$weeks[Carbon::parse($obj->started_at)->isoWeek()] = 1;
$hours += $obj->duration;
}
}
$countWeeks[$i] = count($weeks);
- $avgWeeklyHours[$i] = count($weeks) != 0 ? round($hours/count($weeks)) : 0;
+ $avgWeeklyHours[$i] = count($weeks) != 0 ? round($hours / count($weeks)) : 0;
}
return [
@@ -70,7 +72,7 @@ protected function getData(): array
'yAxisID' => 'y2',
],
],
- 'labels' => $labels
+ 'labels' => $labels,
];
}
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index 77ec359..f1406be 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -8,5 +8,6 @@
class Controller extends BaseController
{
- use AuthorizesRequests, ValidatesRequests;
+ use AuthorizesRequests;
+ use ValidatesRequests;
}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 8be3302..13e9456 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -63,7 +63,7 @@ class Kernel extends HttpKernel
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
- ThrottleRequests::class.':api',
+ ThrottleRequests::class . ':api',
SubstituteBindings::class,
],
];
diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php
index 3391630..e53eb4d 100644
--- a/app/Http/Middleware/TrustProxies.php
+++ b/app/Http/Middleware/TrustProxies.php
@@ -19,10 +19,10 @@ class TrustProxies extends Middleware
*
* @var int
*/
- protected $headers =
- Request::HEADER_X_FORWARDED_FOR |
- Request::HEADER_X_FORWARDED_HOST |
- Request::HEADER_X_FORWARDED_PORT |
- Request::HEADER_X_FORWARDED_PROTO |
- Request::HEADER_X_FORWARDED_AWS_ELB;
+ protected $headers
+ = Request::HEADER_X_FORWARDED_FOR
+ | Request::HEADER_X_FORWARDED_HOST
+ | Request::HEADER_X_FORWARDED_PORT
+ | Request::HEADER_X_FORWARDED_PROTO
+ | Request::HEADER_X_FORWARDED_AWS_ELB;
}
diff --git a/app/Livewire/HeadingWidget.php b/app/Livewire/HeadingWidget.php
index 30dbfd5..554e053 100644
--- a/app/Livewire/HeadingWidget.php
+++ b/app/Livewire/HeadingWidget.php
@@ -10,7 +10,7 @@ class HeadingWidget extends Widget
protected string $view = 'livewire.heading-widget';
- protected int | string | array $columnSpan = 12;
+ protected int|string|array $columnSpan = 12;
protected function getViewData(): array
{
diff --git a/app/Mail/ContactClient.php b/app/Mail/ContactClient.php
index 5d50c4d..f3e6d2b 100644
--- a/app/Mail/ContactClient.php
+++ b/app/Mail/ContactClient.php
@@ -11,7 +11,8 @@
class ContactClient extends Mailable
{
- use Queueable, SerializesModels;
+ use Queueable;
+ use SerializesModels;
/**
* Create a new message instance.
diff --git a/app/Models/Client.php b/app/Models/Client.php
index 3da0664..27da24a 100644
--- a/app/Models/Client.php
+++ b/app/Models/Client.php
@@ -29,6 +29,22 @@ class Client extends Model
'vat_id',
];
+ /**
+ * The projects this client ordered.
+ */
+ public function projects(): HasMany
+ {
+ return $this->hasMany(Project::class);
+ }
+
+ /**
+ * The projects this client ordered.
+ */
+ public function invoices(): HasManyThrough
+ {
+ return $this->hasManyThrough(Invoice::class, Project::class);
+ }
+
protected function casts(): array
{
return [
@@ -49,22 +65,6 @@ protected function casts(): array
];
}
- /**
- * The projects this client ordered.
- */
- public function projects(): HasMany
- {
- return $this->hasMany(Project::class);
- }
-
- /**
- * The projects this client ordered.
- */
- public function invoices(): HasManyThrough
- {
- return $this->hasManyThrough(Invoice::class, Project::class);
- }
-
/**
* All address information of this client as one string
*/
@@ -117,6 +117,6 @@ protected function avgPaymentDelay(): Attribute
}
}
}
- return Attribute::make(fn(): float => count($days) ? array_sum($days)/count($days) : 0.0);
+ return Attribute::make(fn(): float => count($days) ? array_sum($days) / count($days) : 0.0);
}
}
diff --git a/app/Models/Estimate.php b/app/Models/Estimate.php
index 0fcf085..3c41735 100644
--- a/app/Models/Estimate.php
+++ b/app/Models/Estimate.php
@@ -17,6 +17,14 @@ class Estimate extends Model
'weight',
];
+ /**
+ * Get the client that ordered the project.
+ */
+ public function project(): BelongsTo
+ {
+ return $this->belongsTo(Project::class);
+ }
+
protected function casts(): array
{
return [
@@ -28,12 +36,4 @@ protected function casts(): array
'updated_at' => 'datetime',
];
}
-
- /**
- * Get the client that ordered the project.
- */
- public function project(): BelongsTo
- {
- return $this->belongsTo(Project::class);
- }
}
diff --git a/app/Models/Expense.php b/app/Models/Expense.php
index 4406835..7141304 100644
--- a/app/Models/Expense.php
+++ b/app/Models/Expense.php
@@ -23,6 +23,53 @@ class Expense extends Model
'description',
];
+ public static function lastAdvanceVatExists(): bool
+ {
+ $format = 'UStVA ' . now()->year . '-' . now()->subMonth()->isoFormat('MM');
+ return self::where('description', $format)->first() !== null;
+ }
+
+ public static function saveLastAdvanceVat(): bool
+ {
+ [,, $vatIn] = Invoice::ofTime(now()->subMonth(), TimeUnit::MONTH);
+ [, $vatOut] = self::ofTime(now()->subMonth(), TimeUnit::MONTH);
+ $obj = new self([
+ 'expended_at' => now(),
+ 'category' => ExpenseCategory::Vat,
+ 'price' => $vatIn - $vatOut,
+ 'quantity' => 1,
+ 'taxable' => false,
+ 'vat_rate' => 0,
+ 'description' => 'UStVA ' . now()->year . '-' . now()->subMonth()->isoFormat('MM'),
+ ]);
+ return $obj->save();
+ }
+
+ /**
+ * Sum of net and vat amounts of given time range
+ */
+ public static function ofTime(Carbon $d, TimeUnit $u, ?ExpenseCategory $category = null): array
+ {
+ $start = match ($u) {
+ TimeUnit::MONTH => $d->startOfMonth()->toDateString(),
+ TimeUnit::QUARTER => $d->startOfQuarter()->toDateString(),
+ TimeUnit::YEAR => $d->startOfYear()->toDateString(),
+ };
+ $end = match ($u) {
+ TimeUnit::MONTH => $d->endOfMonth()->toDateString(),
+ TimeUnit::QUARTER => $d->endOfQuarter()->toDateString(),
+ TimeUnit::YEAR => $d->endOfYear()->toDateString(),
+ };
+ $categories = $category ? [$category] : ExpenseCategory::deliverableCategories();
+ $records = self::where('expended_at', '>=', $start)
+ ->where('expended_at', '<=', $end)
+ ->whereIn('category', $categories)
+ ->get();
+ $net = array_sum($records->map(fn(self $r) => $r->net)->toArray());
+ $vat = array_sum($records->map(fn(self $r) => $r->vat)->toArray());
+ return [$net, $vat];
+ }
+
protected function casts(): array
{
return [
@@ -70,51 +117,4 @@ protected function vat(): Attribute
{
return Attribute::make(fn(): float => round($this->gross - $this->net, 2));
}
-
- public static function lastAdvanceVatExists(): bool
- {
- $format = 'UStVA ' . now()->year . '-' . now()->subMonth()->isoFormat('MM');
- return self::where('description', $format)->first() !== null;
- }
-
- public static function saveLastAdvanceVat(): bool
- {
- [,, $vatIn] = Invoice::ofTime(now()->subMonth(), TimeUnit::MONTH);
- [, $vatOut] = self::ofTime(now()->subMonth(), TimeUnit::MONTH);
- $obj = new self([
- 'expended_at' => now(),
- 'category' => ExpenseCategory::Vat,
- 'price' => $vatIn - $vatOut,
- 'quantity' => 1,
- 'taxable' => false,
- 'vat_rate' => 0,
- 'description' => 'UStVA ' . now()->year . '-' . now()->subMonth()->isoFormat('MM'),
- ]);
- return $obj->save();
- }
-
- /**
- * Sum of net and vat amounts of given time range
- */
- public static function ofTime(Carbon $d, TimeUnit $u, ?ExpenseCategory $category = null): array
- {
- $start = match ($u) {
- TimeUnit::MONTH => $d->startOfMonth()->toDateString(),
- TimeUnit::QUARTER => $d->startOfQuarter()->toDateString(),
- TimeUnit::YEAR => $d->startOfYear()->toDateString(),
- };
- $end = match ($u) {
- TimeUnit::MONTH => $d->endOfMonth()->toDateString(),
- TimeUnit::QUARTER => $d->endOfQuarter()->toDateString(),
- TimeUnit::YEAR => $d->endOfYear()->toDateString(),
- };
- $categories = $category ? [$category] : ExpenseCategory::deliverableCategories();
- $records = self::where('expended_at', '>=', $start)
- ->where('expended_at', '<=', $end)
- ->whereIn('category', $categories)
- ->get();
- $net = array_sum($records->map(fn (self $r) => $r->net)->toArray());
- $vat = array_sum($records->map(fn (self $r) => $r->vat)->toArray());
- return [$net, $vat];
- }
}
diff --git a/app/Models/Gift.php b/app/Models/Gift.php
index 9b3f69e..1e0a0c6 100644
--- a/app/Models/Gift.php
+++ b/app/Models/Gift.php
@@ -18,19 +18,6 @@ class Gift extends Model
'email',
];
- protected function casts(): array
- {
- return [
- 'received_at' => 'date',
- 'amount' => 'float',
- 'subject' => 'string',
- 'name' => 'string',
- 'email' => 'string',
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
- }
-
/**
* Calculate array holding all years having gifts
* sorted from current to past
@@ -43,9 +30,22 @@ public static function getYearList(): array
$period = Carbon::parse($firstDate)->startOfYear()->yearsUntil(now());
$years = array_reverse(
iterator_to_array(
- $period->map(fn(Carbon $date) => $date->format('Y'))
- )
+ $period->map(fn(Carbon $date) => $date->format('Y')),
+ ),
);
return array_combine($years, $years);
}
+
+ protected function casts(): array
+ {
+ return [
+ 'received_at' => 'date',
+ 'amount' => 'float',
+ 'subject' => 'string',
+ 'name' => 'string',
+ 'email' => 'string',
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+ }
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index c5a6861..e94f65f 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -14,7 +14,6 @@
use Illuminate\Support\Number;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Casts\Attribute;
-use Illuminate\Support\Collection;
class Invoice extends Model
{
@@ -35,6 +34,65 @@ class Invoice extends Model
'deduction',
];
+ /**
+ * Get the project this invoice is assigned to.
+ */
+ public function project(): BelongsTo
+ {
+ return $this->belongsTo(Project::class);
+ }
+
+ /**
+ * The positions of this invoice.
+ */
+ public function positions(): HasMany
+ {
+ return $this->hasMany(Position::class);
+ }
+
+ /**
+ * Calculate array holding all years having paid invoices
+ * sorted from current to past
+ *
+ * @return array
+ */
+ public static function getYearList(): array
+ {
+ $firstDate = self::whereNotNull('paid_at')
+ ->where('transitory', 0)
+ ->oldest('paid_at')
+ ->first()?->paid_at;
+ $period = Carbon::parse($firstDate)->startOfYear()->yearsUntil(now());
+ $years = array_reverse(
+ iterator_to_array(
+ $period->map(fn(Carbon $date) => $date->format('Y')),
+ ),
+ );
+ return array_combine($years, $years);
+ }
+
+ /**
+ * Sum of net and vat amounts of given time range
+ */
+ public static function ofTime(Carbon $d, TimeUnit $u): array
+ {
+ $start = match ($u) {
+ TimeUnit::MONTH => $d->startOfMonth()->toDateString(),
+ TimeUnit::QUARTER => $d->startOfQuarter()->toDateString(),
+ TimeUnit::YEAR => $d->startOfYear()->toDateString(),
+ };
+ $end = match ($u) {
+ TimeUnit::MONTH => $d->endOfMonth()->toDateString(),
+ TimeUnit::QUARTER => $d->endOfQuarter()->toDateString(),
+ TimeUnit::YEAR => $d->endOfYear()->toDateString(),
+ };
+ $records = self::where('paid_at', '>=', $start)->where('paid_at', '<=', $end)->get();
+ $netTaxable = $records->filter(fn(self $r) => $r->taxable)->map(fn(self $r) => $r->net)->sum();
+ $netUntaxable = $records->filter(fn(self $r) => !$r->taxable)->map(fn(self $r) => $r->net)->sum();
+ $vat = $records->map(fn(self $r) => $r->vat)->sum();
+ return [$netTaxable, $netUntaxable, $vat];
+ }
+
protected function casts(): array
{
return [
@@ -55,22 +113,6 @@ protected function casts(): array
];
}
- /**
- * Get the project this invoice is assigned to.
- */
- public function project(): BelongsTo
- {
- return $this->belongsTo(Project::class);
- }
-
- /**
- * The positions of this invoice.
- */
- public function positions(): HasMany
- {
- return $this->hasMany(Position::class);
- }
-
/**
* Scope a query to only include active invoices.
*/
@@ -105,7 +147,7 @@ protected function sortedPositions(): Attribute
{
// If undated, sort by positions creation date, if dated, sort by positions starting date
return Attribute::make(
- get: fn(): array => $this->positions->sortBy($this->undated ? 'created_at' : 'started_at')->all()
+ get: fn(): array => $this->positions->sortBy($this->undated ? 'created_at' : 'started_at')->all(),
);
}
@@ -121,8 +163,8 @@ protected function paginatedPositions(): Attribute
// Take the description lines and the position title (2 lines) into account
$lineCount = count(explode("\n", trim($p->description))) + 2;
$linesProcessed += $lineCount;
- $i = intval(floor($linesProcessed/50));
- if (key_exists($i,$paginated)) {
+ $i = intval(floor($linesProcessed / 50));
+ if (key_exists($i, $paginated)) {
$paginated[$i][] = $p;
} else {
$paginated[$i] = [$p];
@@ -137,7 +179,7 @@ protected function paginatedPositions(): Attribute
protected function positionsFormatted(): Attribute
{
return Attribute::make(
- fn(): string => count($this->positions) . ' ' . trans_choice('position', count($this->positions))
+ fn(): string => count($this->positions) . ' ' . trans_choice('position', count($this->positions)),
);
}
@@ -256,47 +298,4 @@ protected function status(): Attribute
default => InvoiceStatus::INVALID,
});
}
-
- /**
- * Calculate array holding all years having paid invoices
- * sorted from current to past
- *
- * @return array
- */
- public static function getYearList(): array
- {
- $firstDate = self::whereNotNull('paid_at')
- ->where('transitory', 0)
- ->oldest('paid_at')
- ->first()?->paid_at;
- $period = Carbon::parse($firstDate)->startOfYear()->yearsUntil(now());
- $years = array_reverse(
- iterator_to_array(
- $period->map(fn(Carbon $date) => $date->format('Y'))
- )
- );
- return array_combine($years, $years);
- }
-
- /**
- * Sum of net and vat amounts of given time range
- */
- public static function ofTime(Carbon $d, TimeUnit $u): array
- {
- $start = match ($u) {
- TimeUnit::MONTH => $d->startOfMonth()->toDateString(),
- TimeUnit::QUARTER => $d->startOfQuarter()->toDateString(),
- TimeUnit::YEAR => $d->startOfYear()->toDateString(),
- };
- $end = match ($u) {
- TimeUnit::MONTH => $d->endOfMonth()->toDateString(),
- TimeUnit::QUARTER => $d->endOfQuarter()->toDateString(),
- TimeUnit::YEAR => $d->endOfYear()->toDateString(),
- };
- $records = self::where('paid_at', '>=', $start)->where('paid_at', '<=', $end)->get();
- $netTaxable = $records->filter(fn (self $r) => $r->taxable)->map(fn (self $r) => $r->net)->sum();
- $netUntaxable = $records->filter(fn (self $r) => !$r->taxable)->map(fn (self $r) => $r->net)->sum();
- $vat = $records->map(fn (self $r) => $r->vat)->sum();
- return [$netTaxable, $netUntaxable, $vat];
- }
}
diff --git a/app/Models/Offtime.php b/app/Models/Offtime.php
index af84434..cdb7a45 100644
--- a/app/Models/Offtime.php
+++ b/app/Models/Offtime.php
@@ -21,32 +21,6 @@ class Offtime extends Model
'description',
];
- protected function casts(): array
- {
- return [
- 'start' => 'date',
- 'end' => 'date',
- 'category' => OfftimeCategory::class,
- 'description' => 'string',
- ];
- }
-
- /**
- * Year the time off is assigned to
- */
- protected function year(): Attribute
- {
- return Attribute::make(fn(): int => intval($this->start->format('Y')));
- }
-
- /**
- * Number of days this off time consists of
- */
- protected function daysCount(): Attribute
- {
- return Attribute::make(fn(): int => $this->end ? intval($this->start->diffInDays($this->end)) + 1 : 1);
- }
-
/**
* Get a time off on a given date or null if none exists
*/
@@ -106,5 +80,31 @@ public static function daysCountByYear(int $year): array
return [$weekends, $cat['planned'], $cat['unplanned'], $total->count()];
}
+ protected function casts(): array
+ {
+ return [
+ 'start' => 'date',
+ 'end' => 'date',
+ 'category' => OfftimeCategory::class,
+ 'description' => 'string',
+ ];
+ }
+
+ /**
+ * Year the time off is assigned to
+ */
+ protected function year(): Attribute
+ {
+ return Attribute::make(fn(): int => intval($this->start->format('Y')));
+ }
+
+ /**
+ * Number of days this off time consists of
+ */
+ protected function daysCount(): Attribute
+ {
+ return Attribute::make(fn(): int => $this->end ? intval($this->start->diffInDays($this->end)) + 1 : 1);
+ }
+
}
diff --git a/app/Models/Position.php b/app/Models/Position.php
index 9b7add8..0a5d0c4 100644
--- a/app/Models/Position.php
+++ b/app/Models/Position.php
@@ -21,6 +21,14 @@ class Position extends Model
'remote',
];
+ /**
+ * Get the invoice this position was made for.
+ */
+ public function invoice(): BelongsTo
+ {
+ return $this->belongsTo(Invoice::class);
+ }
+
protected function casts(): array
{
return [
@@ -34,14 +42,6 @@ protected function casts(): array
];
}
- /**
- * Get the invoice this position was made for.
- */
- public function invoice(): BelongsTo
- {
- return $this->belongsTo(Invoice::class);
- }
-
/**
* Total duration of the position in hours
*/
@@ -49,7 +49,7 @@ protected function duration(): Attribute
{
return Attribute::make(
fn(): float => Carbon::parse($this->started_at)
- ->diffInMinutes(Carbon::parse($this->finished_at))/60 - $this->pause_duration
+ ->diffInMinutes(Carbon::parse($this->finished_at)) / 60 - $this->pause_duration,
);
}
@@ -64,7 +64,7 @@ protected function net(): Attribute
$net = 0;
if ($this->invoice->pricing_unit === PricingUnit::Project) {
- $net = $this->invoice->hours/$this->invoice->net * $this->duration;
+ $net = $this->invoice->hours / $this->invoice->net * $this->duration;
} else {
$net += $this->duration * $this->invoice->price / $this->invoice->pricing_hours;
}
@@ -78,7 +78,7 @@ protected function timeRange(): Attribute
{
return Attribute::make(
fn(): string => Carbon::parse($this->started_at)->isoFormat('lll')
- . Carbon::parse($this->finished_at)->format(' - H.i')
+ . Carbon::parse($this->finished_at)->format(' - H.i'),
);
}
}
diff --git a/app/Models/Project.php b/app/Models/Project.php
index 3d5edf5..1764f8c 100644
--- a/app/Models/Project.php
+++ b/app/Models/Project.php
@@ -3,7 +3,6 @@
namespace App\Models;
use App\Enums\PricingUnit;
-use App\Models\Setting;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
@@ -30,23 +29,6 @@ class Project extends Model
'aborted',
];
- protected function casts(): array
- {
- return [
- 'title' => 'string',
- 'description' => 'string',
- 'start_at' => 'date',
- 'due_at' => 'date',
- 'minimum' => 'float',
- 'scope' => 'float',
- 'price' => 'float',
- 'pricing_unit' => PricingUnit::class,
- 'aborted' => 'bool',
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
- }
-
/**
* Get the client that ordered the project.
*/
@@ -71,6 +53,23 @@ public function invoices(): HasMany
return $this->hasMany(Invoice::class);
}
+ protected function casts(): array
+ {
+ return [
+ 'title' => 'string',
+ 'description' => 'string',
+ 'start_at' => 'date',
+ 'due_at' => 'date',
+ 'minimum' => 'float',
+ 'scope' => 'float',
+ 'price' => 'float',
+ 'pricing_unit' => PricingUnit::class,
+ 'aborted' => 'bool',
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+ }
+
/**
* Scope a query to only include active projects.
*/
@@ -128,8 +127,8 @@ protected function paginatedEstimates(): Attribute
// Take the description lines and the position title (2 lines) into account
$lineCount = count(explode("\n", trim($e->description))) + 2;
$linesProcessed += $lineCount;
- $i = intval(floor($linesProcessed/50));
- if (key_exists($i,$paginated)) {
+ $i = intval(floor($linesProcessed / 50));
+ if (key_exists($i, $paginated)) {
$paginated[$i][] = $e;
} else {
$paginated[$i] = [$e];
@@ -177,8 +176,8 @@ protected function scopeRange(): Attribute
{
return Attribute::make(
fn(): string => $this->minimum != $this->scope
- ? (int)$this->minimum . ' - ' . (int)$this->scope . ' ' . trans_choice('hour', 2)
- : (int)$this->scope . ' ' . trans_choice('hour', (int)$this->scope)
+ ? (int) $this->minimum . ' - ' . (int) $this->scope . ' ' . trans_choice('hour', 2)
+ : (int) $this->scope . ' ' . trans_choice('hour', (int) $this->scope),
);
}
@@ -187,7 +186,7 @@ protected function scopeRange(): Attribute
*/
protected function pricePerUnit(): Attribute
{
- return Attribute::make(fn(): string => $this->price . ' € / ' . match($this->pricing_unit) {
+ return Attribute::make(fn(): string => $this->price . ' € / ' . match ($this->pricing_unit) {
PricingUnit::Hour => trans_choice('hour', 1),
PricingUnit::Day => trans_choice('day', 1),
PricingUnit::Project => trans_choice('project', 1),
@@ -201,8 +200,8 @@ protected function progress(): Attribute
{
return Attribute::make(
fn(): float => $this->scope > 0
- ? round($this->hours/$this->scope*100, 1)
- : 0.0
+ ? round($this->hours / $this->scope * 100, 1)
+ : 0.0,
);
}
@@ -214,7 +213,7 @@ protected function progressPercent(): Attribute
return Attribute::make(
fn(): string => $this->scope > 0
? strval($this->progress) . ' %'
- : __('n/a')
+ : __('n/a'),
);
}
diff --git a/app/Models/Setting.php b/app/Models/Setting.php
index 1b96beb..762a7a7 100644
--- a/app/Models/Setting.php
+++ b/app/Models/Setting.php
@@ -7,9 +7,8 @@
class Setting extends Model
{
- protected $primaryKey = 'field';
-
public $incrementing = false;
+ protected $primaryKey = 'field';
protected $fillable = [
'field',
@@ -19,6 +18,23 @@ class Setting extends Model
'weight',
];
+ public static function get(string $field)
+ {
+ return self::find($field)?->value;
+ }
+
+ /**
+ * Address field
+ */
+ public static function address()
+ {
+ $name = self::get('name');
+ $street = self::get('street');
+ $zip = self::get('zip');
+ $city = self::get('city');
+ return "$name, $street, $zip $city";
+ }
+
protected function casts(): array
{
return [
@@ -32,10 +48,6 @@ protected function casts(): array
];
}
- public static function get(string $field) {
- return self::find($field)?->value;
- }
-
/**
* Translated setting label
*/
@@ -43,16 +55,4 @@ protected function label(): Attribute
{
return Attribute::make(fn(): string => __($this->field));
}
-
- /**
- * Address field
- */
- public static function address()
- {
- $name = self::get('name');
- $street = self::get('street');
- $zip = self::get('zip');
- $city = self::get('city');
- return "$name, $street, $zip $city";
- }
}
diff --git a/app/Models/User.php b/app/Models/User.php
index 7e1b842..5764488 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -12,7 +12,9 @@
class User extends Authenticatable implements FilamentUser, HasAvatar
{
- use HasApiTokens, HasFactory, Notifiable;
+ use HasApiTokens;
+ use HasFactory;
+ use Notifiable;
/**
* The attributes that are mass assignable.
@@ -31,21 +33,6 @@ class User extends Authenticatable implements FilamentUser, HasAvatar
'remember_token',
];
- /**
- * The attributes that should be cast.
- */
- protected function casts(): array
- {
- return [
- 'name' => 'string',
- 'email' => 'string',
- 'email_verified_at' => 'datetime',
- 'password' => 'hashed',
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
- }
-
public function canAccessPanel(Panel $panel): bool
{
// TODO: limit to defined domains
@@ -63,4 +50,19 @@ public function getFilamentAvatarUrl(): ?string
HTML;
}
+
+ /**
+ * The attributes that should be cast.
+ */
+ protected function casts(): array
+ {
+ return [
+ 'name' => 'string',
+ 'email' => 'string',
+ 'email_verified_at' => 'datetime',
+ 'password' => 'hashed',
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+ }
}
diff --git a/app/Services/InvoiceService.php b/app/Services/InvoiceService.php
index f1c63a8..912d6b9 100644
--- a/app/Services/InvoiceService.php
+++ b/app/Services/InvoiceService.php
@@ -24,7 +24,8 @@ class InvoiceService
* @param Invoice $invoice Record to export
* @return string
*/
- public static function generatePdf(Invoice $invoice): string {
+ public static function generatePdf(Invoice $invoice): string
+ {
$conf = Setting::pluck('value', 'field');
$client = $invoice?->project?->client;
$lang = $client?->language->value ?? 'de';
@@ -46,7 +47,7 @@ public static function generatePdf(Invoice $invoice): string {
'title' => $invoice->title,
'vat' => Number::currency($invoice->vat, 'EUR', locale: $lang),
'vatRate' => $invoice->taxable
- ? Number::percentage($invoice->vat_rate*100, 2, locale: $lang) . ' ' . __("vat", locale: $lang)
+ ? Number::percentage($invoice->vat_rate * 100, 2, locale: $lang) . ' ' . __("vat", locale: $lang)
: __('vatNotChargeable', locale: $lang),
]);
@@ -84,9 +85,9 @@ public static function generatePdf(Invoice $invoice): string {
]);
// Convert to supported char encoding
- $conf = $conf->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
- $data = $data->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
- $label = $label->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
+ $conf = $conf->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
+ $data = $data->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
+ $label = $label->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
// Init document
$pdf = new PdfTemplate($lang);
@@ -221,7 +222,8 @@ public static function generatePdf(Invoice $invoice): string {
$rowHeight = 3.5;
$totalHeight = array_reduce(
$positions,
- fn ($a, $c) => $a + count(explode("\n", $c->description)) + 2, 0
+ fn($a, $c) => $a + count(explode("\n", $c->description)) + 2,
+ 0,
) * $rowHeight + 32;
$pdf->addPage();
@@ -278,7 +280,7 @@ public static function generatePdf(Invoice $invoice): string {
]);
// Convert to supported char encoding
- $posdata = $posdata->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
+ $posdata = $posdata->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
$pdf->setTextColor(Color::DARK->pdfColor())
->setFont('FiraSans-Regular')
@@ -316,7 +318,8 @@ public static function generatePdf(Invoice $invoice): string {
* @param Invoice $invoice Record to export
* @return string
*/
- public static function generateEn16931Xml(Invoice $invoice): string {
+ public static function generateEn16931Xml(Invoice $invoice): string
+ {
$settings = Setting::pluck('value', 'field');
$client = $invoice?->project?->client;
$lang = $client?->language->value ?? 'de';
@@ -330,175 +333,175 @@ public static function generateEn16931Xml(Invoice $invoice): string {
$x->setIndent(true);
$x->setIndentString(' ');
$x->startDocument('1.0', 'UTF-8');
- $x->startElement('Invoice');
- $x->writeAttribute('xmlns:cac', 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2');
- $x->writeAttribute('xmlns:cbc', 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2');
- $x->writeAttribute('xmlns:qdt', 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2');
- $x->writeAttribute('xmlns:udt', 'urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2');
- $x->writeAttribute('xmlns:ccts', 'urn:un:unece:uncefact:documentation:2');
- $x->writeAttribute('xmlns', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2');
- $x->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
- $x->writeAttribute('xsi:schemaLocation', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd');
- // Meta
- $x->writeElement('cbc:CustomizationID', 'urn:cen.eu:en16931:2017');
- $x->writeElement('cbc:ID', $invoice->current_number);
- $x->writeElement('cbc:IssueDate', Carbon::now()->format('Y-m-d'));
- $x->writeElement('cbc:DueDate', Carbon::now()->addWeeks(2)->format('Y-m-d'));
- // 380 Rechnung
- // 381 Gutschrift
- // 384 Rechnungskorrektur
- $x->writeElement('cbc:InvoiceTypeCode', 380);
- $x->writeElement('cbc:DocumentCurrencyCode', $currency);
- // Contractor (me)
- $x->startElement('cac:AccountingSupplierParty');
- $x->startElement('cac:Party');
- $x->startElement('cac:PostalAddress');
- $x->writeElement('cbc:StreetName', $settings['street']);
- $x->writeElement('cbc:CityName', $settings['city']);
- $x->writeElement('cbc:PostalZone', $settings['zip']);
- $x->startElement('cac:Country');
- $x->writeElement('cbc:IdentificationCode', 'DE'); // TODO: $settings['country']
- $x->endElement();
- $x->endElement();
- $x->startElement('cac:PartyTaxScheme');
- $x->writeElement('cbc:CompanyID', $settings['vatId']);
- $x->startElement('cac:TaxScheme');
- $x->writeElement('cbc:ID', 'VAT');
- $x->endElement();
- $x->endElement();
- $x->startElement('cac:PartyLegalEntity');
- $x->writeElement('cbc:RegistrationName', $settings['name']);
- $x->writeElement('cbc:CompanyID', $settings['vatId']);
- $x->endElement();
- $x->startElement('cac:Contact');
- $x->writeElement('cbc:ElectronicMail', $settings['email']);
- $x->endElement();
- $x->endElement();
- $x->endElement();
- // Client
- $x->startElement('cac:AccountingCustomerParty');
- $x->startElement('cac:Party');
- $x->startElement('cac:PostalAddress');
- $x->writeElement('cbc:StreetName', $client?->street);
- $x->writeElement('cbc:CityName', $client?->city);
- $x->writeElement('cbc:PostalZone', $client?->zip);
- $x->startElement('cac:Country');
- $x->writeElement('cbc:IdentificationCode', $client?->country);
- $x->endElement();
- $x->endElement();
- $x->startElement('cac:PartyTaxScheme');
- if ($client?->vat_id) {
- $x->writeElement('cbc:CompanyID', $client->vat_id);
- }
- $x->startElement('cac:TaxScheme');
- $x->writeElement('cbc:ID', 'VAT');
- $x->endElement();
- $x->endElement();
- $x->startElement('cac:PartyLegalEntity');
- $x->writeElement('cbc:RegistrationName', $client?->name);
- if ($client?->vat_id) {
- $x->writeElement('cbc:CompanyID', $client->vat_id);
- }
- $x->endElement();
- $x->endElement();
- $x->endElement();
- // Payment
- $x->startElement('cac:PaymentMeans');
- // 58 SEPA credit transfer
- // 59 SEPA direct debit
- // 57 Standing agreement
- // 30 Credit transfer (non-SEPA)
- // 49 Direct debit (non-SEPA)
- // 48 Bank card
- $x->writeElement('cbc:PaymentMeansCode', 30);
- $x->writeElement('cbc:PaymentID', $invoice->current_number);
- $x->startElement('cac:PayeeFinancialAccount');
- $x->writeElement('cbc:ID', $settings['iban']);
- $x->endElement();
- $x->endElement();
- // Tax
- $x->startElement('cac:TaxTotal');
- $x->startElement('cbc:TaxAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->vat);
- $x->endElement();
- $x->startElement('cac:TaxSubtotal');
- $x->startElement('cbc:TaxableAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->net);
- $x->endElement();
- $x->startElement('cbc:TaxAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->vat);
- $x->endElement();
- $x->startElement('cac:TaxCategory');
- // See https://developer.vertexinc.com/einvoicing/docs/en-16931-tax-categories
- $x->writeElement('cbc:ID', $invoice->taxable ? 'S' : 'G');
- $x->writeElement('cbc:Percent', $invoice->taxable ? $invoice->vat_rate*100 : 0);
- if (!$invoice->taxable) {
- $x->writeElement('cbc:TaxExemptionReasonCode', 'VATEX-EU-G');
- }
- $x->startElement('cac:TaxScheme');
- $x->writeElement('cbc:ID', 'VAT');
- $x->endElement();
- $x->endElement();
- $x->endElement();
- $x->endElement();
- // Finances
- $x->startElement('cac:LegalMonetaryTotal');
- $x->startElement('cbc:LineExtensionAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->net);
- $x->endElement();
- $x->startElement('cbc:TaxExclusiveAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->net);
- $x->endElement();
- $x->startElement('cbc:TaxInclusiveAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->gross);
- $x->endElement();
- $x->startElement('cbc:ChargeTotalAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text(0);
- $x->endElement();
- $x->startElement('cbc:PayableAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->gross);
- $x->endElement();
- $x->endElement();
- // Positions
- foreach($invoice->positions as $key => $position){
- $x->startElement('cac:InvoiceLine');
- $x->writeElement('cbc:ID', $key+1);
- $x->startElement('cbc:InvoicedQuantity');
- $x->writeAttribute('unitCode', 'EA');
- $x->text($position->duration);
- $x->endElement();
- $x->startElement('cbc:LineExtensionAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($position->net);
- $x->endElement();
- $x->startElement('cac:Item');
- $x->writeElement('cbc:Description', $position->description);
- $x->writeElement('cbc:Name', trans_choice('position', 1, locale: $lang));
- $x->startElement('cac:ClassifiedTaxCategory');
- $x->writeElement('cbc:ID', $invoice->taxable ? 'S' : 'G');
- $x->writeElement('cbc:Percent', $invoice->taxable ? $invoice->vat_rate*100 : 0);
- $x->startElement('cac:TaxScheme');
- $x->writeElement('cbc:ID', 'VAT');
- $x->endElement();
- $x->endElement();
- $x->endElement();
- $x->startElement('cac:Price');
- $x->startElement('cbc:PriceAmount');
- $x->writeAttribute('currencyID', $currency);
- $x->text($invoice->price);
- $x->endElement();
- $x->endElement();
- $x->endElement();
- }
+ $x->startElement('Invoice');
+ $x->writeAttribute('xmlns:cac', 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2');
+ $x->writeAttribute('xmlns:cbc', 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2');
+ $x->writeAttribute('xmlns:qdt', 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2');
+ $x->writeAttribute('xmlns:udt', 'urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2');
+ $x->writeAttribute('xmlns:ccts', 'urn:un:unece:uncefact:documentation:2');
+ $x->writeAttribute('xmlns', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2');
+ $x->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+ $x->writeAttribute('xsi:schemaLocation', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd');
+ // Meta
+ $x->writeElement('cbc:CustomizationID', 'urn:cen.eu:en16931:2017');
+ $x->writeElement('cbc:ID', $invoice->current_number);
+ $x->writeElement('cbc:IssueDate', Carbon::now()->format('Y-m-d'));
+ $x->writeElement('cbc:DueDate', Carbon::now()->addWeeks(2)->format('Y-m-d'));
+ // 380 Rechnung
+ // 381 Gutschrift
+ // 384 Rechnungskorrektur
+ $x->writeElement('cbc:InvoiceTypeCode', 380);
+ $x->writeElement('cbc:DocumentCurrencyCode', $currency);
+ // Contractor (me)
+ $x->startElement('cac:AccountingSupplierParty');
+ $x->startElement('cac:Party');
+ $x->startElement('cac:PostalAddress');
+ $x->writeElement('cbc:StreetName', $settings['street']);
+ $x->writeElement('cbc:CityName', $settings['city']);
+ $x->writeElement('cbc:PostalZone', $settings['zip']);
+ $x->startElement('cac:Country');
+ $x->writeElement('cbc:IdentificationCode', 'DE'); // TODO: $settings['country']
+ $x->endElement();
+ $x->endElement();
+ $x->startElement('cac:PartyTaxScheme');
+ $x->writeElement('cbc:CompanyID', $settings['vatId']);
+ $x->startElement('cac:TaxScheme');
+ $x->writeElement('cbc:ID', 'VAT');
+ $x->endElement();
+ $x->endElement();
+ $x->startElement('cac:PartyLegalEntity');
+ $x->writeElement('cbc:RegistrationName', $settings['name']);
+ $x->writeElement('cbc:CompanyID', $settings['vatId']);
+ $x->endElement();
+ $x->startElement('cac:Contact');
+ $x->writeElement('cbc:ElectronicMail', $settings['email']);
+ $x->endElement();
+ $x->endElement();
+ $x->endElement();
+ // Client
+ $x->startElement('cac:AccountingCustomerParty');
+ $x->startElement('cac:Party');
+ $x->startElement('cac:PostalAddress');
+ $x->writeElement('cbc:StreetName', $client?->street);
+ $x->writeElement('cbc:CityName', $client?->city);
+ $x->writeElement('cbc:PostalZone', $client?->zip);
+ $x->startElement('cac:Country');
+ $x->writeElement('cbc:IdentificationCode', $client?->country);
+ $x->endElement();
+ $x->endElement();
+ $x->startElement('cac:PartyTaxScheme');
+ if ($client?->vat_id) {
+ $x->writeElement('cbc:CompanyID', $client->vat_id);
+ }
+ $x->startElement('cac:TaxScheme');
+ $x->writeElement('cbc:ID', 'VAT');
+ $x->endElement();
+ $x->endElement();
+ $x->startElement('cac:PartyLegalEntity');
+ $x->writeElement('cbc:RegistrationName', $client?->name);
+ if ($client?->vat_id) {
+ $x->writeElement('cbc:CompanyID', $client->vat_id);
+ }
+ $x->endElement();
+ $x->endElement();
+ $x->endElement();
+ // Payment
+ $x->startElement('cac:PaymentMeans');
+ // 58 SEPA credit transfer
+ // 59 SEPA direct debit
+ // 57 Standing agreement
+ // 30 Credit transfer (non-SEPA)
+ // 49 Direct debit (non-SEPA)
+ // 48 Bank card
+ $x->writeElement('cbc:PaymentMeansCode', 30);
+ $x->writeElement('cbc:PaymentID', $invoice->current_number);
+ $x->startElement('cac:PayeeFinancialAccount');
+ $x->writeElement('cbc:ID', $settings['iban']);
+ $x->endElement();
+ $x->endElement();
+ // Tax
+ $x->startElement('cac:TaxTotal');
+ $x->startElement('cbc:TaxAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->vat);
+ $x->endElement();
+ $x->startElement('cac:TaxSubtotal');
+ $x->startElement('cbc:TaxableAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->net);
+ $x->endElement();
+ $x->startElement('cbc:TaxAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->vat);
+ $x->endElement();
+ $x->startElement('cac:TaxCategory');
+ // See https://developer.vertexinc.com/einvoicing/docs/en-16931-tax-categories
+ $x->writeElement('cbc:ID', $invoice->taxable ? 'S' : 'G');
+ $x->writeElement('cbc:Percent', $invoice->taxable ? $invoice->vat_rate * 100 : 0);
+ if (!$invoice->taxable) {
+ $x->writeElement('cbc:TaxExemptionReasonCode', 'VATEX-EU-G');
+ }
+ $x->startElement('cac:TaxScheme');
+ $x->writeElement('cbc:ID', 'VAT');
+ $x->endElement();
+ $x->endElement();
+ $x->endElement();
+ $x->endElement();
+ // Finances
+ $x->startElement('cac:LegalMonetaryTotal');
+ $x->startElement('cbc:LineExtensionAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->net);
+ $x->endElement();
+ $x->startElement('cbc:TaxExclusiveAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->net);
+ $x->endElement();
+ $x->startElement('cbc:TaxInclusiveAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->gross);
+ $x->endElement();
+ $x->startElement('cbc:ChargeTotalAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text(0);
+ $x->endElement();
+ $x->startElement('cbc:PayableAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->gross);
+ $x->endElement();
+ $x->endElement();
+ // Positions
+ foreach ($invoice->positions as $key => $position) {
+ $x->startElement('cac:InvoiceLine');
+ $x->writeElement('cbc:ID', $key + 1);
+ $x->startElement('cbc:InvoicedQuantity');
+ $x->writeAttribute('unitCode', 'EA');
+ $x->text($position->duration);
+ $x->endElement();
+ $x->startElement('cbc:LineExtensionAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($position->net);
+ $x->endElement();
+ $x->startElement('cac:Item');
+ $x->writeElement('cbc:Description', $position->description);
+ $x->writeElement('cbc:Name', trans_choice('position', 1, locale: $lang));
+ $x->startElement('cac:ClassifiedTaxCategory');
+ $x->writeElement('cbc:ID', $invoice->taxable ? 'S' : 'G');
+ $x->writeElement('cbc:Percent', $invoice->taxable ? $invoice->vat_rate * 100 : 0);
+ $x->startElement('cac:TaxScheme');
+ $x->writeElement('cbc:ID', 'VAT');
$x->endElement();
+ $x->endElement();
+ $x->endElement();
+ $x->startElement('cac:Price');
+ $x->startElement('cbc:PriceAmount');
+ $x->writeAttribute('currencyID', $currency);
+ $x->text($invoice->price);
+ $x->endElement();
+ $x->endElement();
+ $x->endElement();
+ }
+ $x->endElement();
$x->endDocument();
$x->flush();
unset($x);
diff --git a/app/Services/PdfTemplate.php b/app/Services/PdfTemplate.php
index 458963f..28c96b6 100644
--- a/app/Services/PdfTemplate.php
+++ b/app/Services/PdfTemplate.php
@@ -55,7 +55,7 @@ public function header(): void
DocumentType::QUOTE => $this->getPage() <= 2
? __("quote", locale: $this->lang)
: __("costEstimate", locale: $this->lang),
- }
+ },
);
$this->setFont('FiraSans-ExtraLight', fontSizeInPoint: 26)
->setTextColor(Color::LIGHT->pdfColor())
@@ -181,8 +181,8 @@ protected function putCatalog(): void
}
$this->writer->putf('/Names <>', $this->attachmentNumber);
$array = \array_map(
- static fn (PdfAttachment $attachment): string => $attachment->formatNumber(),
- $this->attachments
+ static fn(PdfAttachment $attachment): string => $attachment->formatNumber(),
+ $this->attachments,
);
$this->writer->putf('/AF [%s]', \implode(' ', $array));
}
diff --git a/app/Services/ProjectService.php b/app/Services/ProjectService.php
index 03da62e..00704b5 100644
--- a/app/Services/ProjectService.php
+++ b/app/Services/ProjectService.php
@@ -23,7 +23,8 @@ class ProjectService
* @param Project $project Record to export
* @return string
*/
- public static function generateQuotePdf(Project $project): string {
+ public static function generateQuotePdf(Project $project): string
+ {
$conf = Setting::pluck('value', 'field');
$client = $project?->client;
$lang = $client?->language->value ?? 'de';
@@ -42,12 +43,12 @@ public static function generateQuotePdf(Project $project): string {
'hours' => Number::format($billedPerProject ? $project->scope ?? 0 : $project->estimated_hours, 1, locale: $lang),
'net' => Number::currency($project->estimated_net, 'EUR', locale: $lang),
'number' => $now->format('Ymd'),
- 'price' => Number::currency($billedPerProject ? ($project->scope ? $project->price/$project->scope : 0) : $project->price, 'EUR', locale: $lang),
+ 'price' => Number::currency($billedPerProject ? ($project->scope ? $project->price / $project->scope : 0) : $project->price, 'EUR', locale: $lang),
'start' => Carbon::parse($project->start_at)->locale($lang)->isoFormat('LL'),
'title' => $project->title,
'validDate' => $now->addWeeks(3)->locale($lang)->isoFormat('LL'),
'vat' => Number::currency($project->estimated_vat, 'EUR', locale: $lang),
- 'vatRate' => Number::percentage($conf['vatRate']*100, 2, locale: $lang) . ' ' . __("vat", locale: $lang),
+ 'vatRate' => Number::percentage($conf['vatRate'] * 100, 2, locale: $lang) . ' ' . __("vat", locale: $lang),
]);
$label = collect([
@@ -93,9 +94,9 @@ public static function generateQuotePdf(Project $project): string {
]);
// Convert to supported char encoding
- $conf = $conf->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
- $data = $data->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
- $label = $label->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
+ $conf = $conf->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
+ $data = $data->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
+ $label = $label->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
// Init document
$pdf = new PdfTemplate($lang, DocumentType::QUOTE);
@@ -232,7 +233,8 @@ public static function generateQuotePdf(Project $project): string {
$rowHeight = 3.5;
$totalHeight = array_reduce(
$estimates,
- fn ($a, $c) => $a + count(explode("\n", $c->description)) + 2, 0
+ fn($a, $c) => $a + count(explode("\n", $c->description)) + 2,
+ 0,
) * $rowHeight + 32;
$pdf->addPage();
@@ -286,7 +288,7 @@ public static function generateQuotePdf(Project $project): string {
]);
// Convert to supported char encoding
- $estData = $estData->map(fn ($e) => iconv('UTF-8', 'windows-1252', $e));
+ $estData = $estData->map(fn($e) => iconv('UTF-8', 'windows-1252', $e));
$pdf->setTextColor(Color::DARK->pdfColor())
->setFont('FiraSans-Regular')
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 037e17d..e6322c4 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -12,7 +12,7 @@
*/
$app = new Illuminate\Foundation\Application(
- $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
+ $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__),
);
/*
@@ -28,17 +28,17 @@
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
- App\Http\Kernel::class
+ App\Http\Kernel::class,
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
- App\Console\Kernel::class
+ App\Console\Kernel::class,
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
- App\Exceptions\Handler::class
+ App\Exceptions\Handler::class,
);
/*
diff --git a/composer.json b/composer.json
index 1759f35..7c9367d 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
- "name": "laravel/laravel",
+ "name": "devmount/sales",
"type": "project",
- "description": "The skeleton application for the Laravel framework.",
+ "description": "A service sales manager made for freelancers",
"keywords": [
"laravel",
"framework"
@@ -54,7 +54,9 @@
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
- ]
+ ],
+ "lint": "vendor/bin/pint --test --parallel",
+ "format": "vendor/bin/pint --parallel"
},
"extra": {
"laravel": {
diff --git a/config/app.php b/config/app.php
index 4c84256..ca6391f 100644
--- a/config/app.php
+++ b/config/app.php
@@ -18,17 +18,17 @@
'name' => env('APP_NAME', 'Laravel'),
- /*
- |--------------------------------------------------------------------------
- | Application Version
- |--------------------------------------------------------------------------
- |
- | This value is the version of your application. This value is used when
- | the framework needs to place the application's version in a notification
- | or any other location as required by the application or its packages.
- */
-
- 'version' => '2.9.0',
+ /*
+ |--------------------------------------------------------------------------
+ | Application Version
+ |--------------------------------------------------------------------------
+ |
+ | This value is the version of your application. This value is used when
+ | the framework needs to place the application's version in a notification
+ | or any other location as required by the application or its packages.
+ */
+
+ 'version' => '2.9.0',
/*
|--------------------------------------------------------------------------
diff --git a/config/cache.php b/config/cache.php
index d4171e2..5115f18 100644
--- a/config/cache.php
+++ b/config/cache.php
@@ -106,6 +106,6 @@
|
*/
- 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
+ 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache_'),
];
diff --git a/config/database.php b/config/database.php
index d21f543..9b6a7c6 100644
--- a/config/database.php
+++ b/config/database.php
@@ -125,7 +125,7 @@
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
- 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
+ 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
],
'default' => [
diff --git a/config/filesystems.php b/config/filesystems.php
index 1ab0d03..99861bc 100644
--- a/config/filesystems.php
+++ b/config/filesystems.php
@@ -40,7 +40,7 @@
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
- 'url' => env('APP_URL').'/storage',
+ 'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
'throw' => false,
],
diff --git a/config/logging.php b/config/logging.php
index c44d276..d000835 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -89,7 +89,7 @@
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
- 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
+ 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'),
],
'processors' => [PsrLogMessageProcessor::class],
],
diff --git a/config/sanctum.php b/config/sanctum.php
index 529cfdc..c393e78 100644
--- a/config/sanctum.php
+++ b/config/sanctum.php
@@ -18,7 +18,7 @@
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
- Sanctum::currentApplicationUrlWithPort()
+ Sanctum::currentApplicationUrlWithPort(),
))),
/*
diff --git a/config/session.php b/config/session.php
index 8fed97c..5fb15f8 100644
--- a/config/session.php
+++ b/config/session.php
@@ -128,7 +128,7 @@
'cookie' => env(
'SESSION_COOKIE',
- Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
+ Str::slug(env('APP_NAME', 'laravel'), '_') . '_session',
),
/*
diff --git a/config/view.php b/config/view.php
index 22b8a18..40cbf77 100644
--- a/config/view.php
+++ b/config/view.php
@@ -30,7 +30,7 @@
'compiled' => env(
'VIEW_COMPILED_PATH',
- realpath(storage_path('framework/views'))
+ realpath(storage_path('framework/views')),
),
];
diff --git a/database/factories/ExpenseFactory.php b/database/factories/ExpenseFactory.php
index ac2a049..180e7be 100644
--- a/database/factories/ExpenseFactory.php
+++ b/database/factories/ExpenseFactory.php
@@ -43,7 +43,7 @@ public function definition(): array
*/
public function notTaxable(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'taxable' => false,
'vat_rate' => null,
]);
diff --git a/database/factories/InvoiceFactory.php b/database/factories/InvoiceFactory.php
index 12cfbf0..f238d19 100644
--- a/database/factories/InvoiceFactory.php
+++ b/database/factories/InvoiceFactory.php
@@ -52,7 +52,7 @@ public function definition(): array
*/
public function active(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'invoiced_at' => null,
'paid_at' => null,
]);
@@ -63,7 +63,7 @@ public function active(): static
*/
public function waiting(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'invoiced_at' => fake()->dateTimeBetween('-6 months', 'now')->format('Y-m-d'),
'paid_at' => null,
]);
@@ -75,7 +75,7 @@ public function waiting(): static
public function finished(): static
{
$invoicedAt = fake()->dateTimeBetween('-6 months', 'now')->format('Y-m-d');
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'invoiced_at' => $invoicedAt,
'paid_at' => fake()->dateTimeBetween($invoicedAt, '+7 days')->format('Y-m-d'),
]);
@@ -86,7 +86,7 @@ public function finished(): static
*/
public function taxable(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'taxable' => true,
'vat_rate' => fake()->randomElement([0.07, 0.19]),
]);
@@ -97,7 +97,7 @@ public function taxable(): static
*/
public function notTaxable(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'taxable' => false,
'vat_rate' => null,
]);
@@ -108,7 +108,7 @@ public function notTaxable(): static
*/
public function hourly(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 50, 150),
'pricing_unit' => PricingUnit::Hour->value,
]);
@@ -119,7 +119,7 @@ public function hourly(): static
*/
public function daily(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 450, 1250),
'pricing_unit' => PricingUnit::Day->value,
]);
@@ -130,7 +130,7 @@ public function daily(): static
*/
public function project(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 500, 15000),
'pricing_unit' => PricingUnit::Project->value,
]);
diff --git a/database/factories/OfftimeFactory.php b/database/factories/OfftimeFactory.php
index a8ef4ba..eaf8de2 100644
--- a/database/factories/OfftimeFactory.php
+++ b/database/factories/OfftimeFactory.php
@@ -41,7 +41,7 @@ public function definition(): array
*/
public function singleDay(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'end' => null,
]);
}
@@ -51,7 +51,7 @@ public function singleDay(): static
*/
public function vacation(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'category' => OfftimeCategory::Vacation->value,
]);
}
@@ -61,7 +61,7 @@ public function vacation(): static
*/
public function sick(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'category' => OfftimeCategory::Sick->value,
]);
}
diff --git a/database/factories/PositionFactory.php b/database/factories/PositionFactory.php
index 2dd5b69..47e652a 100644
--- a/database/factories/PositionFactory.php
+++ b/database/factories/PositionFactory.php
@@ -44,7 +44,7 @@ public function definition(): array
*/
public function remote(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'remote' => true,
]);
}
@@ -54,7 +54,7 @@ public function remote(): static
*/
public function onSite(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'remote' => false,
]);
}
diff --git a/database/factories/ProjectFactory.php b/database/factories/ProjectFactory.php
index fb5df12..ad8e7ce 100644
--- a/database/factories/ProjectFactory.php
+++ b/database/factories/ProjectFactory.php
@@ -48,7 +48,7 @@ public function definition(): array
*/
public function active(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'start_at' => fake()->dateTimeBetween('-3 months', 'now')->format('Y-m-d'),
'due_at' => fake()->dateTimeBetween('now', '+3 months')->format('Y-m-d'),
'aborted' => false,
@@ -60,7 +60,7 @@ public function active(): static
*/
public function upcoming(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'start_at' => fake()->dateTimeBetween('now', '+2 months')->format('Y-m-d'),
'due_at' => fake()->dateTimeBetween('+6 months', '+12 months')->format('Y-m-d'),
'aborted' => false,
@@ -72,7 +72,7 @@ public function upcoming(): static
*/
public function finished(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'start_at' => fake()->dateTimeBetween('-12 months', '-6 months')->format('Y-m-d'),
'due_at' => fake()->dateTimeBetween('-4 months', 'now')->format('Y-m-d'),
'aborted' => false,
@@ -84,7 +84,7 @@ public function finished(): static
*/
public function aborted(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'aborted' => true,
]);
}
@@ -94,7 +94,7 @@ public function aborted(): static
*/
public function hourly(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 50, 150),
'pricing_unit' => PricingUnit::Hour->value,
]);
@@ -105,7 +105,7 @@ public function hourly(): static
*/
public function daily(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 450, 1250),
'pricing_unit' => PricingUnit::Day->value,
]);
@@ -116,7 +116,7 @@ public function daily(): static
*/
public function project(): static
{
- return $this->state(fn (array $attributes) => [
+ return $this->state(fn(array $attributes) => [
'price' => fake()->randomFloat(2, 500, 15000),
'pricing_unit' => PricingUnit::Project->value,
]);
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index 28e61a9..6d2d641 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -32,7 +32,7 @@ public function definition(): array
*/
public function unverified(): static
{
- return $this->state(fn () => [
+ return $this->state(fn() => [
'email_verified_at' => null,
]);
}
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index 444fafb..814b11a 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php
index 81a7229..1bc0eee 100644
--- a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php
+++ b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php
index 249da81..51aaa6f 100644
--- a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php
+++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php
index e828ad8..82dbff5 100644
--- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php
+++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_22_141844_create_clients_table.php b/database/migrations/2023_08_22_141844_create_clients_table.php
index eecf8b4..8097abf 100644
--- a/database/migrations/2023_08_22_141844_create_clients_table.php
+++ b/database/migrations/2023_08_22_141844_create_clients_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_23_123436_create_gifts_table.php b/database/migrations/2023_08_23_123436_create_gifts_table.php
index 21cd860..61f2ff0 100644
--- a/database/migrations/2023_08_23_123436_create_gifts_table.php
+++ b/database/migrations/2023_08_23_123436_create_gifts_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_24_040548_create_expenses_table.php b/database/migrations/2023_08_24_040548_create_expenses_table.php
index 48a44ad..eb06447 100644
--- a/database/migrations/2023_08_24_040548_create_expenses_table.php
+++ b/database/migrations/2023_08_24_040548_create_expenses_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_25_122638_create_projects_table.php b/database/migrations/2023_08_25_122638_create_projects_table.php
index c0ada6c..8197ab3 100644
--- a/database/migrations/2023_08_25_122638_create_projects_table.php
+++ b/database/migrations/2023_08_25_122638_create_projects_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_26_192313_create_estimates_table.php b/database/migrations/2023_08_26_192313_create_estimates_table.php
index 44963e4..7be7392 100644
--- a/database/migrations/2023_08_26_192313_create_estimates_table.php
+++ b/database/migrations/2023_08_26_192313_create_estimates_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_27_192643_create_invoices_table.php b/database/migrations/2023_08_27_192643_create_invoices_table.php
index 570248f..8194bd0 100644
--- a/database/migrations/2023_08_27_192643_create_invoices_table.php
+++ b/database/migrations/2023_08_27_192643_create_invoices_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_08_28_134626_create_positions_table.php b/database/migrations/2023_08_28_134626_create_positions_table.php
index 89a0a7c..870a3f9 100644
--- a/database/migrations/2023_08_28_134626_create_positions_table.php
+++ b/database/migrations/2023_08_28_134626_create_positions_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_09_01_181022_create_settings_table.php b/database/migrations/2023_09_01_181022_create_settings_table.php
index c24120b..ccbb921 100644
--- a/database/migrations/2023_09_01_181022_create_settings_table.php
+++ b/database/migrations/2023_09_01_181022_create_settings_table.php
@@ -5,8 +5,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2023_09_19_000001_modify_expenses_table.php b/database/migrations/2023_09_19_000001_modify_expenses_table.php
index e68b88f..58987e4 100644
--- a/database/migrations/2023_09_19_000001_modify_expenses_table.php
+++ b/database/migrations/2023_09_19_000001_modify_expenses_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2024_12_18_215647_add_address_fields_to_clients_table.php b/database/migrations/2024_12_18_215647_add_address_fields_to_clients_table.php
index ba36994..5b3d429 100644
--- a/database/migrations/2024_12_18_215647_add_address_fields_to_clients_table.php
+++ b/database/migrations/2024_12_18_215647_add_address_fields_to_clients_table.php
@@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/database/migrations/2025_05_03_210539_create_offtimes.php b/database/migrations/2025_05_03_210539_create_offtimes.php
index 55b8134..6bda6d0 100644
--- a/database/migrations/2025_05_03_210539_create_offtimes.php
+++ b/database/migrations/2025_05_03_210539_create_offtimes.php
@@ -5,8 +5,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
-return new class extends Migration
-{
+return new class extends Migration {
/**
* Run the migrations.
*/
diff --git a/pint.json b/pint.json
new file mode 100644
index 0000000..21f4155
--- /dev/null
+++ b/pint.json
@@ -0,0 +1,27 @@
+{
+ "preset": "per",
+ "rules": {
+ "ordered_class_elements": {
+ "order": [
+ "use_trait",
+ "case",
+ "constant_public",
+ "constant_protected",
+ "constant_private",
+ "property_public",
+ "property_protected",
+ "property_private",
+ "construct",
+ "destruct",
+ "magic",
+ "method_public",
+ "method_protected",
+ "method_private"
+ ],
+ "sort_algorithm": "none"
+ },
+ "types_spaces": {
+ "space": "none"
+ }
+ }
+}
diff --git a/public/index.php b/public/index.php
index 1d69f3a..9dd7374 100644
--- a/public/index.php
+++ b/public/index.php
@@ -16,7 +16,7 @@
|
*/
-if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
+if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) {
require $maintenance;
}
@@ -31,7 +31,7 @@
|
*/
-require __DIR__.'/../vendor/autoload.php';
+require __DIR__ . '/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
@@ -44,12 +44,12 @@
|
*/
-$app = require_once __DIR__.'/../bootstrap/app.php';
+$app = require_once __DIR__ . '/../bootstrap/app.php';
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
- $request = Request::capture()
+ $request = Request::capture(),
)->send();
$kernel->terminate($request, $response);
diff --git a/routes/web.php b/routes/web.php
index 83469ef..c6a13f8 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -1,6 +1,5 @@
call('save')
->assertHasFormErrors(['password']);
}
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ // The "save" action is rate-limited by component+method+IP via the file
+ // cache driver, which isn't reset between tests like the database is.
+ Cache::flush();
+ }
}
diff --git a/tests/Feature/InvoiceServiceTest.php b/tests/Feature/InvoiceServiceTest.php
index e242b7e..d9839cf 100644
--- a/tests/Feature/InvoiceServiceTest.php
+++ b/tests/Feature/InvoiceServiceTest.php
@@ -21,84 +21,6 @@ class InvoiceServiceTest extends TestCase
private string $logoPath;
private string $signaturePath;
- protected function setUp(): void
- {
- parent::setUp();
-
- Storage::fake();
-
- $this->logoPath = tempnam(sys_get_temp_dir(), 'logo') . '.jpg';
- imagejpeg(imagecreatetruecolor(10, 10), $this->logoPath);
-
- $this->signaturePath = tempnam(sys_get_temp_dir(), 'signature') . '.png';
- imagepng(imagecreatetruecolor(10, 10), $this->signaturePath);
-
- $this->seedSettings();
- }
-
- protected function tearDown(): void
- {
- @unlink($this->logoPath);
- @unlink($this->signaturePath);
-
- parent::tearDown();
- }
-
- private function seedSettings(): void
- {
- $values = [
- 'accountHolder' => 'Account Holder',
- 'bank' => 'Test Bank',
- 'bic' => 'TESTBIC1',
- 'city' => 'Berlin',
- 'company' => 'Acme UG',
- 'country' => 'Germany',
- 'email' => 'contact@acme.test',
- 'iban' => 'DE00000000000000000000',
- 'logo' => $this->logoPath,
- 'name' => 'Acme UG',
- 'phone' => '+49123456789',
- 'signature' => $this->signaturePath,
- 'street' => 'Main Street 1',
- 'taxOffice' => 'Finanzamt Berlin',
- 'vatId' => 'DE123456789',
- 'vatRate' => '0.19',
- 'website' => 'https://acme.test',
- 'zip' => '12345',
- ];
-
- foreach ($values as $field => $value) {
- Setting::where('field', $field)->update(['value' => $value]);
- }
- }
-
- private function makeInvoice(array $attributes = []): Invoice
- {
- $client = Client::factory()->create([
- 'language' => $attributes['language'] ?? LanguageCode::DE,
- 'name' => 'Client GmbH',
- ]);
- unset($attributes['language']);
- $project = Project::factory()->for($client)->hourly()->create();
-
- return Invoice::factory()->for($project)->create(array_merge([
- 'taxable' => true,
- 'vat_rate' => 0.19,
- 'discount' => null,
- 'undated' => false,
- ], $attributes));
- }
-
- private function expectedPdfFilename(Invoice $invoice, string $locale = 'de'): string
- {
- return strtolower("{$invoice->current_number}_" . trans_choice('invoice', 1, [], $locale) . '_Acme UG.pdf');
- }
-
- private function expectedXmlFilename(Invoice $invoice, string $locale = 'de'): string
- {
- return strtolower("{$invoice->current_number}_" . trans_choice('invoice', 1, [], $locale) . '_Acme UG.xml');
- }
-
#[Test]
public function it_generates_and_saves_an_invoice_pdf_with_an_xml_attachment(): void
{
@@ -200,4 +122,82 @@ public function it_generates_an_en16931_xml_invoice_with_the_expected_content():
$this->assertStringContainsString('' . $invoice->project->client->name . '', $xml);
$this->assertStringContainsString('' . $invoice->gross . '', $xml);
}
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ Storage::fake();
+
+ $this->logoPath = tempnam(sys_get_temp_dir(), 'logo') . '.jpg';
+ imagejpeg(imagecreatetruecolor(10, 10), $this->logoPath);
+
+ $this->signaturePath = tempnam(sys_get_temp_dir(), 'signature') . '.png';
+ imagepng(imagecreatetruecolor(10, 10), $this->signaturePath);
+
+ $this->seedSettings();
+ }
+
+ protected function tearDown(): void
+ {
+ @unlink($this->logoPath);
+ @unlink($this->signaturePath);
+
+ parent::tearDown();
+ }
+
+ private function seedSettings(): void
+ {
+ $values = [
+ 'accountHolder' => 'Account Holder',
+ 'bank' => 'Test Bank',
+ 'bic' => 'TESTBIC1',
+ 'city' => 'Berlin',
+ 'company' => 'Acme UG',
+ 'country' => 'Germany',
+ 'email' => 'contact@acme.test',
+ 'iban' => 'DE00000000000000000000',
+ 'logo' => $this->logoPath,
+ 'name' => 'Acme UG',
+ 'phone' => '+49123456789',
+ 'signature' => $this->signaturePath,
+ 'street' => 'Main Street 1',
+ 'taxOffice' => 'Finanzamt Berlin',
+ 'vatId' => 'DE123456789',
+ 'vatRate' => '0.19',
+ 'website' => 'https://acme.test',
+ 'zip' => '12345',
+ ];
+
+ foreach ($values as $field => $value) {
+ Setting::where('field', $field)->update(['value' => $value]);
+ }
+ }
+
+ private function makeInvoice(array $attributes = []): Invoice
+ {
+ $client = Client::factory()->create([
+ 'language' => $attributes['language'] ?? LanguageCode::DE,
+ 'name' => 'Client GmbH',
+ ]);
+ unset($attributes['language']);
+ $project = Project::factory()->for($client)->hourly()->create();
+
+ return Invoice::factory()->for($project)->create(array_merge([
+ 'taxable' => true,
+ 'vat_rate' => 0.19,
+ 'discount' => null,
+ 'undated' => false,
+ ], $attributes));
+ }
+
+ private function expectedPdfFilename(Invoice $invoice, string $locale = 'de'): string
+ {
+ return strtolower("{$invoice->current_number}_" . trans_choice('invoice', 1, [], $locale) . '_Acme UG.pdf');
+ }
+
+ private function expectedXmlFilename(Invoice $invoice, string $locale = 'de'): string
+ {
+ return strtolower("{$invoice->current_number}_" . trans_choice('invoice', 1, [], $locale) . '_Acme UG.xml');
+ }
}
diff --git a/tests/Feature/OfftimeChartTest.php b/tests/Feature/OfftimeChartTest.php
index 4f6d977..8320c16 100644
--- a/tests/Feature/OfftimeChartTest.php
+++ b/tests/Feature/OfftimeChartTest.php
@@ -63,7 +63,7 @@ public function it_assembles_offtime_and_working_days_per_year(): void
$this->assertSame(0, $unplanned['data'][$yearIndex]);
$this->assertSame(
$weekend['data'][$yearIndex] + $planned['data'][$yearIndex] + $unplanned['data'][$yearIndex],
- $total['data'][$yearIndex]
+ $total['data'][$yearIndex],
);
$this->assertSame(1, $worked['data'][$yearIndex]);
}
diff --git a/tests/Feature/ProjectServiceTest.php b/tests/Feature/ProjectServiceTest.php
index ea07ffa..5ea5222 100644
--- a/tests/Feature/ProjectServiceTest.php
+++ b/tests/Feature/ProjectServiceTest.php
@@ -20,62 +20,6 @@ class ProjectServiceTest extends TestCase
private string $logoPath;
private string $signaturePath;
- protected function setUp(): void
- {
- parent::setUp();
-
- Storage::fake();
-
- $this->logoPath = tempnam(sys_get_temp_dir(), 'logo') . '.jpg';
- imagejpeg(imagecreatetruecolor(10, 10), $this->logoPath);
-
- $this->signaturePath = tempnam(sys_get_temp_dir(), 'signature') . '.png';
- imagepng(imagecreatetruecolor(10, 10), $this->signaturePath);
-
- $this->seedSettings();
- }
-
- protected function tearDown(): void
- {
- @unlink($this->logoPath);
- @unlink($this->signaturePath);
-
- parent::tearDown();
- }
-
- private function seedSettings(): void
- {
- $values = [
- 'accountHolder' => 'Account Holder',
- 'bank' => 'Test Bank',
- 'bic' => 'TESTBIC1',
- 'city' => 'Berlin',
- 'company' => 'Acme UG',
- 'country' => 'Germany',
- 'email' => 'contact@acme.test',
- 'iban' => 'DE00000000000000000000',
- 'logo' => $this->logoPath,
- 'name' => 'Acme UG',
- 'phone' => '+49123456789',
- 'signature' => $this->signaturePath,
- 'street' => 'Main Street 1',
- 'taxOffice' => 'Finanzamt Berlin',
- 'vatId' => 'DE123456789',
- 'vatRate' => '0.19',
- 'website' => 'https://acme.test',
- 'zip' => '12345',
- ];
-
- foreach ($values as $field => $value) {
- Setting::where('field', $field)->update(['value' => $value]);
- }
- }
-
- private function expectedFilename(): string
- {
- return strtolower(now()->format('Ymd') . '_' . __('quote', locale: 'de') . '_Acme UG.pdf');
- }
-
#[Test]
public function it_generates_and_saves_a_quote_pdf_for_an_hourly_project(): void
{
@@ -133,4 +77,60 @@ public function it_generates_a_quote_pdf_with_multiple_estimates(): void
Storage::assertExists($filename);
$this->assertStringStartsWith('%PDF-', Storage::get($filename));
}
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ Storage::fake();
+
+ $this->logoPath = tempnam(sys_get_temp_dir(), 'logo') . '.jpg';
+ imagejpeg(imagecreatetruecolor(10, 10), $this->logoPath);
+
+ $this->signaturePath = tempnam(sys_get_temp_dir(), 'signature') . '.png';
+ imagepng(imagecreatetruecolor(10, 10), $this->signaturePath);
+
+ $this->seedSettings();
+ }
+
+ protected function tearDown(): void
+ {
+ @unlink($this->logoPath);
+ @unlink($this->signaturePath);
+
+ parent::tearDown();
+ }
+
+ private function seedSettings(): void
+ {
+ $values = [
+ 'accountHolder' => 'Account Holder',
+ 'bank' => 'Test Bank',
+ 'bic' => 'TESTBIC1',
+ 'city' => 'Berlin',
+ 'company' => 'Acme UG',
+ 'country' => 'Germany',
+ 'email' => 'contact@acme.test',
+ 'iban' => 'DE00000000000000000000',
+ 'logo' => $this->logoPath,
+ 'name' => 'Acme UG',
+ 'phone' => '+49123456789',
+ 'signature' => $this->signaturePath,
+ 'street' => 'Main Street 1',
+ 'taxOffice' => 'Finanzamt Berlin',
+ 'vatId' => 'DE123456789',
+ 'vatRate' => '0.19',
+ 'website' => 'https://acme.test',
+ 'zip' => '12345',
+ ];
+
+ foreach ($values as $field => $value) {
+ Setting::where('field', $field)->update(['value' => $value]);
+ }
+ }
+
+ private function expectedFilename(): string
+ {
+ return strtolower(now()->format('Ymd') . '_' . __('quote', locale: 'de') . '_Acme UG.pdf');
+ }
}