Merge pull request 'ranjith-dev' (#1218) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #1218
This commit was merged in pull request #1218.
This commit is contained in:
194
app/Filament/Pages/ProductionNonPlannedReport.php
Normal file
194
app/Filament/Pages/ProductionNonPlannedReport.php
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\Item;
|
||||||
|
use App\Models\ProductionPlan;
|
||||||
|
use App\Models\QualityValidation;
|
||||||
|
use App\Models\StickerMaster;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Filament\Forms\Components\DateTimePicker;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use App\Models\Plant;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Filament\Forms\Contracts\HasForms;
|
||||||
|
use Filament\Forms\Concerns\InteractsWithForms;
|
||||||
|
|
||||||
|
class ProductionNonPlannedReport extends Page implements HasForms
|
||||||
|
{
|
||||||
|
use InteractsWithForms;
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static string $view = 'filament.pages.production-non-planned-report';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Production';
|
||||||
|
|
||||||
|
public array $filters = [];
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->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');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
278
app/Livewire/ProductionNonPlanned.php
Normal file
278
app/Livewire/ProductionNonPlanned.php
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\ProductionPlan;
|
||||||
|
use App\Models\QualityValidation;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class ProductionNonPlanned extends Component
|
||||||
|
{
|
||||||
|
public $plantId, $lineId, $month, $year, $category, $date;
|
||||||
|
|
||||||
|
public $records = [];
|
||||||
|
|
||||||
|
public $nonPlannedRecords = [];
|
||||||
|
|
||||||
|
public int $nonPlannedCount = 0;
|
||||||
|
|
||||||
|
public int $nonPlannedQuantity = 0;
|
||||||
|
|
||||||
|
// public $dates = [];
|
||||||
|
|
||||||
|
public $monthlyRecords = [];
|
||||||
|
|
||||||
|
public $efficiency = [];
|
||||||
|
|
||||||
|
public $monthlyActualQuantity = [];
|
||||||
|
|
||||||
|
public $leaveDates = [];
|
||||||
|
|
||||||
|
public $dates;
|
||||||
|
|
||||||
|
public $productionPlanDates = '';
|
||||||
|
|
||||||
|
|
||||||
|
protected $listeners = [
|
||||||
|
'loadData' => '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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
<div class="space-y-4">
|
||||||
|
|
||||||
|
{{-- Render the Select form fields --}}
|
||||||
|
<div class="space-y-4">
|
||||||
|
{{ $this->form }}
|
||||||
|
</div>
|
||||||
|
<x-filament::button
|
||||||
|
wire:click="generateNonPlan"
|
||||||
|
color="primary"
|
||||||
|
class="mt-4"
|
||||||
|
>
|
||||||
|
Generate
|
||||||
|
</x-filament::button>
|
||||||
|
|
||||||
|
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||||
|
<livewire:production-non-planned />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-filament-panels::page>
|
||||||
30
resources/views/livewire/production-non-planned.blade.php
Normal file
30
resources/views/livewire/production-non-planned.blade.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<div class="p-4">
|
||||||
|
<div class="p-4 mt-6">
|
||||||
|
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||||
|
NON PLANNED PRODUCTION:
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div class="overflow-x-auto rounded-lg shadow">
|
||||||
|
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||||
|
<thead class="bg-gray-100 text-sm font-semibold uppercase text-gray-700">
|
||||||
|
<tr>
|
||||||
|
<th class="border px-4 py-2">No</th>
|
||||||
|
<th class="border px-4 py-2">Item Code</th>
|
||||||
|
<th class="border px-4 py-2">Category</th>
|
||||||
|
<th class="border px-4 py-2">Non Planned Quantity</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($nonPlannedRecords as $index => $item)
|
||||||
|
<tr>
|
||||||
|
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ $item['item_code'] }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ $item['item_category'] }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ $item['total_qty'] }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
Reference in New Issue
Block a user