Compare commits
2 Commits
b7ec4f4c1a
...
8cf1063e2a
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cf1063e2a | |||
|
|
3376d35eaa |
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