Compare commits
8 Commits
68dd7d2a7a
...
5e2ecd2460
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e2ecd2460 | ||
|
|
3c70cd0260 | ||
|
|
f641602533 | ||
|
|
fd6aea01ed | ||
|
|
f6d7394ebd | ||
|
|
6b39fc7236 | ||
|
|
2fbae54e6b | ||
|
|
6477c7d47a |
53
app/Filament/Exports/LineExporter.php
Normal file
53
app/Filament/Exports/LineExporter.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\Line;
|
||||
use Filament\Actions\Exports\ExportColumn;
|
||||
use Filament\Actions\Exports\Exporter;
|
||||
use Filament\Actions\Exports\Models\Export;
|
||||
|
||||
class LineExporter extends Exporter
|
||||
{
|
||||
protected static ?string $model = Line::class;
|
||||
|
||||
public static function getColumns(): array
|
||||
{
|
||||
static $rowNumber = 0;
|
||||
|
||||
return [
|
||||
// ExportColumn::make('id')
|
||||
// ->label('ID'),
|
||||
ExportColumn::make('no')
|
||||
->label('NO')
|
||||
->state(function ($record) use (&$rowNumber) {
|
||||
// Increment and return the row number
|
||||
return ++$rowNumber;
|
||||
}),
|
||||
ExportColumn::make('plant.name')
|
||||
->label('PLANT'),
|
||||
ExportColumn::make('name')
|
||||
->label('NAME'),
|
||||
ExportColumn::make('type')
|
||||
->label('TYPE'),
|
||||
ExportColumn::make('created_at')
|
||||
->label('CREATED AT'),
|
||||
ExportColumn::make('updated_at')
|
||||
->label('UPDATED AT'),
|
||||
ExportColumn::make('deleted_at')
|
||||
->enabledByDefault(false)
|
||||
->label('DELETED AT'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getCompletedNotificationBody(Export $export): string
|
||||
{
|
||||
$body = 'Your line export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
|
||||
|
||||
if ($failedRowsCount = $export->getFailedRowsCount()) {
|
||||
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.';
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,21 @@ class QualityValidationExporter extends Exporter
|
||||
|
||||
public static function getColumns(): array
|
||||
{
|
||||
static $rowNumber = 0;
|
||||
|
||||
return [
|
||||
ExportColumn::make('id')
|
||||
->label('ID'),
|
||||
// ExportColumn::make('id')
|
||||
// ->label('ID'),
|
||||
ExportColumn::make('no')
|
||||
->label('NO')
|
||||
->state(function ($record) use (&$rowNumber) {
|
||||
// Increment and return the row number
|
||||
return ++$rowNumber;
|
||||
}),
|
||||
ExportColumn::make('plant.name')
|
||||
->label('PLANT'),
|
||||
ExportColumn::make('line.name')
|
||||
->label('LINE'),
|
||||
ExportColumn::make('production_order')
|
||||
->label('PRODUCTION ORDER'),
|
||||
ExportColumn::make('serial_number')
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Imports;
|
||||
|
||||
use App\Models\Item;
|
||||
use App\Models\Line;
|
||||
use App\Models\Plant;
|
||||
use App\Models\QualityValidation;
|
||||
use App\Models\StickerMaster;
|
||||
@@ -36,21 +37,28 @@ class QualityValidationImporter extends Importer
|
||||
->label('Plant Name')
|
||||
->relationship(resolveUsing:'name')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('sticker_master_id') // stickerMaster.item
|
||||
ImportColumn::make('line')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Line Name')
|
||||
->example('4 inch pump line')
|
||||
->label('Line Name')
|
||||
->relationship(resolveUsing:'name')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('sticker_master_id_code') // stickerMaster.item
|
||||
->requiredMapping()
|
||||
->exampleHeader('Item Code')
|
||||
->example('123456')
|
||||
->label('Item Code')
|
||||
->relationship(
|
||||
name: 'stickerMaster',
|
||||
resolveUsing: function ($state) {
|
||||
$state = trim($state);
|
||||
$item = Item::where('code', $state)->first();
|
||||
return $item
|
||||
? StickerMaster::where('item_id', $item->id)->value('id')
|
||||
: null;
|
||||
}
|
||||
),
|
||||
->label('Item Code'),
|
||||
// ->relationship(
|
||||
// name: 'stickerMaster',
|
||||
// resolveUsing: function ($state) {
|
||||
// $state = trim($state);
|
||||
// $item = Item::where('code', $state)->first();
|
||||
// return $item
|
||||
// ? StickerMaster::where('item_id', $item->id)->value('id')
|
||||
// : null;
|
||||
// }
|
||||
// ),
|
||||
ImportColumn::make('production_order')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Production Order')
|
||||
@@ -176,16 +184,24 @@ class QualityValidationImporter extends Importer
|
||||
{
|
||||
$warnMsg = [];
|
||||
$plant = Plant::where('name', $this->data['plant'])->first();
|
||||
$line = null;
|
||||
$stickMaster = null;
|
||||
if (!$plant) {
|
||||
$warnMsg[] = "Plant not found";
|
||||
}
|
||||
|
||||
$uniqueCode = trim($this->data['sticker_master_id']);// stickerMaster.item
|
||||
|
||||
$stickMaster = StickerMaster::select('id')->with('item')
|
||||
else {
|
||||
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
|
||||
$uniqueCode = trim($this->data['sticker_master_id_code']);// stickerMaster.item
|
||||
$stickMaster = StickerMaster::select('id')->with('item')
|
||||
->whereHas('item', function ($query) use ($uniqueCode, $plant) {
|
||||
$query->where('code', $uniqueCode)->where('plant_id', $plant->id);
|
||||
})->value('id');
|
||||
}
|
||||
|
||||
if (!$line) {
|
||||
$warnMsg[] = "Line not found";
|
||||
}
|
||||
|
||||
if (!$stickMaster) {
|
||||
$warnMsg[] = "Sticker item code not found";
|
||||
}
|
||||
@@ -197,6 +213,7 @@ class QualityValidationImporter extends Importer
|
||||
if (!ctype_alnum($this->data['serial_number']) || Str::length($this->data['serial_number']) < 9) {
|
||||
$warnMsg[] = "Invalid serial number found";
|
||||
}
|
||||
// dd($stickMaster);
|
||||
|
||||
// if (Str::length($this->data['uom']) < 1) {
|
||||
// $warnMsg[] = "Invalid unit of measure found";
|
||||
@@ -261,8 +278,10 @@ class QualityValidationImporter extends Importer
|
||||
if (!empty($warnMsg)) {
|
||||
throw new RowImportFailedException(implode(', ', $warnMsg));
|
||||
}
|
||||
return QualityValidation::updateOrCreate([
|
||||
|
||||
QualityValidation::updateOrCreate([
|
||||
'plant_id' => $plant->id,
|
||||
'line_id' => $line->id,
|
||||
'sticker_master_id' => $stickMaster,//->id
|
||||
'uom' => $this->data['uom'],
|
||||
'production_order' => $this->data['production_order'],
|
||||
@@ -289,6 +308,8 @@ class QualityValidationImporter extends Importer
|
||||
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
|
||||
'operator_id' => $this->data['operator_id'],
|
||||
]);
|
||||
|
||||
return null;
|
||||
// return QualityValidation::firstOrNew([
|
||||
// // Update existing records, matching them by `$this->data['column_name']`
|
||||
// 'email' => $this->data['email'],
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Exports\LineExporter;
|
||||
use App\Filament\Imports\LineImporter;
|
||||
use App\Filament\Resources\LineResource\Pages;
|
||||
use App\Filament\Resources\LineResource\RelationManagers;
|
||||
use App\Models\Line;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Get;
|
||||
@@ -16,6 +18,7 @@ use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Tables\Actions\ExportAction;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Unique;
|
||||
|
||||
@@ -115,9 +118,44 @@ class LineResource extends Resource
|
||||
->where('plant_id', $get('plant_id'))
|
||||
->ignore($get('id')); // Ignore current record during updates
|
||||
}),
|
||||
Forms\Components\TextInput::make('type')
|
||||
// Forms\Components\TextInput::make('type')
|
||||
// ->required()
|
||||
// ->placeholder('Scan the valid type')
|
||||
// ->reactive()
|
||||
// ->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||
// $lineTyp = $get('type');
|
||||
// // Ensure `linestop_id` is not cleared
|
||||
// if (!$lineTyp) {
|
||||
// $set('lTypeError', 'Scan the valid type.');
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// $set('lTypeError', null);
|
||||
// }
|
||||
// })
|
||||
// ->extraAttributes(fn ($get) => [
|
||||
// 'class' => $get('lTypeError') ? 'border-red-500' : '',
|
||||
// ])
|
||||
// ->hint(fn ($get) => $get('lTypeError') ? $get('lTypeError') : null)
|
||||
// ->hintColor('danger'),
|
||||
Forms\Components\Select::make('type')
|
||||
->label('Type')
|
||||
->required()
|
||||
->placeholder('Scan the valid type')
|
||||
->options([
|
||||
'Sub Assembly Serial' => 'Sub Assembly Serial',
|
||||
'Sub Assembly Lot' => 'Sub Assembly Lot',
|
||||
'Base FG Line' => 'Base FG Line',
|
||||
'SFG Line' => 'SFG Line',
|
||||
'FG Line' => 'FG Line',
|
||||
'Machining Cell' => 'Machining Cell',
|
||||
'Blanking Cell' => 'Blanking Cell',
|
||||
'Forming Cell' => 'Forming Cell',
|
||||
'Welding Cell' => 'Welding Cell',
|
||||
'Die-Casting Cell' => 'Die-Casting Cell',
|
||||
'Brazzing Cell' => 'Brazzing Cell',
|
||||
])
|
||||
->searchable()
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||
$lineTyp = $get('type');
|
||||
@@ -148,29 +186,48 @@ class LineResource extends Resource
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
// Tables\Columns\TextColumn::make('id')
|
||||
// ->label('ID')
|
||||
// ->numeric()
|
||||
// ->sortable(),
|
||||
Tables\Columns\TextColumn::make('No.')
|
||||
->label('No.')
|
||||
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
|
||||
$paginator = $livewire->getTableRecords();
|
||||
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
|
||||
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
|
||||
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
|
||||
}),
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->label('Line')
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('type')
|
||||
->label('Type')
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('plant.name')
|
||||
->label('Plant')
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->label('Updated At')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('deleted_at')
|
||||
->label('Deleted At')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
@@ -190,7 +247,15 @@ class LineResource extends Resource
|
||||
])
|
||||
->headerActions([
|
||||
ImportAction::make()
|
||||
->importer(LineImporter::class),
|
||||
->importer(LineImporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view import line');
|
||||
}),
|
||||
ExportAction::make()
|
||||
->exporter(LineExporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view export line');
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Filament\Imports\QualityValidationImporter;
|
||||
use App\Filament\Resources\QualityValidationResource\Pages;
|
||||
use App\Filament\Resources\QualityValidationResource\RelationManagers;
|
||||
use App\Models\Item;
|
||||
use App\Models\Line;
|
||||
use App\Models\Plant;
|
||||
use App\Models\QualityValidation;
|
||||
use App\Models\StickerMaster;
|
||||
@@ -50,12 +51,62 @@ class QualityValidationResource extends Resource
|
||||
Forms\Components\Select::make('plant_id')
|
||||
->relationship('plant', 'name')
|
||||
->reactive()
|
||||
->afterStateUpdated(fn (callable $set) => [
|
||||
$set('item_id', null),
|
||||
$set('validationError', null),
|
||||
])
|
||||
->afterStateUpdated(function (callable $set, callable $get) {
|
||||
$set('item_id', null);
|
||||
$set('line_id', null);
|
||||
$set('production_order', null);
|
||||
|
||||
$pId = $get('plant_id');
|
||||
if (!$pId) {
|
||||
$set('pqPlantError', 'Please select a plant first.');
|
||||
} else {
|
||||
$set('pqPlantError', null);
|
||||
}
|
||||
|
||||
$pId = $get('line_id');
|
||||
if (!$pId) {
|
||||
$set('pqLineError', null);
|
||||
}
|
||||
})
|
||||
->required()
|
||||
->default(fn () => request()->query('plant_id')),
|
||||
->default(fn () => request()->query('plant_id'))
|
||||
->extraAttributes(fn ($get) => [
|
||||
'class' => $get('pqPlantError') ? 'border-red-500' : '',
|
||||
])
|
||||
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
|
||||
->hintColor('danger'),
|
||||
Forms\Components\Select::make('line_id')
|
||||
->relationship('line', titleAttribute: 'name')
|
||||
->reactive()
|
||||
->required()
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
if (!$plantId)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return Line::where('plant_id', $plantId)
|
||||
->where('type', 'FG Line') // Filter by type
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
})
|
||||
->afterStateUpdated(function (callable $set, callable $get) {
|
||||
$set('item_id', null);
|
||||
$set('production_order', null);
|
||||
|
||||
$pId = $get('line_id');
|
||||
if (!$pId) {
|
||||
$set('pqLineError', 'Please select a line.');
|
||||
} else {
|
||||
$set('pqLineError', null);
|
||||
}
|
||||
})
|
||||
->extraAttributes(fn ($get) => [
|
||||
'class' => $get('pqLineError') ? 'border-red-500' : '',
|
||||
])
|
||||
->hint(fn ($get) => $get('pqLineError') ? $get('pqLineError') : null)
|
||||
->hintColor('danger'),
|
||||
Forms\Components\Hidden::make('sticker_master_id')
|
||||
// ->relationship('stickerMaster', 'id')
|
||||
->required(),
|
||||
@@ -111,6 +162,23 @@ class QualityValidationResource extends Resource
|
||||
->live()
|
||||
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
|
||||
|
||||
$pId = $get('line_id');
|
||||
if (!$pId) {
|
||||
$set('pqLineError', 'Please select a line.');
|
||||
} else {
|
||||
$set('pqLineError', null);
|
||||
}
|
||||
|
||||
$pOrder = $get('production_order');
|
||||
if (!$pOrder)
|
||||
{
|
||||
$set('productionError', 'Production Order cant be empty.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$set('productionError', null);
|
||||
}
|
||||
|
||||
$serialFields = [
|
||||
'serial_number_motor_qr', 'serial_number_pump_qr', 'serial_number_pumpset_qr', 'pack_slip_motor_qr', 'pack_slip_pump_qr', 'pack_slip_pumpset_qr', 'name_plate_motor_qr', 'name_plate_pump_qr', 'name_plate_pumpset_qr', 'tube_sticker_motor_qr', 'tube_sticker_pump_qr', 'tube_sticker_pumpset_qr', 'warranty_card_qr'
|
||||
];
|
||||
@@ -1894,21 +1962,37 @@ class QualityValidationResource extends Resource
|
||||
return $table
|
||||
->query(QualityValidation::query())
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
// Tables\Columns\TextColumn::make('id')
|
||||
// ->label('ID')
|
||||
// ->numeric()
|
||||
// ->sortable(),
|
||||
Tables\Columns\TextColumn::make('No.')
|
||||
->label('No.')
|
||||
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
|
||||
$paginator = $livewire->getTableRecords();
|
||||
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
|
||||
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
|
||||
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
|
||||
}),
|
||||
Tables\Columns\TextColumn::make('plant.name')
|
||||
->label('Plant')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('line.name')
|
||||
->label('Line')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('production_order')
|
||||
->label('Production Order')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('serial_number')
|
||||
->label('Serial Number')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('stickerMaster.item.code')
|
||||
->label('Item Code')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('uom')
|
||||
->label('Unit of Measure')
|
||||
@@ -1992,20 +2076,23 @@ class QualityValidationResource extends Resource
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('sap_msg_description')
|
||||
->label('SAP Message Description')
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
->alignCenter()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->label('Updated At')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('deleted_at')
|
||||
->label('Deleted At')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
@@ -2027,6 +2114,26 @@ class QualityValidationResource extends Resource
|
||||
$set('sticker_master_id', null);
|
||||
$set('sap_msg_status', null);
|
||||
}),
|
||||
Select::make('Line')
|
||||
->label('Select Line')
|
||||
->nullable()
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('Plant');
|
||||
if (!$plantId)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return Line::where('plant_id', $plantId)
|
||||
->where('type', 'FG Line') // Filter by type
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||
$set('sticker_master_id', null);
|
||||
$set('sap_msg_status', null);
|
||||
}),
|
||||
TextInput::make('production_order')
|
||||
->label('Production Order')
|
||||
->placeholder('Enter Production Order'),
|
||||
@@ -2083,6 +2190,10 @@ class QualityValidationResource extends Resource
|
||||
$query->where('plant_id', $data['Plant']);
|
||||
}
|
||||
|
||||
if (!empty($data['Line'])) {
|
||||
$query->where('line_id', $data['Line']);
|
||||
}
|
||||
|
||||
if (!empty($data['production_order'])) {
|
||||
$query->where('production_order', 'like', '%' . $data['production_order'] . '%');
|
||||
}
|
||||
@@ -2120,6 +2231,10 @@ class QualityValidationResource extends Resource
|
||||
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
|
||||
}
|
||||
|
||||
if (!empty($data['Line'])) {
|
||||
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
|
||||
}
|
||||
|
||||
if (!empty($data['production_order'])) {
|
||||
$indicators[] = 'Production Order: ' . $data['production_order'];
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Line;
|
||||
use App\Models\ProductionQuantity;
|
||||
use App\Models\QualityValidation;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
|
||||
class CumulativeChart extends ChartWidget
|
||||
@@ -15,13 +17,77 @@ class CumulativeChart extends ChartWidget
|
||||
|
||||
|
||||
protected int|string|array $columnSpan = 12;
|
||||
// protected function getData(): array
|
||||
// {
|
||||
// $selectedPlant = session('selected_plant');
|
||||
// $activeFilter = $this->filter;
|
||||
|
||||
// // Define date range based on filter
|
||||
// switch ($activeFilter) {
|
||||
// case 'yesterday':
|
||||
// $startDate = now()->subDay()->startOfDay();
|
||||
// $endDate = now()->subDay()->endOfDay();
|
||||
// break;
|
||||
// case 'this_week':
|
||||
// $startDate = now()->startOfWeek();
|
||||
// $endDate = now()->endOfWeek();
|
||||
// break;
|
||||
// case 'this_month':
|
||||
// $startDate = now()->startOfMonth();
|
||||
// $endDate = now()->endOfMonth();
|
||||
// break;
|
||||
// default: // today
|
||||
// $startDate = now()->startOfDay();
|
||||
// $endDate = now()->endOfDay();
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // Get all lines for selected plant
|
||||
// $lines = Line::where('plant_id', $selectedPlant)
|
||||
// ->pluck('name', 'id')
|
||||
// ->toArray();
|
||||
|
||||
// // Get total production per line in the date range
|
||||
// $production = \DB::table('production_quantities')
|
||||
// ->select('line_id', \DB::raw('COUNT(*) as total_quantity'))
|
||||
// ->whereBetween('created_at', [$startDate, $endDate])
|
||||
// ->whereIn('line_id', array_keys($lines))
|
||||
// ->groupBy('line_id')
|
||||
// ->pluck('total_quantity', 'line_id')
|
||||
// ->toArray();
|
||||
|
||||
// // Match quantities with lines (fill 0 if missing)
|
||||
// $labels = [];
|
||||
// $data = [];
|
||||
|
||||
// foreach ($lines as $lineId => $lineName) {
|
||||
// $labels[] = $lineName;
|
||||
// $data[] = $production[$lineId] ?? 0;
|
||||
// }
|
||||
|
||||
// return [
|
||||
// 'labels' => $labels,
|
||||
// 'datasets' => [
|
||||
// [
|
||||
// 'label' => match ($activeFilter) {
|
||||
// 'yesterday' => "Production Quantity (Yesterday)",
|
||||
// 'this_week' => "Daily Production This Week",
|
||||
// 'this_month' => "Weekly Production This Month",
|
||||
// default => "Today's Production",
|
||||
// },
|
||||
// 'data' => $data,
|
||||
// ],
|
||||
// ],
|
||||
// ];
|
||||
// }
|
||||
protected function getData(): array
|
||||
{
|
||||
$selectedPlant = session('selected_plant');
|
||||
$activeFilter = $this->filter;
|
||||
|
||||
// Define date range based on filter
|
||||
switch ($activeFilter) {
|
||||
// Define date range
|
||||
switch ($activeFilter)
|
||||
{
|
||||
case 'yesterday':
|
||||
$startDate = now()->subDay()->startOfDay();
|
||||
$endDate = now()->subDay()->endOfDay();
|
||||
@@ -40,46 +106,90 @@ class CumulativeChart extends ChartWidget
|
||||
break;
|
||||
}
|
||||
|
||||
// Get all lines for selected plant
|
||||
$lines = Line::where('plant_id', $selectedPlant)
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
// Get lines with names and types
|
||||
$lines = Line::where('plant_id', $selectedPlant)->get(['id', 'name', 'type']);
|
||||
|
||||
// Get total production per line in the date range
|
||||
$production = \DB::table('production_quantities')
|
||||
->select('line_id', \DB::raw('COUNT(*) as total_quantity'))
|
||||
$lineNames = [];
|
||||
$fgLineIds = [];
|
||||
$nonFgLineIds = [];
|
||||
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
$lineNames[$line->id] = $line->name;
|
||||
|
||||
if ($line->type == 'FG Line')
|
||||
{
|
||||
$fgLineIds[] = $line->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$nonFgLineIds[] = $line->id;
|
||||
}
|
||||
}
|
||||
|
||||
//FG production from quality_validations
|
||||
$fgProduction = QualityValidation::select('line_id', \DB::raw('COUNT(*) as total_quantity'))
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->whereIn('line_id', array_keys($lines))
|
||||
->whereIn('line_id', $fgLineIds)
|
||||
->groupBy('line_id')
|
||||
->pluck('total_quantity', 'line_id')
|
||||
->toArray();
|
||||
|
||||
// Match quantities with lines (fill 0 if missing)
|
||||
$labels = [];
|
||||
$data = [];
|
||||
//Non-FG production from production_quantities
|
||||
$nonFgProduction = ProductionQuantity::select('line_id', \DB::raw('COUNT(*) as total_quantity'))
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->whereIn('line_id', $nonFgLineIds)
|
||||
->groupBy('line_id')
|
||||
->pluck('total_quantity', 'line_id')
|
||||
->toArray();
|
||||
|
||||
foreach ($lines as $lineId => $lineName) {
|
||||
//Separate FG and non-FG into different datasets
|
||||
$labels = [];
|
||||
$fgData = [];
|
||||
$nonFgData = [];
|
||||
|
||||
foreach ($lineNames as $lineId => $lineName) {
|
||||
$labels[] = $lineName;
|
||||
$data[] = $production[$lineId] ?? 0;
|
||||
|
||||
if (in_array($lineId, $fgLineIds))
|
||||
{
|
||||
$fgData[] = $fgProduction[$lineId] ?? 0;
|
||||
$nonFgData[] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$nonFgData[] = $nonFgProduction[$lineId] ?? 0;
|
||||
$fgData[] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'labels' => $labels,
|
||||
'datasets' => [
|
||||
'datasets' => array_filter([
|
||||
[
|
||||
'label' => match ($activeFilter) {
|
||||
'yesterday' => "Production Quantity (Yesterday)",
|
||||
'this_week' => "Daily Production This Week",
|
||||
'this_month' => "Weekly Production This Month",
|
||||
default => "Today's Production",
|
||||
},
|
||||
'data' => $data,
|
||||
},
|
||||
'data' => $nonFgData,
|
||||
//'backgroundColor' => '#3b82f6', // Blue for non-FG
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => match ($activeFilter) {
|
||||
'yesterday' => "FG Count (Yesterday)",
|
||||
'this_week' => "FG Count This Week",
|
||||
'this_month' => "FG Count This Month",
|
||||
default => "Today's FG Count",
|
||||
},
|
||||
'data' => $fgData,
|
||||
// 'backgroundColor' => '#ef4444', // Red for FG
|
||||
],
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'bar';
|
||||
@@ -106,7 +216,6 @@ class CumulativeChart extends ChartWidget
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -34,129 +34,96 @@ class ItemOverview extends ChartWidget
|
||||
];
|
||||
}
|
||||
|
||||
if ($activeFilter === 'yesterday') {
|
||||
$startDate = now()->subDay()->setTime(8, 0, 0); // Yesterday 8:00 AM
|
||||
$endDate = now()->setTime(8, 0, 0); // Today 8:00 AM
|
||||
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
|
||||
}
|
||||
// Determine if line is FG Line
|
||||
$line = \App\Models\Line::find($selectedLine);
|
||||
$isFgLine = $line?->type == 'FG Line';
|
||||
|
||||
else if ($activeFilter === 'this_week') {
|
||||
// Monday 8:00 AM of the current week
|
||||
// Set date range and groupBy logic
|
||||
if ($activeFilter == 'yesterday')
|
||||
{
|
||||
$startDate = now()->subDay()->setTime(8, 0, 0);
|
||||
$endDate = now()->setTime(8, 0, 0);
|
||||
$groupBy = 'EXTRACT(HOUR FROM created_at)';
|
||||
}
|
||||
elseif ($activeFilter == 'this_week')
|
||||
{
|
||||
$startDate = now()->startOfWeek()->setTime(8, 0, 0);
|
||||
|
||||
$endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
|
||||
|
||||
$groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week
|
||||
$groupBy = 'EXTRACT(DOW FROM created_at)';
|
||||
}
|
||||
else if ($activeFilter === 'this_month') {
|
||||
elseif ($activeFilter == 'this_month')
|
||||
{
|
||||
$startDate = now()->startOfMonth();
|
||||
$endDate = now()->endOfMonth();
|
||||
$groupBy = "FLOOR((EXTRACT(DAY FROM production_quantities.created_at) - 1) / 7) + 1";
|
||||
$groupBy = "FLOOR((EXTRACT(DAY FROM created_at) - 1) / 7) + 1";
|
||||
}
|
||||
else
|
||||
{
|
||||
$startDate = now()->setTime(8, 0, 0); // today at 8:00 AM
|
||||
$endDate = now()->copy()->addDay()->setTime(8, 0, 0); // tomorrow at 8:00 AM
|
||||
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
|
||||
|
||||
$startDate = now()->setTime(8, 0, 0);
|
||||
$endDate = now()->copy()->addDay()->setTime(8, 0, 0);
|
||||
$groupBy = 'EXTRACT(HOUR FROM created_at)';
|
||||
}
|
||||
|
||||
$query = \DB::table('production_quantities')
|
||||
->join('plants', 'production_quantities.plant_id', '=', 'plants.id') //inner join
|
||||
->join('lines', 'production_quantities.line_id', '=', 'lines.id')
|
||||
->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity")
|
||||
//->whereBetween('production_quantities.created_at', [$startDate, $endDate])
|
||||
->where('production_quantities.created_at', '>=', $startDate) // $startDate should be >=
|
||||
->where('production_quantities.created_at', '<', $endDate) // $endDate should be <
|
||||
->when($selectedPlant, function ($q) use ($selectedPlant) {
|
||||
return $q->where('plants.id', $selectedPlant);
|
||||
})
|
||||
->when($selectedLine, function ($q) use ($selectedLine) {
|
||||
return $q->where('lines.id', $selectedLine);
|
||||
})
|
||||
$baseTable = $isFgLine ? 'quality_validations' : 'production_quantities';
|
||||
|
||||
->groupByRaw($groupBy)
|
||||
->orderByRaw($groupBy)
|
||||
->pluck('total_quantity', 'time_unit')
|
||||
->toArray();
|
||||
$query = \DB::table($baseTable)
|
||||
->selectRaw("$groupBy AS time_unit, COUNT(*) AS total_quantity")
|
||||
->where('created_at', '>=', $startDate)
|
||||
->where('created_at', '<', $endDate)
|
||||
->where('plant_id', $selectedPlant)
|
||||
->where('line_id', $selectedLine)
|
||||
->groupByRaw($groupBy)
|
||||
->orderByRaw($groupBy)
|
||||
->pluck('total_quantity', 'time_unit')
|
||||
->toArray();
|
||||
|
||||
if ($activeFilter == 'this_month')
|
||||
{
|
||||
$weeksCount = ceil($endDate->day / 7);
|
||||
$allWeeks = array_fill(1, $weeksCount, 0);
|
||||
$data = array_replace($allWeeks, $query);
|
||||
|
||||
if ($activeFilter === 'this_month') {
|
||||
$weeksCount = ceil($endDate->day / 7); // Calculate total weeks dynamically
|
||||
$allWeeks = array_fill(1, $weeksCount, 0); // Initialize all weeks with 0
|
||||
$data = array_replace($allWeeks, $query); // Fill missing weeks with 0
|
||||
|
||||
// Generate dynamic week labels
|
||||
$labels = [];
|
||||
for ($i = 1; $i <= $weeksCount; $i++) {
|
||||
$weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M');
|
||||
$weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M');
|
||||
$labels[] = "Week $i ($weekStart - $weekEnd)";
|
||||
}
|
||||
|
||||
$orderedData = array_values($data);
|
||||
$labels = [];
|
||||
for ($i = 1; $i <= $weeksCount; $i++) {
|
||||
$weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M');
|
||||
$weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M');
|
||||
$labels[] = "Week $i ($weekStart - $weekEnd)";
|
||||
}
|
||||
else if ($activeFilter === 'this_week') {
|
||||
// Correct week labels: ['Mon', 'Tue', ..., 'Sun']
|
||||
$labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
|
||||
// Initialize default data for all 7 days
|
||||
$data = array_fill(0, 7, 0);
|
||||
|
||||
// Fill in data from query results
|
||||
foreach ($query as $dow => $count) {
|
||||
$data[$dow] = $count;
|
||||
}
|
||||
|
||||
// Ensure days are ordered from Monday to Sunday
|
||||
$orderedData = [
|
||||
$data[1] ?? 0, // Monday
|
||||
$data[2] ?? 0, // Tuesday
|
||||
$data[3] ?? 0, // Wednesday
|
||||
$data[4] ?? 0, // Thursday
|
||||
$data[5] ?? 0, // Friday
|
||||
$data[6] ?? 0, // Saturday
|
||||
$data[0] ?? 0, // Sunday (move to last)
|
||||
];
|
||||
$orderedData = array_values($data);
|
||||
}
|
||||
elseif ($activeFilter == 'this_week')
|
||||
{
|
||||
$labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
$data = array_fill(0, 7, 0);
|
||||
foreach ($query as $dow => $count) {
|
||||
$data[$dow] = $count;
|
||||
}
|
||||
else if($activeFilter === 'yesterday')
|
||||
{
|
||||
|
||||
// Hourly data (same as before)
|
||||
$allHours = array_fill(0, 24, 0);
|
||||
$data = array_replace($allHours, $query);
|
||||
|
||||
// Shift hours for proper display (8 AM to 7 AM)
|
||||
$shiftedKeys = array_merge(range(8, 23), range(0, 7));
|
||||
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
|
||||
|
||||
// Labels: ["8 AM", "9 AM", ..., "7 AM"]
|
||||
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
|
||||
$orderedData = [
|
||||
$data[1] ?? 0, $data[2] ?? 0, $data[3] ?? 0,
|
||||
$data[4] ?? 0, $data[5] ?? 0, $data[6] ?? 0,
|
||||
$data[0] ?? 0,
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Hourly data (same as before)
|
||||
$allHours = array_fill(0, 24, 0);
|
||||
$data = array_replace($allHours, $query);
|
||||
|
||||
// Shift hours for proper display (8 AM to 7 AM)
|
||||
$shiftedKeys = array_merge(range(8, 23), range(0, 7));
|
||||
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
|
||||
|
||||
// Labels: ["8 AM", "9 AM", ..., "7 AM"]
|
||||
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => match ($activeFilter) {
|
||||
'this_week' => "Daily Production This Week",
|
||||
'this_month' => "Weekly Production This Month", // Updated Label
|
||||
'yesterday' => "Yesterday's Hourly Production",
|
||||
default => "Today's Hourly Production",
|
||||
'this_week' => $isFgLine ? 'Daily FG Count This Week' : 'Daily Production This Week',
|
||||
'this_month' => $isFgLine ? 'Weekly FG Count This Month' : 'Weekly Production This Month',
|
||||
'yesterday' => $isFgLine ? "Yesterday's FG Count" : "Yesterday's Hourly Production",
|
||||
default => $isFgLine ? "Today's FG Count" : "Today's Hourly Production",
|
||||
},
|
||||
'data' => $orderedData,
|
||||
'interaction' => [
|
||||
@@ -195,32 +162,6 @@ class ItemOverview extends ChartWidget
|
||||
}
|
||||
|
||||
|
||||
// protected function getOptions(): array
|
||||
// {
|
||||
// return [
|
||||
// 'plugins' => [
|
||||
// 'datalabels' => [
|
||||
// 'color' => '#3490dc',
|
||||
// 'font' => [
|
||||
// 'weight' => 'bold',
|
||||
// 'size' => 14,
|
||||
// ],
|
||||
// 'backgroundColor' => 'rgba(255,255,255,0.8)',
|
||||
// 'borderRadius' => 4,
|
||||
// 'formatter' => \Illuminate\Support\Js::from(
|
||||
// new Js('function(value, context) {
|
||||
// if (Number(value) === 0) {
|
||||
// return null;
|
||||
// }
|
||||
// return "Count: " + value;
|
||||
// }')
|
||||
// ),
|
||||
// ]
|
||||
// ]
|
||||
// ];
|
||||
// }
|
||||
|
||||
|
||||
protected function getFilters(): ?array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -13,6 +13,7 @@ class QualityValidation extends Model
|
||||
protected $fillable = [
|
||||
'sticker_master_id',
|
||||
'plant_id',
|
||||
'line_id',
|
||||
'production_order',
|
||||
'serial_number_motor',
|
||||
'serial_number_pump',
|
||||
@@ -48,4 +49,9 @@ class QualityValidation extends Model
|
||||
{
|
||||
return $this->belongsTo(Plant::class);
|
||||
}
|
||||
|
||||
public function line(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Line::class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user