Added Production Calendar screen page
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
This commit is contained in:
163
app/Filament/Pages/ProductionCalender.php
Normal file
163
app/Filament/Pages/ProductionCalender.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?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;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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>
|
||||
151
resources/views/forms/calendar.blade.php
Normal file
151
resources/views/forms/calendar.blade.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<!-- <select id="yearSelect">
|
||||
<option value="">Select Year</option>
|
||||
</select> -->
|
||||
|
||||
|
||||
<div id="calendar" wire:ignore></div>
|
||||
|
||||
|
||||
<!-- <input type="text" name="working_days" placeholder="Working Days"> -->
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
let selectedDates = [];
|
||||
let calendarEl = document.getElementById('calendar');
|
||||
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'dayGridMonth',
|
||||
height: 600,
|
||||
showNonCurrentDates: true,
|
||||
|
||||
datesSet: function(info) {
|
||||
// Clear previous month selections
|
||||
selectedDates = [];
|
||||
|
||||
// Remove background events
|
||||
calendar.removeAllEvents();
|
||||
|
||||
// Recalculate working days for new month
|
||||
updateWorkingDays(info.view.currentStart);
|
||||
},
|
||||
|
||||
dateClick: function(info) {
|
||||
|
||||
let viewMonth = calendar.view.currentStart.getMonth();
|
||||
let clickedMonth = info.date.getMonth();
|
||||
|
||||
if (viewMonth != clickedMonth) return;
|
||||
|
||||
let dateStr = info.dateStr;
|
||||
|
||||
if (selectedDates.includes(dateStr)) {
|
||||
selectedDates = selectedDates.filter(d => d !== dateStr);
|
||||
|
||||
calendar.getEvents().forEach(event => {
|
||||
if (event.startStr == dateStr) event.remove();
|
||||
});
|
||||
|
||||
} else {
|
||||
selectedDates.push(dateStr);
|
||||
|
||||
calendar.addEvent({
|
||||
start: dateStr,
|
||||
display: 'background',
|
||||
color: '#f03f17'
|
||||
});
|
||||
}
|
||||
|
||||
updateWorkingDays(info.date);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
// initialView: 'dayGridMonth',
|
||||
// height: 600,
|
||||
// showNonCurrentDates: true,
|
||||
|
||||
// dateClick: function(info) {
|
||||
|
||||
// let viewMonth = calendar.view.currentStart.getMonth();
|
||||
// let clickedMonth = info.date.getMonth();
|
||||
|
||||
// // let month = info.date.getMonth() + 1; // JS month: 0-11 → 1-12
|
||||
// // let year = info.date.getFullYear();
|
||||
|
||||
// if (viewMonth != clickedMonth) {
|
||||
// return; // Ignore next/prev month dates
|
||||
// }
|
||||
|
||||
// let dateStr = info.dateStr;
|
||||
|
||||
// if (selectedDates.includes(dateStr)) {
|
||||
// selectedDates = selectedDates.filter(d => d !== dateStr);
|
||||
|
||||
// calendar.getEvents().forEach(event => {
|
||||
// if (event.startStr == dateStr) {
|
||||
// event.remove();
|
||||
// }
|
||||
// });
|
||||
|
||||
// } else {
|
||||
// selectedDates.push(dateStr);
|
||||
|
||||
// calendar.addEvent({
|
||||
// start: dateStr,
|
||||
// display: 'background',
|
||||
// color: '#f03f17'
|
||||
// });
|
||||
// }
|
||||
|
||||
// updateWorkingDays(info.date);
|
||||
// }
|
||||
// });
|
||||
|
||||
// yearSelect.addEventListener('change', function () {
|
||||
// let year = this.value;
|
||||
// if (!year) return;
|
||||
|
||||
// let currentDate = calendar.getDate();
|
||||
// let newDate = new Date(year, currentDate.getMonth(), 1);
|
||||
|
||||
// calendar.gotoDate(newDate);
|
||||
// });
|
||||
|
||||
function updateWorkingDays(date) {
|
||||
let totalDays = new Date(
|
||||
date.getFullYear(),
|
||||
date.getMonth()+1,
|
||||
0
|
||||
).getDate();
|
||||
|
||||
let workingDays = totalDays - selectedDates.length;
|
||||
// document.querySelector('input[name="working_days"]').value = workingDays;
|
||||
|
||||
const input = document.querySelector('#working_days');
|
||||
|
||||
input.value = workingDays;
|
||||
|
||||
input.dispatchEvent(new Event('input'));
|
||||
|
||||
const monthInput = document.querySelector('#month');
|
||||
monthInput.value = date.getMonth() + 1; // 1–12 month number
|
||||
monthInput.dispatchEvent(new Event('input'));
|
||||
|
||||
const yearInput = document.querySelector('#year');
|
||||
yearInput.value = date.getFullYear();
|
||||
yearInput.dispatchEvent(new Event('input'));
|
||||
|
||||
const selectedDatesInput = document.querySelector('#selected_dates');
|
||||
selectedDatesInput.value = selectedDates.join(',');
|
||||
selectedDatesInput.dispatchEvent(new Event('input'));
|
||||
|
||||
}
|
||||
|
||||
calendar.render();
|
||||
});
|
||||
</script>
|
||||
9
resources/views/forms/save.php
Normal file
9
resources/views/forms/save.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="flex space-x-2 items-center">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center px-3 py-1 bg-primary-600 text-white rounded hover:bg-primary-700"
|
||||
wire:click="saveWorkingDays"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
Reference in New Issue
Block a user