Merge pull request 'ranjith-dev' (#350) 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: #350
This commit was merged in pull request #350.
This commit is contained in:
169
app/Filament/Pages/ProductionCalender.php
Normal file
169
app/Filament/Pages/ProductionCalender.php
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\CustomerPoMaster;
|
||||||
|
use App\Models\Plant;
|
||||||
|
use App\Models\ProductionPlan;
|
||||||
|
use App\Models\WireMasterPacking;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Forms\Concerns\InteractsWithForms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Grid;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\ViewField;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Forms\Components\Actions\Action;
|
||||||
|
use Filament\Forms\Components\Hidden;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class ProductionCalender extends Page
|
||||||
|
{
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static string $view = 'filament.pages.production-calender';
|
||||||
|
|
||||||
|
use InteractsWithForms;
|
||||||
|
|
||||||
|
protected $listeners = ['setWorkingDays'];
|
||||||
|
|
||||||
|
public $pId;
|
||||||
|
|
||||||
|
public array $filters = [];
|
||||||
|
|
||||||
|
public function setWorkingDays($days = null)
|
||||||
|
{
|
||||||
|
$this->form->fill([
|
||||||
|
'working_days' => $days ?? 0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->statePath('filters')
|
||||||
|
->schema([
|
||||||
|
Section::make('')
|
||||||
|
->schema([
|
||||||
|
Select::make('plant_id')
|
||||||
|
->label('Plant')
|
||||||
|
->reactive()
|
||||||
|
//->options(Plant::pluck('name', 'id'))
|
||||||
|
->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();
|
||||||
|
})
|
||||||
|
->columnSpan(['default' => 10, 'sm' => 7])
|
||||||
|
->required()
|
||||||
|
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
|
$set('working_days', null);
|
||||||
|
}),
|
||||||
|
TextInput::make('working_days')
|
||||||
|
->label('No. of Working Days')
|
||||||
|
->numeric()
|
||||||
|
->readOnly()
|
||||||
|
->columnSpan(['default' => 10, 'sm' => 2])
|
||||||
|
->required()
|
||||||
|
->minValue(0)
|
||||||
|
->maxValue(31)
|
||||||
|
->placeholder('Enter working days')
|
||||||
|
->id('working_days'),
|
||||||
|
|
||||||
|
Hidden::make('month')
|
||||||
|
->label('Month')
|
||||||
|
->id('month'),
|
||||||
|
|
||||||
|
Hidden::make('year')
|
||||||
|
->label('Year')
|
||||||
|
->id('year'),
|
||||||
|
|
||||||
|
Hidden::make('selected_dates')
|
||||||
|
->label('Selected Dates')
|
||||||
|
->id('selected_dates'),
|
||||||
|
|
||||||
|
ViewField::make('save')
|
||||||
|
->view('forms.save')
|
||||||
|
->columnSpan(['default' => 10, 'sm' => 1]),
|
||||||
|
|
||||||
|
ViewField::make('calendar')
|
||||||
|
->view('forms.calendar')
|
||||||
|
->columnspan(10),
|
||||||
|
])
|
||||||
|
->columns(10)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveWorkingDays(){
|
||||||
|
$plantId = $this->filters['plant_id'] ?? null;
|
||||||
|
$workingDays = $this->filters['working_days'] ?? null;
|
||||||
|
$month = $this->filters['month'] ?? null;
|
||||||
|
$year = $this->filters['year'] ?? null;
|
||||||
|
$dates = $this->filters['selected_dates'] ?? null;
|
||||||
|
|
||||||
|
if (!$plantId) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Plant')
|
||||||
|
->body("Please select a plant first!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!$workingDays) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Working Days')
|
||||||
|
->body("Working days can't be empty!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!$month) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Month')
|
||||||
|
->body("month can't be empty!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!$year) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Year')
|
||||||
|
->body("Year can't be empty!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$updated = ProductionPlan::where('plant_id', $plantId)
|
||||||
|
->whereMonth('created_at', $month)
|
||||||
|
->whereYear('created_at', $year)
|
||||||
|
->update([
|
||||||
|
'working_days' => $workingDays,
|
||||||
|
'leave_dates' => $dates,
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($updated) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Success')
|
||||||
|
->body("Working days updated successfully!")
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
} else {
|
||||||
|
Notification::make()
|
||||||
|
->title('No Records Updated')
|
||||||
|
->body("No production plans found for this plant and month.")
|
||||||
|
->warning()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function canAccess(): bool
|
||||||
|
{
|
||||||
|
return Auth::check() && Auth::user()->can('view production calender page');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
189
app/Filament/Pages/ProductionTarget.php
Normal file
189
app/Filament/Pages/ProductionTarget.php
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\Plant;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class ProductionTarget extends Page
|
||||||
|
{
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static string $view = 'filament.pages.production-target';
|
||||||
|
|
||||||
|
public array $filters = [];
|
||||||
|
|
||||||
|
|
||||||
|
public function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->statePath('filters')
|
||||||
|
->schema([
|
||||||
|
Section::make('')
|
||||||
|
->schema([
|
||||||
|
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('year', null);
|
||||||
|
$set('month', 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');
|
||||||
|
|
||||||
|
|
||||||
|
$set('year', null);
|
||||||
|
$set('month', null);
|
||||||
|
$this->dispatch('loadData',$plantId, $state, '', '');
|
||||||
|
}),
|
||||||
|
Select::make('year')
|
||||||
|
->label('Year')
|
||||||
|
->reactive()
|
||||||
|
// ->searchable()
|
||||||
|
->options([
|
||||||
|
'2025' => '2025',
|
||||||
|
'2026' => '2026',
|
||||||
|
'2027' => '2027',
|
||||||
|
'2028' => '2028',
|
||||||
|
'2029' => '2029',
|
||||||
|
'2030' => '2030',
|
||||||
|
'2031' => '2031',
|
||||||
|
'2032' => '2032',
|
||||||
|
'2033' => '2033',
|
||||||
|
'2034' => '2034',
|
||||||
|
'2035' => '2035',
|
||||||
|
'2036' => '2036',
|
||||||
|
'2037' => '2037',
|
||||||
|
'2038' => '2038',
|
||||||
|
'2039' => '2039',
|
||||||
|
'2040' => '2040',
|
||||||
|
])
|
||||||
|
->required()
|
||||||
|
->afterStateUpdated(function ($state, callable $get, $set) {
|
||||||
|
$set('month', null);
|
||||||
|
$plantId = $get('plant_id');
|
||||||
|
$lineId = $get('line_id');
|
||||||
|
$this->dispatch('loadData',$plantId, $lineId, $state, '');
|
||||||
|
}),
|
||||||
|
|
||||||
|
Select::make('month')
|
||||||
|
->label('Month')
|
||||||
|
->reactive()
|
||||||
|
// ->searchable()
|
||||||
|
->options([
|
||||||
|
'01' => 'January',
|
||||||
|
'02' => 'February',
|
||||||
|
'03' => 'March',
|
||||||
|
'04' => 'April',
|
||||||
|
'05' => 'May',
|
||||||
|
'06' => 'June',
|
||||||
|
'07' => 'July',
|
||||||
|
'08' => 'August',
|
||||||
|
'09' => 'September',
|
||||||
|
'10' => 'October',
|
||||||
|
'11' => 'November',
|
||||||
|
'12' => 'December',
|
||||||
|
])
|
||||||
|
->required()
|
||||||
|
->afterStateUpdated(function ($state, callable $get) {
|
||||||
|
|
||||||
|
$plantId = $get('plant_id');
|
||||||
|
$lineId = $get('line_id');
|
||||||
|
// $month = $get('month');
|
||||||
|
$year = $get('year');
|
||||||
|
|
||||||
|
$month = (int) $get('month');
|
||||||
|
|
||||||
|
if (!$month) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->dispatch('loadData', $plantId, $lineId, $month, $year);
|
||||||
|
}),
|
||||||
|
|
||||||
|
])
|
||||||
|
->columns(4)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export(){
|
||||||
|
|
||||||
|
$plantId = $this->filters['plant_id'] ?? null;
|
||||||
|
$lineId = $this->filters['line_id'] ?? null;
|
||||||
|
$year = $this->filters['year'] ?? null;
|
||||||
|
$month = $this->filters['month'] ?? null;
|
||||||
|
|
||||||
|
if (! $plantId) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Plant')
|
||||||
|
->body("please select plant to export data..!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (! $lineId) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Line')
|
||||||
|
->body("please select line to export data..!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (! $year) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Year')
|
||||||
|
->body("please select year to export data..!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (! $month) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Month')
|
||||||
|
->body("please select month to export data..!")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dispatch('loadData1' ,$plantId, $lineId, $year, $month);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function canAccess(): bool
|
||||||
|
{
|
||||||
|
return Auth::check() && Auth::user()->can('view production target page');
|
||||||
|
}
|
||||||
|
}
|
||||||
310
app/Livewire/ProductionTargetPlan.php
Normal file
310
app/Livewire/ProductionTargetPlan.php
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Exports\ProductionPlanExport;
|
||||||
|
use App\Models\ProductionPlan;
|
||||||
|
use App\Models\ProductionQuantity;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use DB;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ProductionTargetPlan extends Component
|
||||||
|
{
|
||||||
|
|
||||||
|
public $plantId, $lineId, $month, $year;
|
||||||
|
|
||||||
|
public $records = [];
|
||||||
|
|
||||||
|
public $dates = [];
|
||||||
|
|
||||||
|
public $leaveDates = [];
|
||||||
|
|
||||||
|
public $productionPlanDates = '';
|
||||||
|
|
||||||
|
|
||||||
|
protected $listeners = [
|
||||||
|
'loadData' => 'loadProductionData',
|
||||||
|
'loadData1' => 'exportProductionData',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getMonthDates($month, $year)
|
||||||
|
{
|
||||||
|
$start = Carbon::createFromDate($year, $month, 1);
|
||||||
|
$days = $start->daysInMonth;
|
||||||
|
|
||||||
|
$dates = [];
|
||||||
|
|
||||||
|
for ($i = 1; $i <= $days; $i++) {
|
||||||
|
$dates[] = Carbon::createFromDate($year, $month, $i)
|
||||||
|
->format('Y-m-d');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dates;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function loadProductionData($plantId, $lineId, $month, $year){
|
||||||
|
|
||||||
|
// if (!$plantId || !$lineId || !$month || !$year) {
|
||||||
|
// $this->records = [];
|
||||||
|
// $this->dates = [];
|
||||||
|
// $this->leaveDates = [];
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $this->dates = $this->getMonthDates($month, $year);
|
||||||
|
|
||||||
|
// $data = 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.created_at',
|
||||||
|
// 'production_plans.operator_id',
|
||||||
|
// 'plants.name as plant',
|
||||||
|
// 'items.code as item_code',
|
||||||
|
// 'items.description as item_description',
|
||||||
|
// 'lines.name as line_name',
|
||||||
|
// 'production_plans.leave_dates'
|
||||||
|
// )
|
||||||
|
// ->first();
|
||||||
|
|
||||||
|
// if ($data && $data->leave_dates) {
|
||||||
|
// $this->leaveDates = array_map('trim', explode(',', $data->leave_dates));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $producedData = ProductionQuantity::selectRaw("
|
||||||
|
// plant_id,
|
||||||
|
// line_id,
|
||||||
|
// item_id,
|
||||||
|
// DATE(created_at) as prod_date,
|
||||||
|
// COUNT(*) as total_qty
|
||||||
|
// ")
|
||||||
|
// ->where('plant_id', $plantId)
|
||||||
|
// ->where('line_id', $lineId)
|
||||||
|
// ->whereMonth('created_at', $month)
|
||||||
|
// ->whereYear('created_at', $year)
|
||||||
|
// ->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
|
||||||
|
// ->get()
|
||||||
|
// ->groupBy(function ($row) {
|
||||||
|
// return $row->plant_id . '_' . $row->line_id . '_' . $row->item_id;
|
||||||
|
// })
|
||||||
|
// ->map(function ($group) {
|
||||||
|
// return $group->keyBy('prod_date');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// $this->records = 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',
|
||||||
|
// 'items.code as item_code',
|
||||||
|
// 'items.description as item_description',
|
||||||
|
// 'lines.name as line_name',
|
||||||
|
// 'plants.name as plant_name'
|
||||||
|
// )
|
||||||
|
// ->get()
|
||||||
|
// ->map(function ($row) use ($producedData) {
|
||||||
|
|
||||||
|
// $row = $row->toArray();
|
||||||
|
|
||||||
|
// $remainingQty = $row['plan_quantity'];
|
||||||
|
// // $remainingDays = $row['working_days'];
|
||||||
|
// $remainingDays = (int) ($row['working_days'] ?? 0);
|
||||||
|
|
||||||
|
// $row['daily_target_dynamic'] = [];
|
||||||
|
// $row['produced_quantity'] = [];
|
||||||
|
|
||||||
|
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
|
||||||
|
|
||||||
|
// foreach ($this->dates as $date) {
|
||||||
|
|
||||||
|
// // Skip leave dates
|
||||||
|
// if (in_array($date, $this->leaveDates)) {
|
||||||
|
// $row['daily_target_dynamic'][$date] = '-';
|
||||||
|
// $row['produced_quantity'][$date] = '-';
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $todayTarget = $remainingDays > 0
|
||||||
|
// ? round($remainingQty / $remainingDays, 2)
|
||||||
|
// : 0;
|
||||||
|
|
||||||
|
// //$todayTarget = $remainingDays > 0
|
||||||
|
// // ? $remainingQty / $remainingDays
|
||||||
|
// // : 0;
|
||||||
|
|
||||||
|
// $producedQty = isset($producedData[$key][$date])
|
||||||
|
// ? $producedData[$key][$date]->total_qty
|
||||||
|
// : 0;
|
||||||
|
|
||||||
|
// $row['daily_target_dynamic'][$date] = $todayTarget;
|
||||||
|
// $row['produced_quantity'][$date] = $producedQty;
|
||||||
|
|
||||||
|
// // Carry forward pending
|
||||||
|
// $remainingQty -= $producedQty;
|
||||||
|
// if ($remainingQty < 0) {
|
||||||
|
// $remainingQty = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if ($remainingDays > 0) {
|
||||||
|
// $remainingDays--;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // $remainingDays--;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $row;
|
||||||
|
// })
|
||||||
|
// ->toArray();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function loadProductionData($plantId, $lineId, $month, $year)
|
||||||
|
{
|
||||||
|
if (!$plantId || !$lineId || !$month || !$year) {
|
||||||
|
$this->records = [];
|
||||||
|
$this->dates = [];
|
||||||
|
$this->leaveDates = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dates = $this->getMonthDates($month, $year);
|
||||||
|
$this->dates = $dates;
|
||||||
|
|
||||||
|
$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.description as item_description',
|
||||||
|
'lines.name as line_name',
|
||||||
|
'lines.line_capacity as line_capacity',
|
||||||
|
'plants.name as plant_name'
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$leaveDates = [];
|
||||||
|
|
||||||
|
if ($plans->isNotEmpty() && $plans[0]->leave_dates) {
|
||||||
|
$leaveDates = array_map('trim', explode(',', $plans[0]->leave_dates));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->leaveDates = $leaveDates;
|
||||||
|
|
||||||
|
$producedData = ProductionQuantity::selectRaw("
|
||||||
|
plant_id,
|
||||||
|
line_id,
|
||||||
|
item_id,
|
||||||
|
DATE(created_at) as prod_date,
|
||||||
|
COUNT(*) as total_qty
|
||||||
|
")
|
||||||
|
->where('plant_id', $plantId)
|
||||||
|
->where('line_id', $lineId)
|
||||||
|
->whereMonth('created_at', $month)
|
||||||
|
->whereYear('created_at', $year)
|
||||||
|
->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
|
||||||
|
->get()
|
||||||
|
->groupBy(fn($row) =>
|
||||||
|
$row->plant_id . '_' . $row->line_id . '_' . $row->item_id
|
||||||
|
)
|
||||||
|
->map(fn($group) => $group->keyBy('prod_date'));
|
||||||
|
|
||||||
|
|
||||||
|
$records = [];
|
||||||
|
|
||||||
|
foreach ($plans as $plan) {
|
||||||
|
|
||||||
|
$row = $plan->toArray();
|
||||||
|
|
||||||
|
$remainingQty = (float) $row['plan_quantity'];
|
||||||
|
$remainingDays = (int) ($row['working_days'] ?? 0);
|
||||||
|
|
||||||
|
$lineCapacity = (float) ($row['line_capacity'] ?? 0);
|
||||||
|
$dailyLineCapacity = (float) ($row['line_capacity'] ?? 0);
|
||||||
|
|
||||||
|
|
||||||
|
$row['daily_line_capacity'] = [];
|
||||||
|
$row['daily_target_dynamic'] = [];
|
||||||
|
$row['produced_quantity'] = [];
|
||||||
|
|
||||||
|
$key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
|
||||||
|
|
||||||
|
foreach ($dates as $date) {
|
||||||
|
|
||||||
|
// Skip leave dates fast
|
||||||
|
if (isset($leaveDates) && in_array($date, $leaveDates)) {
|
||||||
|
$row['daily_line_capacity'][$date] = '-';
|
||||||
|
$row['daily_target_dynamic'][$date] = '-';
|
||||||
|
$row['produced_quantity'][$date] = '-';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$todayTarget = $remainingDays > 0
|
||||||
|
? round($remainingQty / $remainingDays, 2)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
$producedQty = $producedData[$key][$date]->total_qty ?? 0;
|
||||||
|
|
||||||
|
$row['daily_target_dynamic'][$date] = $todayTarget;
|
||||||
|
$row['produced_quantity'][$date] = $producedQty;
|
||||||
|
$row['daily_line_capacity'][$date] = $dailyLineCapacity;
|
||||||
|
|
||||||
|
// Carry forward remaining qty
|
||||||
|
$remainingQty = max(0, $remainingQty - $producedQty);
|
||||||
|
|
||||||
|
if ($remainingDays > 0) {
|
||||||
|
$remainingDays--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$records[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->records = $records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function exportProductionData()
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new ProductionPlanExport($this->records, $this->dates),
|
||||||
|
'production_plan_data.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
// return view('livewire.production-target-plan');
|
||||||
|
return view('livewire.production-target-plan', [
|
||||||
|
'records' => $this->records,
|
||||||
|
'dates' => $this->dates,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
resources/views/filament/pages/production-calender.blade.php
Normal file
13
resources/views/filament/pages/production-calender.blade.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
|
||||||
|
{{-- Render the Select form fields --}}
|
||||||
|
<div class="space-y-4">
|
||||||
|
{{ $this->form }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</x-filament-panels::page>
|
||||||
19
resources/views/filament/pages/production-target.blade.php
Normal file
19
resources/views/filament/pages/production-target.blade.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<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="export"
|
||||||
|
color="primary"
|
||||||
|
class="mt-4"
|
||||||
|
>
|
||||||
|
Export
|
||||||
|
</x-filament::button>
|
||||||
|
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||||
|
<livewire:production-target-plan />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-filament-panels::page>
|
||||||
86
resources/views/livewire/production-target-plan.blade.php
Normal file
86
resources/views/livewire/production-target-plan.blade.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<div class="p-4">
|
||||||
|
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||||
|
PRODUCTION PLAN TABLE:
|
||||||
|
</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-s font-semibold uppercase text-gray-700">
|
||||||
|
<tr>
|
||||||
|
<th class="border px-4 py-2" rowspan="3">No</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Plant</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Line</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Item Code</th>
|
||||||
|
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap" colspan="{{ count($dates) * 3 }}" class="text-center">
|
||||||
|
Production Plan Dates
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
@foreach($dates as $date)
|
||||||
|
{{-- <th colspan="3" class="text-center">
|
||||||
|
{{ $date }}
|
||||||
|
</th> --}}
|
||||||
|
<th colspan="3" class="text-center border-r-4 border-gray-400">
|
||||||
|
{{ $date }}
|
||||||
|
</th>
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
@foreach($dates as $date)
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Line Capacity</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Target Plan</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap border-r-4 border-gray-400">
|
||||||
|
Produced Quantity
|
||||||
|
</th>
|
||||||
|
|
||||||
|
{{-- <th class="border px-4 py-2 whitespace-nowrap">Produced Quantity</th> --}}
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody class="divide-y divide-gray-100">
|
||||||
|
@forelse ($records as $index => $record)
|
||||||
|
<tr class="hover:bg-gray-50">
|
||||||
|
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['plant_name'] }}</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['line_name'] }}</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['item_code'] }}</td>
|
||||||
|
|
||||||
|
{{-- @foreach($dates as $date)
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['target_plan'][$date] ?? '-' }}</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['production_plan'][$date] ?? '-' }}</td>
|
||||||
|
@endforeach --}}
|
||||||
|
|
||||||
|
@foreach($dates as $date)
|
||||||
|
@if(in_array($date, $leaveDates))
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">-</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">-</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">-</td>
|
||||||
|
@else
|
||||||
|
{{-- <td class="border px-4 py-2 whitespace-nowrap">{{ $record['daily_target'] ?? '-' }}</td> --}}
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">
|
||||||
|
{{ $record['daily_line_capacity'][$date] ?? '-' }}
|
||||||
|
</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">
|
||||||
|
{{ $record['daily_target_dynamic'][$date] ?? '-' }}
|
||||||
|
</td>
|
||||||
|
<td class="border px-4 py-2 whitespace-nowrap">
|
||||||
|
{{ $record['produced_quantity'][$date] ?? '-' }}
|
||||||
|
</td>
|
||||||
|
{{-- <td class="border px-4 py-2 whitespace-nowrap">{{ $record['produced_quantity'] ?? '-' }}</td> --}}
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="10" class="px-4 py-4 text-center text-gray-500">
|
||||||
|
No production plan data found.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user