ranjith-dev #580

Merged
jothi merged 7 commits from ranjith-dev into master 2026-05-11 05:13:39 +00:00
10 changed files with 2415 additions and 1112 deletions

View File

@@ -5,9 +5,12 @@ namespace App\Console\Commands;
use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use App\Models\TempClassCharacteristic;
// use App\Models\TempClassCharacteristic;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Schema;
class TriggerPendingApprovalMails extends Command
{
@@ -40,6 +43,8 @@ class TriggerPendingApprovalMails extends Command
public $subjectLine;
// public $tempCharacteristics = [];
public $wfId;
public function handle()
@@ -195,6 +200,38 @@ class TriggerPendingApprovalMails extends Command
$updateData['mail_status'] = 'Sent-Mail3';
}
$totalMinutes =
$this->convertToMinutes($approver->duration1 ?? 0) +
$this->convertToMinutes($approver->duration2 ?? 0) +
$this->convertToMinutes($approver->duration3 ?? 0);
$expiryTime = Carbon::parse($first->created_at)
->copy()
->addMinutes($totalMinutes);
$ids = $groupRecords->pluck('id');
$this->info("Expiry Time for ID {$first->id}: {$expiryTime}, Now: {$now}");
// --- AUTO REJECT ---
if (
$first->mail_status == 'Sent-Mail3' &&
(is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
(is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
(is_null($first->approver_status3) || $first->approver_status3 == 'Hold') &&
$now->gte($expiryTime)
) {
RequestCharacteristic::whereIn('id', $ids)
->update([
'approver_status3' => 'Rejected',
'approver_remark3' => 'Time Limit Reached',
'approved3_at' => now(),
]);
$this->info("Auto Rejected ID: {$first->id}");
continue;
}
if (!$level || !$mail) {
continue;
}
@@ -203,6 +240,8 @@ class TriggerPendingApprovalMails extends Command
$subjectLine = 'Characteristic Approval Mail';
// $emails = array_map('trim', explode(',', $mail));
Mail::to($mail)->send(
new CharacteristicApprovalMail(
$first,
@@ -251,6 +290,23 @@ class TriggerPendingApprovalMails extends Command
return $approver && $approver->approver_type == 'Quality';
});
// $approvers = CharacteristicApproverMaster::where('approver_type', 'Quality')
// ->get()
// ->keyBy('id');
// $qualityRecords = RequestCharacteristic::where(function ($q) {
// $q->whereNull('approver_status1')->orWhere('approver_status1', 'Hold');
// })
// ->where(function ($q) {
// $q->whereNull('approver_status2')->orWhere('approver_status2', 'Hold');
// })
// ->where(function ($q) {
// $q->whereNull('approver_status3')->orWhere('approver_status3', 'Hold');
// })
// ->whereIn('characteristic_approver_master_id', $approvers->keys())
// ->get();
if ($qualityRecords->isEmpty()) {
$this->info('No quality pending approvals');
return;
@@ -283,6 +339,43 @@ class TriggerPendingApprovalMails extends Command
continue;
}
$columns = Schema::getColumnListing('temp_class_characteristics');
$exclude = ['id', 'plant_id', 'machine_id', 'item_id', 'aufnr', 'class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_heading', 'created_at', 'updated_at', 'deleted_at', 'has_work_flow_id', 'model_type', 'created_by', 'updated_by' ];
$filteredColumns = array_diff($columns, $exclude);
$row1 = TempClassCharacteristic::where('plant_id', $first->plant_id)
->where('machine_id', $first->machine_id)
->where('aufnr', $first->aufnr)
->where('model_type', $first->model_type)
->latest()
->first();
$this->info(json_encode([
'id' => $row1->id,
'plant_id' => $row1->plant_id,
'machine_id' => $row1->machine_id,
'aufnr' => $row1->aufnr,
'motor_speed' => $row1->zmm_motor_speed,
'all_data' => $row1->toArray(),
]));
$data = [];
if ($row1) {
foreach ($filteredColumns as $column) {
$value = $row1->getAttribute($column);
if ($value != null && $value != '') {
$data[$column] = $value;
}
}
}
$characteristics = $data;
$level = null;
$mail = null;
$name = null;
@@ -359,6 +452,38 @@ class TriggerPendingApprovalMails extends Command
$updateData['mail_status'] = 'Sent-Mail3';
}
$totalMinutes =
$this->convertToMinutes($approver->duration1 ?? 0) +
$this->convertToMinutes($approver->duration2 ?? 0) +
$this->convertToMinutes($approver->duration3 ?? 0);
$expiryTime = Carbon::parse($first->created_at)
->copy()
->addMinutes($totalMinutes);
$ids = $groupRecords->pluck('id');
$this->info("Expiry Time for ID {$first->id}: {$expiryTime}, Now: {$now}");
// --- AUTO REJECT ---
if (
$first->mail_status == 'Sent-Mail3' &&
(is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
(is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
(is_null($first->approver_status3) || $first->approver_status3 == 'Hold') &&
$now->gte($expiryTime)
) {
RequestCharacteristic::whereIn('id', $ids)
->update([
'approver_status3' => 'Rejected',
'approver_remark3' => 'Time Limit Reached',
'approved3_at' => now(),
]);
$this->info("Auto Rejected ID: {$first->id}");
continue;
}
if (!$level || !$mail) {
continue;
}
@@ -381,8 +506,8 @@ class TriggerPendingApprovalMails extends Command
$pdfPath,
$pendingApprovers,
$approverNameFromMaster,
$subjectLine
// $characteristics
$subjectLine,
$characteristics
)
);
@@ -406,4 +531,16 @@ class TriggerPendingApprovalMails extends Command
$this->info('Approval mail job completed');
}
public function convertToMinutes($duration)
{
if (!$duration) return 0;
$parts = explode('.', (string)$duration);
$hours = (int)($parts[0] ?? 0);
$minutes = (int)($parts[1] ?? 0);
return ($hours * 60) + $minutes;
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace App\Filament\Imports;
use App\Models\RequestCharacteristic;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class RequestCharacteristicImporter extends Importer
{
protected static ?string $model = RequestCharacteristic::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('PLANT CODE')
->example('1000')
->label('PLANT CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('machine')
->requiredMapping()
->exampleHeader('WORK CENTER')
->example('RMGLAS01')
->label('WORK CENTER')
->relationship(resolveUsing: 'work_center')
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('ITEM CODE')
->example('630214')
->label('ITEM CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('characteristicApproverMaster')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('aufnr')
->label('AUFNR')
->exampleHeader('AUFNR')
->example('1234567'),
ImportColumn::make('characteristic_name')
->label('CHARACTERISTIC NAME')
->exampleHeader('CHARACTERISTIC NAME')
->example('ZMM_PUMPSET_MODEL'),
ImportColumn::make('current_value')
->label('CURRENT VALUE')
->exampleHeader('CURRENT VALUE')
->example('MVN-32/02 D R'),
ImportColumn::make('update_value')
->label('UPDATE VALUE')
->exampleHeader('UPDATE VALUE')
->example('MVN-32/02 TR3'),
ImportColumn::make('approver_status1')
->label('APPROVER STATUS 1')
->exampleHeader('APPROVER STATUS 1')
->example('Hold'),
ImportColumn::make('approver_status2')
->label('APPROVER STATUS 2')
->exampleHeader('APPROVER STATUS 2')
->example('Approved'),
ImportColumn::make('approver_status3')
->label('APPROVER STATUS 3')
->exampleHeader('APPROVER STATUS 3')
->example('Rejected'),
ImportColumn::make('approver_remark1')
->label('APPROVER REMARK 1')
->exampleHeader('APPROVER REMARK 1')
->example('Hold for review'),
ImportColumn::make('approver_remark2')
->label('APPROVER REMARK 2')
->exampleHeader('APPROVER REMARK 2')
->example('Approved with comments'),
ImportColumn::make('approver_remark3')
->label('APPROVER REMARK 3')
->exampleHeader('APPROVER REMARK 3')
->example('Rejected due to incorrect value'),
ImportColumn::make('work_flow_id')
->label('WORK FLOW ID')
->exampleHeader('WORK FLOW ID')
->example('WF-260303-0001'),
ImportColumn::make('mail_status')
->label('MAIL STATUS')
->exampleHeader('MAIL STATUS')
->example('Sent'),
ImportColumn::make('trigger_at')
->label('TRIGGER AT')
->exampleHeader('MAIL STATUS')
->rules(['datetime']),
ImportColumn::make('approved1_at')
->label('APPROVED1 AT')
->exampleHeader('APPROVED1 AT')
->rules(['datetime']),
ImportColumn::make('approved2_at')
->label('APPROVED2 AT')
->exampleHeader('APPROVED2 AT')
->rules(['datetime']),
ImportColumn::make('approved3_at')
->label('APPROVED3 AT')
->exampleHeader('APPROVED3 AT')
->rules(['datetime']),
ImportColumn::make('created_by')
->label('CREATED BY')
->exampleHeader('CREATED BY')
->example('RAW01234'),
ImportColumn::make('updated_by')
->label('UPDATED BY')
->exampleHeader('UPDATED BY')
->example('RAW01234'),
ImportColumn::make('model_type')
->label('MODEL TYPE')
->exampleHeader('MODEL TYPE')
->example('PUMP'),
];
}
public function resolveRecord(): ?RequestCharacteristic
{
// return RequestCharacteristic::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new RequestCharacteristic();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your request characteristic import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
if ($failedRowsCount = $import->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
}
return $body;
}
}

View File

@@ -6,6 +6,7 @@ use App\Filament\Exports\CharacteristicApproverMasterExporter;
use App\Filament\Imports\CharacteristicApproverMasterImporter;
use App\Filament\Resources\CharacteristicApproverMasterResource\Pages;
use App\Models\CharacteristicApproverMaster;
use App\Models\Item;
use App\Models\Machine;
use App\Models\Plant;
use Filament\Facades\Filament;
@@ -20,6 +21,10 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Filters\Filter;
class CharacteristicApproverMasterResource extends Resource
{
@@ -392,7 +397,203 @@ class CharacteristicApproverMasterResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('requestCharacteristics', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('machine', null);
// $set('aufnr', null);
}),
Select::make('machine')
->label('Search by Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Machine::whereHas('requestCharacteristics', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('work_center', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get): void {
// $set('item_id', null);
// $set('aufnr', null);
}),
Select::make('approver_type')
->label('Approver Type')
->options([
'Characteristic' => 'Characteristic',
'Quality' => 'Quality',
])
->placeholder('Select Type')
->afterStateUpdated(function ($state, callable $set) {
$set('name1', null);
$set('name2', null);
$set('name3', null);
}),
TextInput::make('machine_name')
->label('Machine Name')
->placeholder('Enter Machine Name'),
TextInput::make('characteristic_field')
->label('Characteristic Field')
->placeholder('Enter Characteristic Field'),
TextInput::make('name1')
->label('Approver Name 1')
->placeholder('Enter Approver Name 2')
->afterStateUpdated(function ($state, callable $set) {
$set('name2', null);
$set('name3', null);
}),
TextInput::make('name2')
->label('Approver Name 2')
->placeholder('Enter Approver Name 2')
->afterStateUpdated(function ($state, callable $set) {
$set('name3', null);
}),
TextInput::make('name3')
->label('Approver Name 3')
->placeholder('Enter Approver Name 2'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder('Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder('Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['machine_name']) && empty($data['characteristic_field']) && empty($data['approver_type']) && empty($data['name1']) && empty($data['name2']) && empty($data['name3']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['machine'])) {
$query->where('machine_id', $data['machine']);
}
if (! empty($data['machine_name'])) {
$query->where('machine_name', 'like', '%'.$data['machine_name'].'%');
}
if (! empty($data['characteristic_field'])) {
$query->where('characteristic_field', 'like', '%'.$data['characteristic_field'].'%');
}
if (! empty($data['approver_type'])) {
$query->where('approver_type', 'like', '%'.$data['approver_type'].'%');
}
if (! empty($data['name1'])) {
$query->where('name1', 'like', '%'.$data['name1'].'%');
}
if (! empty($data['name2'])) {
$query->where('name2', 'like', '%'.$data['name2'].'%');
}
if (! empty($data['name3'])) {
$query->where('name3', 'like', '%'.$data['name3'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant Name: '.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['machine'])) {
$indicators[] = 'Work Center: '.Machine::where('id', $data['machine'])->value('work_center');
}
if (! empty($data['machine_name'])) {
$indicators[] = 'Machine Name: '.$data['machine_name'];
}
if (! empty($data['characteristic_field'])) {
$indicators[] = 'Characteristic Field: '.$data['characteristic_field'];
}
if (! empty($data['approver_type'])) {
$indicators[] = 'Approver Type: '.$data['approver_type'];
}
if (! empty($data['name1'])) {
$indicators[] = 'Approver Name 1: '.$data['name1'];
}
if (! empty($data['name2'])) {
$indicators[] = 'Approver Name 2: '.$data['name2'];
}
if (! empty($data['name3'])) {
$indicators[] = 'Approver Name 3: '.$data['name3'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'To: '.$data['created_to'];
}
return $indicators;
}),
])
->filtersFormMaxHeight('280px')
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),

