Merge branch 'feature/DeliveryCalendar'
# Conflicts: # public/js/admin.js # public/js/module.js # public/mix-manifest.json
This commit is contained in:
commit
5275dfcd0b
28
app/Enums/OverrideScope.php
Normal file
28
app/Enums/OverrideScope.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum OverrideScope: string
|
||||||
|
{
|
||||||
|
case General = 'general'; // Általános – adott beszállítóra, minden régióra és profitcenterre
|
||||||
|
case Region = 'region'; // Régió-specifikus – adott régióra vonatkozó felülbírálás
|
||||||
|
case ProfitCenter = 'profit_center'; // Profitcenter-specifikus – csak 1 konkrét profitcenterre
|
||||||
|
|
||||||
|
public function label(): string
|
||||||
|
{
|
||||||
|
return match($this) {
|
||||||
|
self::General => 'Általános (minden telephely)',
|
||||||
|
self::Region => 'Régió-specifikus',
|
||||||
|
self::ProfitCenter => 'Profitcenter-specifikus',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function color(): string
|
||||||
|
{
|
||||||
|
return match($this) {
|
||||||
|
self::General => 'gray',
|
||||||
|
self::Region => 'warning',
|
||||||
|
self::ProfitCenter => 'info',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
69
app/Filament/Pages/CalendarTest.php
Normal file
69
app/Filament/Pages/CalendarTest.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\ProfitCenter;
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use App\Models\Supplier;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
|
||||||
|
class CalendarTest extends Page
|
||||||
|
{
|
||||||
|
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-calendar';
|
||||||
|
|
||||||
|
protected string $view = 'filament.pages.calendar-test';
|
||||||
|
|
||||||
|
protected static ?string $title = 'Naptár Teszt';
|
||||||
|
|
||||||
|
protected static bool $shouldRegisterNavigation = false;
|
||||||
|
|
||||||
|
public ?int $supplierId = null;
|
||||||
|
|
||||||
|
public ?int $profitCenterId = null;
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$first = ProfitCenterSupplierSchedule::first();
|
||||||
|
|
||||||
|
if ($first) {
|
||||||
|
$this->supplierId = $first->supplier_id;
|
||||||
|
$this->profitCenterId = $first->profit_center_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSuppliers(): array
|
||||||
|
{
|
||||||
|
return Supplier::orderBy('name')->pluck('name', 'id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProfitCenters(): array
|
||||||
|
{
|
||||||
|
if (!$this->supplierId) {
|
||||||
|
return ProfitCenter::orderBy('name')->pluck('name', 'id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pcIds = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)
|
||||||
|
->pluck('profit_center_id');
|
||||||
|
|
||||||
|
return ProfitCenter::whereIn('id', $pcIds)->orderBy('name')->pluck('name', 'id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedSupplierId(): void
|
||||||
|
{
|
||||||
|
$this->profitCenterId = null;
|
||||||
|
|
||||||
|
$first = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)->first();
|
||||||
|
|
||||||
|
if ($first) {
|
||||||
|
$this->profitCenterId = $first->profit_center_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dispatch('calendar-filter-changed', supplierId: $this->supplierId, profitCenterId: $this->profitCenterId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedProfitCenterId(): void
|
||||||
|
{
|
||||||
|
$this->dispatch('calendar-filter-changed', supplierId: $this->supplierId, profitCenterId: $this->profitCenterId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\CreateDeliveryCalendarOverride;
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\EditDeliveryCalendarOverride;
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\ListDeliveryCalendarOverrides;
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\Schemas\DeliveryCalendarOverrideForm;
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\Tables\DeliveryCalendarOverridesTable;
|
||||||
|
use App\Models\DeliveryCalendarOverride;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class DeliveryCalendarOverrideResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = DeliveryCalendarOverride::class;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-exclamation-triangle';
|
||||||
|
|
||||||
|
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Beszállítói felülbírálások';
|
||||||
|
|
||||||
|
protected static ?string $modelLabel = 'Beszállítói felülbírálás';
|
||||||
|
|
||||||
|
protected static ?string $pluralLabel = 'Beszállítói felülbírálások';
|
||||||
|
|
||||||
|
protected static ?string $breadcrumb = 'Beszállítói felülbírálások';
|
||||||
|
|
||||||
|
public static function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return DeliveryCalendarOverrideForm::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return DeliveryCalendarOverridesTable::configure($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => ListDeliveryCalendarOverrides::route('/'),
|
||||||
|
'create' => CreateDeliveryCalendarOverride::route('/create'),
|
||||||
|
'edit' => EditDeliveryCalendarOverride::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getRecordRouteBindingEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateDeliveryCalendarOverride extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||||
|
use Filament\Actions\DeleteAction;
|
||||||
|
use Filament\Actions\ForceDeleteAction;
|
||||||
|
use Filament\Actions\RestoreAction;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditDeliveryCalendarOverride extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
DeleteAction::make(),
|
||||||
|
ForceDeleteAction::make(),
|
||||||
|
RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||||
|
use Filament\Actions\CreateAction;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListDeliveryCalendarOverrides extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides\Schemas;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Schemas\Components\Utilities\Get;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class DeliveryCalendarOverrideForm
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
Select::make('supplier_id')
|
||||||
|
->label('Beszállító')
|
||||||
|
->relationship('supplier', 'name')
|
||||||
|
->searchable()
|
||||||
|
->required(),
|
||||||
|
Select::make('override_scope')
|
||||||
|
->label('Felülbírálás szintje')
|
||||||
|
->options(collect(OverrideScope::cases())->mapWithKeys(
|
||||||
|
fn(OverrideScope $scope) => [$scope->value => $scope->label()]
|
||||||
|
))
|
||||||
|
->default(OverrideScope::General->value)
|
||||||
|
->required()
|
||||||
|
->live(),
|
||||||
|
Select::make('delivery_schedule_id')
|
||||||
|
->label('Szállítási sablon')
|
||||||
|
->relationship('deliverySchedule', 'name')
|
||||||
|
->searchable()
|
||||||
|
->visible(fn(Get $get) => $get('override_scope') === OverrideScope::Region->value)
|
||||||
|
->required(fn(Get $get) => $get('override_scope') === OverrideScope::Region->value),
|
||||||
|
Select::make('profit_center_id')
|
||||||
|
->label('Profitcenter')
|
||||||
|
->relationship('profitCenter', 'name')
|
||||||
|
->searchable()
|
||||||
|
->visible(fn(Get $get) => $get('override_scope') === OverrideScope::ProfitCenter->value)
|
||||||
|
->required(fn(Get $get) => $get('override_scope') === OverrideScope::ProfitCenter->value),
|
||||||
|
DatePicker::make('date')
|
||||||
|
->label('Dátum')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('Y-m-d'),
|
||||||
|
Toggle::make('is_delivery_day')
|
||||||
|
->label('Szállítási nap?')
|
||||||
|
->default(true),
|
||||||
|
TextInput::make('description')
|
||||||
|
->label('Indoklás / Megjegyzés')
|
||||||
|
->maxLength(255),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliveryCalendarOverrides\Tables;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use Filament\Actions\BulkActionGroup;
|
||||||
|
use Filament\Actions\DeleteBulkAction;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ForceDeleteBulkAction;
|
||||||
|
use Filament\Actions\RestoreBulkAction;
|
||||||
|
use Filament\Tables\Columns\IconColumn;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Filters\SelectFilter;
|
||||||
|
use Filament\Tables\Filters\TrashedFilter;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
|
class DeliveryCalendarOverridesTable
|
||||||
|
{
|
||||||
|
public static function configure(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('supplier.name')
|
||||||
|
->label('Beszállító')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('override_scope')
|
||||||
|
->label('Szint')
|
||||||
|
->badge()
|
||||||
|
->formatStateUsing(fn(OverrideScope $state) => $state->label())
|
||||||
|
->color(fn(OverrideScope $state) => $state->color())
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('deliverySchedule.name')
|
||||||
|
->label('Szállítási sablon')
|
||||||
|
->placeholder('—')
|
||||||
|
->toggleable(),
|
||||||
|
TextColumn::make('profitCenter.name')
|
||||||
|
->label('Profitcenter')
|
||||||
|
->placeholder('—')
|
||||||
|
->toggleable(),
|
||||||
|
TextColumn::make('date')
|
||||||
|
->label('Dátum')
|
||||||
|
->date('Y-m-d')
|
||||||
|
->sortable(),
|
||||||
|
IconColumn::make('is_delivery_day')
|
||||||
|
->boolean()
|
||||||
|
->label('Szállítási nap'),
|
||||||
|
TextColumn::make('description')
|
||||||
|
->label('Megjegyzés')
|
||||||
|
->limit(30)
|
||||||
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
SelectFilter::make('override_scope')
|
||||||
|
->label('Felülbírálás szintje')
|
||||||
|
->options(collect(OverrideScope::cases())->mapWithKeys(
|
||||||
|
fn(OverrideScope $scope) => [$scope->value => $scope->label()]
|
||||||
|
)),
|
||||||
|
TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->recordActions([
|
||||||
|
EditAction::make(),
|
||||||
|
])
|
||||||
|
->toolbarActions([
|
||||||
|
BulkActionGroup::make([
|
||||||
|
DeleteBulkAction::make(),
|
||||||
|
ForceDeleteBulkAction::make(),
|
||||||
|
RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliverySchedules\Pages\CreateDeliverySchedule;
|
||||||
|
use App\Filament\Resources\DeliverySchedules\Pages\EditDeliverySchedule;
|
||||||
|
use App\Filament\Resources\DeliverySchedules\Pages\ListDeliverySchedules;
|
||||||
|
use App\Filament\Resources\DeliverySchedules\Schemas\DeliveryScheduleForm;
|
||||||
|
use App\Filament\Resources\DeliverySchedules\Tables\DeliverySchedulesTable;
|
||||||
|
use App\Models\DeliverySchedule;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class DeliveryScheduleResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = DeliverySchedule::class;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-calendar-days';
|
||||||
|
|
||||||
|
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Szállítási sablonok';
|
||||||
|
|
||||||
|
protected static ?string $modelLabel = 'Szállítási sablon';
|
||||||
|
|
||||||
|
protected static ?string $pluralLabel = 'Szállítási sablonok';
|
||||||
|
|
||||||
|
protected static ?string $breadcrumb = 'Szállítási sablonok';
|
||||||
|
|
||||||
|
public static function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return DeliveryScheduleForm::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return DeliverySchedulesTable::configure($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => ListDeliverySchedules::route('/'),
|
||||||
|
'create' => CreateDeliverySchedule::route('/create'),
|
||||||
|
'edit' => EditDeliverySchedule::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getRecordRouteBindingEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateDeliverySchedule extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryScheduleResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||||
|
use Filament\Actions\DeleteAction;
|
||||||
|
use Filament\Actions\ForceDeleteAction;
|
||||||
|
use Filament\Actions\RestoreAction;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditDeliverySchedule extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryScheduleResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
DeleteAction::make(),
|
||||||
|
ForceDeleteAction::make(),
|
||||||
|
RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||||
|
use Filament\Actions\CreateAction;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListDeliverySchedules extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = DeliveryScheduleResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules\Schemas;
|
||||||
|
|
||||||
|
use Filament\Schemas\Components\Grid;
|
||||||
|
use Filament\Schemas\Components\Section;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class DeliveryScheduleForm
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
Section::make('Sablon adatai')
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Grid::make(2)
|
||||||
|
->schema([
|
||||||
|
TextInput::make('name')
|
||||||
|
->label('Sablon neve')
|
||||||
|
->required()
|
||||||
|
->maxLength(255),
|
||||||
|
Toggle::make('is_active')
|
||||||
|
->label('Aktív')
|
||||||
|
->default(true),
|
||||||
|
]),
|
||||||
|
Section::make('Szállítási napok')
|
||||||
|
->columns(7)
|
||||||
|
->schema([
|
||||||
|
Toggle::make('monday')->label('Hétfő')->default(false),
|
||||||
|
Toggle::make('tuesday')->label('Kedd')->default(false),
|
||||||
|
Toggle::make('wednesday')->label('Szerda')->default(false),
|
||||||
|
Toggle::make('thursday')->label('Csütörtök')->default(false),
|
||||||
|
Toggle::make('friday')->label('Péntek')->default(false),
|
||||||
|
Toggle::make('saturday')->label('Szombat')->default(false),
|
||||||
|
Toggle::make('sunday')->label('Vasárnap')->default(false),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\DeliverySchedules\Tables;
|
||||||
|
|
||||||
|
use Filament\Actions\BulkActionGroup;
|
||||||
|
use Filament\Actions\DeleteBulkAction;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ForceDeleteBulkAction;
|
||||||
|
use Filament\Actions\RestoreBulkAction;
|
||||||
|
use Filament\Tables\Filters\TrashedFilter;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
|
class DeliverySchedulesTable
|
||||||
|
{
|
||||||
|
public static function configure(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
\Filament\Tables\Columns\TextColumn::make('name')
|
||||||
|
->label('Név')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('monday')->boolean()->label('H'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('tuesday')->boolean()->label('K'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('wednesday')->boolean()->label('Sze'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('thursday')->boolean()->label('Cs'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('friday')->boolean()->label('P'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('saturday')->boolean()->label('Szo'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('sunday')->boolean()->label('V'),
|
||||||
|
\Filament\Tables\Columns\IconColumn::make('is_active')
|
||||||
|
->boolean()
|
||||||
|
->label('Aktív')
|
||||||
|
->sortable(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->recordActions([
|
||||||
|
EditAction::make(),
|
||||||
|
])
|
||||||
|
->toolbarActions([
|
||||||
|
BulkActionGroup::make([
|
||||||
|
DeleteBulkAction::make(),
|
||||||
|
ForceDeleteBulkAction::make(),
|
||||||
|
RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateProfitCenterSupplierSchedule extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||||
|
use Filament\Actions\DeleteAction;
|
||||||
|
use Filament\Actions\ForceDeleteAction;
|
||||||
|
use Filament\Actions\RestoreAction;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditProfitCenterSupplierSchedule extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
DeleteAction::make(),
|
||||||
|
ForceDeleteAction::make(),
|
||||||
|
RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFooterWidgets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
\App\Filament\Widgets\DeliveryCalendarWidget::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||||
|
use Filament\Actions\CreateAction;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListProfitCenterSupplierSchedules extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules;
|
||||||
|
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\CreateProfitCenterSupplierSchedule;
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\EditProfitCenterSupplierSchedule;
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\ListProfitCenterSupplierSchedules;
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\Schemas\ProfitCenterSupplierScheduleForm;
|
||||||
|
use App\Filament\Resources\ProfitCenterSupplierSchedules\Tables\ProfitCenterSupplierSchedulesTable;
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class ProfitCenterSupplierScheduleResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = ProfitCenterSupplierSchedule::class;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-link';
|
||||||
|
|
||||||
|
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Profitcenter ütemezés';
|
||||||
|
|
||||||
|
protected static ?string $modelLabel = 'Profitcenter ütemezés';
|
||||||
|
|
||||||
|
protected static ?string $pluralLabel = 'Profitcenter ütemezések';
|
||||||
|
|
||||||
|
protected static ?string $breadcrumb = 'Profitcenter ütemezés';
|
||||||
|
|
||||||
|
public static function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return ProfitCenterSupplierScheduleForm::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return ProfitCenterSupplierSchedulesTable::configure($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => ListProfitCenterSupplierSchedules::route('/'),
|
||||||
|
'create' => CreateProfitCenterSupplierSchedule::route('/create'),
|
||||||
|
'edit' => EditProfitCenterSupplierSchedule::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getWidgets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
\App\Filament\Widgets\DeliveryCalendarWidget::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getRecordRouteBindingEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Schemas;
|
||||||
|
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class ProfitCenterSupplierScheduleForm
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
Select::make('profit_center_id')
|
||||||
|
->label('Profit Center')
|
||||||
|
->relationship('profitCenter', 'name')
|
||||||
|
->searchable()
|
||||||
|
->required(),
|
||||||
|
Select::make('supplier_id')
|
||||||
|
->label('Beszállító')
|
||||||
|
->relationship('supplier', 'name')
|
||||||
|
->searchable()
|
||||||
|
->required(),
|
||||||
|
Select::make('delivery_schedule_id')
|
||||||
|
->label('Szállítási sablon')
|
||||||
|
->relationship('deliverySchedule', 'name')
|
||||||
|
->searchable()
|
||||||
|
->required(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Tables;
|
||||||
|
|
||||||
|
use Filament\Actions\BulkActionGroup;
|
||||||
|
use Filament\Actions\DeleteBulkAction;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ForceDeleteBulkAction;
|
||||||
|
use Filament\Actions\RestoreBulkAction;
|
||||||
|
use Filament\Tables\Filters\TrashedFilter;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
|
class ProfitCenterSupplierSchedulesTable
|
||||||
|
{
|
||||||
|
public static function configure(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
\Filament\Tables\Columns\TextColumn::make('profitCenter.name')
|
||||||
|
->label('Profit Center')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
\Filament\Tables\Columns\TextColumn::make('supplier.name')
|
||||||
|
->label('Beszállító')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
\Filament\Tables\Columns\TextColumn::make('deliverySchedule.name')
|
||||||
|
->label('Szállítási sablon')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->recordActions([
|
||||||
|
EditAction::make(),
|
||||||
|
])
|
||||||
|
->toolbarActions([
|
||||||
|
BulkActionGroup::make([
|
||||||
|
DeleteBulkAction::make(),
|
||||||
|
ForceDeleteBulkAction::make(),
|
||||||
|
RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateWorkCalendar extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = WorkCalendarResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||||
|
use Filament\Actions\DeleteAction;
|
||||||
|
use Filament\Actions\ForceDeleteAction;
|
||||||
|
use Filament\Actions\RestoreAction;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditWorkCalendar extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = WorkCalendarResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
DeleteAction::make(),
|
||||||
|
ForceDeleteAction::make(),
|
||||||
|
RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||||
|
use Filament\Actions\CreateAction;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListWorkCalendars extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = WorkCalendarResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars\Schemas;
|
||||||
|
|
||||||
|
use App\Enums\WorkDayType;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class WorkCalendarForm
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
DatePicker::make('date')
|
||||||
|
->label('Dátum')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('Y-m-d'),
|
||||||
|
Select::make('type')
|
||||||
|
->label('Típus')
|
||||||
|
->options(WorkDayType::class)
|
||||||
|
->required(),
|
||||||
|
TextInput::make('description')
|
||||||
|
->label('Leírás')
|
||||||
|
->maxLength(255),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars\Tables;
|
||||||
|
|
||||||
|
use Filament\Actions\BulkActionGroup;
|
||||||
|
use Filament\Actions\DeleteBulkAction;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ForceDeleteBulkAction;
|
||||||
|
use Filament\Actions\RestoreBulkAction;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Filters\TrashedFilter;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
|
class WorkCalendarsTable
|
||||||
|
{
|
||||||
|
public static function configure(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('date')
|
||||||
|
->label('Dátum')
|
||||||
|
->date()
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('type')
|
||||||
|
->label('Típus')
|
||||||
|
->badge()
|
||||||
|
->formatStateUsing(fn ($state) => $state?->label())
|
||||||
|
->color(fn ($state) => $state?->color()),
|
||||||
|
TextColumn::make('description')
|
||||||
|
->label('Leírás')
|
||||||
|
->searchable(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->recordActions([
|
||||||
|
EditAction::make(),
|
||||||
|
])
|
||||||
|
->toolbarActions([
|
||||||
|
BulkActionGroup::make([
|
||||||
|
DeleteBulkAction::make(),
|
||||||
|
ForceDeleteBulkAction::make(),
|
||||||
|
RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\WorkCalendars;
|
||||||
|
|
||||||
|
use App\Filament\Resources\WorkCalendars\Pages\CreateWorkCalendar;
|
||||||
|
use App\Filament\Resources\WorkCalendars\Pages\EditWorkCalendar;
|
||||||
|
use App\Filament\Resources\WorkCalendars\Pages\ListWorkCalendars;
|
||||||
|
use App\Filament\Resources\WorkCalendars\Schemas\WorkCalendarForm;
|
||||||
|
use App\Filament\Resources\WorkCalendars\Tables\WorkCalendarsTable;
|
||||||
|
use App\Models\WorkCalendar;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class WorkCalendarResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = WorkCalendar::class;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-calendar';
|
||||||
|
|
||||||
|
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Munkanaptárak';
|
||||||
|
|
||||||
|
public static function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return WorkCalendarForm::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return WorkCalendarsTable::configure($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => ListWorkCalendars::route('/'),
|
||||||
|
'create' => CreateWorkCalendar::route('/create'),
|
||||||
|
'edit' => EditWorkCalendar::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getRecordRouteBindingEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
387
app/Filament/Widgets/DeliveryCalendarWidget.php
Normal file
387
app/Filament/Widgets/DeliveryCalendarWidget.php
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use App\Models\DeliveryCalendarOverride;
|
||||||
|
use App\Models\WorkCalendar;
|
||||||
|
use App\Enums\WorkDayType;
|
||||||
|
use App\Services\DeliveryCalendarService;
|
||||||
|
use App\Services\WorkCalendarService;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Forms\Components\Hidden;
|
||||||
|
use Filament\Forms\Components\Placeholder;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Livewire\Attributes\On;
|
||||||
|
|
||||||
|
class DeliveryCalendarWidget extends FullCalendarWidget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ProfitCenterSupplierSchedule|null
|
||||||
|
*/
|
||||||
|
public Model | int | string | null $record = null;
|
||||||
|
|
||||||
|
public ?int $supplierId = null;
|
||||||
|
|
||||||
|
public ?int $profitCenterId = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inaktív (nem választható) napok listája.
|
||||||
|
*
|
||||||
|
* @var array<string>
|
||||||
|
*/
|
||||||
|
protected array $inactiveDates = [];
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->loadRecordFromFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedSupplierId(): void
|
||||||
|
{
|
||||||
|
$this->loadRecordFromFilter();
|
||||||
|
$this->refreshRecords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedProfitCenterId(): void
|
||||||
|
{
|
||||||
|
$this->loadRecordFromFilter();
|
||||||
|
$this->refreshRecords();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[On('calendar-filter-changed')]
|
||||||
|
public function onFilterChanged(?int $supplierId, ?int $profitCenterId): void
|
||||||
|
{
|
||||||
|
$this->supplierId = $supplierId;
|
||||||
|
$this->profitCenterId = $profitCenterId;
|
||||||
|
$this->record = null;
|
||||||
|
$this->loadRecordFromFilter();
|
||||||
|
$this->refreshRecords();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadRecordFromFilter(): void
|
||||||
|
{
|
||||||
|
if ($this->record instanceof ProfitCenterSupplierSchedule) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->supplierId && $this->profitCenterId) {
|
||||||
|
$this->record = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)
|
||||||
|
->where('profit_center_id', $this->profitCenterId)
|
||||||
|
->first();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->record) {
|
||||||
|
$this->record = ProfitCenterSupplierSchedule::first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetchEvents(array $info): array
|
||||||
|
{
|
||||||
|
if (!($this->record instanceof ProfitCenterSupplierSchedule)) {
|
||||||
|
$this->loadRecordFromFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->record) {
|
||||||
|
$this->dispatch('calendar-events-done');
|
||||||
|
return $this->getDemoEvents($info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var DeliveryCalendarService $service */
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
/** @var WorkCalendarService $workService */
|
||||||
|
$workService = app(WorkCalendarService::class);
|
||||||
|
|
||||||
|
$start = Carbon::parse($info['start']);
|
||||||
|
$end = Carbon::parse($info['end']);
|
||||||
|
|
||||||
|
$events = [];
|
||||||
|
|
||||||
|
// 1. Szállítási napok – zöld háttér
|
||||||
|
$deliveryDates = $service->getAvailableDeliveryDates(
|
||||||
|
$this->record->profitCenter,
|
||||||
|
$this->record->supplier,
|
||||||
|
$start,
|
||||||
|
$end
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($deliveryDates as $date) {
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'delivery-' . $date->format('Y-m-d'),
|
||||||
|
'title' => '',
|
||||||
|
'start' => $date->format('Y-m-d'),
|
||||||
|
'end' => $date->addDay()->format('Y-m-d'),
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#4CAF50',
|
||||||
|
'extendedProps' => ['type' => 'delivery'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Munkaszüneti napok – piros háttér
|
||||||
|
$workCalendarEntries = $workService->getCalendarEntries($start, $end);
|
||||||
|
foreach ($workCalendarEntries as $entry) {
|
||||||
|
if ($entry->type === WorkDayType::Holiday) {
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'holiday-' . $entry->date->format('Y-m-d'),
|
||||||
|
'title' => '',
|
||||||
|
'start' => $entry->date->format('Y-m-d'),
|
||||||
|
'end' => $entry->date->copy()->addDay()->format('Y-m-d'),
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#EF4444',
|
||||||
|
'extendedProps' => ['type' => 'holiday'],
|
||||||
|
];
|
||||||
|
} elseif ($entry->type === WorkDayType::WorkingDay) {
|
||||||
|
// 3. Áthelyezett munkanapok – narancssárga háttér
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'transferred-' . $entry->date->format('Y-m-d'),
|
||||||
|
'title' => '',
|
||||||
|
'start' => $entry->date->format('Y-m-d'),
|
||||||
|
'end' => $entry->date->copy()->addDay()->format('Y-m-d'),
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#F59E0B',
|
||||||
|
'extendedProps' => ['type' => 'transferred'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Hétvégék – szürke háttér (inaktív napok)
|
||||||
|
$current = $start->copy();
|
||||||
|
while ($current->lte($end)) {
|
||||||
|
if ($current->isWeekend()) {
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'weekend-' . $current->format('Y-m-d'),
|
||||||
|
'title' => '',
|
||||||
|
'start' => $current->format('Y-m-d'),
|
||||||
|
'end' => $current->copy()->addDay()->format('Y-m-d'),
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#E5E7EB',
|
||||||
|
'extendedProps' => ['type' => 'inactive'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dispatch('calendar-events-done');
|
||||||
|
return $events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demo események generálása, ha nincs valós adat.
|
||||||
|
*
|
||||||
|
* @param array{start: string, end: string} $info
|
||||||
|
* @return array<int, array<string, mixed>>
|
||||||
|
*/
|
||||||
|
protected function getDemoEvents(array $info): array
|
||||||
|
{
|
||||||
|
$start = Carbon::parse($info['start']);
|
||||||
|
$end = Carbon::parse($info['end']);
|
||||||
|
$events = [];
|
||||||
|
|
||||||
|
$current = $start->copy();
|
||||||
|
while ($current->lte($end)) {
|
||||||
|
$dayOfWeek = $current->dayOfWeek;
|
||||||
|
$dayOfMonth = $current->day;
|
||||||
|
$dateStr = $current->format('Y-m-d');
|
||||||
|
$nextDateStr = $current->copy()->addDay()->format('Y-m-d');
|
||||||
|
|
||||||
|
if ($current->isWeekend()) {
|
||||||
|
// Hétvégék – szürke háttér (inaktív)
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'weekend-' . $dateStr,
|
||||||
|
'title' => '',
|
||||||
|
'start' => $dateStr,
|
||||||
|
'end' => $nextDateStr,
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#E5E7EB',
|
||||||
|
'extendedProps' => ['type' => 'inactive'],
|
||||||
|
];
|
||||||
|
} elseif ($dayOfWeek === Carbon::MONDAY || $dayOfWeek === Carbon::WEDNESDAY || $dayOfWeek === Carbon::FRIDAY) {
|
||||||
|
// Hétfő, szerda, péntek – zöld háttér (szállítási napok)
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'delivery-' . $dateStr,
|
||||||
|
'title' => '',
|
||||||
|
'start' => $dateStr,
|
||||||
|
'end' => $nextDateStr,
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#4CAF50',
|
||||||
|
'extendedProps' => ['type' => 'delivery'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Néhány speciális nap bemutatóként
|
||||||
|
if ($dayOfMonth === 15) {
|
||||||
|
// Minden hónap 15-e – narancssárga (áthelyezett munkanap)
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'special-orange-' . $dateStr,
|
||||||
|
'title' => '',
|
||||||
|
'start' => $dateStr,
|
||||||
|
'end' => $nextDateStr,
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#F59E0B',
|
||||||
|
'extendedProps' => ['type' => 'transferred'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dayOfMonth === 1) {
|
||||||
|
// Minden hónap 1-je – piros (ünnepnap)
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'special-red-' . $dateStr,
|
||||||
|
'title' => '',
|
||||||
|
'start' => $dateStr,
|
||||||
|
'end' => $nextDateStr,
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#EF4444',
|
||||||
|
'extendedProps' => ['type' => 'holiday'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dayOfMonth === 10 || $dayOfMonth === 20) {
|
||||||
|
// 10-e és 20-a – kék (megrendelési határidő)
|
||||||
|
$events[] = [
|
||||||
|
'id' => 'special-blue-' . $dateStr,
|
||||||
|
'title' => '',
|
||||||
|
'start' => $dateStr,
|
||||||
|
'end' => $nextDateStr,
|
||||||
|
'allDay' => true,
|
||||||
|
'display' => 'background',
|
||||||
|
'backgroundColor' => '#3B82F6',
|
||||||
|
'extendedProps' => ['type' => 'deadline'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $view, ?array $resource): void
|
||||||
|
{
|
||||||
|
$this->mountAction('manageOverride', [
|
||||||
|
'date' => Carbon::parse($start)->format('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEventClick(array $event): void
|
||||||
|
{
|
||||||
|
$date = data_get($event, 'start');
|
||||||
|
|
||||||
|
if (!$date) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->mountAction('manageOverride', [
|
||||||
|
'date' => Carbon::parse($date)->format('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function headerActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Action::make('manageOverride')
|
||||||
|
->label('Felülbírálás kezelése')
|
||||||
|
->modalHeading(fn (array $arguments) => "Szállítás felülbírálása" . (isset($arguments['date']) ? ": " . $arguments['date'] : ""))
|
||||||
|
->form(fn (array $arguments) => [
|
||||||
|
Placeholder::make('info')
|
||||||
|
->hiddenLabel()
|
||||||
|
->content('A háttérben látható naptárban egyszerre több hónapot is áttekinthet. Itt egy konkrét nap módosítását végezheti el.'),
|
||||||
|
\Filament\Forms\Components\DatePicker::make('date')
|
||||||
|
->label('Dátum')
|
||||||
|
->required()
|
||||||
|
->default($arguments['date'] ?? null)
|
||||||
|
->disabled(fn () => isset($arguments['date']))
|
||||||
|
->dehydrated(),
|
||||||
|
Toggle::make('is_delivery_day')
|
||||||
|
->label('Szállítási nap?')
|
||||||
|
->default(function () use ($arguments) {
|
||||||
|
$date = $arguments['date'] ?? null;
|
||||||
|
if (!$date) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$override = DeliveryCalendarOverride::where('supplier_id', $this->record->supplier_id)
|
||||||
|
->whereDate('date', $date)
|
||||||
|
->where('override_scope', OverrideScope::ProfitCenter->value)
|
||||||
|
->where('profit_center_id', $this->record->profit_center_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($override) {
|
||||||
|
return $override->is_delivery_day;
|
||||||
|
}
|
||||||
|
|
||||||
|
return app(DeliveryCalendarService::class)->isDeliveryDay(
|
||||||
|
$this->record->profitCenter,
|
||||||
|
$this->record->supplier,
|
||||||
|
Carbon::parse($date)
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
TextInput::make('description')
|
||||||
|
->label('Indoklás / Megjegyzés')
|
||||||
|
->default(fn () => isset($arguments['date'])
|
||||||
|
? DeliveryCalendarOverride::where('supplier_id', $this->record->supplier_id)
|
||||||
|
->whereDate('date', $arguments['date'])
|
||||||
|
->where('override_scope', OverrideScope::ProfitCenter->value)
|
||||||
|
->where('profit_center_id', $this->record->profit_center_id)
|
||||||
|
->first()?->description
|
||||||
|
: null
|
||||||
|
),
|
||||||
|
])
|
||||||
|
->action(function (array $data) {
|
||||||
|
DeliveryCalendarOverride::updateOrCreate(
|
||||||
|
[
|
||||||
|
'supplier_id' => $this->record->supplier_id,
|
||||||
|
'override_scope' => OverrideScope::ProfitCenter->value,
|
||||||
|
'profit_center_id' => $this->record->profit_center_id,
|
||||||
|
'date' => $data['date'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'is_delivery_day' => (bool) $data['is_delivery_day'],
|
||||||
|
'description' => $data['description'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->refreshRecords();
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function config(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'initialView' => 'multiMonthYear',
|
||||||
|
'views' => [
|
||||||
|
'multiMonthYear' => [
|
||||||
|
'duration' => ['months' => 6],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'multiMonthMaxColumns' => 6,
|
||||||
|
'headerToolbar' => [
|
||||||
|
'left' => 'prev,next today',
|
||||||
|
'center' => 'title',
|
||||||
|
'right' => 'multiMonthYear',
|
||||||
|
],
|
||||||
|
'locale' => 'hu',
|
||||||
|
'firstDay' => 1,
|
||||||
|
'height' => 'auto',
|
||||||
|
'contentHeight' => 'auto',
|
||||||
|
'selectable' => true,
|
||||||
|
'editable' => false,
|
||||||
|
'dayMaxEvents' => false,
|
||||||
|
'fixedWeekCount' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
35
app/Models/DeliveryCalendarOverride.php
Normal file
35
app/Models/DeliveryCalendarOverride.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class DeliveryCalendarOverride extends BaseAuditable
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'date' => 'date',
|
||||||
|
'is_delivery_day' => 'boolean',
|
||||||
|
'override_scope' => OverrideScope::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function supplier(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Supplier::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function profitCenter(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ProfitCenter::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deliverySchedule(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(DeliverySchedule::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
app/Models/DeliverySchedule.php
Normal file
23
app/Models/DeliverySchedule.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class DeliverySchedule extends BaseAuditable
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'monday' => 'boolean',
|
||||||
|
'tuesday' => 'boolean',
|
||||||
|
'wednesday' => 'boolean',
|
||||||
|
'thursday' => 'boolean',
|
||||||
|
'friday' => 'boolean',
|
||||||
|
'saturday' => 'boolean',
|
||||||
|
'sunday' => 'boolean',
|
||||||
|
'is_active' => 'boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
28
app/Models/ProfitCenterSupplierSchedule.php
Normal file
28
app/Models/ProfitCenterSupplierSchedule.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class ProfitCenterSupplierSchedule extends BaseAuditable
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
public function profitCenter(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ProfitCenter::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supplier(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Supplier::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deliverySchedule(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(DeliverySchedule::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -60,6 +60,8 @@ public function boot(): void
|
|||||||
});
|
});
|
||||||
|
|
||||||
\Livewire\Livewire::component('app.filament.pages.price-list-processor', \App\Filament\Pages\PriceListProcessor::class);
|
\Livewire\Livewire::component('app.filament.pages.price-list-processor', \App\Filament\Pages\PriceListProcessor::class);
|
||||||
|
\Livewire\Livewire::component('app.filament.pages.calendar-test', \App\Filament\Pages\CalendarTest::class);
|
||||||
|
\Livewire\Livewire::component('app.filament.widgets.delivery-calendar-widget', \App\Filament\Widgets\DeliveryCalendarWidget::class);
|
||||||
/*
|
/*
|
||||||
\Livewire\Livewire::component('filament.livewire.notifications', \Filament\Livewire\Notifications::class);
|
\Livewire\Livewire::component('filament.livewire.notifications', \Filament\Livewire\Notifications::class);
|
||||||
\Livewire\Livewire::component('filament.livewire.database-notifications', \Filament\Livewire\DatabaseNotifications::class);
|
\Livewire\Livewire::component('filament.livewire.database-notifications', \Filament\Livewire\DatabaseNotifications::class);
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
use Filament\Http\Middleware\AuthenticateSession;
|
use Filament\Http\Middleware\AuthenticateSession;
|
||||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||||
|
use Saade\FilamentFullCalendar\FilamentFullCalendarPlugin;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
use Filament\PanelProvider;
|
use Filament\PanelProvider;
|
||||||
use Filament\Support\Colors\Color;
|
use Filament\Support\Colors\Color;
|
||||||
@ -61,6 +62,7 @@ public function panel(Panel $panel): Panel
|
|||||||
->widgets([
|
->widgets([
|
||||||
AccountWidget::class,
|
AccountWidget::class,
|
||||||
FilamentInfoWidget::class,
|
FilamentInfoWidget::class,
|
||||||
|
\App\Filament\Widgets\DeliveryCalendarWidget::class,
|
||||||
])
|
])
|
||||||
->middleware([
|
->middleware([
|
||||||
EncryptCookies::class,
|
EncryptCookies::class,
|
||||||
@ -78,6 +80,11 @@ public function panel(Panel $panel): Panel
|
|||||||
])
|
])
|
||||||
->darkMode(false)
|
->darkMode(false)
|
||||||
->topNavigation()
|
->topNavigation()
|
||||||
|
->plugins([
|
||||||
|
FilamentFullCalendarPlugin::make()->plugins(['multiMonth'])
|
||||||
|
->selectable()
|
||||||
|
->editable(),
|
||||||
|
])
|
||||||
->breadcrumbs(false)
|
->breadcrumbs(false)
|
||||||
->navigation(false)
|
->navigation(false)
|
||||||
->renderHook(
|
->renderHook(
|
||||||
|
|||||||
109
app/Services/DeliveryCalendarService.php
Normal file
109
app/Services/DeliveryCalendarService.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use App\Models\DeliveryCalendarOverride;
|
||||||
|
use App\Models\ProfitCenter;
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use App\Models\Supplier;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class DeliveryCalendarService extends ServiceBase
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected WorkCalendarService $workCalendarService
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eldönti, hogy egy adott Profit Center, Beszállító és Dátum kombináció esetén van-e szállítás.
|
||||||
|
*
|
||||||
|
* A felülbírálás kiértékelése 3 szinten történik (legspecifikusabbtól az általánosig):
|
||||||
|
* 1. Profitcenter-specifikus override (csak erre az 1 PC-re)
|
||||||
|
* 2. Régió-specifikus override (a PC városához/régiójához tartozó)
|
||||||
|
* 3. Általános override (az összes PC-re vonatkozó)
|
||||||
|
* Ha egyetlen szinten sem található override, folytatódik a normál kiértékelés.
|
||||||
|
*/
|
||||||
|
public function isDeliveryDay(ProfitCenter $pc, Supplier $supplier, Carbon $date): bool
|
||||||
|
{
|
||||||
|
$date = $date->startOfDay();
|
||||||
|
|
||||||
|
// 1. Prioritás: Profitcenter-specifikus felülbírálás
|
||||||
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
||||||
|
->whereDate('date', $date)
|
||||||
|
->where('override_scope', OverrideScope::ProfitCenter->value)
|
||||||
|
->where('profit_center_id', $pc->id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($override) {
|
||||||
|
return $override->is_delivery_day;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PC-hez rendelt szállítási sablon lekérése (2. és 5. prioritáshoz egyaránt szükséges)
|
||||||
|
$assignment = ProfitCenterSupplierSchedule::where('profit_center_id', $pc->id)
|
||||||
|
->where('supplier_id', $supplier->id)
|
||||||
|
->with('deliverySchedule')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// 2. Prioritás: DeliverySchedule-specifikus felülbírálás (a PC-hez rendelt szállítási sablon alapján)
|
||||||
|
if ($assignment && $assignment->delivery_schedule_id) {
|
||||||
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
||||||
|
->whereDate('date', $date)
|
||||||
|
->where('override_scope', OverrideScope::Region->value)
|
||||||
|
->where('delivery_schedule_id', $assignment->delivery_schedule_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($override) {
|
||||||
|
return $override->is_delivery_day;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prioritás: Általános felülbírálás (minden PC-re vonatkozik)
|
||||||
|
$override = DeliveryCalendarOverride::where('supplier_id', $supplier->id)
|
||||||
|
->whereDate('date', $date)
|
||||||
|
->where('override_scope', OverrideScope::General->value)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($override) {
|
||||||
|
return $override->is_delivery_day;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Prioritás: Hivatalos ünnepnap (WorkCalendar)
|
||||||
|
// Ha aznap nem hivatalos munkanap van, akkor nincs szállítás (kivéve ha az 1-3. pont felülbírálta).
|
||||||
|
if (! $this->workCalendarService->isWorkDay($date)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Prioritás: Heti sablon (Schedule)
|
||||||
|
if (! $assignment || ! $assignment->deliverySchedule || ! $assignment->deliverySchedule->is_active) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dayOfWeek = strtolower($date->format('l')); // 'monday', 'tuesday', etc.
|
||||||
|
|
||||||
|
return (bool) $assignment->deliverySchedule->{$dayOfWeek};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visszaadja az elérhető szállítási napokat egy adott időszakban.
|
||||||
|
*
|
||||||
|
* @return Collection<Carbon>
|
||||||
|
*/
|
||||||
|
public function getAvailableDeliveryDates(ProfitCenter $pc, Supplier $supplier, Carbon $start, Carbon $end): Collection
|
||||||
|
{
|
||||||
|
$dates = collect();
|
||||||
|
$current = $start->copy()->startOfDay();
|
||||||
|
$end = $end->copy()->startOfDay();
|
||||||
|
|
||||||
|
while ($current <= $end) {
|
||||||
|
if ($this->isDeliveryDay($pc, $supplier, $current)) {
|
||||||
|
$dates->push($current->copy());
|
||||||
|
}
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dates;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@
|
|||||||
"bensampo/laravel-enum": "^6.12",
|
"bensampo/laravel-enum": "^6.12",
|
||||||
"filament/filament": "4.0@dev",
|
"filament/filament": "4.0@dev",
|
||||||
"flugger/laravel-responder": "^3.5",
|
"flugger/laravel-responder": "^3.5",
|
||||||
|
"guava/calendar": "2.0",
|
||||||
"jeroenzwart/laravel-csv-seeder": "^1.5",
|
"jeroenzwart/laravel-csv-seeder": "^1.5",
|
||||||
"kalnoy/nestedset": "^6.0",
|
"kalnoy/nestedset": "^6.0",
|
||||||
"laravel-json-api/laravel": "^5.1",
|
"laravel-json-api/laravel": "^5.1",
|
||||||
@ -23,6 +24,7 @@
|
|||||||
"livewire/livewire": "^3.7",
|
"livewire/livewire": "^3.7",
|
||||||
"maatwebsite/excel": "^3.1",
|
"maatwebsite/excel": "^3.1",
|
||||||
"rap2hpoutre/fast-excel": "^5.6",
|
"rap2hpoutre/fast-excel": "^5.6",
|
||||||
|
"saade/filament-fullcalendar": "4.x-dev",
|
||||||
"santigarcor/laratrust": "^8.4",
|
"santigarcor/laratrust": "^8.4",
|
||||||
"yajra/laravel-datatables": "^12.0",
|
"yajra/laravel-datatables": "^12.0",
|
||||||
"yajra/laravel-datatables-oracle": "^12.0"
|
"yajra/laravel-datatables-oracle": "^12.0"
|
||||||
|
|||||||
160
composer.lock
generated
160
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "ec185cb1fddcfd26057ef51f712c4c19",
|
"content-hash": "05f09a61a6722503ee896c57c530bf6b",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "ahmedhakeem/extra",
|
"name": "ahmedhakeem/extra",
|
||||||
@ -2888,6 +2888,86 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-12-27T19:43:20+00:00"
|
"time": "2025-12-27T19:43:20+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "guava/calendar",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/GuavaCZ/calendar.git",
|
||||||
|
"reference": "3ef87e6a754bd5a7d65cd387bfc98c58682110ae"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/GuavaCZ/calendar/zipball/3ef87e6a754bd5a7d65cd387bfc98c58682110ae",
|
||||||
|
"reference": "3ef87e6a754bd5a7d65cd387bfc98c58682110ae",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"filament/filament": "^4.0-beta",
|
||||||
|
"illuminate/contracts": "^11.0|^12.0",
|
||||||
|
"php": "^8.1|^8.2",
|
||||||
|
"spatie/laravel-package-tools": "^1.14.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"laravel/pint": "^1.0",
|
||||||
|
"nunomaduro/collision": "^7.8|^8.0",
|
||||||
|
"nunomaduro/larastan": "^2.0.1",
|
||||||
|
"orchestra/testbench": "^9.0|^10.0",
|
||||||
|
"pestphp/pest": "^2.36",
|
||||||
|
"pestphp/pest-plugin": "^2.1.1",
|
||||||
|
"pestphp/pest-plugin-arch": "^2.0",
|
||||||
|
"pestphp/pest-plugin-laravel": "^2.0",
|
||||||
|
"phpstan/extension-installer": "^1.1",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Guava\\Calendar\\CalendarServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Guava\\Calendar\\": "src/",
|
||||||
|
"Guava\\Calendar\\Database\\Factories\\": "database/factories/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Lukas Frey",
|
||||||
|
"email": "lukas.frey@guava.cz",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Adds support for vkurko/calendar to Filament PHP.",
|
||||||
|
"homepage": "https://github.com/GuavaCZ/calendar",
|
||||||
|
"keywords": [
|
||||||
|
"Guava",
|
||||||
|
"calendar",
|
||||||
|
"laravel"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/GuavaCZ/calendar/issues",
|
||||||
|
"source": "https://github.com/GuavaCZ/calendar/tree/2.0.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/GuavaCZ",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-08-17T13:52:37+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "7.10.0",
|
"version": "7.10.0",
|
||||||
@ -8473,6 +8553,81 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-02-25T09:09:36+00:00"
|
"time": "2025-02-25T09:09:36+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "saade/filament-fullcalendar",
|
||||||
|
"version": "4.x-dev",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/saade/filament-fullcalendar.git",
|
||||||
|
"reference": "191d69b9d568a9fdfd3f3586428d8cf5a940fd50"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/saade/filament-fullcalendar/zipball/191d69b9d568a9fdfd3f3586428d8cf5a940fd50",
|
||||||
|
"reference": "191d69b9d568a9fdfd3f3586428d8cf5a940fd50",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"filament/filament": "^4.0|^5.0",
|
||||||
|
"illuminate/contracts": "^10.0|^11.0|^12.0|^13.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"spatie/laravel-package-tools": "^1.92.7"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"nunomaduro/collision": "^7.0|^8.0",
|
||||||
|
"nunomaduro/larastan": "^2.0",
|
||||||
|
"phpstan/extension-installer": "^1.1",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.0|^2.0",
|
||||||
|
"spatie/laravel-ray": "^1.26"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Saade\\FilamentFullCalendar\\FilamentFullCalendarServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Saade\\FilamentFullCalendar\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Saade",
|
||||||
|
"email": "saade@outlook.com.br",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The Most Popular JavaScript Calendar integrated with Filament 💛",
|
||||||
|
"homepage": "https://github.com/saade/filament-fullcalendar",
|
||||||
|
"keywords": [
|
||||||
|
"filament-fullcalendar",
|
||||||
|
"laravel",
|
||||||
|
"saade"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/saade/filament-fullcalendar/issues",
|
||||||
|
"source": "https://github.com/saade/filament-fullcalendar/tree/4.x"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/saade",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-04-14T23:35:46+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sabberworm/php-css-parser",
|
"name": "sabberworm/php-css-parser",
|
||||||
"version": "v9.1.0",
|
"version": "v9.1.0",
|
||||||
@ -17099,7 +17254,8 @@
|
|||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"ahmedhakeem/extra": 20,
|
"ahmedhakeem/extra": 20,
|
||||||
"filament/filament": 20
|
"filament/filament": 20,
|
||||||
|
"saade/filament-fullcalendar": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
|
|||||||
59
database/factories/DeliveryCalendarOverrideFactory.php
Normal file
59
database/factories/DeliveryCalendarOverrideFactory.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use App\Models\DeliveryCalendarOverride;
|
||||||
|
use App\Models\DeliverySchedule;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Factory<DeliveryCalendarOverride>
|
||||||
|
*/
|
||||||
|
class DeliveryCalendarOverrideFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'supplier_id' => \App\Models\Supplier::factory(),
|
||||||
|
'override_scope' => OverrideScope::General,
|
||||||
|
'delivery_schedule_id' => null,
|
||||||
|
'profit_center_id' => null,
|
||||||
|
'date' => $this->faker->date(),
|
||||||
|
'is_delivery_day' => $this->faker->boolean(),
|
||||||
|
'description' => $this->faker->sentence(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function general(): static
|
||||||
|
{
|
||||||
|
return $this->state([
|
||||||
|
'override_scope' => OverrideScope::General,
|
||||||
|
'delivery_schedule_id' => null,
|
||||||
|
'profit_center_id' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forDeliverySchedule(DeliverySchedule $schedule): static
|
||||||
|
{
|
||||||
|
return $this->state([
|
||||||
|
'override_scope' => OverrideScope::Region,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
'profit_center_id' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forProfitCenter(\App\Models\ProfitCenter $profitCenter): static
|
||||||
|
{
|
||||||
|
return $this->state([
|
||||||
|
'override_scope' => OverrideScope::ProfitCenter,
|
||||||
|
'delivery_schedule_id' => null,
|
||||||
|
'profit_center_id' => $profitCenter->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
database/factories/DeliveryScheduleFactory.php
Normal file
32
database/factories/DeliveryScheduleFactory.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\DeliverySchedule;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Factory<DeliverySchedule>
|
||||||
|
*/
|
||||||
|
class DeliveryScheduleFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->faker->word(),
|
||||||
|
'monday' => false,
|
||||||
|
'tuesday' => false,
|
||||||
|
'wednesday' => false,
|
||||||
|
'thursday' => false,
|
||||||
|
'friday' => false,
|
||||||
|
'saturday' => false,
|
||||||
|
'sunday' => false,
|
||||||
|
'is_active' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
29
database/factories/ProfitCenterFactory.php
Normal file
29
database/factories/ProfitCenterFactory.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\ProfitCenter;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Factory<ProfitCenter>
|
||||||
|
*/
|
||||||
|
class ProfitCenterFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => fake()->name(),
|
||||||
|
'hooreycaId' => fake()->uuid(),
|
||||||
|
'postCode' => '1234',
|
||||||
|
'city' => fake()->city(),
|
||||||
|
'street' => fake()->streetAddress(),
|
||||||
|
'note' => fake()->sentence(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
26
database/factories/ProfitCenterSupplierScheduleFactory.php
Normal file
26
database/factories/ProfitCenterSupplierScheduleFactory.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Factory<ProfitCenterSupplierSchedule>
|
||||||
|
*/
|
||||||
|
class ProfitCenterSupplierScheduleFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'profit_center_id' => \App\Models\ProfitCenter::factory(),
|
||||||
|
'supplier_id' => \App\Models\Supplier::factory(),
|
||||||
|
'delivery_schedule_id' => \App\Models\DeliverySchedule::factory(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,13 @@ class SupplierFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
//
|
'name' => fake()->company(),
|
||||||
|
'hooreycaId' => fake()->uuid(),
|
||||||
|
'nameId' => fake()->word(),
|
||||||
|
'orderEmail' => fake()->safeEmail(),
|
||||||
|
'address' => fake()->address(),
|
||||||
|
'phone' => fake()->phoneNumber(),
|
||||||
|
'note' => fake()->sentence(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('delivery_schedules', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
$table->boolean('monday')->default(false);
|
||||||
|
$table->boolean('tuesday')->default(false);
|
||||||
|
$table->boolean('wednesday')->default(false);
|
||||||
|
$table->boolean('thursday')->default(false);
|
||||||
|
$table->boolean('friday')->default(false);
|
||||||
|
$table->boolean('saturday')->default(false);
|
||||||
|
$table->boolean('sunday')->default(false);
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->userIdFields();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('delivery_schedules');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('profit_center_supplier_schedules', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('profit_center_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->foreignId('supplier_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->foreignId('delivery_schedule_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->userIdFields();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('profit_center_supplier_schedules');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('delivery_calendar_overrides', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('supplier_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->date('date');
|
||||||
|
$table->boolean('is_delivery_day');
|
||||||
|
$table->string('description')->nullable();
|
||||||
|
$table->userIdFields();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('delivery_calendar_overrides');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('delivery_calendar_overrides', function (Blueprint $table) {
|
||||||
|
$table->string('override_scope')->default('general')->after('supplier_id');
|
||||||
|
$table->string('region')->nullable()->after('override_scope');
|
||||||
|
$table->foreignId('profit_center_id')->nullable()->constrained()->nullOnDelete()->after('region');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('delivery_calendar_overrides', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['profit_center_id']);
|
||||||
|
$table->dropColumn(['override_scope', 'region', 'profit_center_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('delivery_calendar_overrides', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('region');
|
||||||
|
$table->foreignId('delivery_schedule_id')->nullable()->constrained()->nullOnDelete()->after('override_scope');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('delivery_calendar_overrides', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['delivery_schedule_id']);
|
||||||
|
$table->dropColumn('delivery_schedule_id');
|
||||||
|
$table->string('region')->nullable()->after('override_scope');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
BIN
git_log_nav.txt
Normal file
BIN
git_log_nav.txt
Normal file
Binary file not shown.
BIN
public/images/icons/ico_timetable1.png
Normal file
BIN
public/images/icons/ico_timetable1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
BIN
public/images/icons/ico_timetable2.png
Normal file
BIN
public/images/icons/ico_timetable2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
BIN
public/images/icons/ico_timetable3.png
Normal file
BIN
public/images/icons/ico_timetable3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
File diff suppressed because one or more lines are too long
@ -0,0 +1,6 @@
|
|||||||
|
function d({getContextMenuActionsUsing:o}){return{open:!1,size:{width:0,height:0},position:{x:0,y:0},mountData:{},context:null,actions:[],isLoading:!1,onCloseCallback:null,menu:{"x-show"(){return this.open},"x-bind:style"(){return`
|
||||||
|
position: absolute;
|
||||||
|
z-index: 40;
|
||||||
|
top: ${this.position.y}px;
|
||||||
|
left: ${this.position.x}px;
|
||||||
|
`},"x-on:click.away"(){this.closeMenu()}},init:async function(){let t=this.$el.querySelector('[x-bind="menu"]');this.size={width:t.offsetWidth,height:t.offsetHeight},this.$el.addEventListener("calendar--open-menu",e=>this.openMenu(e))},loadActions:async function(t,e={}){this.isLoading=!0,this.actions=[],o(t,e).then(n=>{this.actions=n}).finally(()=>this.isLoading=!1)},openMenu:async function(t,e=null){this.$nextTick(()=>{let n=t.clientX,i=t.clientY,s=t.pageX,c=t.pageY,a=n+this.size.width>window.innerWidth?n+this.size.width-window.innerWidth:0,h=i+this.size.height>window.innerHeight?i+this.size.height-window.innerHeight:0;if(this.position.x=s-a,this.position.y=c-h,this.open=!0,e){let l=e.getAttribute("data-event-id");document.querySelectorAll(`.ec-event[data-event-id="${l}"]`).forEach(u=>u.classList.add("gu-context-menu-open"))}})},closeMenu:function(){this.open=!1,document.querySelectorAll(".ec-event.gu-context-menu-open").forEach(t=>t.classList.remove("gu-context-menu-open")),this.onCloseCallback&&this.onCloseCallback()}}}export{d as default};
|
||||||
1
public/js/guava/calendar/components/calendar-event.js
Normal file
1
public/js/guava/calendar/components/calendar-event.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
function o({event:t,timeText:r,view:d,hasContextMenu:n}){return{event:t,contextMenu:null,init:function(){n&&this.initializeContextMenu(),this.$el.setAttribute("data-event-id",t.id),this.$el.addEventListener("mouseenter",()=>{document.querySelectorAll(`.ec-event[data-event-id="${t.id}"]`).forEach(e=>{e.classList.add("gu-hover")})}),this.$el.addEventListener("mouseleave",()=>{document.querySelectorAll(`.ec-event[data-event-id="${t.id}"]`).forEach(e=>{e.classList.remove("gu-hover")})})},initializeContextMenu:function(){let e=document.querySelector("[calendar-context-menu]");this.contextMenu=Alpine.$data(e)},onClick:function(e){if(e.event.extendedProps.url){window.open(this.event.extendedProps.url,this.event.extendedProps.url_target??"_blank");return}let i={event:e.event,view:e.view,tzOffset:-new Date().getTimezoneOffset()};if(n){this.contextMenu.loadActions("eventClick",i),this.contextMenu.openMenu(e.jsEvent,this.$el);return}this.$wire.onEventClickJs(i)}}}export{o as default};
|
||||||
6
public/js/guava/calendar/components/calendar.js
Normal file
6
public/js/guava/calendar/components/calendar.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
function M({view:c="dayGridMonth",locale:v="en",firstDay:f=1,dayMaxEvents:w=!1,eventContent:l=null,eventClickEnabled:m=!1,eventDragEnabled:i=!1,eventResizeEnabled:d=!1,noEventsClickEnabled:h=!1,dateClickEnabled:D=!1,dateSelectEnabled:u=!1,datesSetEnabled:E=!1,viewDidMountEnabled:O=!1,eventAllUpdatedEnabled:S=!1,hasDateClickContextMenu:p=null,hasDateSelectContextMenu:z=null,hasEventClickContextMenu:g=null,hasNoEventsClickContextMenu:x=null,resources:$=null,resourceLabelContent:r=null,theme:o=null,options:C={},eventAssetUrl:y}){return{init:function(){let n=this.mountCalendar();window.addEventListener("calendar--refresh",()=>{n.refetchEvents()}),this.$wire.on("calendar--set",e=>{n.setOption(e.key,e.value)})},mountCalendar:function(){return EventCalendar.create(this.$el.querySelector("[data-calendar]"),this.getSettings())},getSettings:function(){let n={view:c,locale:v,firstDay:f,dayMaxEvents:w,eventSources:[{events:e=>this.$wire.getEventsJs({...e,tzOffset:-new Date().getTimezoneOffset()})}],resources:$,selectable:u,eventStartEditable:i,eventDurationEditable:d};return l!==null&&(n.eventContent=e=>{let t=e.event.extendedProps.model,s=l[t]??l._default;if(s!==void 0)return{html:s}}),r!==null&&(n.resourceLabelContent=e=>{let t=e.resource.extendedProps.model,s=r[t]??r._default;if(s!==void 0)return{html:this.wrapContent(s,e)}}),D&&(n.dateClick=e=>{let t={date:e.date,dateStr:e.dateStr,allDay:e.allDay,view:e.view,resource:e.resource,tzOffset:-new Date().getTimezoneOffset()};p?this.openContextMenu(e.jsEvent,t,"dateClick"):this.$wire.onDateClickJs(t)}),u&&(n.select=e=>{let t={start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,allDay:e.allDay,view:e.view,resource:e.resource,tzOffset:-new Date().getTimezoneOffset()};z?this.openContextMenu(e.jsEvent,t,"dateSelect"):this.$wire.onDateSelectJs(t)}),E&&(n.datesSet=e=>{this.$wire.onDatesSetJs({start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,view:e.view,tzOffset:-new Date().getTimezoneOffset()})}),m&&(n.eventClick=e=>{Alpine.$data(e.el).onClick(e)}),n.eventResize=async e=>{let t=e.event.durationEditable,s=d;t!==void 0&&(s=t),s&&await this.$wire.onEventResizeJs({event:e.event,oldEvent:e.oldEvent,endDelta:e.endDelta,view:e.view,tzOffset:-new Date().getTimezoneOffset()}).then(a=>{a===!1&&e.revert()})},n.eventDrop=async e=>{let t=e.event.startEditable,s=i;t!==void 0&&(s=t),s&&await this.$wire.onEventDropJs({event:e.event,oldEvent:e.oldEvent,oldResource:e.oldResource,newResource:e.newResource,delta:e.delta,view:e.view,tzOffset:-new Date().getTimezoneOffset()}).then(a=>{a===!1&&e.revert()})},n.eventDidMount=e=>{e.el.setAttribute("x-load"),e.el.setAttribute("x-load-src",y),e.el.setAttribute("x-data",`calendarEvent({
|
||||||
|
event: ${JSON.stringify(e.event)},
|
||||||
|
timeText: "${e.timeText}",
|
||||||
|
view: ${JSON.stringify(e.view)},
|
||||||
|
hasContextMenu: ${g},
|
||||||
|
})`)},h&&(n.noEventsClick=e=>{let t={view:e.view,tzOffset:-new Date().getTimezoneOffset()};x?this.openContextMenu(e.jsEvent,t,"noEventsClick"):this.$wire.onNoEventsClickJs(t)}),O&&(n.viewDidMount=e=>{this.$wire.onViewDidMountJs({view:e.view,tzOffset:-new Date().getTimezoneOffset()})}),S&&(n.eventAllUpdated=e=>{this.$wire.onEventAllUpdatedJs({view:e.view,tzOffset:-new Date().getTimezoneOffset()})}),o&&(n.theme=function(e){return{...e,...o}}),{...n,...C}},wrapContent:function(n,e){let t=document.createElement("div");return t.innerHTML=n,t.setAttribute("x-data",JSON.stringify(e)),t.classList.add("w-full"),t.outerHTML},openContextMenu:function(n,e,t){let s=document.querySelector("[calendar-context-menu]"),a=Alpine.$data(s);a.loadActions(t,e),a.openMenu(n)}}}export{M as default};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"/js/app.js": "/js/app.js?id=8eebbb7cc03522e40f2a774f36c0d6b0",
|
"/js/app.js": "/js/app.js?id=8eebbb7cc03522e40f2a774f36c0d6b0",
|
||||||
"/js/admin.js": "/js/admin.js?id=d5bb7fcc276f07bda341f6451c61fd6f",
|
"/js/admin.js": "/js/admin.js?id=d76685d0f99353516174c9e2fe1b0f53",
|
||||||
"/js/module.js": "/js/module.js?id=b8f30ac658c1296e35f9210683fe57c9",
|
"/js/module.js": "/js/module.js?id=32c2ae0c49eb610fe11a304d1ca623f1",
|
||||||
"/js/components.js": "/js/components.js?id=34668cee8ac371c98657beffcff579b8",
|
"/js/components.js": "/js/components.js?id=34668cee8ac371c98657beffcff579b8",
|
||||||
"/css/app.css": "/css/app.css?id=11474616a7ef31af1acf43a25d65f4b6",
|
"/css/app.css": "/css/app.css?id=11474616a7ef31af1acf43a25d65f4b6",
|
||||||
"/fonts/vendor/bootstrap-icons/bootstrap-icons.woff2?92ea18a81d737146ff044ddb52010366": "/fonts/vendor/bootstrap-icons/bootstrap-icons.woff2?92ea18a81d737146ff044ddb52010366?id=9ad5aa740d7d5e6a0191b309b9b1986c",
|
"/fonts/vendor/bootstrap-icons/bootstrap-icons.woff2?92ea18a81d737146ff044ddb52010366": "/fonts/vendor/bootstrap-icons/bootstrap-icons.woff2?92ea18a81d737146ff044ddb52010366?id=9ad5aa740d7d5e6a0191b309b9b1986c",
|
||||||
|
|||||||
@ -13,6 +13,13 @@
|
|||||||
['name' => 'statistics', 'displayName' => 'Statisztikák', 'icon' => 'kimutatasok', 'link' => route('legacy.show', ['path' => 'admin/statistics']), 'roles' => ['root','developer','admin']],
|
['name' => 'statistics', 'displayName' => 'Statisztikák', 'icon' => 'kimutatasok', 'link' => route('legacy.show', ['path' => 'admin/statistics']), 'roles' => ['root','developer','admin']],
|
||||||
['name' => 'export', 'displayName' => 'Export', 'icon' => 'export', 'link' => route('legacy.show', ['path' => 'admin/export']), 'roles' => ['root','developer','admin']],
|
['name' => 'export', 'displayName' => 'Export', 'icon' => 'export', 'link' => route('legacy.show', ['path' => 'admin/export']), 'roles' => ['root','developer','admin']],
|
||||||
['name' => 'priceListProcessor', 'displayName' => 'Árlista feldolgozó', 'icon' => 'price_list', 'link' => '/admin/pricelist-files', 'roles' => ['root','developer','admin']],
|
['name' => 'priceListProcessor', 'displayName' => 'Árlista feldolgozó', 'icon' => 'price_list', 'link' => '/admin/pricelist-files', 'roles' => ['root','developer','admin']],
|
||||||
|
['name' => 'delivery', 'displayName' => 'Szállítás', 'icon' => 'timetable3', 'roles' => ['root','admin','developer'], 'children' => [
|
||||||
|
['displayName' => 'Szállítási sablonok', 'link' => \App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource::getUrl()],
|
||||||
|
['displayName' => 'Beszállítói felülbírálások', 'link' => \App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource::getUrl()],
|
||||||
|
['displayName' => 'Profitcenter ütemezés', 'link' => \App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource::getUrl()],
|
||||||
|
['displayName' => 'Munkanaptárak', 'link' => \App\Filament\Resources\WorkCalendars\WorkCalendarResource::getUrl()],
|
||||||
|
]],
|
||||||
|
['name' => 'calendarTest', 'displayName' => 'Naptár Teszt', 'icon' => 'idopontok', 'link' => \App\Filament\Pages\CalendarTest::getUrl(), 'roles' => ['root','developer','admin']],
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@ -21,27 +28,59 @@
|
|||||||
<style>
|
<style>
|
||||||
.fi-topbar-header-container > a { display: none !important; }
|
.fi-topbar-header-container > a { display: none !important; }
|
||||||
.fi-breadcrumbs { display: none !important; }
|
.fi-breadcrumbs { display: none !important; }
|
||||||
.fi-topbar-nav { display: none !important; }
|
|
||||||
.fi-topbar-content-start > a { display: none !important; }
|
.fi-topbar-content-start > a { display: none !important; }
|
||||||
|
.fi-topbar-nav { display: none !important; }
|
||||||
.fi-header-heading-group { display: none !important; }
|
.fi-header-heading-group { display: none !important; }
|
||||||
</style>
|
</style>
|
||||||
<ul class="flex items-center gap-x-1">
|
<ul class="flex items-center gap-x-1">
|
||||||
@foreach ($modules as $module)
|
@foreach ($modules as $module)
|
||||||
@role($module['roles'])
|
@role($module['roles'])
|
||||||
@php
|
@php
|
||||||
$isActive = request()->is(ltrim($module['link'], '/') . '*');
|
$isActive = isset($module['link']) ? request()->is(ltrim(parse_url($module['link'], PHP_URL_PATH), '/') . '*') : false;
|
||||||
|
if (!$isActive && isset($module['children'])) {
|
||||||
|
foreach ($module['children'] as $child) {
|
||||||
|
if (request()->is(ltrim(parse_url($child['link'], PHP_URL_PATH), '/') . '*')) {
|
||||||
|
$isActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@endphp
|
@endphp
|
||||||
<li class="flex-none">
|
<li class="flex-none relative" x-data="{ open: false }" @mouseenter="open = true" @mouseleave="open = false">
|
||||||
<a href="{{ $module['link'] }}"
|
@if(isset($module['children']))
|
||||||
title="{{ $module['displayName'] }}"
|
<button type="button"
|
||||||
class="flex flex-col items-center justify-center w-[110px] h-[105px] rounded-md transition-colors duration-200 {{ $isActive ? 'bg-white/50 shadow-inner' : 'hover:bg-white/30' }}">
|
title="{{ $module['displayName'] }}"
|
||||||
<img src="{{ asset('images/icons/ico_'.$module['icon'].'.png') }}"
|
class="flex flex-col items-center justify-center w-[110px] h-[105px] rounded-md transition-colors duration-200 {{ $isActive ? 'bg-white/50 shadow-inner' : 'hover:bg-white/30' }}">
|
||||||
class="w-16 h-16 object-contain mb-1"
|
<img src="{{ asset('images/icons/ico_'.$module['icon'].'.png') }}"
|
||||||
alt="">
|
class="w-16 h-16 object-contain mb-1"
|
||||||
<span class="text-[11px] font-bold text-[#453821] truncate w-full text-center px-1 leading-tight">
|
alt="">
|
||||||
{{ $module['displayName'] }}
|
<span class="text-[11px] font-bold text-[#453821] truncate w-full text-center px-1 leading-tight">
|
||||||
</span>
|
{{ $module['displayName'] }}
|
||||||
</a>
|
</span>
|
||||||
|
</button>
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition
|
||||||
|
class="absolute top-[100px] left-0 z-50 w-[200px] bg-white border border-gray-200 rounded-md shadow-lg py-1"
|
||||||
|
style="display: none;">
|
||||||
|
@foreach($module['children'] as $child)
|
||||||
|
<a href="{{ $child['link'] }}" class="block px-4 py-2 text-sm text-[#453821] hover:bg-gray-100 font-bold">
|
||||||
|
{{ $child['displayName'] }}
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<a href="{{ $module['link'] }}"
|
||||||
|
title="{{ $module['displayName'] }}"
|
||||||
|
class="flex flex-col items-center justify-center w-[110px] h-[105px] rounded-md transition-colors duration-200 {{ $isActive ? 'bg-white/50 shadow-inner' : 'hover:bg-white/30' }}">
|
||||||
|
<img src="{{ asset('images/icons/ico_'.$module['icon'].'.png') }}"
|
||||||
|
class="w-16 h-16 object-contain mb-1"
|
||||||
|
alt="">
|
||||||
|
<span class="text-[11px] font-bold text-[#453821] truncate w-full text-center px-1 leading-tight">
|
||||||
|
{{ $module['displayName'] }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
</li>
|
</li>
|
||||||
@endrole
|
@endrole
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
163
resources/views/filament/pages/calendar-test.blade.php
Normal file
163
resources/views/filament/pages/calendar-test.blade.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{-- Szűrő panel --}}
|
||||||
|
<div class="mb-4 rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-800">
|
||||||
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||||
|
Beszállító
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
wire:model.live="supplierId"
|
||||||
|
class="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">— Válasszon beszállítót —</option>
|
||||||
|
@foreach ($this->getSuppliers() as $id => $name)
|
||||||
|
<option value="{{ $id }}" @selected($supplierId == $id)>{{ $name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||||
|
Profitcenter
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
wire:model.live="profitCenterId"
|
||||||
|
class="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">— Válasszon profitcentert —</option>
|
||||||
|
@foreach ($this->getProfitCenters() as $id => $name)
|
||||||
|
<option value="{{ $id }}" @selected($profitCenterId == $id)>{{ $name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Jelmagyarázat --}}
|
||||||
|
<div class="mb-4 flex flex-wrap items-center gap-4 text-sm">
|
||||||
|
<span class="font-semibold text-gray-700 dark:text-gray-300">Jelmagyarázat:</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
|
<span class="inline-block w-4 h-4 rounded" style="background-color: #4CAF50;"></span>
|
||||||
|
Szállítási nap
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
|
<span class="inline-block w-4 h-4 rounded" style="background-color: #EF4444;"></span>
|
||||||
|
Ünnepnap
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
|
<span class="inline-block w-4 h-4 rounded" style="background-color: #F59E0B;"></span>
|
||||||
|
Áthelyezett munkanap
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
|
<span class="inline-block w-4 h-4 rounded" style="background-color: #3B82F6;"></span>
|
||||||
|
Megrendelési határidő
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
|
<span class="inline-block w-4 h-4 rounded" style="background-color: #E5E7EB;"></span>
|
||||||
|
Hétvége (inaktív)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Naptár widget spinner overlay-jel --}}
|
||||||
|
<div class="relative"
|
||||||
|
x-data="{ loading: false }"
|
||||||
|
x-init="
|
||||||
|
window.addEventListener('filament-fullcalendar--refresh', () => { loading = true; });
|
||||||
|
$wire.on('calendar-events-done', () => { loading = false; });
|
||||||
|
">
|
||||||
|
<div x-show="loading"
|
||||||
|
x-transition:enter="transition-opacity duration-150"
|
||||||
|
x-transition:leave="transition-opacity duration-300"
|
||||||
|
class="absolute inset-0 z-10 flex items-center justify-center rounded-xl bg-white/80 dark:bg-gray-900/80"
|
||||||
|
style="min-height: 200px; display: none;">
|
||||||
|
<div class="flex flex-col items-center gap-3">
|
||||||
|
<svg class="h-10 w-10 animate-spin text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||||
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.84 3 7.938l3-2.647z"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="text-sm font-medium text-gray-600 dark:text-gray-300">Naptár betöltése...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@livewire(\App\Filament\Widgets\DeliveryCalendarWidget::class, [
|
||||||
|
'supplierId' => $supplierId,
|
||||||
|
'profitCenterId' => $profitCenterId,
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Kompakt multi-hónap nézet a képhez hasonlóan */
|
||||||
|
.filament-fullcalendar {
|
||||||
|
--fc-small-font-size: 0.8em;
|
||||||
|
--fc-page-bg-color: transparent;
|
||||||
|
--fc-neutral-bg-color: transparent;
|
||||||
|
}
|
||||||
|
/* Hónap fejléc */
|
||||||
|
.filament-fullcalendar .fc-multimonth-title {
|
||||||
|
font-size: 0.9rem !important;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 4px 0 !important;
|
||||||
|
color: #453821;
|
||||||
|
}
|
||||||
|
/* Kompaktabb cellaméretek */
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-daygrid-day {
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-daygrid-day-frame {
|
||||||
|
min-height: 24px !important;
|
||||||
|
padding: 1px !important;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-daygrid-day-top {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-daygrid-day-number {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 1px 3px !important;
|
||||||
|
}
|
||||||
|
/* Napfejléc (H, K, Sz, Cs, P, Szo, V) */
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-col-header-cell {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
padding: 2px 0 !important;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #6B7280;
|
||||||
|
}
|
||||||
|
/* Háttér események jobban kitöltik a cellát */
|
||||||
|
.filament-fullcalendar .fc-multimonth .fc-bg-event {
|
||||||
|
opacity: 0.85 !important;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
/* Mai nap kiemelés */
|
||||||
|
.filament-fullcalendar .fc-day-today {
|
||||||
|
background-color: rgba(59, 130, 246, 0.1) !important;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-day-today .fc-daygrid-day-number {
|
||||||
|
font-weight: 800;
|
||||||
|
color: #1D4ED8;
|
||||||
|
}
|
||||||
|
/* Hónapok közötti térköz csökkentése */
|
||||||
|
.filament-fullcalendar .fc-multimonth-month {
|
||||||
|
padding: 0 4px !important;
|
||||||
|
}
|
||||||
|
/* Fejléc toolbar */
|
||||||
|
.filament-fullcalendar .fc-toolbar {
|
||||||
|
margin-bottom: 0.5em !important;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-toolbar-title {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
color: #453821;
|
||||||
|
}
|
||||||
|
/* Szegély finomítás */
|
||||||
|
.filament-fullcalendar .fc-multimonth {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
.filament-fullcalendar .fc-multimonth-daygrid {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
/* Hétvége napok szürke szöveg */
|
||||||
|
.filament-fullcalendar .fc-day-sat .fc-daygrid-day-number,
|
||||||
|
.filament-fullcalendar .fc-day-sun .fc-daygrid-day-number {
|
||||||
|
color: #9CA3AF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</x-filament-panels::page>
|
||||||
@ -29,12 +29,14 @@
|
|||||||
echo view('layout.wherehere')->render();
|
echo view('layout.wherehere')->render();
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
URL::forceScheme('https');
|
||||||
|
/*
|
||||||
if (! in_array(strtolower(env('APP_STAGE')), ['d2dtst', 'e2etst', 'dev','local'])) {
|
if (! in_array(strtolower(env('APP_STAGE')), ['d2dtst', 'e2etst', 'dev','local'])) {
|
||||||
URL::forceScheme('https');
|
URL::forceScheme('https');
|
||||||
} else {
|
} else {
|
||||||
URL::forceScheme('http');
|
URL::forceScheme('http');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Route::get('/l', function () {
|
Route::get('/l', function () {
|
||||||
$M = \App\Models\ProfitCenter::where('name', 'like', 'pro%');
|
$M = \App\Models\ProfitCenter::where('name', 'like', 'pro%');
|
||||||
dd(getSql($M));
|
dd(getSql($M));
|
||||||
|
|||||||
266
tests/Feature/DeliveryCalendarServiceTest.php
Normal file
266
tests/Feature/DeliveryCalendarServiceTest.php
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\OverrideScope;
|
||||||
|
use App\Models\DeliveryCalendarOverride;
|
||||||
|
use App\Models\DeliverySchedule;
|
||||||
|
use App\Models\ProfitCenter;
|
||||||
|
use App\Models\ProfitCenterSupplierSchedule;
|
||||||
|
use App\Models\Supplier;
|
||||||
|
use App\Models\WorkCalendar;
|
||||||
|
use App\Enums\WorkDayType;
|
||||||
|
use App\Enums\DataSource;
|
||||||
|
use App\Services\DeliveryCalendarService;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
uses(TestCase::class, RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('returns true for a scheduled delivery day', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create([
|
||||||
|
'monday' => true,
|
||||||
|
]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
$monday = Carbon::parse('2026-04-13'); // Monday
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for a non-scheduled delivery day', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create([
|
||||||
|
'monday' => true,
|
||||||
|
'tuesday' => false,
|
||||||
|
]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
$tuesday = Carbon::parse('2026-04-14'); // Tuesday
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $tuesday))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects official holidays (WorkCalendar)', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13'); // Monday
|
||||||
|
// Mark this Monday as a holiday
|
||||||
|
WorkCalendar::create([
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'type' => WorkDayType::Holiday,
|
||||||
|
'data_source' => DataSource::Manual,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects general supplier override over holidays', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13'); // Monday
|
||||||
|
WorkCalendar::create([
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'type' => WorkDayType::Holiday,
|
||||||
|
'data_source' => DataSource::Manual,
|
||||||
|
]);
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::General->value,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => true,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects general supplier override to block delivery on a normal day', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13'); // Monday
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::General->value,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects delivery-schedule-specific override over general override', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13');
|
||||||
|
// Általános tiltás
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::General->value,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
// Szállítási sablon-specifikus engedélyezés
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::Region->value,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => true,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
// A sablon-specifikus győz az általánossal szemben
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('delivery-schedule override does not affect profit centers with different schedule', function () {
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$scheduleA = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
$scheduleB = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
$pcA = ProfitCenter::factory()->create();
|
||||||
|
$pcB = ProfitCenter::factory()->create();
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pcA->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $scheduleA->id,
|
||||||
|
]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pcB->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $scheduleB->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13');
|
||||||
|
// Csak az A sablont tiltjuk
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::Region->value,
|
||||||
|
'delivery_schedule_id' => $scheduleA->id,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pcA, $supplier, $monday))->toBeFalse();
|
||||||
|
expect($service->isDeliveryDay($pcB, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects profit-center-specific override over region and general overrides', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create(['city' => 'Budapest']);
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13');
|
||||||
|
// Általános tiltás
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::General->value,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
// Sablon-specifikus tiltás is
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::Region->value,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
// De erre a konkrét PC-re engedélyezve van
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::ProfitCenter->value,
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => true,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pc, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('profit-center-specific override only affects the targeted profit center', function () {
|
||||||
|
$pc1 = ProfitCenter::factory()->create(['city' => 'Budapest']);
|
||||||
|
$pc2 = ProfitCenter::factory()->create(['city' => 'Budapest']);
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create(['monday' => true]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc1->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc2->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$monday = Carbon::parse('2026-04-13');
|
||||||
|
// Csak pc1-re van tiltás
|
||||||
|
DeliveryCalendarOverride::create([
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'override_scope' => OverrideScope::ProfitCenter->value,
|
||||||
|
'profit_center_id' => $pc1->id,
|
||||||
|
'date' => '2026-04-13',
|
||||||
|
'is_delivery_day' => false,
|
||||||
|
]);
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
expect($service->isDeliveryDay($pc1, $supplier, $monday))->toBeFalse();
|
||||||
|
expect($service->isDeliveryDay($pc2, $supplier, $monday))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calculates available delivery dates in a range', function () {
|
||||||
|
$pc = ProfitCenter::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$schedule = DeliverySchedule::factory()->create([
|
||||||
|
'monday' => true,
|
||||||
|
'wednesday' => true,
|
||||||
|
'friday' => true,
|
||||||
|
]);
|
||||||
|
ProfitCenterSupplierSchedule::factory()->create([
|
||||||
|
'profit_center_id' => $pc->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'delivery_schedule_id' => $schedule->id,
|
||||||
|
]);
|
||||||
|
$start = Carbon::parse('2026-04-13'); // Monday
|
||||||
|
$end = Carbon::parse('2026-04-19'); // Sunday
|
||||||
|
$service = app(DeliveryCalendarService::class);
|
||||||
|
$dates = $service->getAvailableDeliveryDates($pc, $supplier, $start, $end);
|
||||||
|
// Should be Mon, Wed, Fri
|
||||||
|
expect($dates)->toHaveCount(3);
|
||||||
|
$dateStrings = $dates->map(fn($d) => $d->toDateString());
|
||||||
|
expect($dateStrings)->toContain('2026-04-13');
|
||||||
|
expect($dateStrings)->toContain('2026-04-15');
|
||||||
|
expect($dateStrings)->toContain('2026-04-17');
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user