Compare commits
52 Commits
eae7e76ea4
...
ranjith-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7244028d02 | ||
|
|
8104da98d4 | ||
|
|
1d51067355 | ||
|
|
1fd2538048 | ||
|
|
d8fdf02417 | ||
|
|
1031a972de | ||
|
|
f5173d9861 | ||
|
|
9602be624d | ||
|
|
85c7a3e286 | ||
|
|
6071c8b898 | ||
|
|
9bf5337383 | ||
|
|
621cf13565 | ||
|
|
6c334359b2 | ||
|
|
fd444a7749 | ||
|
|
f7a421681e | ||
|
|
8bd64c80d4 | ||
|
|
c4177887d6 | ||
|
|
09772d1984 | ||
|
|
3376d35eaa | ||
|
|
8feb2fc612 | ||
|
|
04d472805f | ||
|
|
f9d2e14210 | ||
|
|
13bef51af5 | ||
|
|
1711ce5646 | ||
|
|
b7da185912 | ||
|
|
4a796a670a | ||
|
|
4577f67d0a | ||
|
|
be2151a072 | ||
|
|
a4251ae532 | ||
|
|
93d55765ae | ||
|
|
17d54cc52e | ||
|
|
61467d88cd | ||
|
|
af0b17e674 | ||
|
|
dd7111a8d9 | ||
|
|
464ee6c3c7 | ||
|
|
984d686182 | ||
|
|
fd87748a38 | ||
|
|
f9aa6cd1ba | ||
|
|
d743b2df26 | ||
|
|
814281a6bf | ||
|
|
dc445b17f5 | ||
|
|
cd553651f3 | ||
|
|
ac20e96358 | ||
|
|
0fb9c91b28 | ||
|
|
21d602d86a | ||
|
|
06628072dc | ||
|
|
cdf9f60ffd | ||
|
|
b419a538dc | ||
|
|
fea15e0d1b | ||
|
|
f5a1e453d5 | ||
|
|
fd6149ccbe | ||
|
|
085a4f72fa |
62
app/Exports/ProductionPlanExport.php
Normal file
62
app/Exports/ProductionPlanExport.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromArray;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
|
||||||
|
class ProductionPlanExport implements FromArray, WithHeadings, WithMapping
|
||||||
|
{
|
||||||
|
|
||||||
|
protected array $data;
|
||||||
|
protected array $dates;
|
||||||
|
|
||||||
|
public function __construct(array $data, array $dates)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
$this->dates = $dates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function array(): array
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
$headings = [
|
||||||
|
'Plant Name',
|
||||||
|
'Line Name',
|
||||||
|
'Item Code',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add dynamic headings for each date: Target / Produced
|
||||||
|
foreach ($this->dates as $date) {
|
||||||
|
$headings[] = $date . ' - Target Plan';
|
||||||
|
$headings[] = $date . ' - Produced Quantity';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $headings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($row): array
|
||||||
|
{
|
||||||
|
$mapped = [
|
||||||
|
$row['plant_name'] ?? '',
|
||||||
|
$row['line_name'] ?? '',
|
||||||
|
$row['item_code'] ?? '',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add daily target and produced quantity for each date
|
||||||
|
foreach ($this->dates as $date) {
|
||||||
|
// $mapped[] = $row['daily_target_dynamic'] ?? 0;
|
||||||
|
$mapped[] = $row['daily_target_dynamic'][$date] ?? '-';
|
||||||
|
$mapped[] = $row['produced_quantity'][$date] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $mapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Filament\Imports;
|
namespace App\Filament\Imports;
|
||||||
|
|
||||||
use App\Models\Block;
|
use App\Models\Block;
|
||||||
|
use App\Models\Item;
|
||||||
use App\Models\Line;
|
use App\Models\Line;
|
||||||
use App\Models\Plant;
|
use App\Models\Plant;
|
||||||
use App\Models\ProductionPlan;
|
use App\Models\ProductionPlan;
|
||||||
@@ -23,11 +24,33 @@ class ProductionPlanImporter extends Importer
|
|||||||
public static function getColumns(): array
|
public static function getColumns(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
ImportColumn::make('created_at')
|
// ImportColumn::make('created_at')
|
||||||
|
// ->requiredMapping()
|
||||||
|
// ->exampleHeader('Created DateTime')
|
||||||
|
// ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
|
||||||
|
// ->label('Created DateTime')
|
||||||
|
// ->rules(['required']),
|
||||||
|
|
||||||
|
ImportColumn::make('plant')
|
||||||
->requiredMapping()
|
->requiredMapping()
|
||||||
->exampleHeader('Created DateTime')
|
->exampleHeader('Plant Code')
|
||||||
->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
|
->example(['1000', '1000'])
|
||||||
->label('Created DateTime')
|
->label('Plant Code')
|
||||||
|
->relationship(resolveUsing: 'code')
|
||||||
|
->rules(['required']),
|
||||||
|
ImportColumn::make('line')
|
||||||
|
->requiredMapping()
|
||||||
|
->exampleHeader('Line Name')
|
||||||
|
->example(['4 inch pump line', '4 inch pump line'])
|
||||||
|
->label('Line Name')
|
||||||
|
->relationship(resolveUsing: 'name')
|
||||||
|
->rules(['required']),
|
||||||
|
ImportColumn::make('item')
|
||||||
|
->requiredMapping()
|
||||||
|
->exampleHeader('Item Code')
|
||||||
|
->example(['123456', '210987'])
|
||||||
|
->label('Item Code')
|
||||||
|
->relationship(resolveUsing: 'code')
|
||||||
->rules(['required']),
|
->rules(['required']),
|
||||||
ImportColumn::make('plan_quantity')
|
ImportColumn::make('plan_quantity')
|
||||||
->requiredMapping()
|
->requiredMapping()
|
||||||
@@ -36,175 +59,111 @@ class ProductionPlanImporter extends Importer
|
|||||||
->label('Plan Quantity')
|
->label('Plan Quantity')
|
||||||
->numeric()
|
->numeric()
|
||||||
->rules(['required', 'integer']),
|
->rules(['required', 'integer']),
|
||||||
ImportColumn::make('production_quantity')
|
// ImportColumn::make('production_quantity')
|
||||||
->requiredMapping()
|
// ->requiredMapping()
|
||||||
->exampleHeader('Production Quantity')
|
// ->exampleHeader('Production Quantity')
|
||||||
->example(['0', '0'])
|
// ->example(['0', '0'])
|
||||||
->label('Production Quantity')
|
// ->label('Production Quantity')
|
||||||
->numeric()
|
// ->numeric()
|
||||||
->rules(['required', 'integer']),
|
// ->rules(['required', 'integer']),
|
||||||
ImportColumn::make('line')
|
|
||||||
->requiredMapping()
|
// ImportColumn::make('block_reference')
|
||||||
->exampleHeader('Line Name')
|
// ->requiredMapping() // Or optionalMapping() if not always present
|
||||||
->example(['4 inch pump line', '4 inch pump line'])
|
// ->exampleHeader('Block Name')
|
||||||
->label('Line Name')
|
// ->example(['Block A', 'Block A'])
|
||||||
->relationship(resolveUsing:'name')
|
// ->label('Block Name')
|
||||||
->rules(['required']),
|
// ->rules(['required']), // Or remove if not required
|
||||||
ImportColumn::make('block_reference')
|
// ImportColumn::make('shift')
|
||||||
->requiredMapping() // Or optionalMapping() if not always present
|
// ->requiredMapping()
|
||||||
->exampleHeader('Block Name')
|
// ->exampleHeader('Shift Name') // ID
|
||||||
->example(['Block A', 'Block A'])
|
// ->example(['Day', 'Night']) // '2', '7'
|
||||||
->label('Block Name')
|
// ->label('Shift Name') // ID
|
||||||
->rules(['required']), // Or remove if not required
|
// ->relationship(resolveUsing: 'name')
|
||||||
ImportColumn::make('shift')
|
// ->rules(['required']),
|
||||||
->requiredMapping()
|
|
||||||
->exampleHeader('Shift Name') //ID
|
// ImportColumn::make('updated_at')
|
||||||
->example(['Day', 'Night']) //'2', '7'
|
// ->requiredMapping()
|
||||||
->label('Shift Name') // ID
|
// ->exampleHeader('Updated DateTime')
|
||||||
->relationship(resolveUsing: 'name')
|
// ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
|
||||||
->rules(['required']),
|
// ->label('Updated DateTime')
|
||||||
ImportColumn::make('plant')
|
// ->rules(['required']),
|
||||||
->requiredMapping()
|
// ImportColumn::make('operator_id')
|
||||||
->exampleHeader('Plant Name')
|
// ->requiredMapping()
|
||||||
->example(['Ransar Industries-I', 'Ransar Industries-I'])
|
// ->exampleHeader('Operator ID')
|
||||||
->label('Plant Name')
|
// ->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
|
||||||
->relationship(resolveUsing:'name')
|
// ->label('Operator ID')
|
||||||
->rules(['required']),
|
// ->rules(['required']),
|
||||||
ImportColumn::make('updated_at')
|
|
||||||
->requiredMapping()
|
|
||||||
->exampleHeader('Updated DateTime')
|
|
||||||
->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
|
|
||||||
->label('Updated DateTime')
|
|
||||||
->rules(['required']),
|
|
||||||
ImportColumn::make('operator_id')
|
|
||||||
->requiredMapping()
|
|
||||||
->exampleHeader('Operator ID')
|
|
||||||
->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
|
|
||||||
->label('Operator ID')
|
|
||||||
->rules(['required']),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolveRecord(): ?ProductionPlan
|
public function resolveRecord(): ?ProductionPlan
|
||||||
{
|
{
|
||||||
$warnMsg = [];
|
$warnMsg = [];
|
||||||
$plant = Plant::where('name', $this->data['plant'])->first();
|
$plantCod = $this->data['plant'];
|
||||||
|
$itemCod = $this->data['item'];
|
||||||
|
$plant = null;
|
||||||
$line = null;
|
$line = null;
|
||||||
$block = null;
|
$block = null;
|
||||||
if (!$plant) {
|
|
||||||
$warnMsg[] = "Plant not found";
|
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
|
||||||
|
$warnMsg[] = 'Invalid plant code found';
|
||||||
|
} else {
|
||||||
|
$plant = Plant::where('code', $plantCod)->first();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (! $plant) {
|
||||||
|
$warnMsg[] = 'Plant not found';
|
||||||
|
} else {
|
||||||
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
|
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
|
||||||
//block_reference
|
|
||||||
$block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
|
|
||||||
}
|
|
||||||
if (!$line) {
|
|
||||||
$warnMsg[] = "Line not found";
|
|
||||||
}
|
|
||||||
$shift = null;
|
|
||||||
if (!$block) {
|
|
||||||
$warnMsg[] = "Block not found";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$shift = Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->where('block_id', $block->id)->first();
|
|
||||||
}
|
|
||||||
//$shift = Shift::where('id', $this->data['shift'])->where('plant_id', $plant->id)->first();
|
|
||||||
if (!$shift) {
|
|
||||||
$warnMsg[] = "Shift not found";
|
|
||||||
}
|
|
||||||
if (Str::length($this->data['plan_quantity']) < 0 || !is_numeric($this->data['plan_quantity']) || $this->data['plan_quantity'] <= 0) {
|
|
||||||
$warnMsg[] = "Invalid plan quantity found";
|
|
||||||
}
|
|
||||||
if (Str::length($this->data['production_quantity']) < 0 || !is_numeric($this->data['production_quantity']) || $this->data['production_quantity'] < 0) {
|
|
||||||
$warnMsg[] = "Invalid production quantity found";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$fromDate = $this->data['created_at'];
|
if (! $line) {
|
||||||
$toDate = $this->data['updated_at'];
|
$warnMsg[] = 'Line not found';
|
||||||
|
|
||||||
$formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
|
|
||||||
|
|
||||||
$fdateTime = null;
|
|
||||||
$tdateTime = null;
|
|
||||||
// Try parsing with multiple formats
|
|
||||||
foreach ($formats as $format) {
|
|
||||||
try {
|
|
||||||
$fdateTime = Carbon::createFromFormat($format, $fromDate);
|
|
||||||
break;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
// Optionally collect warning messages
|
|
||||||
// $warnMsg[] = "Date format mismatch with format: $format";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($formats as $format) {
|
if (Str::length($itemCod) < 6 || ! is_numeric($itemCod)) {
|
||||||
try {
|
$warnMsg[] = 'Invalid item code found';
|
||||||
$tdateTime = Carbon::createFromFormat($format, $toDate);
|
} else {
|
||||||
break;
|
$item = Item::where('code', $itemCod)->first();
|
||||||
} catch (\Exception $e) {
|
|
||||||
// Optionally collect warning messages
|
|
||||||
// $warnMsg[] = "Date format mismatch with format: $format";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$fDateOnly = '';
|
if (! $item) {
|
||||||
if (!isset($fdateTime)) {
|
$warnMsg[] = 'Item not found';
|
||||||
// throw new \Exception('Invalid date time format');
|
|
||||||
$warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$fDateOnly = $fdateTime->toDateString();
|
|
||||||
}
|
|
||||||
if (!isset($tdateTime)) {
|
|
||||||
$warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($fdateTime) && isset($tdateTime)) {
|
$plantId = $plant->id;
|
||||||
if ($fdateTime->greaterThan($tdateTime)) {
|
|
||||||
$warnMsg[] = "'Created DataTime' is greater than 'Updated DateTime'.";
|
$itemAgaPlant = Item::where('plant_id', $plantId)->where('code', $itemCod)->first();
|
||||||
}
|
|
||||||
|
if(!$itemAgaPlant){
|
||||||
|
$warnMsg[] = 'Item not found against plant code';
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!$fromDate) {
|
$user = Filament::auth()->user();
|
||||||
// $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
|
|
||||||
// }
|
|
||||||
// else if (!$toDate) {
|
|
||||||
// $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
|
|
||||||
// }
|
|
||||||
|
|
||||||
$user = User::where('name', $this->data['operator_id'])->first();
|
$operatorName = $user->name;
|
||||||
if (!$user) {
|
|
||||||
$warnMsg[] = "Operator ID not found";
|
if (Str::length($this->data['plan_quantity']) < 0 || ! is_numeric($this->data['plan_quantity']) || $this->data['plan_quantity'] <= 0) {
|
||||||
|
$warnMsg[] = 'Invalid plan quantity found';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($warnMsg)) {
|
if (! empty($warnMsg)) {
|
||||||
throw new RowImportFailedException(implode(', ', $warnMsg));
|
throw new RowImportFailedException(implode(', ', $warnMsg));
|
||||||
}
|
} else {
|
||||||
else { //if (empty($warnMsg))
|
|
||||||
$productionPlan = ProductionPlan::where('plant_id', $plant->id)
|
$productionPlan = ProductionPlan::where('plant_id', $plant->id)
|
||||||
->where('shift_id', $shift->id)
|
->where('line_id', $line->id)
|
||||||
->where('line_id', $line->id)
|
->where('item_id', $itemAgaPlant->id)
|
||||||
->whereDate('created_at', $fDateOnly)
|
->latest()
|
||||||
// ->where('plan_quantity', $productionQuantity->plan_quantity)
|
->first();
|
||||||
->latest()
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($productionPlan) {
|
if ($productionPlan) {
|
||||||
// if($productionPlan->production_quantity)
|
|
||||||
// {
|
|
||||||
// throw new RowImportFailedException("{$productionPlan->created_at}, {$productionPlan->production_quantity}");
|
|
||||||
// }
|
|
||||||
// $warnMsg[] = "Production plan already exist on '{$fDateOnly}'!";
|
|
||||||
|
|
||||||
$productionPlan->update([
|
$productionPlan->update([
|
||||||
'plan_quantity' => $this->data['plan_quantity'],
|
'plan_quantity' => $this->data['plan_quantity'],
|
||||||
// 'production_quantity' => $productionPlan->production_quantity,
|
'operator_id' => $operatorName,
|
||||||
// 'created_at' => $productionPlan->created_at,//$fdateTime->format('Y-m-d H:i:s'),
|
|
||||||
// 'updated_at' => $tdateTime->format('Y-m-d H:i:s'),
|
|
||||||
'operator_id' => $this->data['operator_id'],
|
|
||||||
]);
|
]);
|
||||||
$productionPlan->save();
|
$productionPlan->save();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,28 +171,23 @@ class ProductionPlanImporter extends Importer
|
|||||||
ProductionPlan::updateOrCreate([
|
ProductionPlan::updateOrCreate([
|
||||||
'plant_id' => $plant->id,
|
'plant_id' => $plant->id,
|
||||||
'line_id' => $line->id,
|
'line_id' => $line->id,
|
||||||
'shift_id' => $shift->id,
|
'item_id' => $itemAgaPlant->id,
|
||||||
|
// 'shift_id' => $shift->id,
|
||||||
'plan_quantity' => $this->data['plan_quantity'],
|
'plan_quantity' => $this->data['plan_quantity'],
|
||||||
'production_quantity' => $this->data['production_quantity'],
|
'created_at' =>now(),
|
||||||
'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
|
'updated_at' => now(),
|
||||||
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
|
'operator_id' => $operatorName,
|
||||||
'operator_id' => $this->data['operator_id'],
|
|
||||||
]);
|
]);
|
||||||
return null;
|
|
||||||
// return ProductionPlan::firstOrNew([
|
|
||||||
// // Update existing records, matching them by `$this->data['column_name']`
|
|
||||||
// 'email' => $this->data['email'],
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// return new ProductionPlan();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getCompletedNotificationBody(Import $import): string
|
public static function getCompletedNotificationBody(Import $import): string
|
||||||
{
|
{
|
||||||
$body = 'Your production plan import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
|
$body = 'Your production plan import has completed and '.number_format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';
|
||||||
|
|
||||||
if ($failedRowsCount = $import->getFailedRowsCount()) {
|
if ($failedRowsCount = $import->getFailedRowsCount()) {
|
||||||
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
|
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $body;
|
return $body;
|
||||||
|
|||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
173
app/Filament/Pages/ProductionTarget.php
Normal file
173
app/Filament/Pages/ProductionTarget.php
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
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')
|
||||||
|
->reactive()
|
||||||
|
->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) {
|
||||||
|
$set('line_id', null);
|
||||||
|
$set('year', null);
|
||||||
|
$set('month', null);
|
||||||
|
$this->dispatch('loadData',$state, '', '', '');
|
||||||
|
}),
|
||||||
|
Select::make('line_id')
|
||||||
|
->label('Line')
|
||||||
|
->required()
|
||||||
|
->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()
|
||||||
|
->options([
|
||||||
|
'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()
|
||||||
|
->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,6 +82,9 @@ class ItemResource extends Resource
|
|||||||
Forms\Components\TextInput::make('category')
|
Forms\Components\TextInput::make('category')
|
||||||
->label('Category')
|
->label('Category')
|
||||||
->placeholder('Scan the Category'),
|
->placeholder('Scan the Category'),
|
||||||
|
Forms\Components\TextInput::make('category')
|
||||||
|
->label('Category')
|
||||||
|
->placeholder('Scan the Category'),
|
||||||
Forms\Components\TextInput::make('code')
|
Forms\Components\TextInput::make('code')
|
||||||
->required()
|
->required()
|
||||||
->placeholder('Scan the valid code')
|
->placeholder('Scan the valid code')
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@ use AlperenErsoy\FilamentExport\Actions\FilamentExportBulkAction;
|
|||||||
use App\Filament\Exports\ProductionPlanExporter;
|
use App\Filament\Exports\ProductionPlanExporter;
|
||||||
use App\Filament\Imports\ProductionPlanImporter;
|
use App\Filament\Imports\ProductionPlanImporter;
|
||||||
use App\Filament\Resources\ProductionPlanResource\Pages;
|
use App\Filament\Resources\ProductionPlanResource\Pages;
|
||||||
use App\Filament\Resources\ProductionPlanResource\RelationManagers;
|
|
||||||
use App\Models\Block;
|
use App\Models\Block;
|
||||||
|
use App\Models\Item;
|
||||||
use App\Models\Line;
|
use App\Models\Line;
|
||||||
use App\Models\Plant;
|
use App\Models\Plant;
|
||||||
use App\Models\ProductionPlan;
|
use App\Models\ProductionPlan;
|
||||||
@@ -16,19 +16,18 @@ use Carbon\Carbon;
|
|||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Components\DateTimePicker;
|
use Filament\Forms\Components\DateTimePicker;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Forms\Get;
|
use Filament\Forms\Get;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Actions\ExportAction;
|
||||||
use Filament\Tables\Actions\ImportAction;
|
use Filament\Tables\Actions\ImportAction;
|
||||||
|
use Filament\Tables\Filters\Filter;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
use Filament\Forms\Components\Section;
|
|
||||||
use Filament\Forms\Components\Select;
|
|
||||||
use Filament\Tables\Actions\ExportAction;
|
|
||||||
use Filament\Tables\Filters\Filter;
|
|
||||||
use Illuminate\Support\Facades\Request;
|
|
||||||
|
|
||||||
class ProductionPlanResource extends Resource
|
class ProductionPlanResource extends Resource
|
||||||
{
|
{
|
||||||
@@ -55,22 +54,22 @@ class ProductionPlanResource extends Resource
|
|||||||
->reactive()
|
->reactive()
|
||||||
->options(function (callable $get) {
|
->options(function (callable $get) {
|
||||||
$userHas = Filament::auth()->user()->plant_id;
|
$userHas = Filament::auth()->user()->plant_id;
|
||||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
|
||||||
|
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
|
||||||
})
|
})
|
||||||
->default(function () {
|
->default(function () {
|
||||||
return optional(ProductionPlan::latest()->first())->plant_id;
|
return optional(ProductionPlan::latest()->first())->plant_id;
|
||||||
})
|
})
|
||||||
->disabled(fn (Get $get) => !empty($get('id')))
|
->disabled(fn (Get $get) => ! empty($get('id')))
|
||||||
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
|
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
|
||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
$plantId = $get('plant_id');
|
$plantId = $get('plant_id');
|
||||||
$set('block_name', null);
|
$set('block_name', null);
|
||||||
if (!$plantId) {
|
if (! $plantId) {
|
||||||
$set('ppPlantError', 'Please select a plant first.');
|
$set('ppPlantError', 'Please select a plant first.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$set('ppPlantError', null);
|
$set('ppPlantError', null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -79,102 +78,6 @@ class ProductionPlanResource extends Resource
|
|||||||
])
|
])
|
||||||
->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
|
->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
|
||||||
->hintColor('danger'),
|
->hintColor('danger'),
|
||||||
Forms\Components\Select::make('block_name')
|
|
||||||
->required()
|
|
||||||
// ->nullable()
|
|
||||||
->label('Block')
|
|
||||||
->options(function (callable $get) {
|
|
||||||
if (!$get('plant_id')) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Block::where('plant_id', $get('plant_id'))
|
|
||||||
->pluck('name', 'id')
|
|
||||||
->toArray();
|
|
||||||
})
|
|
||||||
->reactive()
|
|
||||||
->default(function () {
|
|
||||||
$latestShiftId = optional(ProductionPlan::latest()->first())->shift_id;
|
|
||||||
return optional(Shift::where('id', $latestShiftId)->first())->block_id;
|
|
||||||
})
|
|
||||||
//->afterStateUpdated(fn ($set) => $set('shift_id', null))
|
|
||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
|
||||||
if($get('id'))
|
|
||||||
{
|
|
||||||
$getShift = ProductionPlan::where('id', $get('id'))->first();
|
|
||||||
$getBlock = Shift::where('id', $getShift->shift_id)->first();
|
|
||||||
if($getBlock->block_id)
|
|
||||||
{
|
|
||||||
$set('block_name', $getBlock->block_id);
|
|
||||||
$set('ppBlockError', null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$blockId = $get('block_name');
|
|
||||||
$set('shift_id', null);
|
|
||||||
|
|
||||||
if (!$blockId) {
|
|
||||||
$set('ppBlockError', 'Please select a block first.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$set('ppBlockError', null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
->extraAttributes(fn ($get) => [
|
|
||||||
'class' => $get('ppBlockError') ? 'border-red-500' : '',
|
|
||||||
])
|
|
||||||
->hint(fn ($get) => $get('ppBlockError') ? $get('ppBlockError') : null)
|
|
||||||
->hintColor('danger'),
|
|
||||||
Forms\Components\Select::make('shift_id')
|
|
||||||
->relationship('shift', 'name')
|
|
||||||
->required()
|
|
||||||
// ->nullable()
|
|
||||||
->autofocus(true)
|
|
||||||
->options(function (callable $get) {
|
|
||||||
if (!$get('plant_id') || !$get('block_name')) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Shift::where('plant_id', $get('plant_id'))
|
|
||||||
->where('block_id', $get('block_name'))
|
|
||||||
->pluck('name', 'id')
|
|
||||||
->toArray();
|
|
||||||
})
|
|
||||||
->reactive()
|
|
||||||
->default(function () {
|
|
||||||
return optional(ProductionPlan::latest()->first())->shift_id;
|
|
||||||
})
|
|
||||||
// ->afterStateUpdated(fn ($set) => $set('line_id', null))
|
|
||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
|
||||||
if($get('id'))
|
|
||||||
{
|
|
||||||
$getShift = ProductionPlan::where('id', $get('id'))->first();
|
|
||||||
if($getShift->shift_id)
|
|
||||||
{
|
|
||||||
$set('shift_id', $getShift->shift_id);
|
|
||||||
$set('ppShiftError', null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$curShiftId = $get('shift_id');
|
|
||||||
$set('line_id', null);
|
|
||||||
|
|
||||||
if (!$curShiftId) {
|
|
||||||
$set('ppShiftError', 'Please select a shift first.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$set('ppShiftError', null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
->extraAttributes(fn ($get) => [
|
|
||||||
'class' => $get('ppShiftError') ? 'border-red-500' : '',
|
|
||||||
])
|
|
||||||
->hint(fn ($get) => $get('ppShiftError') ? $get('ppShiftError') : null)
|
|
||||||
->hintColor('danger'),
|
|
||||||
Forms\Components\Select::make('line_id')
|
Forms\Components\Select::make('line_id')
|
||||||
->relationship('line', 'name')
|
->relationship('line', 'name')
|
||||||
->required()
|
->required()
|
||||||
@@ -185,7 +88,7 @@ class ProductionPlanResource extends Resource
|
|||||||
// ->toArray() // Convert collection to array
|
// ->toArray() // Convert collection to array
|
||||||
// )
|
// )
|
||||||
->options(function (callable $get) {
|
->options(function (callable $get) {
|
||||||
if (!$get('plant_id') || !$get('block_name') || !$get('shift_id')) {
|
if (! $get('plant_id')) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,248 +100,257 @@ class ProductionPlanResource extends Resource
|
|||||||
// ->default(function () {
|
// ->default(function () {
|
||||||
// return optional(ProductionPlan::latest()->first())->line_id;
|
// return optional(ProductionPlan::latest()->first())->line_id;
|
||||||
// })
|
// })
|
||||||
|
// ->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
|
// if ($get('id')) {
|
||||||
|
// $getShift = ProductionPlan::where('id', $get('id'))->first();
|
||||||
|
// if ($getShift->line_id) {
|
||||||
|
// $set('line_id', $getShift->line_id);
|
||||||
|
// $set('ppLineError', null);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// $currentDT = Carbon::now()->toDateTimeString();
|
||||||
|
// $set('created_at', $currentDT);
|
||||||
|
// $set('update_date', null);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $lineId = $get('line_id');
|
||||||
|
// // $set('plan_quantity', null);
|
||||||
|
|
||||||
|
// if (! $lineId) {
|
||||||
|
// $set('ppLineError', 'Please select a line first.');
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// } else {
|
||||||
|
// $isUpdate = ! empty($get('id'));
|
||||||
|
// if (! $isUpdate) {
|
||||||
|
// $exists = ProductionPlan::where('plant_id', $get('plant_id'))
|
||||||
|
// ->where('shift_id', $get('shift_id'))
|
||||||
|
// ->where('line_id', $get('line_id'))
|
||||||
|
// ->whereDate('created_at', today())
|
||||||
|
// ->latest()
|
||||||
|
// ->exists();
|
||||||
|
|
||||||
|
// if ($exists) {
|
||||||
|
// $set('line_id', null);
|
||||||
|
// $set('ppLineError', 'Production plan already updated.');
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// } else {
|
||||||
|
// $existShifts = ProductionPlan::where('plant_id', $get('plant_id'))
|
||||||
|
// ->where('shift_id', $get('shift_id'))
|
||||||
|
// ->where('line_id', $get('line_id'))
|
||||||
|
// ->whereDate('created_at', Carbon::yesterday())
|
||||||
|
// ->latest()
|
||||||
|
// ->exists();
|
||||||
|
|
||||||
|
// if ($existShifts) { // if ($existShifts->count() > 0)
|
||||||
|
// // $currentDate = date('Y-m-d');
|
||||||
|
// $yesterday = date('Y-m-d', strtotime('-1 days'));
|
||||||
|
|
||||||
|
// $shiftId = Shift::where('id', $get('shift_id'))
|
||||||
|
// ->first();
|
||||||
|
|
||||||
|
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
||||||
|
// $hRs = (int) $hRs;
|
||||||
|
// // $miNs = (int) $miNs;-*/
|
||||||
|
|
||||||
|
// $totalMinutes = $hRs * 60 + $miNs;
|
||||||
|
|
||||||
|
// $from_dt = $yesterday.' '.$shiftId->start_time;
|
||||||
|
|
||||||
|
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
|
||||||
|
|
||||||
|
// $currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// // Check if current date time is within the range
|
||||||
|
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
||||||
|
// // echo "Choosed a valid shift...";
|
||||||
|
|
||||||
|
// $set('line_id', null);
|
||||||
|
// $set('ppLineError', 'Production plan already updated.');
|
||||||
|
|
||||||
|
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
||||||
|
// return;
|
||||||
|
// } else {
|
||||||
|
// $currentDate = date('Y-m-d');
|
||||||
|
|
||||||
|
// $shiftId = Shift::where('id', $get('shift_id'))
|
||||||
|
// ->first();
|
||||||
|
|
||||||
|
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
||||||
|
// $hRs = (int) $hRs;
|
||||||
|
// // $miNs = (int) $miNs;-*/
|
||||||
|
|
||||||
|
// $totalMinutes = $hRs * 60 + $miNs;
|
||||||
|
|
||||||
|
// $from_dt = $currentDate.' '.$shiftId->start_time;
|
||||||
|
|
||||||
|
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
|
||||||
|
|
||||||
|
// $currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// // Check if current date time is within the range
|
||||||
|
// if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
|
||||||
|
// // echo "Choosed a valid shift...";
|
||||||
|
|
||||||
|
// $set('line_id', null);
|
||||||
|
// $set('ppLineError', 'Choosed a invalid shift.');
|
||||||
|
|
||||||
|
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $set('ppLineError', null);
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// } else {
|
||||||
|
// // $currentDate = date('Y-m-d');
|
||||||
|
// $yesterday = date('Y-m-d', strtotime('-1 days'));
|
||||||
|
|
||||||
|
// $shiftId = Shift::where('id', $get('shift_id'))
|
||||||
|
// ->first();
|
||||||
|
|
||||||
|
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
||||||
|
// $hRs = (int) $hRs;
|
||||||
|
// // $miNs = (int) $miNs;-*/
|
||||||
|
|
||||||
|
// $totalMinutes = $hRs * 60 + $miNs;
|
||||||
|
|
||||||
|
// $from_dt = $yesterday.' '.$shiftId->start_time;
|
||||||
|
|
||||||
|
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
|
||||||
|
|
||||||
|
// $currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// // Check if current date time is within the range
|
||||||
|
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
||||||
|
// // echo "Choosed a valid shift...";
|
||||||
|
|
||||||
|
// // here i'm updating created as yesterday
|
||||||
|
// $set('created_at', $from_dt);
|
||||||
|
// $set('update_date', '1');
|
||||||
|
|
||||||
|
// $set('ppLineError', null);
|
||||||
|
|
||||||
|
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
||||||
|
// return;
|
||||||
|
// } else {
|
||||||
|
// $currentDate = date('Y-m-d');
|
||||||
|
|
||||||
|
// $shiftId = Shift::where('id', $get('shift_id'))
|
||||||
|
// ->first();
|
||||||
|
|
||||||
|
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
||||||
|
// $hRs = (int) $hRs;
|
||||||
|
// // $miNs = (int) $miNs;-*/
|
||||||
|
|
||||||
|
// $totalMinutes = $hRs * 60 + $miNs;
|
||||||
|
|
||||||
|
// $from_dt = $currentDate.' '.$shiftId->start_time;
|
||||||
|
|
||||||
|
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
|
||||||
|
|
||||||
|
// $currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// // Check if current date time is within the range
|
||||||
|
// if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
|
||||||
|
// // echo "Choosed a valid shift...";
|
||||||
|
|
||||||
|
// $set('line_id', null);
|
||||||
|
// $set('ppLineError', 'Choosed a invalid shift.');
|
||||||
|
|
||||||
|
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $set('ppLineError', null);
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // $exists = ProductionPlan::where('plant_id', $get('plant_id'))
|
||||||
|
// // //->where('shift_id', $get('shift_id'))
|
||||||
|
// // ->where('line_id', $get('line_id'))
|
||||||
|
// // ->whereDate('created_at', today())
|
||||||
|
// // ->latest() // Orders by created_at DESC
|
||||||
|
// // ->first();
|
||||||
|
|
||||||
|
// // if ($exists)
|
||||||
|
// // {
|
||||||
|
// // $existingShifts = ProductionPlan::where('plant_id', $get('plant_id'))
|
||||||
|
// // //->where('shift_id', $get('shift_id'))
|
||||||
|
// // ->where('line_id', $get('line_id'))
|
||||||
|
// // // ->whereDate('created_at', today())
|
||||||
|
// // ->whereDate('created_at', today())
|
||||||
|
// // ->get();
|
||||||
|
|
||||||
|
// // foreach ($existingShifts as $shift) {
|
||||||
|
// // $curShiftId = $shift->shift_id;
|
||||||
|
|
||||||
|
// // $currentDate = date('Y-m-d');
|
||||||
|
|
||||||
|
// // $shiftId = \App\Models\Shift::where('id', $curShiftId)
|
||||||
|
// // ->first();
|
||||||
|
|
||||||
|
// // [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
||||||
|
// // $hRs = (int) $hRs;
|
||||||
|
// // // $miNs = (int) $miNs;-*/
|
||||||
|
|
||||||
|
// // $totalMinutes = $hRs * 60 + $miNs;
|
||||||
|
|
||||||
|
// // $from_dt = $currentDate . ' ' . $shiftId->start_time;
|
||||||
|
|
||||||
|
// // $to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
||||||
|
|
||||||
|
// // $currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// // // Check if current date time is within the range
|
||||||
|
// // if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
||||||
|
// // //echo "Choosed a valid shift...";
|
||||||
|
// // // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
||||||
|
|
||||||
|
// // $set('line_id', null);
|
||||||
|
// // $set('ppLineError', 'Production plan already updated.');
|
||||||
|
// // return;
|
||||||
|
// // }
|
||||||
|
// // // else {
|
||||||
|
// // // $set('ppLineError', 'Choosed a invalid shift...');
|
||||||
|
// // // return;
|
||||||
|
// // // }
|
||||||
|
// // }
|
||||||
|
// // $set('ppLineError', null);
|
||||||
|
// // return;
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// $set('ppLineError', null);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
if($get('id'))
|
$set('item_id', null);
|
||||||
{
|
$set('plan_quantity', null);
|
||||||
$getShift = ProductionPlan::where('id', $get('id'))->first();
|
|
||||||
if($getShift->line_id)
|
|
||||||
{
|
|
||||||
$set('line_id', $getShift->line_id);
|
|
||||||
$set('ppLineError', null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$currentDT = Carbon::now()->toDateTimeString();
|
|
||||||
$set('created_at', $currentDT);
|
|
||||||
$set('update_date', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lineId = $get('line_id');
|
|
||||||
// $set('plan_quantity', null);
|
|
||||||
|
|
||||||
if (!$lineId) {
|
|
||||||
$set('ppLineError', 'Please select a line first.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$isUpdate = !empty($get('id'));
|
|
||||||
if (!$isUpdate)
|
|
||||||
{
|
|
||||||
$exists = ProductionPlan::where('plant_id', $get('plant_id'))
|
|
||||||
->where('shift_id', $get('shift_id'))
|
|
||||||
->where('line_id', $get('line_id'))
|
|
||||||
->whereDate('created_at', today())
|
|
||||||
->latest()
|
|
||||||
->exists();
|
|
||||||
|
|
||||||
if ($exists)
|
|
||||||
{
|
|
||||||
$set('line_id', null);
|
|
||||||
$set('ppLineError', 'Production plan already updated.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$existShifts = ProductionPlan::where('plant_id', $get('plant_id'))
|
|
||||||
->where('shift_id', $get('shift_id'))
|
|
||||||
->where('line_id', $get('line_id'))
|
|
||||||
->whereDate('created_at', Carbon::yesterday())
|
|
||||||
->latest()
|
|
||||||
->exists();
|
|
||||||
|
|
||||||
if ($existShifts) //if ($existShifts->count() > 0)
|
|
||||||
{
|
|
||||||
//$currentDate = date('Y-m-d');
|
|
||||||
$yesterday = date('Y-m-d', strtotime('-1 days'));
|
|
||||||
|
|
||||||
$shiftId = Shift::where('id', $get('shift_id'))
|
|
||||||
->first();
|
|
||||||
|
|
||||||
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
|
||||||
$hRs = (int) $hRs;
|
|
||||||
// $miNs = (int) $miNs;-*/
|
|
||||||
|
|
||||||
$totalMinutes = $hRs * 60 + $miNs;
|
|
||||||
|
|
||||||
$from_dt = $yesterday . ' ' . $shiftId->start_time;
|
|
||||||
|
|
||||||
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
|
||||||
|
|
||||||
$currentDateTime = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// Check if current date time is within the range
|
|
||||||
if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
|
||||||
//echo "Choosed a valid shift...";
|
|
||||||
|
|
||||||
$set('line_id', null);
|
|
||||||
$set('ppLineError', 'Production plan already updated.');
|
|
||||||
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$currentDate = date('Y-m-d');
|
|
||||||
|
|
||||||
$shiftId = Shift::where('id', $get('shift_id'))
|
|
||||||
->first();
|
|
||||||
|
|
||||||
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
|
||||||
$hRs = (int) $hRs;
|
|
||||||
// $miNs = (int) $miNs;-*/
|
|
||||||
|
|
||||||
$totalMinutes = $hRs * 60 + $miNs;
|
|
||||||
|
|
||||||
$from_dt = $currentDate . ' ' . $shiftId->start_time;
|
|
||||||
|
|
||||||
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
|
||||||
|
|
||||||
$currentDateTime = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// Check if current date time is within the range
|
|
||||||
if (!($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
|
|
||||||
//echo "Choosed a valid shift...";
|
|
||||||
|
|
||||||
$set('line_id', null);
|
|
||||||
$set('ppLineError', 'Choosed a invalid shift.');
|
|
||||||
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$set('ppLineError', null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//$currentDate = date('Y-m-d');
|
|
||||||
$yesterday = date('Y-m-d', strtotime('-1 days'));
|
|
||||||
|
|
||||||
$shiftId = Shift::where('id', $get('shift_id'))
|
|
||||||
->first();
|
|
||||||
|
|
||||||
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
|
||||||
$hRs = (int) $hRs;
|
|
||||||
// $miNs = (int) $miNs;-*/
|
|
||||||
|
|
||||||
$totalMinutes = $hRs * 60 + $miNs;
|
|
||||||
|
|
||||||
$from_dt = $yesterday . ' ' . $shiftId->start_time;
|
|
||||||
|
|
||||||
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
|
||||||
|
|
||||||
$currentDateTime = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// Check if current date time is within the range
|
|
||||||
if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
|
||||||
//echo "Choosed a valid shift...";
|
|
||||||
|
|
||||||
// here i'm updating created as yesterday
|
|
||||||
$set('created_at', $from_dt);
|
|
||||||
$set('update_date', '1');
|
|
||||||
|
|
||||||
$set('ppLineError', null);
|
|
||||||
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$currentDate = date('Y-m-d');
|
|
||||||
|
|
||||||
$shiftId = Shift::where('id', $get('shift_id'))
|
|
||||||
->first();
|
|
||||||
|
|
||||||
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
|
||||||
$hRs = (int) $hRs;
|
|
||||||
// $miNs = (int) $miNs;-*/
|
|
||||||
|
|
||||||
$totalMinutes = $hRs * 60 + $miNs;
|
|
||||||
|
|
||||||
$from_dt = $currentDate . ' ' . $shiftId->start_time;
|
|
||||||
|
|
||||||
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
|
||||||
|
|
||||||
$currentDateTime = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// Check if current date time is within the range
|
|
||||||
if (!($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
|
|
||||||
//echo "Choosed a valid shift...";
|
|
||||||
|
|
||||||
$set('line_id', null);
|
|
||||||
$set('ppLineError', 'Choosed a invalid shift.');
|
|
||||||
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$set('ppLineError', null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// $exists = ProductionPlan::where('plant_id', $get('plant_id'))
|
|
||||||
// //->where('shift_id', $get('shift_id'))
|
|
||||||
// ->where('line_id', $get('line_id'))
|
|
||||||
// ->whereDate('created_at', today())
|
|
||||||
// ->latest() // Orders by created_at DESC
|
|
||||||
// ->first();
|
|
||||||
|
|
||||||
// if ($exists)
|
|
||||||
// {
|
|
||||||
// $existingShifts = ProductionPlan::where('plant_id', $get('plant_id'))
|
|
||||||
// //->where('shift_id', $get('shift_id'))
|
|
||||||
// ->where('line_id', $get('line_id'))
|
|
||||||
// // ->whereDate('created_at', today())
|
|
||||||
// ->whereDate('created_at', today())
|
|
||||||
// ->get();
|
|
||||||
|
|
||||||
// foreach ($existingShifts as $shift) {
|
|
||||||
// $curShiftId = $shift->shift_id;
|
|
||||||
|
|
||||||
// $currentDate = date('Y-m-d');
|
|
||||||
|
|
||||||
// $shiftId = \App\Models\Shift::where('id', $curShiftId)
|
|
||||||
// ->first();
|
|
||||||
|
|
||||||
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
|
|
||||||
// $hRs = (int) $hRs;
|
|
||||||
// // $miNs = (int) $miNs;-*/
|
|
||||||
|
|
||||||
// $totalMinutes = $hRs * 60 + $miNs;
|
|
||||||
|
|
||||||
// $from_dt = $currentDate . ' ' . $shiftId->start_time;
|
|
||||||
|
|
||||||
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
|
|
||||||
|
|
||||||
// $currentDateTime = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// // Check if current date time is within the range
|
|
||||||
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
|
|
||||||
// //echo "Choosed a valid shift...";
|
|
||||||
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
|
|
||||||
|
|
||||||
// $set('line_id', null);
|
|
||||||
// $set('ppLineError', 'Production plan already updated.');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // else {
|
|
||||||
// // $set('ppLineError', 'Choosed a invalid shift...');
|
|
||||||
// // return;
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// $set('ppLineError', null);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$set('ppLineError', null);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
->extraAttributes(fn ($get) => [
|
->extraAttributes(fn ($get) => [
|
||||||
'class' => $get('ppLineError') ? 'border-red-500' : '',
|
'class' => $get('ppLineError') ? 'border-red-500' : '',
|
||||||
])
|
])
|
||||||
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
|
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
|
||||||
->hintColor('danger'),
|
->hintColor('danger'),
|
||||||
|
Forms\Components\Select::make('item_id')
|
||||||
|
->label('Item')
|
||||||
|
->reactive()
|
||||||
|
->searchable()
|
||||||
|
->required()
|
||||||
|
->options(function (callable $get) {
|
||||||
|
if (! $get('plant_id')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Item::where('plant_id', $get('plant_id'))
|
||||||
|
->pluck('code', 'id')
|
||||||
|
->toArray();
|
||||||
|
}),
|
||||||
Forms\Components\TextInput::make('plan_quantity')
|
Forms\Components\TextInput::make('plan_quantity')
|
||||||
->required()
|
->required()
|
||||||
->integer()
|
->integer()
|
||||||
@@ -449,21 +361,18 @@ class ProductionPlanResource extends Resource
|
|||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
$planQuan = $get('plan_quantity');
|
$planQuan = $get('plan_quantity');
|
||||||
|
|
||||||
if(!$get('update_date') )
|
if (! $get('update_date')) {
|
||||||
{
|
if (! $get('id')) {
|
||||||
if(!$get('id'))
|
|
||||||
{
|
|
||||||
$currentDT = Carbon::now()->toDateTimeString();
|
$currentDT = Carbon::now()->toDateTimeString();
|
||||||
$set('created_at', $currentDT);
|
$set('created_at', $currentDT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$planQuan) {
|
if (! $planQuan) {
|
||||||
$set('ppPlanQuanError', 'Scan the valid plan quantity.');
|
$set('ppPlanQuanError', 'Scan the valid plan quantity.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$set('ppPlanQuanError', null);
|
$set('ppPlanQuanError', null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -472,29 +381,19 @@ class ProductionPlanResource extends Resource
|
|||||||
])
|
])
|
||||||
->hint(fn ($get) => $get('ppPlanQuanError') ? $get('ppPlanQuanError') : null)
|
->hint(fn ($get) => $get('ppPlanQuanError') ? $get('ppPlanQuanError') : null)
|
||||||
->hintColor('danger'),
|
->hintColor('danger'),
|
||||||
Forms\Components\TextInput::make('production_quantity')
|
// Forms\Components\TextInput::make('production_quantity')
|
||||||
->required()
|
// ->required()
|
||||||
->integer()
|
// ->integer()
|
||||||
->label('Production Quantity')
|
// ->label('Production Quantity')
|
||||||
->readOnly(fn (callable $get) => !$get('id'))
|
// ->readOnly(fn (callable $get) => ! $get('id'))
|
||||||
->default(0),
|
// ->default(0),
|
||||||
Forms\Components\TextInput::make('id')
|
Forms\Components\TextInput::make('id')
|
||||||
->hidden()
|
->hidden()
|
||||||
->readOnly(),
|
->readOnly(),
|
||||||
Forms\Components\TextInput::make('update_date')
|
|
||||||
->hidden()
|
|
||||||
->reactive()
|
|
||||||
->readOnly(),
|
|
||||||
Forms\Components\DateTimePicker::make('created_at')
|
|
||||||
->label('Created DateTime')
|
|
||||||
->hidden()
|
|
||||||
->reactive()
|
|
||||||
->required()
|
|
||||||
->readOnly(),
|
|
||||||
Forms\Components\Hidden::make('operator_id')
|
Forms\Components\Hidden::make('operator_id')
|
||||||
->default(Filament::auth()->user()->name),
|
->default(Filament::auth()->user()->name),
|
||||||
])
|
])
|
||||||
->columns(2),
|
->columns(4),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,34 +428,55 @@ class ProductionPlanResource extends Resource
|
|||||||
$paginator = $livewire->getTableRecords();
|
$paginator = $livewire->getTableRecords();
|
||||||
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
|
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
|
||||||
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
|
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
|
||||||
|
|
||||||
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
|
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
|
||||||
}),
|
}),
|
||||||
|
Tables\Columns\TextColumn::make('plant.name')
|
||||||
|
->label('Plant')
|
||||||
|
->alignCenter()
|
||||||
|
->sortable()
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('line.name')
|
||||||
|
->label('Plant')
|
||||||
|
->alignCenter()
|
||||||
|
->sortable()
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('item.code')
|
||||||
|
->label('Item')
|
||||||
|
->alignCenter()
|
||||||
|
->sortable()
|
||||||
|
->searchable(),
|
||||||
Tables\Columns\TextColumn::make('plan_quantity')
|
Tables\Columns\TextColumn::make('plan_quantity')
|
||||||
->label('Plan Quantity')
|
->label('Plan Quantity')
|
||||||
->alignCenter()
|
->alignCenter()
|
||||||
->numeric()
|
->numeric()
|
||||||
->sortable(),
|
->sortable()
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('working_days')
|
||||||
|
->label('Working Days')
|
||||||
|
->alignCenter()
|
||||||
|
->numeric()
|
||||||
|
->sortable()
|
||||||
|
->searchable(),
|
||||||
Tables\Columns\TextColumn::make('production_quantity')
|
Tables\Columns\TextColumn::make('production_quantity')
|
||||||
->label('Production Quantity')
|
->label('Production Quantity')
|
||||||
->alignCenter()
|
->alignCenter()
|
||||||
->numeric()
|
->numeric()
|
||||||
->sortable(),
|
->sortable()
|
||||||
Tables\Columns\TextColumn::make('line.name')
|
->searchable(),
|
||||||
->label('Line')
|
// Tables\Columns\TextColumn::make('line.name')
|
||||||
->alignCenter()
|
// ->label('Line')
|
||||||
->sortable(),// ->searchable(),
|
// ->alignCenter()
|
||||||
Tables\Columns\TextColumn::make('shift.block.name')
|
// ->sortable(), // ->searchable(),
|
||||||
->label('Block')
|
// Tables\Columns\TextColumn::make('shift.block.name')
|
||||||
->alignCenter()
|
// ->label('Block')
|
||||||
->sortable(),
|
// ->alignCenter()
|
||||||
Tables\Columns\TextColumn::make('shift.name')
|
// ->sortable(),
|
||||||
->label('Shift')
|
// Tables\Columns\TextColumn::make('shift.name')
|
||||||
->alignCenter()
|
// ->label('Shift')
|
||||||
->sortable(),// ->searchable(),
|
// ->alignCenter()
|
||||||
Tables\Columns\TextColumn::make('plant.name')
|
// ->sortable(), // ->searchable(),
|
||||||
->label('Plant')
|
|
||||||
->alignCenter()
|
|
||||||
->sortable(),// ->searchable(),
|
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->label('Created At')
|
->label('Created At')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
@@ -584,7 +504,7 @@ class ProductionPlanResource extends Resource
|
|||||||
Filter::make('advanced_filters')
|
Filter::make('advanced_filters')
|
||||||
->label('Advanced Filters')
|
->label('Advanced Filters')
|
||||||
->form([
|
->form([
|
||||||
//plant
|
// plant
|
||||||
Select::make('Plant')
|
Select::make('Plant')
|
||||||
->label('Select Plant')
|
->label('Select Plant')
|
||||||
->nullable()
|
->nullable()
|
||||||
@@ -593,7 +513,8 @@ class ProductionPlanResource extends Resource
|
|||||||
// })
|
// })
|
||||||
->options(function (callable $get) {
|
->options(function (callable $get) {
|
||||||
$userHas = Filament::auth()->user()->plant_id;
|
$userHas = Filament::auth()->user()->plant_id;
|
||||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
|
||||||
|
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
|
||||||
})
|
})
|
||||||
->reactive()
|
->reactive()
|
||||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||||
@@ -602,31 +523,33 @@ class ProductionPlanResource extends Resource
|
|||||||
$set('Shift', null);
|
$set('Shift', null);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
//line
|
// line
|
||||||
Select::make('Line')
|
Select::make('Line')
|
||||||
->label('Select line')
|
->label('Select line')
|
||||||
->nullable()
|
->nullable()
|
||||||
->options(function (callable $get) {
|
->options(function (callable $get) {
|
||||||
$plantId = $get('Plant');
|
$plantId = $get('Plant');
|
||||||
|
|
||||||
if (!$plantId ) {
|
if (! $plantId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Line::where('plant_id', $plantId)
|
return Line::where('plant_id', $plantId)
|
||||||
->pluck('name', 'id');
|
->pluck('name', 'id');
|
||||||
})
|
})
|
||||||
->reactive(),
|
->reactive(),
|
||||||
|
|
||||||
//block
|
// block
|
||||||
Select::make('Block')
|
Select::make('Block')
|
||||||
->label('Select Block')
|
->label('Select Block')
|
||||||
->nullable()
|
->nullable()
|
||||||
->options(function (callable $get) {
|
->options(function (callable $get) {
|
||||||
$plantId = $get('Plant');
|
$plantId = $get('Plant');
|
||||||
|
|
||||||
if (!$plantId ) {
|
if (! $plantId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
|
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
|
||||||
})
|
})
|
||||||
->reactive()
|
->reactive()
|
||||||
@@ -634,7 +557,7 @@ class ProductionPlanResource extends Resource
|
|||||||
$set('Shift', null);
|
$set('Shift', null);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
//shift
|
// shift
|
||||||
Select::make('Shift')
|
Select::make('Shift')
|
||||||
->label('Select Shift')
|
->label('Select Shift')
|
||||||
->nullable()
|
->nullable()
|
||||||
@@ -642,7 +565,7 @@ class ProductionPlanResource extends Resource
|
|||||||
$plantId = $get('Plant');
|
$plantId = $get('Plant');
|
||||||
$blockId = $get('Block');
|
$blockId = $get('Block');
|
||||||
|
|
||||||
if (!$plantId || !$blockId) {
|
if (! $plantId || ! $blockId) {
|
||||||
return []; // Return empty if plant or block is not selected
|
return []; // Return empty if plant or block is not selected
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,52 +592,66 @@ class ProductionPlanResource extends Resource
|
|||||||
return $query->whereRaw('1 = 0');
|
return $query->whereRaw('1 = 0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($plant = $data['Plant'] ?? null) {
|
if (! empty($data['Plant'])) {// if ($plant = $data['Plant'] ?? null) {
|
||||||
$query->where('plant_id', $plant);
|
$query->where('plant_id', $data['Plant']);
|
||||||
|
} else {
|
||||||
|
$userHas = Filament::auth()->user()->plant_id;
|
||||||
|
|
||||||
|
if ($userHas && strlen($userHas) > 0) {
|
||||||
|
return $query->whereRaw('1 = 0');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($shift = $data['Shift'] ?? null) {
|
if (! empty($data['Shift'])) {// if ($shift = $data['Shift'] ?? null) {
|
||||||
$query->where('shift_id', $shift);
|
$query->where('shift_id', $data['Shift']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($line = $data['Line'] ?? null) {
|
|
||||||
$query->where('line_id', $line);
|
if (! empty($data['Line'])) {// if ($line = $data['Line'] ?? null) {
|
||||||
|
$query->where('line_id', $data['Line']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($from = $data['created_from'] ?? null) {
|
if (! empty($data['created_from'])) {// if ($from = $data['created_from'] ?? null) {
|
||||||
$query->where('created_at', '>=', $from);
|
$query->where('created_at', '>=', $data['created_from']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($to = $data['created_to'] ?? null) {
|
if (! empty($data['created_to'])) {// if ($to = $data['created_to'] ?? null) {
|
||||||
$query->where('created_at', '<=', $to);
|
$query->where('created_at', '<=', $data['created_to']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
})
|
})
|
||||||
->indicateUsing(function (array $data) {
|
->indicateUsing(function (array $data) {
|
||||||
$indicators = [];
|
$indicators = [];
|
||||||
|
|
||||||
if (!empty($data['Plant'])) {
|
if (! empty($data['Plant'])) {
|
||||||
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
|
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
|
||||||
|
} else {
|
||||||
|
$userHas = Filament::auth()->user()->plant_id;
|
||||||
|
|
||||||
|
if ($userHas && strlen($userHas) > 0) {
|
||||||
|
return 'Plant: Choose plant to filter records.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['Shift'])) {
|
if (! empty($data['Shift'])) {
|
||||||
$indicators[] = 'Shift: ' . Shift::where('id', $data['Shift'])->value('name');
|
$indicators[] = 'Shift: '.Shift::where('id', $data['Shift'])->value('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['Line'])) {
|
if (! empty($data['Line'])) {
|
||||||
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
|
$indicators[] = 'Line: '.Line::where('id', $data['Line'])->value('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['created_from'])) {
|
if (! empty($data['created_from'])) {
|
||||||
$indicators[] = 'From: ' . $data['created_from'];
|
$indicators[] = 'From: '.$data['created_from'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['created_to'])) {
|
if (! empty($data['created_to'])) {
|
||||||
$indicators[] = 'To: ' . $data['created_to'];
|
$indicators[] = 'To: '.$data['created_to'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $indicators;
|
return $indicators;
|
||||||
})
|
}),
|
||||||
])
|
])
|
||||||
->filtersFormMaxHeight('280px')
|
->filtersFormMaxHeight('280px')
|
||||||
->actions([
|
->actions([
|
||||||
@@ -726,7 +663,7 @@ class ProductionPlanResource extends Resource
|
|||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
Tables\Actions\ForceDeleteBulkAction::make(),
|
Tables\Actions\ForceDeleteBulkAction::make(),
|
||||||
Tables\Actions\RestoreBulkAction::make(),
|
Tables\Actions\RestoreBulkAction::make(),
|
||||||
FilamentExportBulkAction::make('export')
|
FilamentExportBulkAction::make('export'),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
->headerActions([
|
->headerActions([
|
||||||
@@ -734,14 +671,14 @@ class ProductionPlanResource extends Resource
|
|||||||
->label('Import Production Plans')
|
->label('Import Production Plans')
|
||||||
->color('warning')
|
->color('warning')
|
||||||
->importer(ProductionPlanImporter::class)
|
->importer(ProductionPlanImporter::class)
|
||||||
->visible(function() {
|
->visible(function () {
|
||||||
return Filament::auth()->user()->can('view import production plan');
|
return Filament::auth()->user()->can('view import production plan');
|
||||||
}),
|
}),
|
||||||
ExportAction::make()
|
ExportAction::make()
|
||||||
->label('Export Production Plans')
|
->label('Export Production Plans')
|
||||||
->color('warning')
|
->color('warning')
|
||||||
->exporter(ProductionPlanExporter::class)
|
->exporter(ProductionPlanExporter::class)
|
||||||
->visible(function() {
|
->visible(function () {
|
||||||
return Filament::auth()->user()->can('view export production plan');
|
return Filament::auth()->user()->can('view export production plan');
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
|
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\RfqTransporterBidResource;
|
use App\Filament\Resources\RfqTransporterBidResource;
|
||||||
|
use App\Models\RequestQuotation;
|
||||||
use App\Models\RfqTransporterBid;
|
use App\Models\RfqTransporterBid;
|
||||||
|
use App\Models\SpotRateTransportMaster;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\PushAlertNotification;
|
use App\Notifications\PushAlertNotification;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Pages\EditRecord;
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class EditRfqTransporterBid extends EditRecord
|
class EditRfqTransporterBid extends EditRecord
|
||||||
{
|
{
|
||||||
@@ -17,52 +20,145 @@ class EditRfqTransporterBid extends EditRecord
|
|||||||
|
|
||||||
protected function afterSave(): void
|
protected function afterSave(): void
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (! $this->record->wasChanged('total_freight_charge')) {
|
if (! $this->record->wasChanged('total_freight_charge')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dd($this->record);
|
|
||||||
|
|
||||||
$rank = RfqTransporterBid::where('request_quotation_id', $this->record->request_quotation_id)
|
$rank = RfqTransporterBid::where('request_quotation_id', $this->record->request_quotation_id)
|
||||||
->orderBy('total_freight_charge')
|
->orderBy('total_freight_charge')
|
||||||
->pluck('id')
|
->pluck('id')
|
||||||
->search($this->record->id) + 1;
|
->search($this->record->id) + 1;
|
||||||
|
|
||||||
$recipients = User::role(['Super Admin', 'Rfq Supervisor', 'TransporterBid Employee'])->get();
|
$requestQuotation = RequestQuotation::findOrFail(
|
||||||
|
$this->record->request_quotation_id
|
||||||
|
);
|
||||||
|
|
||||||
|
$spotRateId = $requestQuotation->spot_rate_transport_master_id;
|
||||||
|
|
||||||
|
$spotRate = SpotRateTransportMaster::findOrFail($spotRateId);
|
||||||
|
|
||||||
|
$userNames = $spotRate->user_name;
|
||||||
|
|
||||||
|
Log::info('User names from spot rate', [
|
||||||
|
'user_name_raw' => $spotRate->user_name,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!is_array($userNames)) {
|
||||||
|
Log::warning('user_name is not array, resetting', [
|
||||||
|
'user_name' => $userNames,
|
||||||
|
]);
|
||||||
|
$userNames = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$users = User::whereIn('name', $userNames)->get();
|
||||||
|
|
||||||
|
Log::info('Matched users', [
|
||||||
|
'count' => $users->count(),
|
||||||
|
'user_ids' => $users->pluck('id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $recipients = User::role(['Super Admin', 'Rfq Supervisor', 'TransporterBid Employee'])->get();
|
||||||
|
|
||||||
|
// $recipients1 = User::role(['Super Admin', 'Rfq Supervisor', 'TransporterBid Employee'])->whereHas('pushSubscriptions')->get();
|
||||||
|
|
||||||
$currentUser = Filament::auth()->user();
|
$currentUser = Filament::auth()->user();
|
||||||
|
|
||||||
|
// if ($currentUser && ! $recipients1->contains('id', $currentUser->id)) {
|
||||||
|
// $recipients1->push($currentUser);
|
||||||
|
// }
|
||||||
|
|
||||||
if ($currentUser && ! $recipients->contains('id', $currentUser->id)) {
|
// if ($currentUser && ! $recipients->contains('id', $currentUser->id)) {
|
||||||
$recipients->push($currentUser);
|
// $recipients->push($currentUser);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// $user1 = Filament::auth()->user();
|
// $user1 = Filament::auth()->user();
|
||||||
|
|
||||||
|
|
||||||
$body = "{$currentUser->name} current rank is #{$rank}";
|
$rfqNumber = $this->record->requestQuotation->rfq_number;
|
||||||
|
$body = "{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.";
|
||||||
|
|
||||||
|
// Notification::make()
|
||||||
|
// ->title('Rank Updated')
|
||||||
|
// ->body("{$currentUser->name} current rank is #{$rank}")
|
||||||
|
// ->success()
|
||||||
|
// ->sendToDatabase($recipients);
|
||||||
|
|
||||||
|
// \Log::info('Notification sent', [
|
||||||
|
// 'rank' => $rank,
|
||||||
|
// 'recipients' => $recipients->pluck('id'),
|
||||||
|
// ]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Rank Updated')
|
->title('Rank Updated')
|
||||||
->body("{$currentUser->name} current rank is #{$rank}")
|
->body("{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.")
|
||||||
->success()
|
->success()
|
||||||
->sendToDatabase($recipients);
|
->sendToDatabase($users);
|
||||||
|
|
||||||
\Log::info('Notification sent', [
|
// foreach ($recipients1 as $user) {
|
||||||
'rank' => $rank,
|
// $user->notify(
|
||||||
'recipients' => $recipients->pluck('id'),
|
// new PushAlertNotification(
|
||||||
]);
|
// 'Rank Updated',
|
||||||
|
// $body
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
foreach ($recipients as $user) {
|
// foreach ($users as $user) {
|
||||||
$user->notify(
|
|
||||||
new PushAlertNotification(
|
// Log::info('Checking push subscription for user', [
|
||||||
|
// 'user_id' => $user->id,
|
||||||
|
// 'name' => $user->name,
|
||||||
|
// 'subscription_count' => $user->pushSubscriptions()->count(),
|
||||||
|
// ]);
|
||||||
|
// if ($user->pushSubscriptions()->exists()) {
|
||||||
|
|
||||||
|
// Log::info('Sending push notification', [
|
||||||
|
// 'user_id' => $user->id,
|
||||||
|
// ]);
|
||||||
|
// $user->notify(
|
||||||
|
// new PushAlertNotification(
|
||||||
|
// 'Rank Updated',
|
||||||
|
// $body
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// Log::warning('User has NO push subscription', [
|
||||||
|
// 'user_id' => $user->id,
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($users as $user) {
|
||||||
|
|
||||||
|
$count = $user->pushSubscriptions()->count();
|
||||||
|
|
||||||
|
Log::info('Checking push subscription for user', [
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'name' => $user->name,
|
||||||
|
'subscription_count' => $count,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($count == 0) {
|
||||||
|
Log::warning('User has NO push subscription', [
|
||||||
|
'user_id' => $user->id,
|
||||||
|
]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('Sending push notification', [
|
||||||
|
'user_id' => $user->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// ✅ THIS IS ALL YOU NEED
|
||||||
|
$user->notify(new PushAlertNotification(
|
||||||
'Rank Updated',
|
'Rank Updated',
|
||||||
$body
|
$body
|
||||||
)
|
));
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
236
app/Livewire/ProductionTargetPlan.php
Normal file
236
app/Livewire/ProductionTargetPlan.php
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
<?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();
|
||||||
|
|
||||||
|
// $row['daily_target'] = ($row['working_days'] > 0)
|
||||||
|
// ? round($row['plan_quantity'] / $row['working_days'], 2)
|
||||||
|
// : 0;
|
||||||
|
|
||||||
|
// // $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
|
||||||
|
|
||||||
|
// // foreach ($this->dates as $date) {
|
||||||
|
// // $found = $producedData[$key][$date] ?? null;
|
||||||
|
// // $row['produced_quantity'][$date] = $found->total_qty ?? 0;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// $remainingDays = $row['working_days'];
|
||||||
|
// $pendingQty = 0;
|
||||||
|
|
||||||
|
// $row['daily_target_dynamic'] = [];
|
||||||
|
// $row['produced_quantity'] = [];
|
||||||
|
|
||||||
|
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
|
||||||
|
|
||||||
|
// foreach ($this->dates as $date) {
|
||||||
|
|
||||||
|
// $found = $producedData[$key][$date] ?? null;
|
||||||
|
// $producedQty = $found->total_qty ?? 0;
|
||||||
|
|
||||||
|
// // today's adjusted target
|
||||||
|
// $todayTarget = $baseDailyTarget;
|
||||||
|
|
||||||
|
// if ($remainingDays > 1 && $pendingQty > 0) {
|
||||||
|
// $todayTarget += $pendingQty / $remainingDays;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $row['daily_target_dynamic'][$date] = round($todayTarget, 2);
|
||||||
|
// $row['produced_quantity'][$date] = $producedQty;
|
||||||
|
|
||||||
|
// // calculate today's shortfall
|
||||||
|
// $pendingQty += ($todayTarget - $producedQty);
|
||||||
|
|
||||||
|
// if ($pendingQty < 0) {
|
||||||
|
// $pendingQty = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $remainingDays--;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $row;
|
||||||
|
// })
|
||||||
|
->map(function ($row) use ($producedData) {
|
||||||
|
|
||||||
|
$row = $row->toArray();
|
||||||
|
|
||||||
|
$remainingQty = $row['plan_quantity'];
|
||||||
|
$remainingDays = $row['working_days'];
|
||||||
|
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$remainingDays--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,11 +12,13 @@ class Item extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'plant_id',
|
'plant_id',
|
||||||
|
'line_id',
|
||||||
'category',
|
'category',
|
||||||
'code',
|
'code',
|
||||||
'description',
|
'description',
|
||||||
'hourly_quantity',
|
'hourly_quantity',
|
||||||
'uom',
|
'uom',
|
||||||
|
'line_capacity',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function plant(): BelongsTo
|
public function plant(): BelongsTo
|
||||||
@@ -24,6 +26,11 @@ class Item extends Model
|
|||||||
return $this->belongsTo(Plant::class);
|
return $this->belongsTo(Plant::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function line(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Line::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function stickerMasters()
|
public function stickerMasters()
|
||||||
{
|
{
|
||||||
return $this->hasMany(StickerMaster::class, 'item_id', 'id');
|
return $this->hasMany(StickerMaster::class, 'item_id', 'id');
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Line extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
"plant_id",
|
"plant_id",
|
||||||
|
"block_id",
|
||||||
"name",
|
"name",
|
||||||
"type",
|
"type",
|
||||||
"group_work_center",
|
"group_work_center",
|
||||||
@@ -34,6 +35,11 @@ class Line extends Model
|
|||||||
return $this->belongsTo(Plant::class);
|
return $this->belongsTo(Plant::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function block(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Block::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function testingPanelReadings()
|
public function testingPanelReadings()
|
||||||
{
|
{
|
||||||
return $this->hasMany(TestingPanelReading::class);
|
return $this->hasMany(TestingPanelReading::class);
|
||||||
|
|||||||
@@ -12,12 +12,15 @@ class ProductionPlan extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
"plant_id",
|
"plant_id",
|
||||||
|
"item_id",
|
||||||
"shift_id",
|
"shift_id",
|
||||||
"created_at",
|
"created_at",
|
||||||
"line_id",
|
"line_id",
|
||||||
"plan_quantity",
|
"plan_quantity",
|
||||||
"production_quantity",
|
"production_quantity",
|
||||||
"operator_id",
|
"operator_id",
|
||||||
|
"working_days",
|
||||||
|
"leave_dates",
|
||||||
];
|
];
|
||||||
|
|
||||||
public function plant(): BelongsTo
|
public function plant(): BelongsTo
|
||||||
@@ -34,4 +37,9 @@ class ProductionPlan extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Line::class);
|
return $this->belongsTo(Line::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function item(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Item::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class ProductionQuantity extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
"plant_id",
|
"plant_id",
|
||||||
|
"machine_id",
|
||||||
"shift_id",
|
"shift_id",
|
||||||
"line_id",
|
"line_id",
|
||||||
"item_id",
|
"item_id",
|
||||||
@@ -50,6 +51,11 @@ class ProductionQuantity extends Model
|
|||||||
return $this->belongsTo(Item::class);
|
return $this->belongsTo(Item::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function machine(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Machine::class);
|
||||||
|
}
|
||||||
|
|
||||||
protected static function booted()
|
protected static function booted()
|
||||||
{
|
{
|
||||||
static::created(function ($productionQuantity) {
|
static::created(function ($productionQuantity) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use Illuminate\Notifications\Notifiable;
|
|||||||
use Spatie\Permission\Traits\HasRoles;
|
use Spatie\Permission\Traits\HasRoles;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use NotificationChannels\WebPush\HasPushSubscriptions;
|
use NotificationChannels\WebPush\HasPushSubscriptions;
|
||||||
|
use NotificationChannels\WebPush\PushSubscription;
|
||||||
|
|
||||||
class User extends Authenticatable implements FilamentUser
|
class User extends Authenticatable implements FilamentUser
|
||||||
{
|
{
|
||||||
@@ -64,4 +65,9 @@ class User extends Authenticatable implements FilamentUser
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Plant::class);
|
return $this->belongsTo(Plant::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pushSubscriptions()
|
||||||
|
{
|
||||||
|
return $this->morphMany(PushSubscription::class, 'subscribable');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql = <<<'SQL'
|
||||||
|
ALTER TABLE production_plans
|
||||||
|
ADD COLUMN item_id BIGINT DEFAULT NULL,
|
||||||
|
ADD CONSTRAINT production_plans_item_id_fkey
|
||||||
|
FOREIGN KEY (item_id) REFERENCES items(id);
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('production_plans', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql = <<<'SQL'
|
||||||
|
ALTER TABLE lines
|
||||||
|
ADD COLUMN block_id BIGINT DEFAULT NULL,
|
||||||
|
ADD CONSTRAINT lines_block_id_fkey
|
||||||
|
FOREIGN KEY (block_id) REFERENCES blocks(id);
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('lines', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql1 = <<<'SQL'
|
||||||
|
ALTER TABLE items
|
||||||
|
ADD COLUMN line_id BIGINT DEFAULT NULL,
|
||||||
|
ADD CONSTRAINT items_line_id_fkey
|
||||||
|
FOREIGN KEY (line_id) REFERENCES lines(id);
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql1);
|
||||||
|
|
||||||
|
$sql2 = <<<'SQL'
|
||||||
|
ALTER TABLE items
|
||||||
|
ADD COLUMN line_capacity TEXT DEFAULT NULL
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('items', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql = <<<'SQL'
|
||||||
|
ALTER TABLE production_quantities
|
||||||
|
ADD COLUMN machine_id BIGINT DEFAULT NULL,
|
||||||
|
ADD CONSTRAINT production_quantities_machine_id_fkey
|
||||||
|
FOREIGN KEY (machine_id) REFERENCES machines(id);
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('production_quantities', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql1 = <<<'SQL'
|
||||||
|
ALTER TABLE production_plans
|
||||||
|
ADD COLUMN working_days TEXT DEFAULT NULL
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('production_plans', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$sql1 = <<<'SQL'
|
||||||
|
ALTER TABLE production_plans
|
||||||
|
ADD COLUMN leave_dates TEXT DEFAULT NULL
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
DB::statement($sql1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Schema::table('production_plans', function (Blueprint $table) {
|
||||||
|
// //
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -65,7 +65,6 @@
|
|||||||
},
|
},
|
||||||
body: JSON.stringify(subscription)
|
body: JSON.stringify(subscription)
|
||||||
});
|
});
|
||||||
|
|
||||||
alert("Push notifications enabled ✅");
|
alert("Push notifications enabled ✅");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
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>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
</div> --}}
|
</div> --}}
|
||||||
<div class="flex gap-6 -mt-6">
|
<div class="flex gap-6 -mt-6">
|
||||||
<!-- Scan QR Code -->
|
<!-- Scan QR Code -->
|
||||||
<div class="w-1/2">
|
<div class="w-full">
|
||||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
SCAN QR CODE
|
SCAN QR CODE
|
||||||
</label>
|
</label>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Last Scanned QR -->
|
<!-- Last Scanned QR -->
|
||||||
<div class="w-1/2">
|
{{-- <div class="w-1/2">
|
||||||
<label for="recent-qr-input" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="recent-qr-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
LAST SCANNED QR
|
LAST SCANNED QR
|
||||||
</label>
|
</label>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
readonly
|
readonly
|
||||||
wire:model="recent_qr"
|
wire:model="recent_qr"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div> --}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
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>
|
||||||
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>
|
||||||
85
resources/views/livewire/production-target-plan.blade.php
Normal file
85
resources/views/livewire/production-target-plan.blade.php
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<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">No</th>
|
||||||
|
<th class="border px-4 py-2">Created Datetime</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Created By</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Plant</th>
|
||||||
|
<th class="border px-4 py-2">Line</th>
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Item Code</th>
|
||||||
|
<th class="border px-4 py-2">Production Plan Dates</th>
|
||||||
|
</tr>
|
||||||
|
</thead> --}}
|
||||||
|
<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) * 2 }}" class="text-center">
|
||||||
|
Production Plan Dates
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
@foreach($dates as $date)
|
||||||
|
<th colspan="2" class="text-center">
|
||||||
|
{{ $date }}
|
||||||
|
</th>
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
@foreach($dates as $date)
|
||||||
|
<th class="border px-4 py-2 whitespace-nowrap">Target Plan</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>
|
||||||
|
@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_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="9" class="px-4 py-4 text-center text-gray-500">
|
||||||
|
No production plan data found.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -25,12 +25,15 @@ use App\Http\Controllers\ObdController;
|
|||||||
use App\Http\Controllers\PalletController;
|
use App\Http\Controllers\PalletController;
|
||||||
use App\Http\Controllers\PdfController;
|
use App\Http\Controllers\PdfController;
|
||||||
use App\Http\Controllers\PlantController;
|
use App\Http\Controllers\PlantController;
|
||||||
|
use App\Http\Controllers\PrintController;
|
||||||
use App\Http\Controllers\ProductionStickerReprintController;
|
use App\Http\Controllers\ProductionStickerReprintController;
|
||||||
use App\Http\Controllers\SapFileController;
|
use App\Http\Controllers\SapFileController;
|
||||||
use App\Http\Controllers\StickerMasterController;
|
use App\Http\Controllers\StickerMasterController;
|
||||||
// use App\Http\Controllers\TelegramController;
|
// use App\Http\Controllers\TelegramController;
|
||||||
use App\Http\Controllers\TestingPanelController;
|
use App\Http\Controllers\TestingPanelController;
|
||||||
use App\Http\Controllers\UserController;
|
use App\Http\Controllers\UserController;
|
||||||
|
use App\Models\WebPushSubscription;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
@@ -185,3 +188,46 @@ Route::post('file/store', [SapFileController::class, 'store'])->name('file.store
|
|||||||
// Route::post('send-telegram', [TelegramController::class, 'sendMessage']);
|
// Route::post('send-telegram', [TelegramController::class, 'sendMessage']);
|
||||||
|
|
||||||
// Route::post('invoice-exit', [InvoiceValidationController::class, 'handle']);
|
// Route::post('invoice-exit', [InvoiceValidationController::class, 'handle']);
|
||||||
|
|
||||||
|
|
||||||
|
Route::post('/print-pdf', [PrintController::class, 'print']);
|
||||||
|
|
||||||
|
|
||||||
|
Route::post('/push/subscribe', function (Request $request) {
|
||||||
|
|
||||||
|
$user = Filament::auth()->user();
|
||||||
|
abort_if(!$user, 401);
|
||||||
|
|
||||||
|
$request->validate([
|
||||||
|
'endpoint' => 'required|string',
|
||||||
|
'keys.p256dh' => 'required|string',
|
||||||
|
'keys.auth' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// WebPushSubscription::updateOrCreate(
|
||||||
|
// ['endpoint' => $request->endpoint],
|
||||||
|
// [
|
||||||
|
// 'subscribable_type' => get_class($user),
|
||||||
|
// 'subscribable_id' => $user->id,
|
||||||
|
// 'public_key' => $request->keys['p256dh'],
|
||||||
|
// 'auth_token' => $request->keys['auth'],
|
||||||
|
// 'content_encoding' => $request->contentEncoding ?? 'aesgcm',
|
||||||
|
// ]
|
||||||
|
// );
|
||||||
|
|
||||||
|
WebPushSubscription::updateOrCreate(
|
||||||
|
[
|
||||||
|
'endpoint' => $request->endpoint,
|
||||||
|
'subscribable_type' => get_class($user),
|
||||||
|
'subscribable_id' => $user->id,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'public_key' => $request->keys['p256dh'],
|
||||||
|
'auth_token' => $request->keys['auth'],
|
||||||
|
'content_encoding' => $request->contentEncoding ?? 'aesgcm',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return response()->json(['success' => true]);
|
||||||
|
});
|
||||||
|
|||||||
@@ -59,10 +59,9 @@ use App\Http\Livewire\CustomLogin;
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
WebPushSubscription::updateOrCreate(
|
WebPushSubscription::updateOrCreate(
|
||||||
// ✅ UNIQUE PER DEVICE
|
|
||||||
['endpoint' => $request->endpoint],
|
['endpoint' => $request->endpoint],
|
||||||
[
|
[
|
||||||
'subscribable_type' => get_class($user), // 🔥 important
|
'subscribable_type' => get_class($user),
|
||||||
'subscribable_id' => $user->id,
|
'subscribable_id' => $user->id,
|
||||||
'public_key' => $request->keys['p256dh'],
|
'public_key' => $request->keys['p256dh'],
|
||||||
'auth_token' => $request->keys['auth'],
|
'auth_token' => $request->keys['auth'],
|
||||||
@@ -70,6 +69,20 @@ use App\Http\Livewire\CustomLogin;
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// WebPushSubscription::updateOrCreate(
|
||||||
|
// [
|
||||||
|
// 'endpoint' => $request->endpoint,
|
||||||
|
// 'subscribable_type' => get_class($user),
|
||||||
|
// 'subscribable_id' => $user->id,
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// 'public_key' => $request->keys['p256dh'],
|
||||||
|
// 'auth_token' => $request->keys['auth'],
|
||||||
|
// 'content_encoding' => $request->contentEncoding ?? 'aesgcm',
|
||||||
|
// ]
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
return response()->json(['success' => true]);
|
return response()->json(['success' => true]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user