diff --git a/app/Filament/Pages/ProductionNonPlannedReport.php b/app/Filament/Pages/ProductionNonPlannedReport.php
new file mode 100644
index 00000000..2c0af18d
--- /dev/null
+++ b/app/Filament/Pages/ProductionNonPlannedReport.php
@@ -0,0 +1,194 @@
+form->fill([
+ 'date' => null,
+ 'plant_id' => null,
+ 'line_id' => null,
+ 'category' => null,
+ ]);
+ }
+
+
+ public function form(Form $form): Form
+ {
+ return $form
+ ->statePath('filters')
+ ->schema([
+ Section::make('')
+ ->schema([
+
+ DateTimePicker::make('date')
+ ->label('Choose Date')
+ ->native(false)
+ ->displayFormat('d-m-Y')
+ ->reactive(),
+
+ Select::make('plant_id')
+ ->label('Plant')
+ ->relationship('plant', 'name')
+ ->reactive()
+ // ->searchable()
+ ->options(function (callable $get) {
+ $userHas = Filament::auth()->user()->plant_id;
+ return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
+ })
+ ->required()
+ ->afterStateUpdated(function ($state, callable $get, $set) {
+ // dd($state);
+ $set('line_id', null);
+ $set('category', null);
+ $this->dispatch('loadData',$state, '', '', '', '');
+ }),
+ Select::make('line_id')
+ ->label('Line')
+ ->required()
+ // ->relationship('line', 'name')
+ // ->searchable()
+ ->columnSpan(1)
+ ->options(function (callable $get) {
+ if (!$get('plant_id')) {
+ return [];
+ }
+
+ return \App\Models\Line::where('plant_id', $get('plant_id'))
+ ->pluck('name', 'id')
+ ->toArray();
+ })
+ ->reactive()
+ ->afterStateUpdated(function ($state, callable $get, $set) {
+ $plantId = $get('plant_id');
+ $lineId = $state;
+ $month = $get('month');
+ $year = $get('year');
+ $date = $get('date');
+
+ $month = (int) $get('month');
+ $this->dispatch('loadData',$year, $month, $plantId, $lineId, $date);
+ }),
+
+ // Select::make('item_id')
+ // ->label('Item Code')
+ // ->placeholder('Select Item Code')
+ // ->options(function (callable $get) {
+ // $plantId = $get('plant_id');
+ // $lineId = $get('line_id');
+ // $date = $get('date');
+
+ // if (!$plantId || !$lineId || !$date) {
+ // return [];
+ // }
+
+ // $selectedDate = Carbon::parse($date)->startOfDay();
+ // $startDate = $selectedDate->copy()->setTime(8, 0, 0);
+ // $endDate = $startDate->copy()->addDay();
+
+ // $month = $selectedDate->month;
+ // $year = $selectedDate->year;
+
+ // $plannedItemIds = ProductionPlan::query()
+ // ->where('plant_id', $plantId)
+ // ->where('line_id', $lineId)
+ // ->whereMonth('production_plans.created_at', $month)
+ // ->whereYear('production_plans.created_at', $year)
+ // ->whereNotNull('item_id')
+ // ->distinct()
+ // ->pluck('item_id');
+
+ // $stickerMasterIds = QualityValidation::query()
+ // ->where('plant_id', $plantId)
+ // ->where('line_id', $lineId)
+ // ->where('created_at', '>=', $startDate)
+ // ->where('created_at', '<', $endDate)
+ // ->whereNotNull('sticker_master_id')
+ // ->distinct()
+ // ->pluck('sticker_master_id');
+
+ // $producedItemIds = StickerMaster::query()
+ // ->whereIn('id', $stickerMasterIds)
+ // ->whereNotNull('item_id')
+ // ->distinct()
+ // ->pluck('item_id');
+
+ // return Item::query()
+ // ->whereIn('id', $producedItemIds)
+ // ->whereNotIn('id', $plannedItemIds)
+ // ->orderBy('code')
+ // ->pluck('code', 'id')
+ // ->toArray();
+ // })
+ // ->searchable()
+ // ->reactive()
+ // ->required(),
+
+ TextInput::make('category')
+ ->label('Category')
+ ->reactive()
+ ->afterStateUpdated(function ($state, callable $get, $set) {
+ $plantId = $get('plant_id');
+ $lineId = $get('line_id');
+ // $month = $get('month');
+ $year = $get('year');
+
+ $month = (int) $get('month');
+ $category = $get('category');
+
+ }),
+
+ ])
+ ->columns(4)
+ ]);
+ }
+
+ public function generateNonPlan(){
+ $plantId = $this->filters['plant_id'] ?? null;
+ $lineId = $this->filters['line_id'] ?? null;
+ $date = $this->filters['date'] ?? null;
+ $category = $this->filters['category'] ?? null;
+ if($category == '' || $category == null){
+ $this->dispatch('loadData', $date, $plantId, $lineId);
+ }
+ else{
+ $this->dispatch('loadDataCategory',$date, $plantId, $lineId, $category);
+ }
+ }
+
+ public static function canAccess(): bool
+ {
+ return Auth::check() && Auth::user()->can('view production non planned page');
+ }
+
+}
diff --git a/app/Livewire/ProductionNonPlanned.php b/app/Livewire/ProductionNonPlanned.php
new file mode 100644
index 00000000..4f5eb9fb
--- /dev/null
+++ b/app/Livewire/ProductionNonPlanned.php
@@ -0,0 +1,278 @@
+ 'loadProductionData',
+ 'loadDataCategory' => 'loadProductionCategoryData'
+ ];
+
+ public function loadProductionData($date, $plantId, $lineId)
+ {
+ $this->dates = [];
+ $this->leaveDates = [];
+
+ $this->nonPlannedRecords = [];
+ $this->nonPlannedCount = 0;
+ $this->nonPlannedQuantity = 0;
+
+ if (!$plantId || !$lineId || !$date) {
+ return;
+ }
+
+ $selectedDate = Carbon::parse($date);
+
+ $date = $selectedDate->toDateString();
+ $month = $selectedDate->month;
+ $year = $selectedDate->year;
+
+ $startDate = Carbon::parse($date)->setTime(8, 0, 0);
+ $endDate = $startDate->copy()->addDay();
+
+ $plans = ProductionPlan::query()
+ ->join('items', 'items.id', '=', 'production_plans.item_id')
+ ->join('lines', 'lines.id', '=', 'production_plans.line_id')
+ ->join('plants', 'plants.id', '=', 'production_plans.plant_id')
+ ->where('production_plans.plant_id', $plantId)
+ ->where('production_plans.line_id', $lineId)
+ ->whereMonth('production_plans.created_at', $month)
+ ->whereYear('production_plans.created_at', $year)
+ ->select(
+ 'production_plans.item_id',
+ 'production_plans.plant_id',
+ 'production_plans.line_id',
+ 'production_plans.plan_quantity',
+ 'production_plans.working_days',
+ 'production_plans.leave_dates',
+ 'items.code as item_code',
+ 'items.category as category',
+ 'items.description as item_description',
+ 'items.hourly_quantity as hourly_quantity',
+ 'lines.name as line_name',
+ 'plants.name as plant_name'
+ )
+ ->get();
+
+ $plannedItemIds = $plans
+ ->pluck('item_id')
+ ->filter(fn ($id) => $id != null)
+ ->unique()
+ ->values();
+
+ $leaveDates = [];
+
+ if ($plans->isNotEmpty() && $plans->first()->leave_dates) {
+ $leaveDates = array_map(
+ 'trim',
+ explode(',', $plans->first()->leave_dates)
+ );
+ }
+
+ $this->leaveDates = $leaveDates;
+
+ $nonPlannedQuery = QualityValidation::query()
+ ->join(
+ 'sticker_masters',
+ 'sticker_masters.id',
+ '=',
+ 'quality_validations.sticker_master_id'
+ )
+ ->join(
+ 'items',
+ 'items.id',
+ '=',
+ 'sticker_masters.item_id'
+ )
+ ->where('quality_validations.plant_id', $plantId)
+ ->where('quality_validations.line_id', $lineId)
+ ->where('quality_validations.created_at', '>=', $startDate)
+ ->where('quality_validations.created_at', '<', $endDate);
+
+ if ($plannedItemIds->isNotEmpty()) {
+ $nonPlannedQuery->whereNotIn(
+ 'sticker_masters.item_id',
+ $plannedItemIds
+ );
+ }
+
+ $nonPlannedData = $nonPlannedQuery
+ ->selectRaw("
+ sticker_masters.item_id,
+ items.code as item_code,
+ items.description as item_description,
+ items.category as item_category,
+ COUNT(*) as total_qty
+ ")
+ ->groupBy(
+ 'sticker_masters.item_id',
+ 'items.code',
+ 'items.description',
+ 'items.category'
+ )
+ ->get();
+
+ $this->nonPlannedRecords = $nonPlannedData->toArray();
+
+ $this->nonPlannedCount = $nonPlannedData->count();
+
+ $this->nonPlannedQuantity = (int) $nonPlannedData->sum('total_qty');
+ }
+
+ public function loadProductionCategoryData($date, $plantId, $lineId, $category)
+ {
+ $this->dates = [];
+ $this->leaveDates = [];
+
+ $this->nonPlannedRecords = [];
+ $this->nonPlannedCount = 0;
+ $this->nonPlannedQuantity = 0;
+
+ if (!$plantId || !$lineId || !$date) {
+ return;
+ }
+
+ $selectedDate = Carbon::parse($date);
+
+ $date = $selectedDate->toDateString();
+ $month = $selectedDate->month;
+ $year = $selectedDate->year;
+
+ $startDate = Carbon::parse($date)->setTime(8, 0, 0);
+ $endDate = $startDate->copy()->addDay();
+
+ $plans = ProductionPlan::query()
+ ->join('items', 'items.id', '=', 'production_plans.item_id')
+ ->join('lines', 'lines.id', '=', 'production_plans.line_id')
+ ->join('plants', 'plants.id', '=', 'production_plans.plant_id')
+ ->where('production_plans.plant_id', $plantId)
+ ->where('production_plans.line_id', $lineId)
+ ->where('items.category', $category)
+ ->whereMonth('production_plans.created_at', $month)
+ ->whereYear('production_plans.created_at', $year)
+ ->select(
+ 'production_plans.item_id',
+ 'production_plans.plant_id',
+ 'production_plans.line_id',
+ 'production_plans.plan_quantity',
+ 'production_plans.working_days',
+ 'production_plans.leave_dates',
+ 'items.code as item_code',
+ 'items.category as category',
+ 'items.description as item_description',
+ 'items.hourly_quantity as hourly_quantity',
+ 'lines.name as line_name',
+ 'plants.name as plant_name'
+ )
+ ->get();
+
+ $plannedItemIds = $plans
+ ->pluck('item_id')
+ ->filter(fn ($id) => $id != null)
+ ->unique()
+ ->values();
+
+ $leaveDates = [];
+
+ if ($plans->isNotEmpty() && $plans->first()->leave_dates) {
+ $leaveDates = array_map(
+ 'trim',
+ explode(',', $plans->first()->leave_dates)
+ );
+ }
+
+ $this->leaveDates = $leaveDates;
+
+ $nonPlannedQuery = QualityValidation::query()
+ ->join(
+ 'sticker_masters',
+ 'sticker_masters.id',
+ '=',
+ 'quality_validations.sticker_master_id'
+ )
+ ->join(
+ 'items',
+ 'items.id',
+ '=',
+ 'sticker_masters.item_id'
+ )
+ ->where('quality_validations.plant_id', $plantId)
+ ->where('quality_validations.line_id', $lineId)
+ ->where('items.category', $category)
+ ->where('quality_validations.created_at', '>=', $startDate)
+ ->where('quality_validations.created_at', '<', $endDate);
+
+ if ($plannedItemIds->isNotEmpty()) {
+ $nonPlannedQuery->whereNotIn(
+ 'sticker_masters.item_id',
+ $plannedItemIds
+ );
+ }
+
+ $nonPlannedData = $nonPlannedQuery
+ ->selectRaw("
+ sticker_masters.item_id,
+ items.code as item_code,
+ items.description as item_description,
+ items.category as item_category,
+ COUNT(*) as total_qty
+ ")
+ ->groupBy(
+ 'sticker_masters.item_id',
+ 'items.code',
+ 'items.description',
+ 'items.category'
+ )
+ ->get();
+
+ $this->nonPlannedRecords = $nonPlannedData->toArray();
+
+ $this->nonPlannedCount = $nonPlannedData->count();
+
+ $this->nonPlannedQuantity = (int) $nonPlannedData->sum('total_qty');
+ }
+
+ public function render()
+ {
+ // return view('livewire.production-non-planned');
+ return view('livewire.production-non-planned', [
+ 'records' => $this->records,
+ 'monthlyRecords' => $this->monthlyRecords,
+ 'monthlyActualRecords' => $this->monthlyActualQuantity,
+ 'monthlyEfficiency' => $this->efficiency,
+ 'dates' => $this->dates,
+ ]);
+ }
+}
diff --git a/resources/views/filament/pages/production-non-planned-report.blade.php b/resources/views/filament/pages/production-non-planned-report.blade.php
new file mode 100644
index 00000000..d34369c1
--- /dev/null
+++ b/resources/views/filament/pages/production-non-planned-report.blade.php
@@ -0,0 +1,20 @@
+
| No | +Item Code | +Category | +Non Planned Quantity | +
|---|---|---|---|
| {{ $index + 1 }} | +{{ $item['item_code'] }} | +{{ $item['item_category'] }} | +{{ $item['total_qty'] }} | +