fishh UI
This commit is contained in:
parent
caf0cc3f54
commit
9e90feb662
@ -24,6 +24,7 @@ ##### Modellek és Auditálás
|
|||||||
- Minden fő modellnek a `App\Models\BaseAuditable` osztályból kell származnia.
|
- Minden fő modellnek a `App\Models\BaseAuditable` osztályból kell származnia.
|
||||||
- Ez biztosítja a `created_by`, `updated_by` és `deleted_by` mezők automatikus töltését a `ModelUserIdAppenderTrait` segítségével.
|
- Ez biztosítja a `created_by`, `updated_by` és `deleted_by` mezők automatikus töltését a `ModelUserIdAppenderTrait` segítségével.
|
||||||
- Használjunk `SoftDeletes`-t, ahol az adatok megőrzése fontos.
|
- Használjunk `SoftDeletes`-t, ahol az adatok megőrzése fontos.
|
||||||
|
- **Enums**: Amennyiben egy modell mezőjéhez meghatározott értékkészlet tartozik, kötelező PHP Enum használata és annak beállítása a `$casts` tömbben.
|
||||||
|
|
||||||
##### Hibrid Frontend Architektúra (Mix & Vite) és a "Clean Cut" elv
|
##### Hibrid Frontend Architektúra (Mix & Vite) és a "Clean Cut" elv
|
||||||
A projekt fokozatos modernizáció alatt áll, ezért két párhuzamos build rendszert használunk a **"Clean Cut"** (tiszta vágás) elv mentén:
|
A projekt fokozatos modernizáció alatt áll, ezért két párhuzamos build rendszert használunk a **"Clean Cut"** (tiszta vágás) elv mentén:
|
||||||
@ -79,12 +80,17 @@ ##### JavaScript Kódolási Stílus
|
|||||||
##### Blade Sablonok
|
##### Blade Sablonok
|
||||||
- A nézetek az `resources/views` mappában találhatóak, logikusan csoportosítva (pl. `admin/product`, `admin/statistics`).
|
- A nézetek az `resources/views` mappában találhatóak, logikusan csoportosítva (pl. `admin/product`, `admin/statistics`).
|
||||||
- A szűrők és közös komponensek gyakran külön fájlokba vannak kiszervezve (pl. `filter.blade.php`).
|
- A szűrők és közös komponensek gyakran külön fájlokba vannak kiszervezve (pl. `filter.blade.php`).
|
||||||
|
#### Eszközök és Konvenciók - CLI
|
||||||
|
- **Artisan parancsok**: Generáló parancsok (pl. `make:filament-resource`) esetén törekedni kell az interakciómentes futtatásra a `--no-interaction` kapcsoló használatával.
|
||||||
|
- **Filament Resource**: Új Resource létrehozásakor kötelező megadni a `--record-title-attribute` paramétert (pl. `name` vagy `filename`), és javasolt a `--generate` használata, ha az adatbázis séma már rendelkezésre áll.
|
||||||
|
|
||||||
#### Verziókezelés (Git)
|
#### Verziókezelés (Git)
|
||||||
* **Üzenetek**: Angol vagy magyar nyelven, rövid de tömör leírással, hogy mit változtattál. Példa: `feature: Add order archive export functionality`.
|
* **Üzenetek**: Angol vagy magyar nyelven, rövid de tömör leírással, hogy mit változtattál. Példa: `feature: Add order archive export functionality`.
|
||||||
* **Méretes fájlok**: Ne committolj nagyméretű képeket, build artifactokat vagy érzékeny adatokat (`.env`).
|
* **Méretes fájlok**: Ne committolj nagyméretű képeket, build artifactokat vagy érzékeny adatokat (`.env`).
|
||||||
|
|
||||||
#### Adatbázis kezelés
|
#### Adatbázis kezelés
|
||||||
* **Migrációk**: Minden adatbázis sémaváltoztatást migrációval kell végrehajtani.
|
* **Migrációk**: Minden adatbázis sémaváltoztatást migrációval kell végrehajtani.
|
||||||
|
* **Enums**: Ha egy mező meghatározott értékkészlettel rendelkezik, a migrációban is `enum` típust kell használni, az értékeket pedig dinamikusan a megfelelő PHP Enum osztályból kell kinyerni (pl. `array_column(Enum::cases(), 'value')`).
|
||||||
* **Factories/Seeders**: Új modulokhoz hozz létre gyárat (factory) és seedert a könnyű tesztelhetőségért.
|
* **Factories/Seeders**: Új modulokhoz hozz létre gyárat (factory) és seedert a könnyű tesztelhetőségért.
|
||||||
|
|
||||||
#### Tesztelés
|
#### Tesztelés
|
||||||
|
|||||||
25
app/Enums/PricelistFileStatusEnum.php
Normal file
25
app/Enums/PricelistFileStatusEnum.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum PricelistFileStatusEnum: string
|
||||||
|
{
|
||||||
|
case todo = 'todo';
|
||||||
|
case inprogress = 'inprogress';
|
||||||
|
case fail = 'fail';
|
||||||
|
case done = 'done';
|
||||||
|
case waiting_for_approval = 'waiting_for_approval';
|
||||||
|
case closed = 'closed';
|
||||||
|
|
||||||
|
public function label(): string
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::todo => 'elvégzendő',
|
||||||
|
self::inprogress => 'folyamatban',
|
||||||
|
self::fail => 'hiba',
|
||||||
|
self::done => 'elkészült',
|
||||||
|
self::waiting_for_approval => 'jóváhagyásra vár',
|
||||||
|
self::closed => 'lezárva',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ class Schema extends BaseSchema
|
|||||||
/**
|
/**
|
||||||
* Get a schema builder instance for a connection.
|
* Get a schema builder instance for a connection.
|
||||||
*/
|
*/
|
||||||
public static function connection(?string $name): Builder
|
public static function connection($name)
|
||||||
{
|
{
|
||||||
/** @var Builder $builder */
|
/** @var Builder $builder */
|
||||||
$builder = static::$app['db']->connection($name)->getSchemaBuilder();
|
$builder = static::$app['db']->connection($name)->getSchemaBuilder();
|
||||||
|
|||||||
@ -3,11 +3,26 @@
|
|||||||
namespace App\Filament\Pages;
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
use Filament\Pages\Page;
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Textarea;
|
||||||
|
use Filament\Forms\Components\FileUpload;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Forms\Contracts\HasForms;
|
||||||
|
use Filament\Forms\Concerns\InteractsWithForms;
|
||||||
|
use App\Models\Supplier;
|
||||||
|
use App\Models\PricelistFile;
|
||||||
|
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||||
|
use App\Jobs\PricelistPreProcessJob;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
|
||||||
use Illuminate\Contracts\Support\Htmlable;
|
use Illuminate\Contracts\Support\Htmlable;
|
||||||
|
|
||||||
class PriceListProcessor extends Page
|
class PriceListProcessor extends Page implements HasForms
|
||||||
{
|
{
|
||||||
|
use InteractsWithForms;
|
||||||
|
|
||||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-text';
|
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
protected string $view = 'filament.pages.price-list-processor';
|
protected string $view = 'filament.pages.price-list-processor';
|
||||||
@ -17,4 +32,80 @@ class PriceListProcessor extends Page
|
|||||||
protected static ?string $navigationLabel = 'Árlista feldolgozó';
|
protected static ?string $navigationLabel = 'Árlista feldolgozó';
|
||||||
|
|
||||||
protected static bool $shouldRegisterNavigation = false;
|
protected static bool $shouldRegisterNavigation = false;
|
||||||
|
|
||||||
|
public ?array $data = [];
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->form->fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form(Schema $form): Schema
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Select::make('supplier_id')
|
||||||
|
->label('Beszállító')
|
||||||
|
->options(Supplier::query()->pluck('name', 'id'))
|
||||||
|
->required()
|
||||||
|
->searchable(),
|
||||||
|
DatePicker::make('available_date')
|
||||||
|
->label('Életbelépés dátuma')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('Y.m.d'),
|
||||||
|
Textarea::make('note')
|
||||||
|
->label('Megjegyzés')
|
||||||
|
->rows(3),
|
||||||
|
FileUpload::make('filename')
|
||||||
|
->label('Fájl kiválasztása')
|
||||||
|
->required()
|
||||||
|
->acceptedFileTypes(['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/csv'])
|
||||||
|
->disk('public')
|
||||||
|
->directory('pricelist-uploads')
|
||||||
|
->preserveFilenames(),
|
||||||
|
])
|
||||||
|
->statePath('data');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFormActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Action::make('save')
|
||||||
|
->label('Feltöltés és feldolgozás indítása')
|
||||||
|
->submit('save')
|
||||||
|
->color('primary'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$data = $this->form->getState();
|
||||||
|
|
||||||
|
$pricelistFile = PricelistFile::create([
|
||||||
|
'filename' => $data['filename'],
|
||||||
|
'supplier_id' => $data['supplier_id'],
|
||||||
|
'available_date' => $data['available_date'],
|
||||||
|
'note' => $data['note'],
|
||||||
|
'status' => \App\Enums\PricelistFileStatusEnum::todo,
|
||||||
|
'workflow_steps' => [
|
||||||
|
['name' => 'preprocess', 'label' => 'Előfeldolgozás', 'status' => 'pending'],
|
||||||
|
['name' => 'validation', 'label' => 'Validálás', 'status' => 'pending'],
|
||||||
|
['name' => 'approval', 'label' => 'Jóváhagyás', 'status' => 'pending'],
|
||||||
|
['name' => 'execution', 'label' => 'Végrehajtás', 'status' => 'pending']
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
PricelistPreProcessJob::dispatch($pricelistFile);
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->title('Sikeres feltöltés')
|
||||||
|
->body('Az árlista fájl rögzítve lett és a feldolgozás elindult.')
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill();
|
||||||
|
|
||||||
|
return redirect()->to(PricelistFileResource::getUrl('view', ['record' => $pricelistFile]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreatePricelistFile extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = PricelistFileResource::class;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||||
|
use Filament\Actions\DeleteAction;
|
||||||
|
use Filament\Actions\ForceDeleteAction;
|
||||||
|
use Filament\Actions\RestoreAction;
|
||||||
|
use Filament\Actions\ViewAction;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditPricelistFile extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = PricelistFileResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
ViewAction::make(),
|
||||||
|
DeleteAction::make(),
|
||||||
|
ForceDeleteAction::make(),
|
||||||
|
RestoreAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use App\Filament\Pages\PriceListProcessor;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListPricelistFiles extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = PricelistFileResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Action::make('create_pricelist')
|
||||||
|
->label('Új árlista felvitele')
|
||||||
|
->url(fn (): string => PriceListProcessor::getUrl())
|
||||||
|
->button()
|
||||||
|
->color('primary'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Resources\Pages\ViewRecord;
|
||||||
|
|
||||||
|
class ViewPricelistFile extends ViewRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = PricelistFileResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
EditAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeading(): string
|
||||||
|
{
|
||||||
|
return "Árlista fájl: " . $this->record->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderWidgets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// Később ide jöhetnek widgetek, pl. statisztika a feldolgozásról
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubheading(): ?string
|
||||||
|
{
|
||||||
|
return "Beszállító: " . $this->record->supplier?->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PricelistFiles\Pages\CreatePricelistFile;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Pages\EditPricelistFile;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Pages\ListPricelistFiles;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Pages\ViewPricelistFile;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Schemas\PricelistFileForm;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Schemas\PricelistFileInfolist;
|
||||||
|
use App\Filament\Resources\PricelistFiles\Tables\PricelistFilesTable;
|
||||||
|
use App\Models\PricelistFile;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Filament\Support\Enums\MaxWidth;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class PricelistFileResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = PricelistFile::class;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Árlista feldolgozó';
|
||||||
|
|
||||||
|
protected static ?string $breadcrumb = 'Árlista feldolgozó';
|
||||||
|
|
||||||
|
protected static ?string $pluralLabel = 'Árlista feldolgozó';
|
||||||
|
|
||||||
|
protected static ?string $modelLabel = 'Árlista fájl';
|
||||||
|
|
||||||
|
public static function getMaxWidth(): MaxWidth|string|null
|
||||||
|
{
|
||||||
|
return MaxWidth::Full;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return PricelistFileForm::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function infolist(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return PricelistFileInfolist::configure($schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return PricelistFilesTable::configure($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => ListPricelistFiles::route('/'),
|
||||||
|
'create' => CreatePricelistFile::route('/create'),
|
||||||
|
'view' => ViewPricelistFile::route('/{record}'),
|
||||||
|
'edit' => EditPricelistFile::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||||
|
{
|
||||||
|
return parent::getRecordRouteBindingEloquentQuery()
|
||||||
|
->withoutGlobalScopes([
|
||||||
|
SoftDeletingScope::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Schemas;
|
||||||
|
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class PricelistFileForm
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
//
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Schemas;
|
||||||
|
|
||||||
|
use App\Enums\PricelistFileStatusEnum;
|
||||||
|
use Filament\Schemas\Components\Section;
|
||||||
|
use Filament\Infolists\Components\TextEntry;
|
||||||
|
use Filament\Infolists\Components\RepeatableEntry;
|
||||||
|
use Filament\Schemas\Components\Grid;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
|
||||||
|
class PricelistFileInfolist
|
||||||
|
{
|
||||||
|
public static function configure(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->components([
|
||||||
|
Section::make('Fájl információk')
|
||||||
|
->poll('5s')
|
||||||
|
->schema([
|
||||||
|
Grid::make(3)
|
||||||
|
->schema([
|
||||||
|
TextEntry::make('filename')
|
||||||
|
->label('Fájlnév')
|
||||||
|
->icon('heroicon-o-document-text')
|
||||||
|
->color('primary'),
|
||||||
|
TextEntry::make('supplier.name')
|
||||||
|
->label('Beszállító')
|
||||||
|
->icon('heroicon-o-user'),
|
||||||
|
TextEntry::make('status')
|
||||||
|
->label('Státusz')
|
||||||
|
->badge()
|
||||||
|
->formatStateUsing(fn (PricelistFileStatusEnum $state): string => $state->label())
|
||||||
|
->color(fn (PricelistFileStatusEnum $state): string => match ($state) {
|
||||||
|
PricelistFileStatusEnum::todo => 'gray',
|
||||||
|
PricelistFileStatusEnum::inprogress => 'info',
|
||||||
|
PricelistFileStatusEnum::done => 'success',
|
||||||
|
PricelistFileStatusEnum::fail => 'danger',
|
||||||
|
PricelistFileStatusEnum::waiting_for_approval => 'primary',
|
||||||
|
PricelistFileStatusEnum::closed => 'warning',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
Grid::make(3)
|
||||||
|
->schema([
|
||||||
|
TextEntry::make('available_date')
|
||||||
|
->label('Életbelépés dátuma')
|
||||||
|
->date('Y.m.d'),
|
||||||
|
TextEntry::make('created_at')
|
||||||
|
->label('Feltöltés időpontja')
|
||||||
|
->dateTime('Y.m.d H:i'),
|
||||||
|
TextEntry::make('processing_current_step')
|
||||||
|
->label('Aktuális folyamat')
|
||||||
|
->weight('bold')
|
||||||
|
->color('info')
|
||||||
|
->formatStateUsing(fn ($state, $record) => "$state ({$record->processing_current_step_percentage}%)"),
|
||||||
|
]),
|
||||||
|
TextEntry::make('note')
|
||||||
|
->label('Megjegyzés')
|
||||||
|
->placeholder('Nincs megjegyzés')
|
||||||
|
->columnSpanFull(),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Section::make('Feldolgozási folyamat (Workflow)')
|
||||||
|
->poll('5s')
|
||||||
|
->schema([
|
||||||
|
RepeatableEntry::make('workflow_steps')
|
||||||
|
->label(false)
|
||||||
|
->schema([
|
||||||
|
TextEntry::make('label')
|
||||||
|
->label('Lépés')
|
||||||
|
->weight('bold')
|
||||||
|
->inlineLabel(),
|
||||||
|
TextEntry::make('status')
|
||||||
|
->label('Állapot')
|
||||||
|
->badge()
|
||||||
|
->inlineLabel()
|
||||||
|
->formatStateUsing(fn (string $state): string => match ($state) {
|
||||||
|
'pending' => 'várakozik',
|
||||||
|
'inprogress' => 'folyamatban',
|
||||||
|
'done' => 'kész',
|
||||||
|
'fail' => 'hiba',
|
||||||
|
default => $state,
|
||||||
|
})
|
||||||
|
->color(fn (string $state): string => match ($state) {
|
||||||
|
'pending' => 'gray',
|
||||||
|
'inprogress' => 'info',
|
||||||
|
'done' => 'success',
|
||||||
|
'fail' => 'danger',
|
||||||
|
default => 'gray',
|
||||||
|
})
|
||||||
|
->icon(fn (string $state): string => match ($state) {
|
||||||
|
'pending' => 'heroicon-o-clock',
|
||||||
|
'inprogress' => 'heroicon-o-arrow-path',
|
||||||
|
'done' => 'heroicon-o-check-circle',
|
||||||
|
'fail' => 'heroicon-o-x-circle',
|
||||||
|
default => 'heroicon-o-question-mark-circle',
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
->columns(2)
|
||||||
|
->columnSpanFull(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PricelistFiles\Tables;
|
||||||
|
|
||||||
|
use Filament\Actions\BulkActionGroup;
|
||||||
|
use Filament\Actions\DeleteBulkAction;
|
||||||
|
use Filament\Actions\EditAction;
|
||||||
|
use Filament\Actions\ForceDeleteBulkAction;
|
||||||
|
use Filament\Actions\RestoreBulkAction;
|
||||||
|
use Filament\Actions\ViewAction;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Filters\TrashedFilter;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use App\Enums\PricelistFileStatusEnum;
|
||||||
|
|
||||||
|
class PricelistFilesTable
|
||||||
|
{
|
||||||
|
public static function configure(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->poll('5s')
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('filename')
|
||||||
|
->label('Fájlnév')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('supplier.name')
|
||||||
|
->label('Beszállító')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('status')
|
||||||
|
->label('Státusz')
|
||||||
|
->badge()
|
||||||
|
->formatStateUsing(fn (PricelistFileStatusEnum $state): string => $state->label())
|
||||||
|
->color(fn (PricelistFileStatusEnum $state): string => match ($state) {
|
||||||
|
PricelistFileStatusEnum::todo => 'gray',
|
||||||
|
PricelistFileStatusEnum::inprogress => 'info',
|
||||||
|
PricelistFileStatusEnum::done => 'success',
|
||||||
|
PricelistFileStatusEnum::fail => 'danger',
|
||||||
|
PricelistFileStatusEnum::waiting_for_approval => 'primary',
|
||||||
|
PricelistFileStatusEnum::closed => 'warning',
|
||||||
|
})
|
||||||
|
->sortable(),
|
||||||
|
TextColumn::make('processing_current_step')
|
||||||
|
->label('Aktuális lépés')
|
||||||
|
->placeholder('Nincs adat'),
|
||||||
|
TextColumn::make('processing_current_step_percentage')
|
||||||
|
->label('Készültség')
|
||||||
|
->suffix('%')
|
||||||
|
->alignCenter(),
|
||||||
|
TextColumn::make('created_at')
|
||||||
|
->label('Feltöltve')
|
||||||
|
->dateTime('Y.m.d H:i')
|
||||||
|
->sortable(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
TrashedFilter::make(),
|
||||||
|
])
|
||||||
|
->recordActions([
|
||||||
|
ViewAction::make(),
|
||||||
|
EditAction::make(),
|
||||||
|
])
|
||||||
|
->toolbarActions([
|
||||||
|
BulkActionGroup::make([
|
||||||
|
DeleteBulkAction::make(),
|
||||||
|
ForceDeleteBulkAction::make(),
|
||||||
|
RestoreBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/Jobs/PricelistPreProcessJob.php
Normal file
30
app/Jobs/PricelistPreProcessJob.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\PricelistFile;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Queue\Queueable;
|
||||||
|
|
||||||
|
class PricelistPreProcessJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public PricelistFile $pricelistFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
// Ide kerül majd az üzleti logika a PricelistFileProcessService segítségével
|
||||||
|
}
|
||||||
|
}
|
||||||
29
app/Models/PricelistFile.php
Normal file
29
app/Models/PricelistFile.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\PricelistFileStatusEnum;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class PricelistFile extends BaseAuditable
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'status' => PricelistFileStatusEnum::class,
|
||||||
|
'processing_current_step_percentage' => 'integer',
|
||||||
|
'available_date' => 'date',
|
||||||
|
'workflow_steps' => 'array',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function supplier(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Supplier::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function priceList(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PriceList::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,6 +45,13 @@ public function register(): void
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
//
|
\Livewire\Livewire::component('app.filament.pages.price-list-processor', \App\Filament\Pages\PriceListProcessor::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.sidebar', \Filament\Livewire\Sidebar::class);
|
||||||
|
\Livewire\Livewire::component('filament.livewire.topbar', \Filament\Livewire\Topbar::class);
|
||||||
|
\Livewire\Livewire::component('filament.livewire.global-search', \Filament\Livewire\GlobalSearch::class);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
91
app/Services/PricelistFileProcessService.php
Normal file
91
app/Services/PricelistFileProcessService.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\PricelistFile;
|
||||||
|
use App\Enums\PricelistFileStatusEnum;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class PricelistFileProcessService
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected PriceListService $priceListService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Előfeldolgozás (Pre-processing) - Adatok ellenőrzése és validálása
|
||||||
|
*
|
||||||
|
* @param PricelistFile $pricelistFile
|
||||||
|
* @param array $data Az XLS-ből beolvasott adatok
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function preProcess(PricelistFile $pricelistFile, array $data): bool
|
||||||
|
{
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::inprogress,
|
||||||
|
'processing_current_step' => 'Előfeldolgozás: Adatok ellenőrzése...',
|
||||||
|
'processing_current_step_percentage' => 10,
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Itt hívjuk majd meg a PriceListService ellenőrző metódusait
|
||||||
|
// $results = $this->priceListService->importPriceListCheck($pricelistFile->supplier_id, $data);
|
||||||
|
|
||||||
|
// TODO: Eredmények mentése (pl. preview_data JSON mezőbe vagy fájlba)
|
||||||
|
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::todo, // Visszaállítjuk, vagy egy új 'waiting_for_approval' státuszra, ha létezik
|
||||||
|
'processing_current_step' => 'Előfeldolgozás kész, jóváhagyásra vár.',
|
||||||
|
'processing_current_step_percentage' => 100,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Pricelist pre-process error: ' . $e->getMessage());
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::fail,
|
||||||
|
'processing_current_step' => 'Hiba az előfeldolgozás során: ' . $e->getMessage(),
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Végrehajtás (Execution) - Módosítások tényleges alkalmazása tranzakcióban
|
||||||
|
*
|
||||||
|
* @param PricelistFile $pricelistFile
|
||||||
|
* @param array $dataToImport A véglegesítendő adatok
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function execute(PricelistFile $pricelistFile, array $dataToImport): bool
|
||||||
|
{
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::inprogress,
|
||||||
|
'processing_current_step' => 'Végrehajtás: Árlista frissítése...',
|
||||||
|
'processing_current_step_percentage' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// Tényleges importálás végrehajtása a PriceListService segítségével
|
||||||
|
// $this->priceListService->importPriceList(...);
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::done,
|
||||||
|
'processing_current_step' => 'Sikeresen befejezve.',
|
||||||
|
'processing_current_step_percentage' => 100,
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
Log::error('Pricelist execution error: ' . $e->getMessage());
|
||||||
|
$pricelistFile->update([
|
||||||
|
'status' => PricelistFileStatusEnum::fail,
|
||||||
|
'processing_current_step' => 'Hiba a végrehajtás során: ' . $e->getMessage(),
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Database\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$builder = DB::connection()->getSchemaBuilder();
|
||||||
|
$builder->blueprintResolver(function ($table, $callback) {
|
||||||
|
return new Blueprint($table, $callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
$builder->create('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('filename');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->userIdFields();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
DB::connection()->getSchemaBuilder()->dropIfExists('pricelist_files');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Database\Blueprint;
|
||||||
|
use App\Enums\PricelistFileStatusEnum;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function ($table) {
|
||||||
|
$table->integer('file_size')->nullable()->after('filename');
|
||||||
|
$table->enum('status', array_column(PricelistFileStatusEnum::cases(), 'value'))->default(PricelistFileStatusEnum::todo->value)->after('file_size');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function ($table) {
|
||||||
|
$table->dropColumn(['file_size', 'status']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->string('processing_current_step')->nullable()->default(null)->after('status');
|
||||||
|
$table->integer('processing_current_step_percentage')->nullable()->default(null)->after('processing_current_step');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['processing_current_step', 'processing_current_step_percentage']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?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('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('supplier_id')->nullable()->after('filename');
|
||||||
|
$table->unsignedBigInteger('price_list_id')->nullable()->after('supplier_id');
|
||||||
|
|
||||||
|
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');
|
||||||
|
$table->foreign('price_list_id')->references('id')->on('price_lists')->onDelete('set null');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['supplier_id']);
|
||||||
|
$table->dropForeign(['price_list_id']);
|
||||||
|
$table->dropColumn(['supplier_id', 'price_list_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?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('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->date('available_date')->nullable()->after('price_list_id');
|
||||||
|
$table->text('note')->nullable()->after('available_date');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['available_date', 'note']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?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('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->json('workflow_steps')->nullable()->after('processing_current_step_percentage');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pricelist_files', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('workflow_steps');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -7,7 +7,7 @@
|
|||||||
['name' => 'product', 'displayName' => 'Termék', 'icon' => 'raktar', 'link' => route('admin.product.index'), 'roles' => ['root','developer','admin']],
|
['name' => 'product', 'displayName' => 'Termék', 'icon' => 'raktar', 'link' => route('admin.product.index'), 'roles' => ['root','developer','admin']],
|
||||||
['name' => 'supplier', 'displayName' => 'Beszállító adatbázis', 'icon' => 'supplier', 'link' => route('admin.supplier.index'), 'roles' => ['root','developer','admin','profit-center']],
|
['name' => 'supplier', 'displayName' => 'Beszállító adatbázis', 'icon' => 'supplier', 'link' => route('admin.supplier.index'), 'roles' => ['root','developer','admin','profit-center']],
|
||||||
['name' => 'priceList', 'displayName' => 'Webrendelős árlisták', 'icon' => 'price_list2', 'link' => route('admin.priceList.index'), 'roles' => ['root','developer','admin','profit-center']],
|
['name' => 'priceList', 'displayName' => 'Webrendelős árlisták', 'icon' => 'price_list2', 'link' => route('admin.priceList.index'), 'roles' => ['root','developer','admin','profit-center']],
|
||||||
['name' => 'priceListProcessor', 'displayName' => 'Árlista feldolgozó', 'icon' => 'price_list', 'link' => '/admin/price-list-processor', 'roles' => ['root','developer','admin']],
|
['name' => 'priceListProcessor', 'displayName' => 'Árlista feldolgozó', 'icon' => 'price_list', 'link' => '/admin/pricelist-files', 'roles' => ['root','developer','admin']],
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,20 @@
|
|||||||
<x-filament-panels::page>
|
<x-filament-panels::page>
|
||||||
<div class="p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700">
|
<div class="space-y-6">
|
||||||
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Árlista feldolgozó</h5>
|
<div class="p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700">
|
||||||
<p class="mb-3 font-normal text-gray-700 dark:text-gray-400">Ez az új, Filament-alapú árlista feldolgozó felület.</p>
|
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Árlista feldolgozó</h5>
|
||||||
|
<p class="mb-3 font-normal text-gray-700 dark:text-gray-400">Töltse fel az új árlistát a feldolgozás indításához.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<form wire:submit="save">
|
||||||
|
{{ $this->form }}
|
||||||
|
|
||||||
|
<div class="mt-6">
|
||||||
|
<x-filament::actions
|
||||||
|
:actions="$this->getFormActions()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-filament-panels::page>
|
</x-filament-panels::page>
|
||||||
|
|||||||
@ -114,13 +114,13 @@
|
|||||||
//'link'=>route('order.newOrderShow'),
|
//'link'=>route('order.newOrderShow'),
|
||||||
'roles'=>['root','developer','admin']
|
'roles'=>['root','developer','admin']
|
||||||
],
|
],
|
||||||
'priceListProcessor'=>[
|
'priceListProcessor' => [
|
||||||
'name'=>'priceListProcessor',
|
'name' => 'priceListProcessor',
|
||||||
'DisplayName'=>'Árlista feldolgozó',
|
'DisplayName' => 'Árlista feldolgozó',
|
||||||
'icon'=>'price_list',
|
'icon' => 'price_list',
|
||||||
'link'=>'/admin/price-list-processor',
|
'link' => '/admin/pricelist-files',
|
||||||
'noAjax'=>true,
|
'noAjax' => true,
|
||||||
'roles'=>['root','developer','admin']
|
'roles' => ['root', 'developer', 'admin'],
|
||||||
],
|
],
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user