View File

@@ -2028,6 +2028,12 @@ class ClassCharacteristicResource extends Resource
TextInput::make('gernr')
->label('Serial Number')
->placeholder('Enter Serial Number'),
TextInput::make('zmm_heading')
->label('Heading')
->placeholder('Enter Heading'),
TextInput::make('model_type')
->label('Model Type')
->placeholder('Enter Model Type'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder('Select From DateTime')
@@ -2041,7 +2047,7 @@ class ClassCharacteristicResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['created_from']) && empty($data['created_to'])) {
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['zmm_heading']) && empty($data['model_type']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -2071,6 +2077,14 @@ class ClassCharacteristicResource extends Resource
$query->where('gernr', 'like', '%'.$data['gernr'].'%');
}
if (! empty($data['zmm_heading'])) {
$query->where('zmm_heading', 'like', '%'.$data['zmm_heading'].'%');
}
if (! empty($data['model_type'])) {
$query->where('model_type', 'like', '%'.$data['model_type'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
@@ -2108,6 +2122,14 @@ class ClassCharacteristicResource extends Resource
$indicators[] = 'Serial Number: '.$data['gernr'];
}
if (! empty($data['zmm_heading'])) {
$indicators[] = 'Heading: '.$data['zmm_heading'];
}
if (! empty($data['model_type'])) {
$indicators[] = 'Model Type: '.$data['model_type'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}

View File

@@ -3,12 +3,14 @@
namespace App\Filament\Resources;
use App\Filament\Exports\RequestCharacteristicExporter;
use App\Filament\Imports\RequestCharacteristicImporter;
use App\Filament\Resources\RequestCharacteristicResource\Pages;
use App\Models\CharacteristicApproverMaster;
use App\Models\Item;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\RequestCharacteristic;
use App\Models\StickerMaster;
use Closure;
use Filament\Facades\Filament;
use Filament\Forms;
@@ -19,6 +21,7 @@ use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
@@ -27,6 +30,7 @@ use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Validation\Rule;
@@ -128,6 +132,16 @@ class RequestCharacteristicResource extends Resource
$set('updated_by', Filament::auth()->user()?->name);
})
->disabled(fn ($get) => self::isFieldDisabled($get)),
Forms\Components\Hidden::make('show_validation_image')
->reactive()
->default(false),
Forms\Components\Hidden::make('validation1_image_url')
->reactive(),
Forms\Components\View::make('components.part-validation-error-icon')
->statePath('validation1_image_url')
->visible(fn ($get) => $get('show_validation_image') == true)
->reactive(),
Forms\Components\TextInput::make('work_flow_id')
->label('Work Flow ID')
->readOnly()
@@ -139,7 +153,42 @@ class RequestCharacteristicResource extends Resource
return self::isNewWorkFlow($get);
}
$set('updated_by', Filament::auth()->user()?->name);
}),
})
->suffixAction(
Forms\Components\Actions\Action::make('toggleValidationImage')
->icon(fn (callable $get) => $get('show_validation_image') ? 'heroicon-o-eye-slash' : 'heroicon-o-eye')
->tooltip('View Validation Image')
->action(function (callable $get, $set) {
$currentState = $get('show_validation_image');
$set('show_validation_image', ! $currentState);
if ($currentState == true) {
$set('validation1_image_url', null);
return;
}
$workFlowId = $get('work_flow_id');
if (!$workFlowId) {
Notification::make()
->title('Missing Workflow ID')
->body('Please select a Workflow ID.')
->danger()
->send();
return;
}
// Build filename
$fileName = "{$workFlowId}.png";
$imageUrl = route('workflow.image', [
'filename' => $fileName,
]);
$set('validation1_image_url', $imageUrl);
})
),
// ->rule(function (callable $get) {
// return Rule::unique('request_characteristics', 'work_flow_id')
// ->where('plant_id', $get('plant_id'))
@@ -312,7 +361,7 @@ class RequestCharacteristicResource extends Resource
Forms\Components\Select::make('characteristic_approver_master_id')
->label('Master Characteristic Field')
// ->relationship('characteristicApproverMaster', 'characteristic_field')
->columnSpan(2)
// ->columnSpan(2)
->reactive()
->nullable()
->searchable()
@@ -340,6 +389,17 @@ class RequestCharacteristicResource extends Resource
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('model_type')
->label('Model Type')
->reactive()
->nullable()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('characteristic_name', null);
$set('current_value', null);
$set('update_value', null);
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
// ->disabled(fn ($get) => self::isFieldDisabled($get))
Section::make('Request Characteristic Details')
// ->columnSpan(['default' => 2, 'sm' => 4])
@@ -500,6 +560,7 @@ class RequestCharacteristicResource extends Resource
Forms\Components\TextInput::make('approver_remark1')
->label('Approver Remark')
->live()
->maxLength(60)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$appStat = $get('approver_status1');
if ($appStat && $state) {
@@ -615,6 +676,7 @@ class RequestCharacteristicResource extends Resource
Forms\Components\TextInput::make('approver_remark2')
->label('Approver Remark')
->live()
->maxLength(60)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$appStat = $get('approver_status2');
if ($appStat && $state) {
@@ -727,6 +789,7 @@ class RequestCharacteristicResource extends Resource
Forms\Components\TextInput::make('approver_remark3')
->label('Approver Remark')
->live()
->maxLength(60)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$appStat = $get('approver_status3');
if ($appStat && $state) {
@@ -916,6 +979,11 @@ class RequestCharacteristicResource extends Resource
->formatStateUsing(fn (string $state): string => strtoupper(__($state)))
->extraAttributes(['class' => 'uppercase'])
->sortable(),
Tables\Columns\TextColumn::make('model_type')
->label('Model Type')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('characteristic_name')
->label('Characteristic Name')
->default('-')
@@ -956,12 +1024,14 @@ class RequestCharacteristicResource extends Resource
default => 'gray',
})
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approver_remark1')
->label('Approver Remark 1')
// ->color('success')
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approved1_at')
@@ -984,12 +1054,14 @@ class RequestCharacteristicResource extends Resource
default => 'gray',
})
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approver_remark2')
->label('Approver Remark 2')
// ->color('success')
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approved2_at')
@@ -1012,12 +1084,14 @@ class RequestCharacteristicResource extends Resource
default => 'gray',
})
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approver_remark3')
->label('Approver Remark 3')
// ->color('success')
->alignCenter()
->default('-')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('approved3_at')
@@ -1160,6 +1234,67 @@ class RequestCharacteristicResource extends Resource
->numeric()
->minlength(7)
->maxlength(10),
TextInput::make('work_flow_id')
->label('Work Flow ID')
->placeholder('Enter Work Flow ID'),
TextInput::make('machine_name')
->label('Machine Name')
->placeholder('Enter Machine Name'),
Select::make('request_type')
->label('Request Type')
->options([
'Characteristic' => 'Characteristic',
'Quality' => 'Quality',
])
->placeholder('Select Request Type'),
TextInput::make('master_characteristic_field')
->label('Master Characteristic Field')
->placeholder('Enter Master Characteristic Field'),
TextInput::make('model_type')
->label('Model Type')
->placeholder('Enter Model Type'),
Select::make('approver_status')
->label('Approver Status')
->options([
'Approved' => 'Approved',
'Hold' => 'Hold',
'Rejected' => 'Rejected',
])
->placeholder('Select Status')
->afterStateUpdated(function ($state, callable $set) {
$set('approver_status1', null);
$set('approver_status2', null);
$set('approver_status3', null);
}),
Select::make('approver_status1')
->label('Approver Status 1')
->options([
'Approved' => 'Approved',
'Hold' => 'Hold',
'Rejected' => 'Rejected',
])
->placeholder('Select Status')
->afterStateUpdated(function ($state, callable $set) {
$set('approver_status2', null);
$set('approver_status3', null);
}),
Select::make('approver_status2')
->label('Approver Status 2')
->options([
'Approved' => 'Approved',
'Hold' => 'Hold',
'Rejected' => 'Rejected',
])
->placeholder('Select Status'),
Select::make('approver_status3')
->label('Approver Status 3')
->options([
'Approved' => 'Approved',
'Hold' => 'Hold',
'Rejected' => 'Rejected',
])
->placeholder('Select Status'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder('Select From DateTime')
@@ -1173,7 +1308,7 @@ class RequestCharacteristicResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['created_from']) && empty($data['created_to'])) {
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['model_type']) && empty($data['work_flow_id']) && empty($data['machine_name']) && empty($data['request_type']) && empty($data['master_characteristic_field'])&& empty($data['approver_status1']) && empty($data['approver_status2']) && empty($data['approver_status3']) && empty($data['approver_status']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -1199,6 +1334,70 @@ class RequestCharacteristicResource extends Resource
$query->where('aufnr', 'like', '%'.$data['aufnr'].'%');
}
if (! empty($data['model_type'])) {
$query->where('model_type', 'like', '%'.$data['model_type'].'%');
}
if (! empty($data['work_flow_id'])) {
$query->where('work_flow_id', 'like', '%'.$data['work_flow_id'].'%');
}
if (!empty($data['machine_name'])) {
$query->whereHas('characteristicApproverMaster', function ($q) use ($data) {
$q->where('characteristic_approver_masters.machine_name', '=', (string) $data['machine_name']);
});
}
if (!empty($data['request_type'])) {
$query->whereHas('characteristicApproverMaster', function ($q) use ($data) {
$q->where('characteristic_approver_masters.approver_type', '=', (string) $data['request_type']);
});
}
if (!empty($data['master_characteristic_field'])) {
$query->whereHas('characteristicApproverMaster', function ($q) use ($data) {
$q->where('characteristic_approver_masters.characteristic_field', '=', (string) $data['master_characteristic_field']);
});
}
if (! empty($data['approver_status1'])) {
$query->where('approver_status1', 'like', '%'.$data['approver_status1'].'%');
}
if (! empty($data['approver_status2'])) {
$query->where('approver_status2', 'like', '%'.$data['approver_status2'].'%');
}
if (! empty($data['approver_status3'])) {
$query->where('approver_status3', 'like', '%'.$data['approver_status3'].'%');
}
if (!empty($data['approver_status'])) {
$status = $data['approver_status'];
$query->whereRaw("
CASE
-- If status3 exists, it must be considered first
WHEN approver_status3 IS NOT NULL AND approver_status3 != ''
THEN approver_status3
-- then status2 overrides only if status3 is empty
WHEN approver_status2 IS NOT NULL AND approver_status2 != ''
THEN approver_status2
-- finally status1 only if both 2 and 3 are empty
WHEN approver_status1 IS NOT NULL AND approver_status1 != ''
THEN approver_status1
ELSE NULL
END = ?
", [$status]);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
@@ -1232,6 +1431,42 @@ class RequestCharacteristicResource extends Resource
$indicators[] = 'Job No: '.$data['aufnr'];
}
if (! empty($data['model_type'])) {
$indicators[] = 'Model Type: '.$data['model_type'];
}
if (! empty($data['work_flow_id'])) {
$indicators[] = 'Work Flow ID: '.$data['work_flow_id'];
}
if (! empty($data['machine_name'])) {
$indicators[] = 'Machine Name: '.$data['machine_name'];
}
if (! empty($data['request_type'])) {
$indicators[] = 'Request Type: '.$data['request_type'];
}
if (! empty($data['master_characteristic_field'])) {
$indicators[] = 'Master Characteristic Field: '.$data['master_characteristic_field'];
}
if (! empty($data['approver_status'])) {
$indicators[] = 'Approver Status: '.$data['approver_status'];
}
if (! empty($data['approver_status1'])) {
$indicators[] = 'Approver Status 1: '.$data['approver_status1'];
}
if (! empty($data['approver_status2'])) {
$indicators[] = 'Approver Status 2: '.$data['approver_status2'];
}
if (! empty($data['approver_status3'])) {
$indicators[] = 'Approver Status 3: '.$data['approver_status3'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}
@@ -1256,13 +1491,13 @@ class RequestCharacteristicResource extends Resource
]),
])
->headerActions([
// ImportAction::make()
// ->label('Import Request Characteristics')
// ->color('warning')
// ->importer(RequestCharacteristicImporter::class)
// ->visible(function () {
// return Filament::auth()->user()->can('view import request characteristic');
// }),
ImportAction::make()
->label('Import Request Characteristics')
->color('warning')
->importer(RequestCharacteristicImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import request characteristic');
}),
ExportAction::make()
->label('Export Request Characteristics')
->color('warning')

View File

@@ -5,28 +5,27 @@ namespace App\Filament\Resources;
use App\Filament\Exports\TempClassCharacteristicExporter;
use App\Filament\Imports\TempClassCharacteristicImporter;
use App\Filament\Resources\TempClassCharacteristicResource\Pages;
use App\Filament\Resources\TempClassCharacteristicResource\RelationManagers;
use App\Models\Item;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\TempClassCharacteristic;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Forms\Get;
use Illuminate\Validation\Rule;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
class TempClassCharacteristicResource extends Resource
{
@@ -1029,6 +1028,10 @@ class TempClassCharacteristicResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('model_type')
->label('MODEL TYPE')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('aufnr')
->label('AUFNR')
->alignCenter()
@@ -1055,10 +1058,6 @@ class TempClassCharacteristicResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('model_type')
->label('MODEL TYPE')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('zz1_cn_bill_ord')
->label('ZZ1 CN BILL ORD')
->alignCenter()
@@ -1181,6 +1180,7 @@ class TempClassCharacteristicResource extends Resource
->sortable(),
Tables\Columns\TextColumn::make('zmm_ratedpower')
->label('ZMM RATEDPOWER')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('zmm_region')
->label('ZMM REGION')
@@ -1577,14 +1577,12 @@ class TempClassCharacteristicResource extends Resource
Tables\Columns\TextColumn::make('winded_serial_number')
->label('WINDED SERIAL NUMBER')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('part_validation_1')
->label('PART VALIDATION 1')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('part_validation_2')
->label('PART VALIDATION 2')
Tables\Columns\TextColumn::make('model_type')
->label('MODEL TYPE')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('has_work_flow_id')
->label('HAS WORK FLOW ID')
@@ -1599,14 +1597,28 @@ class TempClassCharacteristicResource extends Resource
};
}),
Tables\Columns\TextColumn::make('created_at')
->label('CREATED AT')
->alignCenter()
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('CREATED BY')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('UPDATED AT')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
Tables\Columns\TextColumn::make('updated_by')
->label('UPDATED BY')
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('DELETED AT')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
@@ -1690,6 +1702,12 @@ class TempClassCharacteristicResource extends Resource
TextInput::make('gernr')
->label('Serial Number')
->placeholder('Enter Serial Number'),
TextInput::make('zmm_heading')
->label('Heading')
->placeholder('Enter Heading'),
TextInput::make('model_type')
->label('Model Type')
->placeholder('Enter Model Type'),
Select::make('work_flow_status')
->label('Work Flow Status')
->placeholder('Select Work Flow Status')
@@ -1711,7 +1729,7 @@ class TempClassCharacteristicResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['created_from']) && empty($data['created_to']) && !array_key_exists('work_flow_status', $data)) {
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['zmm_heading']) && empty($data['model_type']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -1741,6 +1759,14 @@ class TempClassCharacteristicResource extends Resource
$query->where('gernr', 'like', '%'.$data['gernr'].'%');
}
if (! empty($data['zmm_heading'])) {
$query->where('zmm_heading', 'like', '%'.$data['zmm_heading'].'%');
}
if (! empty($data['model_type'])) {
$query->where('model_type', 'like', '%'.$data['model_type'].'%');
}
if (array_key_exists('work_flow_status', $data) && $data['work_flow_status'] != '') {
$query->where('has_work_flow_id', $data['work_flow_status']);
}
@@ -1782,6 +1808,14 @@ class TempClassCharacteristicResource extends Resource
$indicators[] = 'Serial Number: '.$data['gernr'];
}
if (! empty($data['zmm_heading'])) {
$indicators[] = 'Heading: '.$data['zmm_heading'];
}
if (! empty($data['model_type'])) {
$indicators[] = 'Model Type: '.$data['model_type'];
}
if (array_key_exists('work_flow_status', $data) && $data['work_flow_status'] != '') {
$statusMap = [
'1' => 'Pending Approval',
@@ -1789,7 +1823,7 @@ class TempClassCharacteristicResource extends Resource
'0' => 'Approved',
];
$indicators[] = 'Work Flow Status: ' . ($statusMap[$data['work_flow_status']] ?? '');
$indicators[] = 'Work Flow Status: '.($statusMap[$data['work_flow_status']] ?? '');
}
if (! empty($data['created_from'])) {

View File

@@ -2,10 +2,12 @@
namespace App\Http\Controllers;
use App\Models\CharacteristicApproverMaster;
use App\Models\ClassCharacteristic;
use App\Models\RequestCharacteristic;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class CharacteristicApprovalController extends Controller
{
@@ -358,10 +360,26 @@ class CharacteristicApprovalController extends Controller
->where('work_flow_id', $record->work_flow_id)
->get();
$approverMasterNames = CharacteristicApproverMaster::find($record->characteristic_approver_master_id);
if (! $approverMasterNames) {
abort(500, 'Approver master not found');
}
$approverNameColumn = match ($level) {
1 => 'name1',
2 => 'name2',
3 => 'name3',
default => null,
};
$updatedBy = $approverNameColumn ? $approverMasterNames->$approverNameColumn : null;
$updateData = [
$statusColumn => $status,
$remarkColumn => $request->input('remark'),
$approvedAtColumn => Carbon::now(),
'updated_by' => $updatedBy,
];
if (in_array($status, ['Approved', 'Rejected'])) {
@@ -386,6 +404,14 @@ class CharacteristicApprovalController extends Controller
// ->where('aufnr', $record->aufnr)
// ->update(['has_work_flow_id' => $record->work_flow_id]);
if ($status == 'Rejected') {
$filePath = 'uploads/LaserDocs/'.$record->work_flow_id.'.png';
if (Storage::disk('local')->exists($filePath)) {
Storage::disk('local')->delete($filePath);
}
}
if ($returnView) {
return match ($status) {
'Approved' => view('approval.success'),

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,8 @@ class CharacteristicApprovalMail extends Mailable
public $subjectLine;
public $characteristics;
/**
* Create a new message instance.
*/

View File

@@ -33,6 +33,10 @@
<td>Job Number</td>
<td style="text-align: center;">{{ $request->aufnr }}</td>
</tr>
<tr>
<td>Model Type</td>
<td style="text-align: center;">{{ $request->model_type }}</td>
</tr>
<tr>
<td>Work Flow ID</td>
<td style="text-align: center;">{{ $request->work_flow_id }}</td>
@@ -103,8 +107,8 @@
<td style="text-align: center;">
<a href="{{ $approveUrl }}" style="color: #28a745; font-weight: bold; text-decoration: underline;">Approve</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
<a href="{{ $holdUrl }}" style="color: #FF8800; font-weight: bold; text-decoration: underline;">Hold</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
{{-- <a href="{{ $holdUrl }}" style="color: #FF8800; font-weight: bold; text-decoration: underline;">Hold</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; --}}
<a href="{{ $rejectUrl }}" style="color: #dc3545; font-weight: bold; text-decoration: underline;">Reject</a>
</td>
</tr>
@@ -123,6 +127,30 @@
@endif
</table>
@elseif($approverNameFromMaster && $approverNameFromMaster->approver_type == 'Quality')
{{-- <table style="margin-left: 3%" border="1" width="30%" cellpadding="6" cellspacing="0"> --}}
<table style="margin-left: 3%; " border="1" width="30%" cellpadding="6" cellspacing="0">
<tr>
<th colspan="2" style="text-align: center; font-weight: bold;">
TEMPLATE CHARACTERISTICS
</th>
</tr>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
@forelse ($tableData as $key => $value)
<tr>
<td style="text-align: center;">{{ strtoupper($key) }}</td>
<td style="text-align: center;">{{ $value }}</td>
</tr>
@empty
<tr>
<td colspan="2">No Characteristics Found</td>
</tr>
@endforelse
</table>
<br>
<table style="margin-left: 3%" border="1" width="50%" cellpadding="6" cellspacing="0">
<tr>
@@ -159,8 +187,8 @@
<td style="text-align: center;">
<a href="{{ $approveUrl }}" style="color: #28a745; font-weight: bold; text-decoration: underline;">Approve</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
<a href="{{ $holdUrl }}" style="color: #FF8800; font-weight: bold; text-decoration: underline;">Hold</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
{{-- <a href="{{ $holdUrl }}" style="color: #FF8800; font-weight: bold; text-decoration: underline;">Hold</a>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp; --}}
<a href="{{ $rejectUrl }}" style="color: #dc3545; font-weight: bold; text-decoration: underline;">Reject</a>
</td>
</tr>