Quality Validation - Dashboard - Production Quantity Validation and Plan Quantity Updation
This commit is contained in:
@@ -226,6 +226,7 @@ class ProductionLineStopResource extends Resource
|
||||
Forms\Components\DateTimePicker::make('to_datetime')
|
||||
->label('To DateTime')
|
||||
->required()
|
||||
->after('from_datetime')
|
||||
->reactive()
|
||||
->afterStateUpdated(fn ($state, callable $set, callable $get) =>
|
||||
self::updateStopDuration($get, $set) //self means it calling the function within the class
|
||||
@@ -260,11 +261,21 @@ class ProductionLineStopResource extends Resource
|
||||
|
||||
if ($fromTime->lt($toTime)) {
|
||||
$diffInMinutes = $fromTime->diffInMinutes($toTime);
|
||||
$set('stop_hour', floor($diffInMinutes / 60));
|
||||
$set('stop_min', $diffInMinutes % 60);
|
||||
// $set('stop_hour', floor($diffInMinutes / 60));
|
||||
// $set('stop_min', $diffInMinutes % 60);
|
||||
if((floor($diffInMinutes / 60) === 0.0) && ($diffInMinutes % 60 === 0))
|
||||
{
|
||||
$set('stop_hour', null);
|
||||
$set('stop_min', null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$set('stop_hour', floor($diffInMinutes / 60));
|
||||
$set('stop_min', $diffInMinutes % 60);
|
||||
}
|
||||
} else {
|
||||
$set('stop_hour', 0);
|
||||
$set('stop_min', 0);
|
||||
$set('stop_hour', null);
|
||||
$set('stop_min', null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
|
||||
class ProductionPlanResource extends Resource
|
||||
{
|
||||
@@ -147,6 +148,25 @@ class ProductionPlanResource extends Resource
|
||||
}
|
||||
else
|
||||
{
|
||||
//SELECT COUNT(*) FROM plant_quantity_details WHERE DATE(created_at) = '{DateTime.Now.ToString("yyyy-MM-dd")}' AND shift_id = '{userShiftId}' AND plant_id = '{userPlantId}' AND line_id = '{userLineId}'
|
||||
//Day shift 'Plant Production Quantity' already updated into database
|
||||
|
||||
// $currentPath = url()->current();
|
||||
// $currentPath = $_SERVER['REQUEST_URI'];
|
||||
// dd($currentPath);
|
||||
$exists = ProductionPlan::where('plant_id', $get('plant_id'))
|
||||
->where('shift_id', $get('shift_id'))
|
||||
->where('line_id', $get('line_id'))
|
||||
->whereDate('created_at', today())
|
||||
->exists();
|
||||
|
||||
if ($exists)
|
||||
{
|
||||
$set('line_id', null);
|
||||
$set('ppLineError', $get('shift_id.name').' Production Plan already updated.');
|
||||
return;
|
||||
}
|
||||
|
||||
$set('ppLineError', null);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -143,20 +143,24 @@ class ProductionQuantityResource extends Resource
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||
$lineId = $get('line_id');
|
||||
$set('item_code', null);
|
||||
if (!$lineId) {
|
||||
$set('ppLineError', 'Please select a line first.');
|
||||
$set('pqLineError', 'Please select a line first.');
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$set('validationError', null);
|
||||
$set('ppLineError', null);
|
||||
$set('pqLineError', null);
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
}
|
||||
})
|
||||
->extraAttributes(fn ($get) => [
|
||||
'class' => $get('ppLineError') ? 'border-red-500' : '',
|
||||
'class' => $get('pqLineError') ? 'border-red-500' : '',
|
||||
])
|
||||
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
|
||||
->hint(fn ($get) => $get('pqLineError') ? $get('pqLineError') : null)
|
||||
->hintColor('danger'),
|
||||
// Forms\Components\Select::make('item_id')
|
||||
// ->label('Item Code')
|
||||
@@ -214,62 +218,128 @@ class ProductionQuantityResource extends Resource
|
||||
$set('validationError', 'Please select a line first.');
|
||||
return;
|
||||
}
|
||||
|
||||
$exists = \App\Models\ProductionPlan::where('plant_id', $get('plant_id'))
|
||||
->where('shift_id', $get('shift_id'))
|
||||
->where('line_id', $get('line_id'))
|
||||
->whereDate('created_at', today())
|
||||
->exists();
|
||||
|
||||
if (!$exists)
|
||||
{
|
||||
$set('item_code', null);
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
$set('validationError', 'Please set production plan first.');
|
||||
return;
|
||||
}
|
||||
|
||||
$set('validationError', null);
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]+\|[a-zA-Z0-9]+(\|)?$/', $state)) {
|
||||
if (!preg_match('/^[a-zA-Z0-9]{6,}+\|[1-9][a-zA-Z0-9]{8,}+(\|)?$/', $state)) {
|
||||
if (strpos($state, '|') === false) {
|
||||
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$splits = explode('|', $state);
|
||||
$iCode = trim($splits[0]);
|
||||
$sNumber = isset($splits[1]) ? trim($splits[1]) : null;
|
||||
|
||||
if (!ctype_alnum($iCode)) {
|
||||
$set('validationError', 'Item code must contain alpha-numeric values.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if (strlen($iCode) < 6) {
|
||||
$set('validationError', 'Item code must be at least 6 digits.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if (!ctype_alnum($sNumber)) {
|
||||
$set('validationError', 'Serial Number must contain alpha-numeric values.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if (strlen($sNumber) < 9) {
|
||||
$set('validationError', 'Serial Number must be at least 9 digits.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only search when all parent IDs are selected
|
||||
$parts = explode('|', $state);
|
||||
|
||||
$itemCode = trim($parts[0]); // Extract item code // 123456|123456789
|
||||
|
||||
$serialNumber = isset($parts[1]) ? trim($parts[1]) : null;
|
||||
|
||||
if (strlen($itemCode) < 6) {
|
||||
$set('validationError', 'Item code must be at least 6 digits.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if (!ctype_alnum($itemCode)) {
|
||||
$set('validationError', 'Item code should contain alpha-numeric values.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if ($serialNumber === '') {
|
||||
$set('validationError', 'Waiting for full QR scan...');
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return; // Do not clear item_id, just wait for full input
|
||||
}
|
||||
else if (strlen($serialNumber) < 9) {
|
||||
$set('validationError', 'Serial Number must be at least 9 digits.');
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else if (!ctype_alnum($serialNumber)) {
|
||||
$set('validationError', 'Serial Number should contain alpha-numeric values.');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$set('validationError', null);
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
}
|
||||
|
||||
// Only search when all parent IDs are selected
|
||||
$parts = explode('|', $state);
|
||||
$itemCode = trim($parts[0]);
|
||||
$serialNumber = isset($parts[1]) ? trim($parts[1]) : null;
|
||||
|
||||
// if (strlen($itemCode) < 6) {
|
||||
// $set('validationError', 'Item code must be at least 6 digits.');
|
||||
// $set('item_id', null);
|
||||
// $set('item_description', null);
|
||||
// $set('serial_number', null);
|
||||
// return;
|
||||
// }
|
||||
// else if (!ctype_alnum($itemCode)) {
|
||||
// $set('validationError', 'Item code must contain alpha-numeric values.');
|
||||
// $set('item_id', null);
|
||||
// $set('item_description', null);
|
||||
// $set('serial_number', null);
|
||||
// return;
|
||||
// }
|
||||
// else if ($serialNumber === '') {
|
||||
// $set('validationError', 'Waiting for full QR scan...');
|
||||
// $set('item_id', null);
|
||||
// $set('item_description', null);
|
||||
// $set('serial_number', null);
|
||||
// return; // Do not clear item_id, just wait for full input
|
||||
// }
|
||||
// else if (strlen($serialNumber) < 9) {
|
||||
// $set('validationError', 'Serial Number must be at least 9 digits.');
|
||||
// $set('item_description', null);
|
||||
// $set('serial_number', null);
|
||||
// return;
|
||||
// }
|
||||
// else if (!ctype_alnum($serialNumber)) {
|
||||
// $set('validationError', 'Serial Number must contain alpha-numeric values.');
|
||||
// $set('item_id', null);
|
||||
// $set('item_description', null);
|
||||
// $set('serial_number', null);
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// $set('validationError', null);
|
||||
// }
|
||||
|
||||
// Fetch item using item code and plant_id
|
||||
$item = \App\Models\Item::where('code', $itemCode)
|
||||
->where('plant_id', $get('plant_id'))
|
||||
@@ -284,7 +354,7 @@ class ProductionQuantityResource extends Resource
|
||||
{
|
||||
$set('serial_number', $serialNumber);
|
||||
$set('item_id', $item->id);
|
||||
$set('item_code', $itemCode); //$itemCode
|
||||
$set('item_code', $itemCode);
|
||||
$set('item_description', $item->description);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -7,12 +7,19 @@ use App\Filament\Resources\QualityValidationResource\RelationManagers;
|
||||
use App\Models\QualityValidation;
|
||||
use Closure;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\Relationship;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
|
||||
|
||||
class QualityValidationResource extends Resource
|
||||
@@ -73,29 +80,70 @@ class QualityValidationResource extends Resource
|
||||
}
|
||||
|
||||
// Proceed with validation logic for new scanned QR code
|
||||
if (!$state) {
|
||||
if (!$state || trim($state) === '') {
|
||||
$set('validationError', null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($state, '|') === false)
|
||||
{
|
||||
// Check if QR format contains '|'
|
||||
if (strpos($state, '|') === false) {
|
||||
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]{6,}+\|[1-9][a-zA-Z0-9]{8,}+(\|)?$/', $state)) {
|
||||
if (strpos($state, '|') === false) {
|
||||
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
|
||||
$set('item_id', null);
|
||||
$set('item_description', null);
|
||||
$set('serial_number', null);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$splits = explode('|', $state);
|
||||
$iCode = trim($splits[0]);
|
||||
$sNumber = isset($splits[1]) ? trim($splits[1]) : null;
|
||||
|
||||
if (!ctype_alnum($iCode)) {
|
||||
$set('validationError', 'Item code must contain alpha-numeric values.');
|
||||
return;
|
||||
}
|
||||
else if (strlen($iCode) < 6) {
|
||||
$set('validationError', 'Item code must be at least 6 digits.');
|
||||
return;
|
||||
}
|
||||
else if (!ctype_alnum($sNumber)) {
|
||||
$set('validationError', 'Serial Number must contain alpha-numeric values.');
|
||||
return;
|
||||
}
|
||||
else if (strlen($sNumber) < 9) {
|
||||
$set('validationError', 'Serial Number must be at least 9 digits.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$set('validationError', null);
|
||||
}
|
||||
|
||||
$parts = explode('|', $state);
|
||||
|
||||
$itemCode = trim($parts[0]); // Extract item code // 123456|123456789
|
||||
|
||||
$serialNumber = trim($parts[1]);
|
||||
|
||||
// Store serial number before resetting fields
|
||||
// Store serial number before resetting fields
|
||||
$previousSerialNumber = $serialNumber;
|
||||
|
||||
$previousItemCode = $itemCode;
|
||||
|
||||
if (strlen($itemCode) < 6) {
|
||||
$set('validationError', 'Item code must be at least 6 digits.');
|
||||
$set('item_id', null);
|
||||
return;
|
||||
}
|
||||
else if (!ctype_alnum($itemCode)) {
|
||||
@@ -121,13 +169,6 @@ class QualityValidationResource extends Resource
|
||||
$set('validationError', null);
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]+\|[a-zA-Z0-9]+(\|)?$/', $state)) {
|
||||
$set('validationError', 'Invalid QR code format. Expected: Item_Code|Serial_Number.');
|
||||
return;
|
||||
}
|
||||
|
||||
//$set('validationError', null);
|
||||
|
||||
$plantId = $get('plant_id'); // Get selected plant
|
||||
|
||||
if (!$plantId) {
|
||||
@@ -144,7 +185,7 @@ class QualityValidationResource extends Resource
|
||||
|
||||
|
||||
if (!$stickerMaster) {
|
||||
$set('validationError', 'Scanned item code does not exist for the selected plant.');
|
||||
$set('validationError', 'Item code does not exist in master data.');
|
||||
$set('sticker_master_id', null);
|
||||
return;
|
||||
}
|
||||
@@ -168,18 +209,18 @@ class QualityValidationResource extends Resource
|
||||
}
|
||||
}
|
||||
|
||||
$serialExists = QualityValidation::where('sticker_master_id', $stickerMaster->id)
|
||||
->where(function ($query) use ($serialNumber, $serialFields) {
|
||||
foreach ($serialFields as $column) {
|
||||
$query->orWhere($column, $serialNumber);
|
||||
}
|
||||
})->exists();
|
||||
// $serialExists = QualityValidation::where('sticker_master_id', $stickerMaster->id)
|
||||
// ->where(function ($query) use ($serialNumber, $serialFields) {
|
||||
// foreach ($serialFields as $column) {
|
||||
// $query->orWhere($column, $serialNumber);
|
||||
// }
|
||||
// })->exists();
|
||||
|
||||
if ($serialExists) {
|
||||
$set('validationError', 'Already scanning process completed.');
|
||||
$set('item_id', "$previousItemCode|$previousSerialNumber"); // Restore original QR code
|
||||
return;
|
||||
}
|
||||
// if ($serialExists) {
|
||||
// $set('validationError', 'Already scanning process completed.');
|
||||
// $set('item_id', "$previousItemCode|$previousSerialNumber"); // Restore original QR code
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Check if the serial number exists in any column of any row
|
||||
$serialExists = QualityValidation::where(function ($query) use ($serialNumber, $serialFields) {
|
||||
@@ -507,17 +548,56 @@ class QualityValidationResource extends Resource
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->searchable()
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('plant.name')
|
||||
->numeric()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('stickerMaster.id')
|
||||
->numeric()
|
||||
Tables\Columns\TextColumn::make('stickerMaster.item.code')
|
||||
->label('Item Code')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('production_order')
|
||||
->label('Production Order')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('serial_number_motor')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('serial_number_pump')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('serial_number_pumpset')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('pack_slip_motor')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('pack_slip_pump')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('pack_slip_pumpset')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('name_plate_motor')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('name_plate_pump')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('name_plate_pumpset')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('tube_sticker_motor')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('tube_sticker_pump')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('tube_sticker_pumpset')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('warranty_card')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('part_validation1')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('part_validation2')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('part_validation3')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('part_validation4')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('part_validation5')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
@@ -532,12 +612,73 @@ class QualityValidationResource extends Resource
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
|
||||
Tables\Filters\TrashedFilter::make(),
|
||||
SelectFilter::make('item_code')
|
||||
->relationship('stickerMaster.item', 'code')
|
||||
->label('Filter by item code')
|
||||
->searchable(),
|
||||
|
||||
Filter::make('production_order')
|
||||
->label('Filter by Production Order')
|
||||
->form([
|
||||
TextInput::make('production_order')
|
||||
->placeholder('Enter Production Order'),
|
||||
|
||||
])
|
||||
->query(function ($query, array $data) {
|
||||
return $query
|
||||
->when(
|
||||
$data['production_order'] ?? null,
|
||||
fn ($q) => $q->where('production_order', 'like', '%' . $data['production_order'] . '%')
|
||||
);
|
||||
})
|
||||
|
||||
// This function adds indicators to show applied filters in the UI.
|
||||
// It helps users see what filters are currently active.
|
||||
|
||||
->indicateUsing(function (array $data) {
|
||||
return empty($data['production_order']) ? [] : ['Production Order: ' . $data['production_order']];
|
||||
}),
|
||||
|
||||
// Created Date Range Filter
|
||||
Filter::make('created_at')
|
||||
->form([
|
||||
DateTimePicker::make('created_from')
|
||||
->label('Created From')
|
||||
->native(false), // Optional: Use a nice date picker UI
|
||||
|
||||
DateTimePicker::make('created_to')
|
||||
->label('Created To')
|
||||
->native(false),
|
||||
])
|
||||
->query(function ($query, array $data) {
|
||||
return $query
|
||||
->when(
|
||||
$data['created_from'] ?? null,
|
||||
fn ($q) => $q->where('created_at', '>=', $data['created_from'])
|
||||
)
|
||||
->when(
|
||||
$data['created_to'] ?? null,
|
||||
fn ($q) => $q->where('created_at', '<=', $data['created_to'])
|
||||
);
|
||||
})
|
||||
->indicateUsing(function (array $data) {
|
||||
$indicators = [];
|
||||
if (!empty($data['created_from'])) {
|
||||
$indicators[] = 'From: ' . $data['created_from'];
|
||||
}
|
||||
if (!empty($data['created_to'])) {
|
||||
$indicators[] = 'To: ' . $data['created_to'];
|
||||
}
|
||||
return $indicators;
|
||||
}),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
@@ -545,6 +686,7 @@ class QualityValidationResource extends Resource
|
||||
Tables\Actions\RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
|
||||
@@ -187,6 +187,7 @@ class StickerMasterResource extends Resource
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->searchable()
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -12,72 +12,169 @@ class ItemOverview extends ChartWidget
|
||||
|
||||
//protected $listeners = ['filtersUpdated' => '$refresh']; // Listen for filter updates
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$activeFilter = $this->filter;
|
||||
// Get filter values from session
|
||||
$selectedPlant = session('selected_plant');
|
||||
$selectedLine = session('selected_line');
|
||||
// protected function getData(): array
|
||||
// {
|
||||
// $activeFilter = $this->filter;
|
||||
// // Get filter values from session
|
||||
// $selectedPlant = session('selected_plant');
|
||||
// $selectedLine = session('selected_line');
|
||||
|
||||
$query = \DB::table('production_quantities')
|
||||
->join('plants', 'production_quantities.plant_id', '=', 'plants.id') // Join plants table
|
||||
->join('lines', 'production_quantities.line_id', '=', 'lines.id') // Join lines table
|
||||
->selectRaw('EXTRACT(HOUR FROM production_quantities.created_at) AS hour, count(*) AS total_quantity')
|
||||
->whereBetween('production_quantities.created_at', [now()->startOfDay(), now()->endOfDay()])
|
||||
// $query = \DB::table('production_quantities')
|
||||
// ->join('plants', 'production_quantities.plant_id', '=', 'plants.id') // Join plants table
|
||||
// ->join('lines', 'production_quantities.line_id', '=', 'lines.id') // Join lines table
|
||||
// ->selectRaw('EXTRACT(HOUR FROM production_quantities.created_at) AS hour, count(*) AS total_quantity')
|
||||
// ->whereBetween('production_quantities.created_at', [now()->startOfDay(), now()->endOfDay()])
|
||||
// ->when($selectedPlant, function ($q) use ($selectedPlant) {
|
||||
// return $q->where('plants.id', $selectedPlant);
|
||||
// })
|
||||
// ->when($selectedLine, function ($q) use ($selectedLine) {
|
||||
// return $q->where('lines.id', $selectedLine);
|
||||
// })
|
||||
// ->groupByRaw('EXTRACT(HOUR FROM production_quantities.created_at)')
|
||||
// ->orderByRaw('EXTRACT(HOUR FROM production_quantities.created_at)')
|
||||
// ->pluck('total_quantity', 'hour')
|
||||
// ->toArray();
|
||||
|
||||
// $allHours = array_fill(0, 24, 0);
|
||||
// $data = array_replace($allHours, $query);
|
||||
|
||||
// $shiftedKeys = range(8, 23); // 8 AM to 11 PM
|
||||
// $shiftedKeys = array_merge($shiftedKeys, range(0, 8));
|
||||
|
||||
// $orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
|
||||
|
||||
// return [
|
||||
// 'datasets' => [
|
||||
// [
|
||||
// 'label' => 'Hourly Production',
|
||||
// 'data' => array_values($orderedData),
|
||||
// 'borderColor' => 'rgba(75, 192, 192, 1)',
|
||||
// 'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
|
||||
// 'fill' => false,
|
||||
// 'tension' => 0.3,
|
||||
// ],
|
||||
// ],
|
||||
// // Correct label sequence from 8 AM to 7 AM
|
||||
// 'labels' => array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys),
|
||||
// ];
|
||||
|
||||
// }
|
||||
protected function getData(): array
|
||||
{
|
||||
$activeFilter = $this->filter;
|
||||
$selectedPlant = session('selected_plant');
|
||||
$selectedLine = session('selected_line');
|
||||
|
||||
if ($activeFilter === 'yesterday') {
|
||||
$startDate = now()->subDay()->startOfDay();
|
||||
$endDate = now()->subDay()->endOfDay();
|
||||
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
|
||||
}
|
||||
else if ($activeFilter === 'this_week') {
|
||||
$startDate = now()->startOfWeek(); // Monday 12:00 AM
|
||||
$endDate = now()->endOfWeek(); // Sunday 11:59 PM
|
||||
$groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week
|
||||
}
|
||||
else if ($activeFilter === 'this_month') {
|
||||
$startDate = now()->startOfMonth();
|
||||
$endDate = now()->endOfMonth();
|
||||
|
||||
// Group records into weeks
|
||||
$groupBy = "FLOOR((EXTRACT(DAY FROM production_quantities.created_at) - 1) / 7) + 1";
|
||||
}
|
||||
else
|
||||
{
|
||||
$startDate = now()->startOfDay();
|
||||
$endDate = now()->endOfDay();
|
||||
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
|
||||
}
|
||||
|
||||
$query = \DB::table('production_quantities')
|
||||
->join('plants', 'production_quantities.plant_id', '=', 'plants.id')
|
||||
->join('lines', 'production_quantities.line_id', '=', 'lines.id')
|
||||
->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity")
|
||||
->whereBetween('production_quantities.created_at', [$startDate, $endDate])
|
||||
->when($selectedPlant, function ($q) use ($selectedPlant) {
|
||||
return $q->where('plants.id', $selectedPlant);
|
||||
})
|
||||
->when($selectedLine, function ($q) use ($selectedLine) {
|
||||
return $q->where('lines.id', $selectedLine);
|
||||
})
|
||||
->groupByRaw('EXTRACT(HOUR FROM production_quantities.created_at)')
|
||||
->orderByRaw('EXTRACT(HOUR FROM production_quantities.created_at)')
|
||||
->pluck('total_quantity', 'hour')
|
||||
|
||||
->groupByRaw($groupBy)
|
||||
->orderByRaw($groupBy)
|
||||
->pluck('total_quantity', 'time_unit')
|
||||
->toArray();
|
||||
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
|
||||
|
||||
// // Ensure all 24 hours are covered, filling missing ones with zero
|
||||
// $data = array_replace(array_fill(8, 24, 0), $query);
|
||||
// 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)";
|
||||
}
|
||||
|
||||
// return [
|
||||
// 'datasets' => [
|
||||
// [
|
||||
// 'label' => 'Hourly Production',
|
||||
// 'data' => array_values($data),
|
||||
// 'borderColor' => 'rgba(75, 192, 192, 1)',
|
||||
// 'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
|
||||
// 'fill' => false,
|
||||
// 'tension' => 0.3,
|
||||
// ],
|
||||
// ],
|
||||
// // 'labels' => array_map(fn ($hour) => ($hour == 0 ? '12 AM' : ($hour == 12 ? '12 PM' : ($hour < 12 ? "{$hour} AM" : ($hour - 12) . " PM"))), array_keys($data)),
|
||||
// // Labels in 24-hour format
|
||||
// 'labels' => array_map(fn ($hour) => date("g A", strtotime("$hour:00")), array_keys($data)), // Improved hour formatting
|
||||
// ];
|
||||
$orderedData = array_values($data);
|
||||
}
|
||||
else if ($activeFilter === 'this_week') {
|
||||
// Correct week labels: ['Mon', 'Tue', ..., 'Sun']
|
||||
$labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
|
||||
$allHours = array_fill(0, 24, 0);
|
||||
$data = array_replace($allHours, $query);
|
||||
// Initialize default data for all 7 days
|
||||
$data = array_fill(0, 7, 0);
|
||||
|
||||
$shiftedKeys = range(8, 23); // 8 AM to 11 PM
|
||||
$shiftedKeys = array_merge($shiftedKeys, range(0, 8));
|
||||
// Fill in data from query results
|
||||
foreach ($query as $dow => $count) {
|
||||
$data[$dow] = $count;
|
||||
}
|
||||
|
||||
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
|
||||
// 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)
|
||||
];
|
||||
|
||||
} 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, 8));
|
||||
$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' => 'Hourly Production',
|
||||
'data' => array_values($orderedData),
|
||||
'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",
|
||||
},
|
||||
'data' => $orderedData,
|
||||
'borderColor' => 'rgba(75, 192, 192, 1)',
|
||||
'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
|
||||
'fill' => false,
|
||||
'tension' => 0.3,
|
||||
],
|
||||
],
|
||||
// Correct label sequence from 8 AM to 7 AM
|
||||
'labels' => array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys),
|
||||
'labels' => $labels,
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
@@ -102,6 +199,9 @@ class ItemOverview extends ChartWidget
|
||||
{
|
||||
return [
|
||||
'today' => 'Today',
|
||||
'yesterday' => 'Yesterday',
|
||||
'this_week'=> 'This Week',
|
||||
'this_month'=> 'This Month',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -37,4 +37,23 @@ class ProductionQuantity extends Model
|
||||
{
|
||||
return $this->belongsTo(Item::class);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($productionQuantity) {
|
||||
$productionPlan = ProductionPlan::where('plant_id', $productionQuantity->plant_id)
|
||||
->where('shift_id', $productionQuantity->shift_id)
|
||||
->where('line_id', $productionQuantity->line_id)
|
||||
->whereDate('created_at',today())
|
||||
// ->where('plan_quantity', $productionQuantity->plan_quantity)
|
||||
->first();
|
||||
|
||||
if ($productionPlan) {
|
||||
$productionPlan->update([
|
||||
'production_quantity' => $productionPlan->production_quantity + 1,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user