45 Commits

Author SHA1 Message Date
0430d605e7 Merge pull request 'ranjith-dev' (#268) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #268
2026-01-28 11:38:45 +00:00
dhanabalan
7cc4cd45ff Added approval trigger mail inisde the scheduler
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-01-28 17:07:58 +05:30
dhanabalan
83527e49f6 Added 'remark' column on model
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Failing after 12m32s
2026-01-28 16:22:50 +05:30
dhanabalan
ebaa2b11cf Updated focus capacitor input logic
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-01-28 16:19:44 +05:30
dhanabalan
21827fd30f Updated alignment on livewire
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 16:17:45 +05:30
dhanabalan
b1cdab2900 Updated alignment on controller
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 16:16:11 +05:30
dhanabalan
2d3fda57b7 Added characteristic approval function for testing purpose
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 16:14:30 +05:30
dhanabalan
896e2f5fb2 Commented dd(arg) statement on import
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
2026-01-28 16:12:10 +05:30
dhanabalan
ee9d8247b2 Added store logic for controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:11:19 +05:30
dhanabalan
d33b1c7ccb Updated alignment for controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:09:10 +05:30
dhanabalan
eb343f1d0c Updated alignment for controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:07:33 +05:30
dhanabalan
d74e1d73c9 Added reprint process order qr
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:05:37 +05:30
dhanabalan
3531bfe250 Updated capacitor qr within page and improve scanning speed
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:03:28 +05:30
dhanabalan
c738195cd4 Commented unused code
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 16:01:57 +05:30
dhanabalan
b17f675f73 Added line type options for process order report
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 15:59:20 +05:30
0decbc6e29 Merge pull request 'Updated alignment for controller' (#267) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #267
2026-01-28 10:27:56 +00:00
dhanabalan
0d1aff8871 Updated alignment for controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 5m49s
Laravel Pint / pint (pull_request) Successful in 7m47s
2026-01-28 15:57:39 +05:30
9aa727cc36 Merge pull request 'Add CharacteristicApprovalController with approval, hold, and reject functionalities' (#266) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #266
2026-01-28 10:25:44 +00:00
dhanabalan
08a3b9f69d Add CharacteristicApprovalController with approval, hold, and reject functionalities
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Pint / pint (pull_request) Successful in 4m36s
Laravel Larastan / larastan (pull_request) Failing after 7m24s
2026-01-28 15:55:22 +05:30
22ece583b7 Merge pull request 'Changed logic in pdf controller' (#265) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #265
2026-01-28 10:22:47 +00:00
dhanabalan
dee82279c0 Changed logic in pdf controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 6m31s
Laravel Pint / pint (pull_request) Successful in 6m30s
2026-01-28 15:52:35 +05:30
8c90d1fc03 Merge pull request 'Added scrap quantity in pdf controller' (#264) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #264
2026-01-28 10:17:12 +00:00
dhanabalan
244500eb74 Added scrap quantity in pdf controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 4m33s
Laravel Larastan / larastan (pull_request) Failing after 6m2s
2026-01-28 15:47:01 +05:30
5e68debd87 Merge pull request 'ranjith-dev' (#263) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #263
2026-01-28 10:05:52 +00:00
dhanabalan
7b7d953b79 Enhance RequestCharacteristicResource form with default values and export action
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 6m21s
Laravel Pint / pint (pull_request) Successful in 5m51s
2026-01-28 15:34:57 +05:30
dhanabalan
7b6762c2a1 Enhance Characteristic Approver Master Resource form and table with required fields and export action
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-01-28 15:33:59 +05:30
855e9f91c8 Merge pull request 'Added all blade files of approval mails' (#262) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #262
2026-01-28 09:58:56 +00:00
dhanabalan
1e612a1452 Added all blade files of approval mails
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 26s
Laravel Pint / pint (pull_request) Successful in 5m56s
Laravel Larastan / larastan (pull_request) Failing after 7m17s
2026-01-28 15:28:29 +05:30
6d088471bf Merge pull request 'Added trigger approval mail pages' (#261) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #261
2026-01-28 09:56:23 +00:00
dhanabalan
97ce3df038 Added trigger approval mail pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Pint / pint (pull_request) Successful in 6m33s
Laravel Larastan / larastan (pull_request) Failing after 6m51s
2026-01-28 15:26:03 +05:30
f167b732c0 Merge pull request 'changed logic in post api of process order' (#260) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #260
2026-01-28 09:43:17 +00:00
dhanabalan
5d23e7a13d changed logic in post api of process order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 6m21s
Laravel Pint / pint (pull_request) Successful in 5m17s
2026-01-28 15:13:04 +05:30
4264c5493c Merge pull request 'Added three column in process order resource page' (#259) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #259
2026-01-28 09:42:16 +00:00
dhanabalan
b6f3ec794d Added three column in process order resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 31s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 4m27s
Laravel Larastan / larastan (pull_request) Failing after 6m47s
2026-01-28 15:11:46 +05:30
61774d240a Merge pull request 'ranjith-dev' (#258) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #258
2026-01-28 09:41:05 +00:00
dhanabalan
77ba58e100 Added three column sin process model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Pint / pint (pull_request) Successful in 4m49s
Laravel Larastan / larastan (pull_request) Failing after 5m52s
2026-01-28 15:10:45 +05:30
dhanabalan
845b912508 Added exporter file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-01-28 15:09:43 +05:30
dhanabalan
1daa4b044b Added three columns in process order table
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 15:08:58 +05:30
dhanabalan
c994dcd37b Added exporter file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 13:21:16 +05:30
dhanabalan
1b3b0843ea Added importer for ClassCharacteristics
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 09:29:43 +05:30
dhanabalan
6ebf9fc3b6 Added exporter for ClassCharacteristic
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-28 09:28:56 +05:30
ae01370107 Merge pull request 'ranjith-dev' (#257) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #257
2026-01-27 10:25:55 +00:00
dhanabalan
c8bfbb122b Refactor CharacteristicApproverMasterResource form structure and enhance table columns for improved usability and search functionality
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 5m27s
Laravel Larastan / larastan (pull_request) Failing after 5m36s
2026-01-27 15:54:37 +05:30
dhanabalan
11d48a7a91 Refactor RequestCharacteristicResource form and table structure for improved organization and functionality
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-01-27 15:54:09 +05:30
dhanabalan
75fd3d9841 Enhanced validation and error handling in storeLaserRequestChar method
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-01-27 15:52:05 +05:30
38 changed files with 4487 additions and 681 deletions

View File

@@ -39,7 +39,7 @@ class Scheduler extends Command
public function handle()
{
// $this->call('approval:trigger-mails');
$this->call('approval:trigger-mails');
// --- Production Rules ---
$productionRules = AlertMailRule::where('module', 'ProductionQuantities')
@@ -112,6 +112,7 @@ class Scheduler extends Command
break;
}
}
// foreach ($invoiceRules as $rule) {
// switch ($rule->schedule_type) {

View File

@@ -0,0 +1,204 @@
<?php
namespace App\Console\Commands;
use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Carbon;
class TriggerPendingApprovalMails extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
// protected $signature = 'app:trigger-pending-approval-mails';
/**
* The console command description.
*
* @var string
*/
// protected $description = 'Command description';
// /**
// * Execute the console command.
// */
// public function handle()
// {
// //
// }
protected $signature = 'approval:trigger-mails';
protected $description = 'Trigger approval mail manually';
public $pdfPath;
public function handle()
{
$this->info('Approval mail job started');
$records = RequestCharacteristic::whereNull('approver_status1')
->whereNull('approver_status2')
->whereNull('approver_status3')
->get();
if ($records->isEmpty()) {
$this->info('No pending approvals');
return;
}
$grouped = $records->groupBy(function ($item) {
return $item->plant_id . '|' . $item->machine_id . '|' . $item->aufnr . '|' . $item->work_flow_id;
});
$rows = [];
foreach ($grouped as $groupRecords) {
$first = $groupRecords->first();
$approver = CharacteristicApproverMaster::where('plant_id', $first->plant_id)
->where('machine_id', $first->machine_id)
->where('id', $first->characteristic_approver_master_id)
->first();
if (!$approver) {
continue;
}
$characteristics = $groupRecords->map(fn ($r) => [
'work_flow_id' => $r->work_flow_id,
'characteristic_name' => $r->characteristic_name,
'current_value' => $r->current_value,
'update_value' => $r->update_value,
])->toArray();
$level = null;
$mail = null;
$name = null;
$updateData = [];
$now = Carbon::now();
// --- FIRST MAIL ---
if (is_null($first->mail_status)){
$level = 1;
$mail = $approver->mail1;
$name = $approver->name1;
$updateData['mail_status'] = 'Sent';
// $updateData['trigger_at'] = $approver->duration1 > 0
// ? $now->copy()->addMinutes($approver->duration1 * 10)
// : null;
if ($approver->duration1 > 0)
{
$duration = number_format((float)$approver->duration1, 2, '.', '');
[$hours, $minutes] = explode('.', $duration);
$totalMinutes = ((int)$hours * 60) + (int)$minutes;
$updateData['trigger_at'] = $now
->copy()
->addMinutes($totalMinutes)
->startOfMinute();
}
else
{
$updateData['trigger_at'] = null;
}
}
// --- SECOND MAIL ---
elseif (
$first->mail_status == 'Sent' &&
is_null($first->approver_status1) &&
$first->trigger_at &&
\Carbon\Carbon::parse($first->trigger_at)->lte($now)
// $first->trigger_at <= $now
) {
$level = 2;
$mail = $approver->mail2;
$name = $approver->name2;
// $updateData['trigger_at'] = $approver->duration2 > 0
// ? $now->copy()->addMinutes($approver->duration2 * 10)
// : null;
// $updateData['mail_status'] = 'Sent-Mail2';
if ($approver->duration2 > 0) {
$duration = number_format((float)$approver->duration2, 2, '.', '');
[$hours, $minutes] = explode('.', $duration);
$totalMinutes = ((int)$hours * 60) + (int)$minutes;
// IMPORTANT: use NOW, not old trigger
$updateData['trigger_at'] = $now->copy()->addMinutes($totalMinutes);
} else {
$updateData['trigger_at'] = null;
}
$updateData['mail_status'] = 'Sent-Mail2';
}
// --- THIRD MAIL ---
elseif (
$first->mail_status == 'Sent-Mail2' &&
is_null($first->approver_status1) &&
is_null($first->approver_status2) &&
$first->trigger_at &&
// $first->trigger_at <= $now
\Carbon\Carbon::parse($first->trigger_at)->lte($now)
) {
$level = 3;
$mail = $approver->mail3;
$name = $approver->name3;
$updateData['trigger_at'] = null;
$updateData['mail_status'] = 'Sent-Mail3';
}
if (!$level || !$mail) {
continue;
}
$pdfPath = 'uploads/LaserDocs/' . $first->work_flow_id . '.pdf';
Mail::to($mail)->send(
new CharacteristicApprovalMail(
$first,
$name,
$level,
$pdfPath,
$characteristics
)
);
RequestCharacteristic::whereIn('id', $groupRecords->pluck('id'))
->update($updateData);
$rows[] = [
$first->id,
$first->plant_id,
$first->machine_id,
"Level $level",
$mail,
'SENT'
];
}
$this->table(
['ID', 'Plant', 'Machine', 'Level', 'Mail', 'Status'],
$rows
);
$this->info('Approval mail job completed');
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Filament\Exports;
use App\Models\CharacteristicApproverMaster;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class CharacteristicApproverMasterExporter extends Exporter
{
protected static ?string $model = CharacteristicApproverMaster::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
// ExportColumn::make('id')
// ->label('ID'),
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('machine_name')
->label('MACHINE NAME'),
ExportColumn::make('characteristic_field')
->label('MASTER CHARACTERISTIC FIELD 1'),
ExportColumn::make('name1')
->label('APPROVER NAME 1'),
ExportColumn::make('mail1')
->label('APPROVER MAIL 1'),
ExportColumn::make('duration1')
->label('DURATION 1'),
ExportColumn::make('name2')
->label('APPROVER NAME 2'),
ExportColumn::make('mail2')
->label('APPROVER MAIL 2'),
ExportColumn::make('duration2')
->label('DURATION 2'),
ExportColumn::make('name3')
->label('APPROVER NAME 3'),
ExportColumn::make('mail3')
->label('APPROVER MAIL 3'),
ExportColumn::make('duration3')
->label('DURATION 3'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your characteristic approver master export has completed and '.number_format($export->successful_rows).' '.str('row')->plural($export->successful_rows).' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;
}
}

View File

@@ -0,0 +1,335 @@
<?php
namespace App\Filament\Exports;
use App\Models\ClassCharacteristic;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class ClassCharacteristicExporter extends Exporter
{
protected static ?string $model = ClassCharacteristic::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('aufnr')
->label('AUFNR'),
ExportColumn::make('class')
->label('CLASS'),
ExportColumn::make('arbid')
->label('ARBID'),
ExportColumn::make('gamng')
->label('GAMNG'),
ExportColumn::make('lmnga')
->label('LMNGA'),
ExportColumn::make('gernr')
->label('GERNR'),
ExportColumn::make('zz1_cn_bill_ord')
->label('ZZ1 CN BILL ORD'),
ExportColumn::make('zmm_amps')
->label('ZMM AMPSTEXT'),
ExportColumn::make('zmm_brand')
->label('ZMM BRAND'),
ExportColumn::make('zmm_degreeofprotection')
->label('ZMM DEGREEOFPROTECTION'),
ExportColumn::make('zmm_delivery')
->label('ZMM DELIVERY'),
ExportColumn::make('zmm_dir_rot')
->label('ZMM DIR ROT'),
ExportColumn::make('zmm_discharge')
->label('ZMM DISCHARGE'),
ExportColumn::make('zmm_discharge_max')
->label('ZMM DISCHARGE MAX'),
ExportColumn::make('zmm_discharge_min')
->label('ZMM DISCHARGE MIN'),
ExportColumn::make('zmm_duty')
->label('ZMM DUTY'),
ExportColumn::make('zmm_eff_motor')
->label('ZMM EFF MOTOR'),
ExportColumn::make('zmm_eff_pump')
->label('ZMM EFF PUMP'),
ExportColumn::make('zmm_frequency')
->label('ZMM FREQUENCY'),
ExportColumn::make('zmm_head')
->label('ZMM HEAD'),
ExportColumn::make('zmm_heading')
->label('ZMM HEADING'),
ExportColumn::make('zmm_head_max')
->label('ZMM HEAD MAX'),
ExportColumn::make('zmm_head_minimum')
->label('ZMM HEAD MINIMUM'),
ExportColumn::make('zmm_idx_eff_mtr')
->label('ZMM IDX EFF MTR'),
ExportColumn::make('zmm_idx_eff_pump')
->label('ZMM IDX EFF PUMP'),
ExportColumn::make('zmm_kvacode')
->label('ZMM KVACODE'),
ExportColumn::make('zmm_maxambtemp')
->label('ZMM MAXAMBTEMP'),
ExportColumn::make('zmm_mincoolingflow')
->label('ZMM MINCOOLING FLOW'),
ExportColumn::make('zmm_motorseries')
->label('ZMM MOTORSERIES'),
ExportColumn::make('zmm_motor_model')
->label('ZMM MOTOR MODEL'),
ExportColumn::make('zmm_outlet')
->label('ZMM OUTLET'),
ExportColumn::make('zmm_phase')
->label('ZMM PHASE'),
ExportColumn::make('zmm_pressure')
->label('ZMM PRESSURE'),
ExportColumn::make('zmm_pumpflowtype')
->label('ZMM PUMPFLOWTYPE'),
ExportColumn::make('zmm_pumpseries')
->label('ZMM PUMPSERIES'),
ExportColumn::make('zmm_pump_model')
->label('ZMM PUMP MODEL'),
ExportColumn::make('zmm_ratedpower')
->label('ZMM RATEDPOWER'),
ExportColumn::make('zmm_region')
->label('ZMM REGION'),
ExportColumn::make('zmm_servicefactor')
->label('ZMM SERVICEFACTOR'),
ExportColumn::make('zmm_servicefactormaximumamps')
->label('ZMM SERVICEFACTORMAXIMUMAMPS'),
ExportColumn::make('zmm_speed')
->label('ZMM SPEED'),
ExportColumn::make('zmm_suction')
->label('ZMM SUCTION'),
ExportColumn::make('zmm_suctionxdelivery')
->label('ZMM SUCTIONXDELIVERY'),
ExportColumn::make('zmm_supplysource')
->label('ZMM SUPPLYSOURCE'),
ExportColumn::make('zmm_temperature')
->label('ZMM TEMPERATURE'),
ExportColumn::make('zmm_thrustload')
->label('ZMM THRUSTLOAD'),
ExportColumn::make('zmm_volts')
->label('ZMM VOLTS'),
ExportColumn::make('zmm_wire')
->label('ZMM WIRE'),
ExportColumn::make('zmm_package')
->label('ZMM PACKAGE'),
ExportColumn::make('zmm_pvarrayrating')
->label('ZMM PVARRAYRATING'),
ExportColumn::make('zmm_isi')
->label('ZMM ISI'),
ExportColumn::make('zmm_isimotor')
->label('ZMM ISIMOTOR'),
ExportColumn::make('zmm_isipump')
->label('ZMM ISIPUMP'),
ExportColumn::make('zmm_isipumpset')
->label('ZMM ISIPUMPSET'),
ExportColumn::make('zmm_pumpset_model')
->label('ZMM PUMPSET MODEL'),
ExportColumn::make('zmm_stages')
->label('ZMM STAGES'),
ExportColumn::make('zmm_headrange')
->label('ZMM HEADRANGE'),
ExportColumn::make('zmm_overall_efficiency')
->label('ZMM OVERALL EFFICIENCY'),
ExportColumn::make('zmm_connection')
->label('ZMM CONNECTION'),
ExportColumn::make('zmm_min_bore_size')
->label('ZMM MIN BORE SIZE'),
ExportColumn::make('zmm_isireference')
->label('ZMM ISIREFERENCE'),
ExportColumn::make('zmm_category')
->label('ZMM CATEGORY'),
ExportColumn::make('zmm_submergence')
->label('ZMM SUBMERGENCE'),
ExportColumn::make('zmm_capacitorstart')
->label('ZMM CAPACITORSTART'),
ExportColumn::make('zmm_capacitorrun')
->label('ZMM CAPACITORRUN'),
ExportColumn::make('zmm_inch')
->label('ZMM INCH'),
ExportColumn::make('zmm_motor_type')
->label('ZMM MOTOR TYPE'),
ExportColumn::make('zmm_dismantle_direction')
->label('ZMM DISMANTLE DIRECTION'),
ExportColumn::make('zmm_eff_ovrall')
->label('ZMM EFF OVRALL'),
ExportColumn::make('zmm_bodymoc')
->label('ZMM BODYMOC'),
ExportColumn::make('zmm_rotormoc')
->label('ZMM ROTORMOC'),
ExportColumn::make('zmm_dlwl')
->label('ZMM DLWL'),
ExportColumn::make('zmm_inputpower')
->label('ZMM INPUTPOWER'),
ExportColumn::make('zmm_imp_od')
->label('ZMM IMP OD'),
ExportColumn::make('zmm_ambtemp')
->label('ZMM AMBTEMP'),
ExportColumn::make('zmm_de')
->label('ZMM DE'),
ExportColumn::make('zmm_dischargerange')
->label('ZMM DISCHARGERANGE'),
ExportColumn::make('zmm_efficiency_class')
->label('ZMM EFFICIENCY CLASS'),
ExportColumn::make('zmm_framesize')
->label('ZMM FRAMESIZE'),
ExportColumn::make('zmm_impellerdiameter')
->label('ZMM IMPELLERDIAMETER'),
ExportColumn::make('zmm_insulationclass')
->label('ZMM INSULATIONCLASS'),
ExportColumn::make('zmm_maxflow')
->label('ZMM MAXFLOW'),
ExportColumn::make('zmm_minhead')
->label('ZMM MINHEAD'),
ExportColumn::make('zmm_mtrlofconst')
->label('ZMM MTRLOFCONST'),
ExportColumn::make('zmm_nde')
->label('ZMM NDE'),
ExportColumn::make('zmm_powerfactor')
->label('ZMM POWERFACTOR'),
ExportColumn::make('zmm_tagno')
->label('ZMM TANGO'),
ExportColumn::make('zmm_year')
->label('ZMM YEAR'),
ExportColumn::make('zmm_laser_name')
->label('ZMM LASER NAME'),
ExportColumn::make('zmm_beenote')
->label('ZMM BEENOTE'),
ExportColumn::make('zmm_beenumber')
->label('ZMM BEENUMBER'),
ExportColumn::make('zmm_beestar')
->label('ZMM BEESTAR'),
ExportColumn::make('zmm_codeclass')
->label('ZMM CODECLASS'),
ExportColumn::make('zmm_colour')
->label('ZMM COLOUR'),
ExportColumn::make('zmm_logo_cp')
->label('ZMM LOGO CP'),
ExportColumn::make('zmm_logo_ce')
->label('ZMM LOGO CE'),
ExportColumn::make('zmm_logo_nsf')
->label('ZMM LOGO NSF'),
ExportColumn::make('zmm_grade')
->label('ZMM GRADE'),
ExportColumn::make('zmm_grwt_pset')
->label('ZMM GRWT PSET'),
ExportColumn::make('zmm_grwt_cable')
->label('ZMM GRWT CABLE'),
ExportColumn::make('zmm_grwt_motor')
->label('ZMM GRWT MOTOR'),
ExportColumn::make('zmm_grwt_pf')
->label('ZMM GRWT PF'),
ExportColumn::make('zmm_grwt_pump')
->label('ZMM GRWT PUMP'),
ExportColumn::make('zmm_isivalve')
->label('ZMM ISIVALVE'),
ExportColumn::make('zmm_isi_wc')
->label('ZMM ISI WC'),
ExportColumn::make('zmm_labelperiod')
->label('ZMM LABELPERIOD'),
ExportColumn::make('zmm_length')
->label('ZMM LENGTH'),
ExportColumn::make('zmm_license_cml_no')
->label('ZMM LICENSE CML NO'),
ExportColumn::make('zmm_mfgmonyr')
->label('ZMM MFGMONYR'),
ExportColumn::make('zmm_modelyear')
->label('ZMM MODELYEAR'),
ExportColumn::make('zmm_motoridentification')
->label('ZMM MOTORIDENTIFICATION'),
ExportColumn::make('zmm_newt_pset')
->label('ZMM NEWT PSET'),
ExportColumn::make('zmm_newt_cable')
->label('ZMM NEWT CABLE'),
ExportColumn::make('zmm_newt_motor')
->label('ZMM NEWT MOTOR'),
ExportColumn::make('zmm_newt_pf')
->label('ZMM NEWT PF'),
ExportColumn::make('zmm_newt_pump')
->label('ZMM NEWT PUMP'),
ExportColumn::make('zmm_packtype')
->label('ZMM PACKTYPE'),
ExportColumn::make('zmm_panel')
->label('ZMM PANEL'),
ExportColumn::make('zmm_performance_factor')
->label('ZMM PERFORMANCE FACTOR'),
ExportColumn::make('zmm_pumpidentification')
->label('ZMM PUMPIDENTIFICATION'),
ExportColumn::make('zmm_psettype')
->label('ZMM PSETTYPE'),
ExportColumn::make('zmm_size')
->label('ZMM SIZE'),
ExportColumn::make('zmm_eff_ttl')
->label('ZMM EFF TTL'),
ExportColumn::make('zmm_type')
->label('ZMM TYPE'),
ExportColumn::make('zmm_usp')
->label('ZMM USP'),
ExportColumn::make('mark_status')
->label('MARKED STATUS'),
ExportColumn::make('marked_datetime')
->label('MARKED DATETIME'),
ExportColumn::make('marked_by')
->label('MARKED BY'),
ExportColumn::make('man_marked_status')
->label('MANUAL MARKED STATUS'),
ExportColumn::make('man_marked_datetime')
->label('MANUAL MARKED DATETIME'),
ExportColumn::make('man_marked_by')
->label('MANUAL MARKED BY'),
ExportColumn::make('motor_marked_status')
->label('MOTOR MARKED STATUS'),
ExportColumn::make('pump_marked_status')
->label('PUMP MARKED STATUS'),
ExportColumn::make('motor_pump_pumpset_status')
->label('MOTOR PUMP PUMPSET STATUS'),
ExportColumn::make('part_validation_1')
->label('PART VALIDATION 1'),
ExportColumn::make('part_validation_2')
->label('PART VALIDATION 2'),
ExportColumn::make('samlight_logged_name')
->label('SAMLIGHT LOGGED NAME'),
ExportColumn::make('pending_released_status')
->label('PENDING RELEASED STATUS'),
ExportColumn::make('motor_expected_time')
->label('MOTOR EXPECTED TIME'),
ExportColumn::make('pump_expected_time')
->label('PUMP EXPECTED TIME'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT')
->enabledByDefault(true),
ExportColumn::make('updated_by')
->label('UPDATED BY')
->enabledByDefault(true),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your class characteristic export has completed and '.number_format($export->successful_rows).' '.str('row')->plural($export->successful_rows).' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace App\Filament\Exports;
use App\Models\RequestCharacteristic;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class RequestCharacteristicExporter extends Exporter
{
protected static ?string $model = RequestCharacteristic::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
// ExportColumn::make('id')
// ->label('ID'),
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('work_flow_id')
->label('WORK FLOW ID'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('aufnr')
->label('AUFNR'),
ExportColumn::make('characteristicApproverMaster.machine_name')
->label('MACHINE NAME'),
ExportColumn::make('characteristicApproverMaster.characteristic_field')
->label('MASTER CHARACTERISTIC FIELD'),
ExportColumn::make('characteristic_name')
->label('CHARACTERISTIC NAME'),
ExportColumn::make('current_value')
->label('CURRENT VALUE'),
ExportColumn::make('update_value')
->label('UPDATE VALUE'),
ExportColumn::make('characteristicApproverMaster.name1')
->label('APPROVER NAME 1'),
ExportColumn::make('approver_status1')
->label('APPROVER STATUS 1'),
ExportColumn::make('approver_remark1')
->label('APPROVER REMARK 1'),
ExportColumn::make('approved1_at')
->label('APPROVED AT 1'),
ExportColumn::make('characteristicApproverMaster.name2')
->label('APPROVER NAME 2'),
ExportColumn::make('approver_status2')
->label('APPROVER STATUS 2'),
ExportColumn::make('approver_remark2')
->label('APPROVER REMARK 2'),
ExportColumn::make('approved2_at')
->label('APPROVED AT 2'),
ExportColumn::make('characteristicApproverMaster.name3')
->label('APPROVER NAME 3'),
ExportColumn::make('approver_status3')
->label('APPROVER STATUS 3'),
ExportColumn::make('approver_remark3')
->label('APPROVER REMARK 3'),
ExportColumn::make('approved3_at')
->label('APPROVED AT 1'),
ExportColumn::make('mail_status')
->label('MAIL STATUS'),
ExportColumn::make('trigger_at')
->label('TRIGGERED AT'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your request characteristic export has completed and '.number_format($export->successful_rows).' '.str('row')->plural($export->successful_rows).' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;
}
}

View File

@@ -0,0 +1,651 @@
<?php
namespace App\Filament\Imports;
use App\Models\ClassCharacteristic;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class ClassCharacteristicImporter extends Importer
{
protected static ?string $model = ClassCharacteristic::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('item')
->requiredMapping()
->exampleHeader('Item Code')
->example('630214')
->label('Item Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('aufnr')
->label('Aufnr')
->exampleHeader('Aufnr')
->example(''),
ImportColumn::make('class')
->label('Class')
->exampleHeader('Class')
->example(''),
ImportColumn::make('arbid')
->label('Arbid')
->exampleHeader('Arbid')
->example(''),
ImportColumn::make('gamng')
->label('Gamng')
->exampleHeader('Gamng')
->example(''),
ImportColumn::make('lmnga')
->label('Lmnga')
->exampleHeader('Lmnga')
->example(''),
ImportColumn::make('gernr')
->label('Gernr')
->exampleHeader('Gernr')
->example(''),
ImportColumn::make('zz1_cn_bill_ord')
->label('zz1 ccn bill ord')
->exampleHeader('zz1 ccn bill ord')
->example(''),
ImportColumn::make('zmm_amps')
->label('zmm amps')
->exampleHeader('zmm amps')
->example(''),
ImportColumn::make('zmm_brand')
->label('zmm brand')
->exampleHeader('zmm brand')
->example(''),
ImportColumn::make('zmm_degreeofprotection')
->label('zmm degreeofprotection')
->exampleHeader('zmm degreeofprotection')
->example(''),
ImportColumn::make('zmm_delivery')
->label('zmm delivery')
->exampleHeader('zmm delivery')
->example(''),
ImportColumn::make('zmm_dir_rot')
->label('zmm dir rot')
->exampleHeader('zmm dir rot')
->example(''),
ImportColumn::make('zmm_discharge')
->label('zmm discharge')
->exampleHeader('zmm discharge')
->example(''),
ImportColumn::make('zmm_discharge_max')
->label('zmm discharge max')
->exampleHeader('zmm discharge max')
->example(''),
ImportColumn::make('zmm_discharge_min')
->label('zmm discharge min')
->exampleHeader('zmm discharge min')
->example(''),
ImportColumn::make('zmm_duty')
->label('zmm duty')
->exampleHeader('zmm duty')
->example(''),
ImportColumn::make('zmm_eff_motor')
->label('zmm eff motor')
->exampleHeader('zmm eff motor')
->example(''),
ImportColumn::make('zmm_eff_pump')
->label('zmm eff pump')
->exampleHeader('zmm eff pump')
->example(''),
ImportColumn::make('zmm_frequency')
->label('zmm frequency')
->exampleHeader('zmm frequency')
->example(''),
ImportColumn::make('zmm_head')
->label('zmm head')
->exampleHeader('zmm head')
->example(''),
ImportColumn::make('zmm_heading')
->label('zmm heading')
->exampleHeader('zmm heading')
->example(''),
ImportColumn::make('zmm_head_max')
->label('zmm head max')
->exampleHeader('zmm head max')
->example(''),
ImportColumn::make('zmm_head_minimum')
->label('zmm head minimum')
->exampleHeader('zmm head minimum')
->example(''),
ImportColumn::make('zmm_idx_eff_mtr')
->label('zmm idx eff mtr')
->exampleHeader('zmm idx eff mtr')
->example(''),
ImportColumn::make('zmm_idx_eff_pump')
->label('zmm idx eff pump')
->exampleHeader('zmm idx eff pump')
->example(''),
ImportColumn::make('zmm_kvacode')
->label('zmm kvacode')
->exampleHeader('zmm kvacode')
->example(''),
ImportColumn::make('zmm_maxambtemp')
->label('zmm maxambtemp')
->exampleHeader('zmm maxambtemp')
->example(''),
ImportColumn::make('zmm_mincoolingflow')
->label('zmm mincoolingflow')
->exampleHeader('zmm mincoolingflow')
->example(''),
ImportColumn::make('zmm_motorseries')
->label('zmm motorseries')
->exampleHeader('zmm motorseries')
->example(''),
ImportColumn::make('zmm_motor_model')
->label('zmm motor model')
->exampleHeader('zmm motor model')
->example(''),
ImportColumn::make('zmm_outlet')
->label('zmm outlet')
->exampleHeader('zmm outlet')
->example(''),
ImportColumn::make('zmm_phase')
->label('zmm phase')
->exampleHeader('zmm phase')
->example(''),
ImportColumn::make('zmm_pressure')
->label('zmm pressure')
->exampleHeader('zmm pressure')
->example(''),
ImportColumn::make('zmm_pumpflowtype')
->label('zmm pumpflowtype')
->exampleHeader('zmm pumpflowtype')
->example(''),
ImportColumn::make('zmm_pumpseries')
->label('zmm pumpseries')
->exampleHeader('zmm pumpseries')
->example(''),
ImportColumn::make('zmm_pump_model')
->label('zmm pump model')
->exampleHeader('zmm pump model')
->example(''),
ImportColumn::make('zmm_ratedpower')
->label('zmm ratedpower')
->exampleHeader('zmm ratedpower')
->example(''),
ImportColumn::make('zmm_region')
->label('zmm region')
->exampleHeader('zmm region')
->example(''),
ImportColumn::make('zmm_servicefactor')
->label('zmm servicefactor')
->exampleHeader('zmm servicefactor')
->example(''),
ImportColumn::make('zmm_servicefactormaximumamps')
->label('zmm servicefactormaximumamps')
->exampleHeader('zmm servicefactormaximumamps')
->example(''),
ImportColumn::make('zmm_speed')
->label('zmm speed')
->exampleHeader('zmm speed')
->example(''),
ImportColumn::make('zmm_suction')
->label('zmm suction')
->exampleHeader('zmm suction')
->example(''),
ImportColumn::make('zmm_suctionxdelivery')
->label('zmm suctionxdelivery')
->exampleHeader('zmm suctionxdelivery')
->example(''),
ImportColumn::make('zmm_supplysource')
->label('zmm supplysource')
->exampleHeader('zmm supplysource')
->example(''),
ImportColumn::make('zmm_temperature')
->label('zmm temperature')
->exampleHeader('zmm temperature')
->example(''),
ImportColumn::make('zmm_thrustload')
->label('zmm thrustload')
->exampleHeader('zmm thrustload')
->example(''),
ImportColumn::make('zmm_volts')
->label('zmm volts')
->exampleHeader('zmm volts')
->example(''),
ImportColumn::make('zmm_wire')
->label('zmm wire')
->exampleHeader('zmm wire')
->example(''),
ImportColumn::make('zmm_package')
->label('zmm package')
->exampleHeader('zmm package')
->example(''),
ImportColumn::make('zmm_pvarrayrating')
->label('zmm pvarrayrating')
->exampleHeader('zmm pvarrayrating')
->example(''),
ImportColumn::make('zmm_isi')
->label('zmm isi')
->exampleHeader('zmm isi')
->example(''),
ImportColumn::make('zmm_isimotor')
->label('zmm isimotor')
->exampleHeader('zmm isimotor')
->example(''),
ImportColumn::make('zmm_isipump')
->label('zmm isipump')
->exampleHeader('zmm isipump')
->example(''),
ImportColumn::make('zmm_isipumpset')
->label('zmm isipumpset')
->exampleHeader('zmm isipumpset')
->example(''),
ImportColumn::make('zmm_pumpset_model')
->label('zmm pumpset model')
->exampleHeader('zmm pumpset model')
->example(''),
ImportColumn::make('zmm_stages')
->label('zmm stages')
->exampleHeader('zmm stages')
->example(''),
ImportColumn::make('zmm_headrange')
->label('zmm headrange')
->exampleHeader('zmm headrange')
->example(''),
ImportColumn::make('zmm_overall_efficiency')
->label('zmm overall efficiency')
->exampleHeader('zmm overall efficiency')
->example(''),
ImportColumn::make('zmm_connection')
->label('zmm connection')
->exampleHeader('zmm connection')
->example(''),
ImportColumn::make('zmm_min_bore_size')
->label('zmm min bore size')
->exampleHeader('zmm min bore size')
->example(''),
ImportColumn::make('zmm_isireference')
->label('zmm isireference')
->exampleHeader('zmm isireference')
->example(''),
ImportColumn::make('zmm_category')
->label('zmm category')
->exampleHeader('zmm category')
->example(''),
ImportColumn::make('zmm_submergence')
->label('zmm submergence')
->exampleHeader('zmm submergence')
->example(''),
ImportColumn::make('zmm_capacitorstart')
->label('zmm capacitorstart')
->exampleHeader('zmm capacitorstart')
->example(''),
ImportColumn::make('zmm_capacitorrun')
->label('zmm capacitorrun')
->exampleHeader('zmm capacitorrun')
->example(''),
ImportColumn::make('zmm_inch')
->label('zmm inch')
->exampleHeader('zmm inch')
->example(''),
ImportColumn::make('zmm_motor_type')
->label('zmm motor type')
->exampleHeader('zmm motor type')
->example(''),
ImportColumn::make('zmm_dismantle_direction')
->label('zmm dismantle direction')
->exampleHeader('zmm dismantle direction')
->example(''),
ImportColumn::make('zmm_eff_ovrall')
->label('zmm eff ovrall')
->exampleHeader('zmm eff ovrall')
->example(''),
ImportColumn::make('zmm_bodymoc')
->label('zmm bodymoc')
->exampleHeader('zmm bodymoc')
->example(''),
ImportColumn::make('zmm_rotormoc')
->label('zmm rotormoc')
->exampleHeader('zmm rotormoc')
->example(''),
ImportColumn::make('zmm_dlwl')
->label('zmm dlwl')
->exampleHeader('zmm dlwl')
->example(''),
ImportColumn::make('zmm_inputpower')
->label('zmm inputpower')
->exampleHeader('zmm inputpower')
->example(''),
ImportColumn::make('zmm_imp_od')
->label('zmm imp od')
->exampleHeader('zmm imp od')
->example(''),
ImportColumn::make('zmm_ambtemp')
->label('zmm ambtemp')
->exampleHeader('zmm ambtemp')
->example(''),
ImportColumn::make('zmm_de')
->label('zmm de')
->exampleHeader('zmm de')
->example(''),
ImportColumn::make('zmm_dischargerange')
->label('zmm dischargerange')
->exampleHeader('zmm dischargerange')
->example(''),
ImportColumn::make('zmm_efficiency_class')
->label('zmm efficiency class')
->exampleHeader('zmm efficiency class')
->example(''),
ImportColumn::make('zmm_framesize')
->label('zmm framesize')
->exampleHeader('zmm framesize')
->example(''),
ImportColumn::make('zmm_impellerdiameter')
->label('zmm impellerdiameter')
->exampleHeader('zmm impellerdiameter')
->example(''),
ImportColumn::make('zmm_insulationclass')
->label('zmm insulationclass')
->exampleHeader('zmm insulationclass')
->example(''),
ImportColumn::make('zmm_maxflow')
->label('zmm maxflow')
->exampleHeader('zmm maxflow')
->example(''),
ImportColumn::make('zmm_minhead')
->label('zmm minhead')
->exampleHeader('zmm minhead')
->example(''),
ImportColumn::make('zmm_mtrlofconst')
->label('zmm mtrlofconst')
->exampleHeader('zmm mtrlofconst')
->example(''),
ImportColumn::make('zmm_nde')
->label('zmm nde')
->exampleHeader('zmm nde')
->example(''),
ImportColumn::make('zmm_powerfactor')
->label('zmm powerfactor')
->exampleHeader('zmm powerfactor')
->example(''),
ImportColumn::make('zmm_tagno')
->label('zmm tagno')
->exampleHeader('zmm tagno')
->example(''),
ImportColumn::make('zmm_year')
->label('zmm year')
->exampleHeader('zmm year')
->example(''),
ImportColumn::make('zmm_laser_name')
->label('zmm laser name')
->exampleHeader('zmm laser name')
->example(''),
ImportColumn::make('zmm_beenote')
->label('zmm beenote')
->exampleHeader('zmm beenote')
->example(''),
ImportColumn::make('zmm_beenumber')
->label('zmm beenumber')
->exampleHeader('zmm beenumber')
->example(''),
ImportColumn::make('zmm_beestar')
->label('zmm beenumber')
->exampleHeader('zmm beenumber')
->example(''),
ImportColumn::make('zmm_codeclass')
->label('zmm codeclass')
->exampleHeader('zmm codeclass')
->example(''),
ImportColumn::make('zmm_colour')
->label('zmm colour')
->exampleHeader('zmm colour')
->example(''),
ImportColumn::make('zmm_logo_cp')
->label('zmm logo cp')
->exampleHeader('zmm logo cp')
->example(''),
ImportColumn::make('zmm_logo_ce')
->label('zmm logo ce')
->exampleHeader('zmm logo ce')
->example(''),
ImportColumn::make('zmm_logo_nsf')
->label('zmm logo nsf')
->exampleHeader('zmm logo nsf')
->example(''),
ImportColumn::make('zmm_grade')
->label('zmm grade')
->exampleHeader('zmm grade')
->example(''),
ImportColumn::make('zmm_grwt_pset')
->label('zmm grwt pset')
->exampleHeader('zmm grwt pset')
->example(''),
ImportColumn::make('zmm_grwt_cable')
->label('zmm grwt cable')
->exampleHeader('zmm grwt cable')
->example(''),
ImportColumn::make('zmm_grwt_motor')
->label('zmm grwt motor')
->exampleHeader('zmm grwt motor')
->example(''),
ImportColumn::make('zmm_grwt_pf')
->label('zmm grwt pf')
->exampleHeader('zmm grwt pf')
->example(''),
ImportColumn::make('zmm_grwt_pump')
->label('zmm grwt pump')
->exampleHeader('zmm grwt pump')
->example(''),
ImportColumn::make('zmm_isivalve')
->label('zmm isivalve')
->exampleHeader('zmm isivalve')
->example(''),
ImportColumn::make('zmm_isi_wc')
->label('zmm isi wc')
->exampleHeader('zmm isi wc')
->example(''),
ImportColumn::make('zmm_labelperiod')
->label('zmm labelperiod')
->exampleHeader('zmm labelperiod')
->example(''),
ImportColumn::make('zmm_length')
->label('zmm length')
->exampleHeader('zmm length')
->example(''),
ImportColumn::make('zmm_license_cml_no')
->label('zmm license cml no')
->exampleHeader('zmm license cml no')
->example(''),
ImportColumn::make('zmm_mfgmonyr')
->label('zmm mfgmonyr')
->exampleHeader('zmm mfgmonyr')
->example(''),
ImportColumn::make('zmm_modelyear')
->label('zmm modelyear')
->exampleHeader('zmm modelyear')
->example(''),
ImportColumn::make('zmm_motoridentification')
->label('zmm motoridentification')
->exampleHeader('zmm motoridentification')
->example(''),
ImportColumn::make('zmm_newt_pset')
->label('zmm newt pset')
->exampleHeader('zmm newt pset')
->example(''),
ImportColumn::make('zmm_newt_cable')
->label('zmm newt cable')
->exampleHeader('zmm newt cable')
->example(''),
ImportColumn::make('zmm_newt_motor')
->label('zmm newt motor')
->exampleHeader('zmm newt motor')
->example(''),
ImportColumn::make('zmm_newt_pf')
->label('zmm newt pf')
->exampleHeader('zmm newt pf')
->example(''),
ImportColumn::make('zmm_newt_pump')
->label('zmm newt pump')
->exampleHeader('zmm newt pump')
->example(''),
ImportColumn::make('zmm_packtype')
->label('zmm packtype')
->exampleHeader('zmm packtype')
->example(''),
ImportColumn::make('zmm_panel')
->label('zmm panel')
->exampleHeader('zmm panel')
->example(''),
ImportColumn::make('zmm_performance_factor')
->label('zmm performance factor')
->exampleHeader('zmm performance factor')
->example(''),
ImportColumn::make('zmm_pumpidentification')
->label('zmm pumpidentification')
->exampleHeader('zmm pumpidentification')
->example(''),
ImportColumn::make('zmm_psettype')
->label('zmm psettype')
->exampleHeader('zmm psettype')
->example(''),
ImportColumn::make('zmm_size')
->label('zmm size')
->exampleHeader('zmm size')
->example(''),
ImportColumn::make('zmm_eff_ttl')
->label('zmm eff ttl')
->exampleHeader('zmm eff ttl')
->example(''),
ImportColumn::make('zmm_type')
->label('zmm type')
->exampleHeader('zmm type')
->example(''),
ImportColumn::make('zmm_usp')
->label('zmm usp')
->exampleHeader('zmm usp')
->example(''),
ImportColumn::make('mark_status')
->label('MARKED STATUS')
->exampleHeader('MARKED STATUS')
->example(''),
ImportColumn::make('marked_datetime')
->label('MARKED DATETIME')
->exampleHeader('MARKED DATETIME')
->example(''),
ImportColumn::make('marked_by')
->label('MARKED BY')
->exampleHeader('MARKED BY')
->example(''),
ImportColumn::make('man_marked_status')
->label('MANUAL MARKED STATUS')
->exampleHeader('MANUAL MARKED STATUS')
->example(''),
ImportColumn::make('man_marked_datetime')
->label('MANUAL MARKED DATETIME')
->exampleHeader('MANUAL MARKED DATETIME')
->example(''),
ImportColumn::make('man_marked_by')
->label('MANUAL MARKED BY')
->exampleHeader('MANUAL MARKED BY')
->example(''),
ImportColumn::make('motor_marked_status')
->label('MOTOR MARKED STATUS')
->exampleHeader('MOTOR MARKED STATUS')
->example(''),
ImportColumn::make('motor_marked_by')
->label('MOTOR MARKED BY')
->exampleHeader('MOTOR MARKED BY')
->example(''),
ImportColumn::make('pump_marked_status')
->label('PUMP MARKED STATUS')
->exampleHeader('PUMP MARKED STATUS')
->example(''),
ImportColumn::make('pump_marked_by')
->label('PUMP MARKED BY')
->exampleHeader('PUMP MARKED BY')
->example(''),
ImportColumn::make('motor_pump_pumpset_status')
->label('MOTOR PUMP PUMPSET STATUS')
->exampleHeader('MOTOR PUMP PUMPSET STATUS')
->example(''),
ImportColumn::make('motor_machine_name')
->label('MOTOR MACHINE NAME')
->exampleHeader('MOTOR MACHINE NAME')
->example(''),
ImportColumn::make('pump_machine_name')
->label('PUMP MACHINE NAME')
->exampleHeader('PUMP MACHINE NAME')
->example(''),
ImportColumn::make('pumpset_machine_name')
->label('PUMPSET MACHINE NAME')
->exampleHeader('PUMPSET MACHINE NAME')
->example(''),
ImportColumn::make('part_validation_1')
->label('PART VALIDATION 1')
->exampleHeader('PART VALIDATION 1')
->example(''),
ImportColumn::make('part_validation_2')
->label('PART VALIDATION 2')
->exampleHeader('PART VALIDATION 2')
->example(''),
ImportColumn::make('samlight_logged_name')
->label('SAMLGHT LOGGED NAME')
->exampleHeader('SAMLGHT LOGGED NAME')
->example(''),
ImportColumn::make('pending_released_status')
->label('PENDING RELEASED STATUS')
->exampleHeader('PENDING RELEASED STATUS')
->example(''),
ImportColumn::make('motor_expected_time')
->label('MOTOR EXPECTED TIME')
->exampleHeader('MOTOR EXPECTED TIME')
->example(''),
ImportColumn::make('pump_expected_time')
->label('PUMP EXPECTED TIME')
->exampleHeader('PUMP EXPECTED TIME')
->example(''),
ImportColumn::make('created_at')
->label('CREATED AT')
->exampleHeader('CREATED AT')
->example(''),
ImportColumn::make('created_by')
->label('CREATED BY')
->exampleHeader('CREATED BY')
->example('RAW01234'),
ImportColumn::make('updated_at')
->label('UPDATED AT')
->exampleHeader('UPDATED AT')
->example(''),
ImportColumn::make('updated_by')
->label('UPDATED BY')
->exampleHeader('UPDATED BY')
->example(''),
// ImportColumn::make('updated_by'),
];
}
public function resolveRecord(): ?ClassCharacteristic
{
// return ClassCharacteristic::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new ClassCharacteristic;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your class 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

@@ -2,14 +2,18 @@
namespace App\Filament\Resources;
use App\Filament\Exports\CharacteristicApproverMasterExporter;
use App\Filament\Resources\CharacteristicApproverMasterResource\Pages;
use App\Models\CharacteristicApproverMaster;
use App\Models\Machine;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\Section;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
@@ -26,53 +30,137 @@ class CharacteristicApproverMasterResource extends Resource
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->reactive()
->relationship('plant', 'name')
->required(),
Forms\Components\Select::make('machine_id')
->label('Work Center')
// ->relationship('machine', 'name')
->reactive()
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
return [];
}
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->columnSpan(2)
->reactive()
->relationship('plant', 'name')
->required()
->default(function () {
return optional(CharacteristicApproverMaster::latest()->first())->plant_id;
})
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('machine_id')
->label('Work Center')
->columnSpan(2)
// ->relationship('machine', 'name')
->reactive()
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
return [];
}
return Machine::where('plant_id', $plantId)->pluck('work_center', 'id');
})
->required(),
Forms\Components\TextInput::make('characteristic_field')
->label('Characteristic Field'),
Forms\Components\TextInput::make('machine_name')
->label('Machine Name'),
Forms\Components\TextInput::make('name1')
->label('Name-1'),
Forms\Components\TextInput::make('mail1')
->label('Mail-1'),
Forms\Components\TextInput::make('duration1')
->label('Duration-1 (Hour.Minute)'),
Forms\Components\TextInput::make('name2')
->label('Name-2'),
Forms\Components\TextInput::make('mail2')
->label('Mail-2'),
Forms\Components\TextInput::make('duration2')
->label('Duration-2 (Hour.Minute)'),
Forms\Components\TextInput::make('name3')
->label('Name-3'),
Forms\Components\TextInput::make('mail3')
->label('Mail-3'),
Forms\Components\TextInput::make('duration3')
->label('Duration-3 (Hour.Minute)'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
return Machine::where('plant_id', $plantId)->pluck('work_center', 'id');
})
->required()
->default(function () {
return optional(CharacteristicApproverMaster::latest()->first())->machine_id ?? [];
})
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('characteristic_field')
->label('Master Characteristic Field')
->columnSpan(2)
->required()
->default('NIL')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('machine_name')
->label('Machine')
->columnSpan(2)
->required()
->default(function () {
return optional(CharacteristicApproverMaster::latest()->first())->machine_name ?? '';
})
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Section::make('Approver - 1')
// ->description('Prevent abuse by limiting the number of requests per period')
->columnSpan(['default' => 2, 'sm' => 4])
->schema([
Forms\Components\TextInput::make('name1')
->label('Name')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('mail1')
->label('Mail')
->columnSpan(['default' => 1, 'sm' => 2])
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('duration1')
->label('Duration (HH.MM)')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
])
->collapsed()// collapsible()
->columns(['default' => 1, 'sm' => 4]),
Section::make('Approver - 2')
->columnSpan(['default' => 2, 'sm' => 4])
->schema([
Forms\Components\TextInput::make('name2')
->label('Name')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('mail2')
->label('Mail')
->columnSpan(['default' => 1, 'sm' => 2])
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('duration2')
->label('Duration (HH.MM)')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
])
->collapsed()// collapsible()
->columns(['default' => 1, 'sm' => 4]),
Section::make('Approver - 3')
->columnSpan(['default' => 2, 'sm' => 4])
->schema([
Forms\Components\TextInput::make('name3')
->label('Name')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('mail3')
->label('Mail')
->columnSpan(['default' => 1, 'sm' => 2])
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('duration3')
->label('Duration (HH.MM)')
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
])
->collapsed()// collapsible()
->columns(['default' => 1, 'sm' => 4]),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
])
->columns(['default' => 1, 'sm' => 4]),
]);
}
@@ -92,26 +180,34 @@ class CharacteristicApproverMasterResource extends Resource
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('characteristic_field')
->label('Characteristic Field')
->label('Master Characteristic Field')
->alignCenter()
->searchable()
->formatStateUsing(fn (string $state): string => strtoupper(__($state)))
->extraAttributes(['class' => 'uppercase'])
->sortable(),
Tables\Columns\TextColumn::make('machine_name')
->label('Machine Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('name1')
->label('Approver Name 1')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('mail1')
->label('Mail 1')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('duration1')
->label('Duration 1 (Hour.Minute)')
@@ -120,10 +216,12 @@ class CharacteristicApproverMasterResource extends Resource
Tables\Columns\TextColumn::make('name2')
->label('Approver Name 2')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('mail2')
->label('Mail 2')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('duration2')
->label('Duration 2 (Hour.Minute)')
@@ -132,10 +230,12 @@ class CharacteristicApproverMasterResource extends Resource
Tables\Columns\TextColumn::make('name3')
->label('Approver Name 3')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('mail3')
->label('Mail 3')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('duration3')
->label('Duration 3 (Hour.Minute)')
@@ -145,16 +245,31 @@ class CharacteristicApproverMasterResource extends Resource
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->dateTime()
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
@@ -171,6 +286,22 @@ class CharacteristicApproverMasterResource extends Resource
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
// ImportAction::make()
// ->label('Import Request Characteristics')
// ->color('warning')
// ->importer(CharacteristicApproverMasterImporter::class)
// ->visible(function () {
// return Filament::auth()->user()->can('view import characteristic approver master');
// }),
ExportAction::make()
->label('Export Request Characteristics')
->color('warning')
->exporter(CharacteristicApproverMasterExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export characteristic approver master');
}),
]);
}

View File

@@ -156,6 +156,9 @@ class LineResource extends Resource
'Base FG Line' => 'Base FG Line',
'SFG Line' => 'SFG Line',
'FG Line' => 'FG Line',
'Process Base FG Line' => 'Process Base FG Line',
'Process SFG Line' => 'Process SFG Line',
'Process FG Line' => 'Process FG Line',
'Machining Cell' => 'Machining Cell',
'Blanking Cell' => 'Blanking Cell',
'Forming Cell' => 'Forming Cell',

View File

@@ -6,6 +6,7 @@ use App\Filament\Exports\ProcessOrderExporter;
use App\Filament\Imports\ProcessOrderImporter;
use App\Filament\Resources\ProcessOrderResource\Pages;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProcessOrder;
use Filament\Facades\Filament;
@@ -71,6 +72,28 @@ class ProcessOrderResource extends Resource
->hint(fn ($get) => $get('poPlantError') ? $get('poPlantError') : null)
->hintColor('danger')
->required(),
Forms\Components\Select::make('line_id')
->label('Line')
->reactive()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
return [];
}
return Line::where('plant_id', $plantId)->pluck('name', 'id');
})
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('item_id', null);
$set('item_description', null);
$set('item_uom', null);
$set('process_order', null);
$set('order_quantity', null);
$set('received_quantity', null);
$set('sfg_number', null);
$set('machine_name', null);
})
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
// ->relationship('item', 'id')
@@ -131,6 +154,7 @@ class ProcessOrderResource extends Resource
Forms\Components\TextInput::make('item_uom')
->label('UOM')
->readOnly()
->required()
->reactive()
->afterStateHydrated(function ($component, $state, Get $get, Set $set) {
@@ -245,6 +269,8 @@ class ProcessOrderResource extends Resource
->label('Received Quantity')
->default('0')
->required(),
Forms\Components\TextInput::make('scrap_quantity')
->label('Scrap Quantity'),
Forms\Components\TextInput::make('sfg_number')
->label('SFG Number')
->reactive()
@@ -279,6 +305,9 @@ class ProcessOrderResource extends Resource
->hintColor('danger'),
Forms\Components\TextInput::make('machine_name')
->label('Machine ID'),
Forms\Components\TextInput::make('rework_status')
->label('Rework Status')
->default(0),
Forms\Components\FileUpload::make('attachment')
->label('PDF Upload')
->acceptedFileTypes(['application/pdf'])
@@ -488,6 +517,11 @@ class ProcessOrderResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item')
->searchable()
@@ -523,6 +557,11 @@ class ProcessOrderResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('scrap_quantity')
->label('Scrap Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('sfg_number')
->label('SFG Number')
->alignCenter()
@@ -533,6 +572,12 @@ class ProcessOrderResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('rework_status')
->label('Rework Status')
->alignCenter()
->searchable()
->formatStateUsing(fn ($state) => $state == 1 ? 'Yes' : 'No')
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,9 @@ use Storage;
use Maatwebsite\Excel\Facades\Excel;
use Livewire\Livewire;
use Str;
use Livewire\Attributes\On;
use App\Services\SmbService;
use Illuminate\Support\Facades\Log;
class CreateSerialValidation extends CreateRecord
{
@@ -61,10 +64,13 @@ class CreateSerialValidation extends CreateRecord
return $this->getResource()::getUrl('create');
}
public function processInvoice($invoiceNumber)
{
$invoiceNumber = trim($invoiceNumber);
$fileName = $invoiceNumber . '.txt';
$this->showCapacitorInput = false;
$user = Filament::auth()->user();
@@ -88,6 +94,187 @@ class CreateSerialValidation extends CreateRecord
//..GET SERIAL INVOICE API
$content = SmbService::readTextFile($fileName);
if ($content == '') {
Notification::make()
->title('File Not Found')
->body("Unable to locate file: {$fileName}")
->danger()
->send();
return;
}
$lines = preg_split("/\r\n|\n|\r/", trim($content));
$insertData = [];
$missingItemCodes = [];
$InvalidLenSno = [];
$InvalidSno = [];
$InvalidLenItem = [];
$InvalidItem = [];
foreach ($lines as $line)
{
$line = trim($line);
if ($line == '') {
continue;
}
$parts = array_map('trim', explode(',', $line));
if (count($parts) != 2) {
Notification::make()
->title("Invalid data found inside the file.")
->danger()
->seconds(1)
->send();
return;
}
[$itemCode, $serialNumber] = $parts;
$sticker = StickerMaster::where('plant_id', $plantId)
->whereHas('item', function ($query) use ($itemCode, $plantId) {
$query->where('plant_id', $plantId)
->where('code', $itemCode);
})
->first();
if (Str::length($itemCode) < 6)
{
$InvalidLenItem [] = $itemCode;
continue;
}
else if(!is_numeric($itemCode)){
$InvalidItem [] = $itemCode;
continue;
}
if (Str::length($serialNumber) < 9)
{
$InvalidLenSno [] = $serialNumber;
continue;
}
else if(!ctype_alnum($serialNumber)){
$InvalidSno [] = $serialNumber;
continue;
}
if (!$sticker) {
$missingItemCodes[] = $itemCode;
continue;
}
$insertData[] = [
'plant_id' => $plantId,
'sticker_master_id' => $sticker->id,
'invoice_number' => $invoiceNumber,
'serial_number' => $serialNumber,
'created_at' => now(),
'operator_id' => $operatorName,
'updated_at' => now(),
];
}
if (!empty($InvalidLenItem))
{
$count = count($InvalidLenItem);
if ($count <= 10) {
$body = 'Item Code should contain minimum 6 digits: ' . implode(', ', $InvalidLenItem);
} else {
$body = "{$count} item codes contain minimum 6 digits.";
}
Notification::make()
->title("Invalid Item Code.")
->body("$body")
->danger()
->seconds(1)
->send();
return;
}
else if (!empty($InvalidItem))
{
$count = count($InvalidItem);
if ($count <= 10) {
$body = 'Item code must be in numeric values: ' . implode(', ', $InvalidSno);
} else {
$body = "{$count} item codes must be in numeric values.";
}
Notification::make()
->title("Invalid Item Code.")
->body("$body")
->danger()
->seconds(1)
->send();
return;
}
else if (!empty($InvalidLenSno))
{
$count = count($InvalidLenSno);
if ($count <= 10) {
$body = 'Serial number should be minimum 9 digits: ' . implode(', ', $InvalidLenSno);
} else {
$body = "{$count} serial number should be minimum 9 digits.";
}
Notification::make()
->title("Invalid Serial Number.")
->body("$body")
->danger()
->seconds(1)
->send();
return;
}
else if (!empty($InvalidSno))
{
$count = count($InvalidSno);
if ($count <= 10) {
$body = 'Serial number should be conatin alpha numeric values: ' . implode(', ', $InvalidSno);
} else {
$body = "{$count} serial number should be conatin alpha numeric values.";
}
Notification::make()
->title("Invalid Serial Number.")
->body("$body")
->danger()
->seconds(1)
->send();
return;
}
else if (!empty($missingItemCodes))
{
$count = count($missingItemCodes);
if ($count <= 10) {
$body = 'Item codes not found in sticker master: ' . implode(', ', $missingItemCodes);
} else {
$body = "{$count} item codes not found in sticker master table.";
}
Notification::make()
->title("Unknown Item Code.")
->body("$body")
->danger()
->seconds(1)
->send();
return;
}
if (!empty($insertData)) {
SerialValidation::insert($insertData);
}
else{
Notification::make()
->title("Insert Failed.")
->body("Data insertion failed")
->danger()
->seconds(1)
->send();
return;
}
//..
@@ -2311,8 +2498,9 @@ class CreateSerialValidation extends CreateRecord
}
}
public function processSerialNumber($serNo)
public function processSer($serNo)
{
$serNo = trim($serNo);
$user = Filament::auth()->user();
$operatorName = $user->name;
@@ -2795,24 +2983,28 @@ class CreateSerialValidation extends CreateRecord
return;
}
$this->dispatch('openCapacitorModal', itemCode: $itemCode, serialNumber: $serialNumber, plantId: $plantId);
// $this->dispatch('openCapacitorModal', itemCode: $itemCode, serialNumber: $serialNumber, plantId: $plantId);
//$this->dispatch('focusCapacitor', invoiceNumber: $invoiceNumber, plantId: $plantId);
$scannedQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
$this->dispatch('focusCapacitor', itemCode: $itemCode);
$totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
$scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
$totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '')
$scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totQuan,
'update_invoice' => false,
'scanned_quantity'=> $scannedQuantity,
]);
$this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
//$scannedQuantity = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
// $totQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
// $scanSQuan = SerialValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
// $totMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('quantity')->where('plant_id', $plantId)->count(); //->where('quantity', '!=', '')
// $scanMQuan = SerialValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
// $this->form->fill([
// 'plant_id' => $plantId,
// 'invoice_number' => $invoiceNumber,
// 'serial_number' => $serNo,
// 'total_quantity' => $totQuan,
// 'update_invoice' => false,
// 'scanned_quantity'=> $scanSQuan,
// ]);
// $this->dispatch( 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
return;
}
else if ($isMarkPs)
@@ -2958,6 +3150,173 @@ class CreateSerialValidation extends CreateRecord
}
}
#[On('process-scan')]
public function processSerial($serial)
{
$this->processSer($serial);
}
public function processCapacitor($serial, $itemCode)
{
$user = Filament::auth()->user();
$operatorName = $user->name;
$this->currentItemCode = $itemCode;
if (!$serial) {
return;
}
if (!preg_match('/^[^\/]+\/[^\/]+\/.+$/', $serial)) {
Notification::make()
->title('Invalid Panel Box QR Format:')
->body('Scan the valid panel box QR code to proceed!')
->danger()
// ->duration(3000)
->seconds(2)
->send();
return;
}
$parts = explode('/', $serial);
$supplier = $parts[0];
$itemCode = $parts[1];
$serialNumber = implode('/', array_slice($parts, 2)); // Keep rest of the string
$existsInStickerMaster = StickerMaster::where('panel_box_code', $itemCode)->where('plant_id', $this->plantId)->whereHas('item', function ($query) {
$query->where('code', $this->currentItemCode);
})
->exists();
if (!$existsInStickerMaster) {
Notification::make()
->title('Unknown: Panel Box Code')
->body("Unknown panel box code: $itemCode found for item code: $this->currentItemCode")
->danger()
// ->duration(4000)
->seconds(2)
->send();
return;
}
foreach ($this->invoiceData as &$row) {
if (
($row['code'] ?? '') === $this->currentItemCode &&
($row['serial_number'] ?? '') === $this->currentSerialNumber
) {
$row['panel_box_supplier'] = $supplier;
$row['panel_box_item_code'] = $itemCode;
$row['panel_box_serial_number'] = $serialNumber;
$row['capacitor_scanned_status'] = 1;
// $row['scanned_status_set'] = true;
$matchingValidation = SerialValidation::with('stickerMaster.item')
->where('serial_number', $this->currentSerialNumber)
->where('plant_id', $this->plantId)
->get()
->first(function ($validation) {
return $validation->stickerMaster?->item?->code === $this->currentItemCode;
});
if ($matchingValidation) {
$hasMotorQr = $matchingValidation->stickerMasterRelation->tube_sticker_motor ?? null;
$hasPumpQr = $matchingValidation->stickerMasterRelation->tube_sticker_pump ?? null;
$hasPumpSetQr = $matchingValidation->stickerMasterRelation->tube_sticker_pumpset ?? null;
// $hasCapacitorQr = $matchingValidation->stickerMasterRelation->panel_box_code ?? null;
$hadMotorQr = $matchingValidation->motor_scanned_status ?? null;
$hadPumpQr = $matchingValidation->pump_scanned_status ?? null;
$hadPumpSetQr = $matchingValidation->scanned_status_set ?? null;
// $hadCapacitorQr = $matchingValidation->capacitor_scanned_status ?? null;
$packCnt = 1;
$scanCnt = 1;
// if($hadMotorQr === $hasMotorQr && $hadPumpQr === $hasPumpQr && $hadPumpSetQr === $hasPumpSetQr)
if($hasMotorQr || $hasPumpQr || $hasPumpSetQr)
{
$packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt;
$packCnt = $hasPumpQr ? $packCnt + 1 : $packCnt;
$packCnt = $hasPumpSetQr ? $packCnt + 1 : $packCnt;
$scanCnt = $hadMotorQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadPumpQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt;
if($packCnt === $scanCnt)
{
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'scanned_status' => 'Scanned',
'operator_id'=> $operatorName,
]);
}
else
{
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'operator_id'=> $operatorName,
]);
}
}
else
{
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'scanned_status' => 'Scanned',
'operator_id'=> $operatorName,
]);
}
// Notification::make()
// ->title('Success: Capacitor QR')
// // ->title("Panel box code scanned: $itemCode")
// ->body("'Capacitor' QR scanned status updated, Scan next QR.")
// ->success() // commented
// ->seconds(2)
// ->send();
$totalQuantity = SerialValidation::where('invoice_number', $matchingValidation->invoice_number)->where('plant_id', $this->plantId)->count();
$scannedQuantity = SerialValidation::where('invoice_number', $matchingValidation->invoice_number)->where('plant_id', $this->plantId)->where('scanned_status', 'Scanned')->count();
// $this->form->fill([
// 'plant_id' => $matchingValidation->plant_id,
// 'invoice_number' => $matchingValidation->invoice_number,
// 'serial_number' => null,
// 'total_quantity' => $totalQuantity,
// 'scanned_quantity'=> $scannedQuantity,
// ]);
if($totalQuantity === $scannedQuantity)
{
Notification::make()
->title('Completed: Serial Invoice')
->body("Serial invoice '$matchingValidation->invoice_number' completed the scanning process.<br>Scan the next 'Serial Invoice' to proceed!")
->success()
->seconds(2)
->send();
$this->loadCompletedData($matchingValidation->invoice_number, $matchingValidation->plant_id, true);
}
else
{
$this->loadData($matchingValidation->invoice_number, $matchingValidation->plant_id);
}
}
break;
}
}
$this->showCapacitorInput = false;
$this->dispatch('focus-serial-number');
}
public function getHeading(): string
{
return 'Scan Serial Validation';

View File

@@ -0,0 +1,327 @@
<?php
namespace App\Http\Controllers;
use App\Models\RequestCharacteristic;
use Carbon\Carbon;
use Illuminate\Http\Request;
class CharacteristicApprovalController extends Controller
{
/**
* Display a listing of the resource.
*/
public function approve(Request $request)
{
return $this->updateStatus($request, 'Approved');
}
/**
* HOLD
*/
// public function hold(Request $request)
// {
// return $this->updateStatus($request, 'Hold');
// }
/**
* REJECT
*/
public function reject(Request $request)
{
return $this->updateStatus($request, 'Rejected');
}
public function holdForm(Request $request)
{
$id = $request->query('id');
// $level = $request->query('level');
$level = (int) $request->query('level');
$record = RequestCharacteristic::findOrFail($id);
[$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
default => abort(403, 'Invalid approver level'),
};
$currentStatus = $record->$statusColumn;
if (in_array($currentStatus, ['Approved', 'Rejected'])) {
return view('approval.already-processed', [
'status' => $currentStatus,
]);
}
return view('approval.hold-form', compact('id', 'level'));
}
public function rejectForm(Request $request)
{
$id = $request->query('id');
// $level = $request->query('level');
$level = (int) $request->query('level');
$record = RequestCharacteristic::findOrFail($id);
[$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
default => abort(403, 'Invalid approver level'),
};
$currentStatus = $record->$statusColumn;
if (in_array($currentStatus, ['Approved', 'Rejected'])) {
return view('approval.already-processed', [
'status' => $currentStatus,
]);
}
return view('approval.reject-form', compact('id', 'level'));
}
public function holdSave(Request $request)
{
$request->validate([
'id' => 'required|integer',
'level' => 'required|integer',
'remark' => 'required|string',
]);
return $this->updateStatus($request, 'Hold', false);
}
public function rejectSave(Request $request)
{
$request->validate([
'id' => 'required|integer',
'level' => 'required|integer',
'remark' => 'required|string',
]);
return $this->updateStatus($request, 'Rejected', false);
}
// protected function updateStatus(Request $request, string $status)
// {
// $requestId = $request->query('id');
// $level = (int) $request->query('level');
// $record = RequestCharacteristic::findOrFail($requestId);
// $column = match ($level) {
// 1 => 'approver_status1',
// 2 => 'approver_status2',
// 3 => 'approver_status3',
// default => abort(403, 'Invalid approver level'),
// };
// $pendingRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
// ->where('machine_id', $record->machine_id)
// ->where('aufnr', $record->aufnr)
// ->whereNull('approver_status1')
// ->whereNull('approver_status2')
// ->whereNull('approver_status3')
// ->get();
// if ($pendingRecords->isEmpty()) {
// return view('approval.already-processed', [
// 'status' => 'No pending records for this group'
// ]);
// }
// if ($pendingRecords->first()->$column != null) {
// return view('approval.already-processed', [
// 'status' => $pendingRecords->first()->$column
// ]);
// }
// // Update all records in the group for this approver level
// foreach ($pendingRecords as $rec) {
// $rec->update([$column => $status]);
// }
// return match ($status) {
// 'Approved' => view('approval.success'),
// 'Hold' => view('approval.hold-success'),
// 'Rejected' => view('approval.reject-success'),
// default => abort(500),
// };
// }
// protected function updateStatus(Request $request, string $status)
// {
// $requestId = $request->query('id');
// $level = (int) $request->query('level');
// $record = RequestCharacteristic::findOrFail($requestId);
// [$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
// 1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
// 2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
// 3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
// default => abort(403, 'Invalid approver level'),
// };
// $pendingRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
// ->where('machine_id', $record->machine_id)
// ->where('aufnr', $record->aufnr)
// ->where('work_flow_id', $record->work_flow_id)
// ->whereNull('approver_status1')
// ->whereNull('approver_status2')
// ->whereNull('approver_status3')
// ->get();
// if ($pendingRecords->isEmpty()) {
// return view('approval.already-processed', [
// 'status' => 'No pending records for this group',
// ]);
// }
// if ($pendingRecords->first()->$statusColumn !== null) {
// return view('approval.already-processed', [
// 'status' => $pendingRecords->first()->$statusColumn,
// ]);
// }
// $updateData = [
// $statusColumn => $status,
// $remarkColumn => $request->input('remark')
// ];
// if ($status == 'Approved') {
// $updateData[$approvedAtColumn] = Carbon::now();
// }
// foreach ($pendingRecords as $rec) {
// $rec->update($updateData);
// }
// return match ($status) {
// 'Approved' => view('approval.success'),
// 'Hold' => view('approval.hold-success'),
// 'Rejected' => view('approval.reject-success'),
// default => abort(500),
// };
// }
protected function updateStatus(Request $request, string $status, bool $returnView = true)
{
$requestId = $request->input('id');
$level = (int) $request->input('level');
$record = RequestCharacteristic::findOrFail($requestId);
[$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
default => abort(403, 'Invalid approver level'),
};
$pendingRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
->where('machine_id', $record->machine_id)
->where('aufnr', $record->aufnr)
->where('work_flow_id', $record->work_flow_id)
->whereNull('approver_status1')
->whereNull('approver_status2')
->whereNull('approver_status3')
->get();
$processRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
->where('machine_id', $record->machine_id)
->where('aufnr', $record->aufnr)
->where('work_flow_id', $record->work_flow_id)
->where(function ($query) {
$query->whereNotNull('approver_status1')
->orWhereNotNull('approver_status2')
->orWhereNotNull('approver_status3');
})
->get();
$alreadyProcessed = RequestCharacteristic::whereIn($statusColumn, ['Approved', 'Rejected'])->exists();
if ($alreadyProcessed) {
if ($returnView) {
return view('approval.already-processed', [
'status' => 'Already processed',
]);
}
return response()->json([
'status' => false,
'message' => 'This request has already been processed.',
], 404);
}
$updateData = [
$statusColumn => $status,
$remarkColumn => $request->input('remark'),
];
if ($status == 'Approved') {
$updateData[$approvedAtColumn] = Carbon::now();
}
foreach ($pendingRecords as $rec) {
$rec->update($updateData);
}
foreach ($processRecords as $recd) {
$recd->update($updateData);
}
if ($returnView) {
return match ($status) {
'Approved' => view('approval.success'),
'Hold' => view('approval.hold-success'),
'Rejected' => view('approval.reject-success'),
default => abort(500),
};
}
return response()->json(['status' => true, 'message' => 'Status updated successfully']);
}
public function index()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@@ -3011,6 +3011,8 @@ class CharacteristicsController extends Controller
$userName = 'Admin';
}
$charField = $request->header('characteristic-field');
$json = $request->input('data');
$data = json_decode($json, true);
@@ -3034,6 +3036,10 @@ class CharacteristicsController extends Controller
], 404);
}
if ($charField == null || $charField == '') {
$charField = 'nil';
}
$plant = Plant::where('code', $plantCode)->first();
if (! $plant) {
return response()->json([
@@ -3072,24 +3078,6 @@ class CharacteristicsController extends Controller
], 404);
}
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found!",
], 404);
}
$machineAgaPlant = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machineAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}'!",
], 404);
}
$MachineId = $machineAgaPlant->id;
if ($machineName == null || $machineName == '' || ! $machineName) {
return response()->json([
'status_code' => 'ERROR',
@@ -3097,11 +3085,82 @@ class CharacteristicsController extends Controller
], 404);
}
if ($itemCode == null || $itemCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code can't be empty!",
], 400);
} elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid item code found!',
], 404);
}
if (! $jobNo) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Job number can't be empty",
], 404);
} elseif (Str::length($jobNo) < 7) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Job number '{$jobNo}' should contain minimum 7 digits!",
], 404);
} elseif (! is_numeric($jobNo)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Job number '{$jobNo}' should contain only numeric values!",
], 404);
}
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found in master!",
], 404);
}
$machineAgaPlant = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machineAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}' in master!",
], 404);
}
$MachineId = $machineAgaPlant->id;
$pCode = CharacteristicApproverMaster::where('plant_id', $plantId)->first();
if (! $pCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' not found in characteristic approver master!",
], 404);
}
$wCenter = CharacteristicApproverMaster::where('machine_id', $MachineId)->first();
if (! $wCenter) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found in characteristic approver master!",
], 404);
}
$wCenterAgaPlant = CharacteristicApproverMaster::where('machine_id', $MachineId)->where('plant_id', $plantId)->first();
if (! $wCenterAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}' in characteristic approver master!",
], 404);
}
$mName = CharacteristicApproverMaster::where('machine_name', $machineName)->first();
if (! $mName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Machine name '{$machineName}' not found in master!",
'status_description' => "Machine name '{$machineName}' not found in characteristic approver master!",
], 404);
}
@@ -3109,19 +3168,28 @@ class CharacteristicsController extends Controller
if (! $mNameAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Machine name '{$machineName}' not found in master against plant code '{$plantCode}'!",
'status_description' => "Machine name '{$machineName}' not found for the plant code '{$plantCode}' in characteristic approver master!",
], 404);
}
$charId = $mNameAgaPlant->id;
if ($itemCode == null || $itemCode == '' || ! $itemCode) {
$mNameAgaWorkCenter = CharacteristicApproverMaster::where('machine_name', $machineName)->where('machine_id', $MachineId)->first();
if (! $mNameAgaWorkCenter) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code can't be empty!",
'status_description' => "Machine name '{$machineName}' not found for the work center '{$workCenter}' in characteristic approver master!",
], 404);
}
$mNameAgaWorkCenterForPlant = CharacteristicApproverMaster::where('machine_name', $machineName)->where('machine_id', $MachineId)->where('plant_id', $plantId)->first();
if (! $mNameAgaWorkCenterForPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Machine name '{$machineName}' and work center '{$workCenter}' not found for the plant code '{$plantCode}' in characteristic approver master!",
], 404);
}
$charId = $mNameAgaWorkCenterForPlant->id;
$iCode = Item::where('code', $itemCode)->first();
if (! $iCode) {
return response()->json([
@@ -3144,10 +3212,7 @@ class CharacteristicsController extends Controller
foreach ($characteristics as $char) {
$charName = strtolower($char['characteristic_name']) ?? null;
$pendingExists = RequestCharacteristic::where('aufnr', $jobNo)
->where('characteristic_name', $charName)
->latest()
->first();
$pendingExists = RequestCharacteristic::where('plant_id', $plantId)->where('aufnr', $jobNo)->where('characteristic_name', $charName)->latest()->first();
if ($pendingExists) {
@@ -3176,7 +3241,8 @@ class CharacteristicsController extends Controller
$year = now()->format('y');
$month = now()->format('m');
$prefix = "WF-{$year}{$month}-";
$date = now()->format('d');
$prefix = "WF-{$year}{$month}{$date}-";
// $existingWorkflowId = RequestCharacteristic::where('plant_id', $plantId)
// ->where('machine_id', $MachineId)
@@ -3188,8 +3254,9 @@ class CharacteristicsController extends Controller
// }
$lastWorkflow = RequestCharacteristic::where('plant_id', $plantId)
->where('machine_id', $MachineId)
$lastWorkflow = RequestCharacteristic::where('work_flow_id', 'like', "{$prefix}%")
// ->where('plant_id', $plantId)
// ->where('machine_id', $MachineId)
->where('work_flow_id', 'like', "{$prefix}%")
->orderByDesc('work_flow_id')
->first();

View File

@@ -808,4 +808,29 @@ class InvoiceValidationController extends Controller
{
//
}
// public function handle(Request $request)
// {
// $invoice = InvoiceValidation::withCount([
// 'serialNumbers as scanned_count' => function ($q) {
// $q->where('is_scanned', 1);
// }
// ])->find($request->invoice_id);
// if (!$invoice) {
// return response()->json(['error' => 'Invoice not found'], 404);
// }
// if ($invoice->scanned_count < $invoice->total_serials) {
// Mail::to('alerts@example.com')->send(
// new \App\Mail\IncompleteInvoiceMail(
// $invoice,
// $invoice->scanned_count,
// $invoice->total_serials
// )
// );
// }
// return response()->json(['status' => 'ok']);
// }
}

View File

@@ -33,29 +33,28 @@ class MachineController extends Controller
public function get_all_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$machines = Machine::with('plant')->with('workGroupMaster')->orderBy('plant_id')->get();
$machinesData = $machines->map(function($machine) {
$machinesData = $machines->map(function ($machine) {
return [
'plant_code' => $machine->plant ? (String)$machine->plant->code : "",
'group_work_center' => $machine->workGroupMaster ? (String)$machine->workGroupMaster->name : "",
'work_center' => $machine->work_center ?? "",
'plant_code' => $machine->plant ? (string) $machine->plant->code : '',
'group_work_center' => $machine->workGroupMaster ? (string) $machine->workGroupMaster->name : '',
'work_center' => $machine->work_center ?? '',
];
});
return response()->json([
'machines' => $machinesData
'machines' => $machinesData,
]);
}
@@ -65,80 +64,70 @@ class MachineController extends Controller
public function get_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$plantCode = $request->header('plant-code');
$lineName = $request->header('line-name');
if ($plantCode == null || $plantCode == '')
{
if ($plantCode == null || $plantCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($plantCode) < 4 || !is_numeric($plantCode) || !preg_match('/^[1-9]\d{3,}$/', $plantCode))
{
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
else if ($lineName == null || $lineName == '' || Str::length($lineName) <= 0)
{
} elseif ($lineName == null || $lineName == '' || Str::length($lineName) <= 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name can't be empty!"
'status_description' => "Line name can't be empty!",
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant)
{
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code '{$plantCode}' not found!"
'status_description' => "Plant Code '{$plantCode}' not found!",
], 400);
}
$plantId = $plant->id;
$line = Line::where('name', $lineName)->first();
if (!$line)
{
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '{$lineName}' not found!"
'status_description' => "Line Name '{$lineName}' not found!",
], 400);
}
$line = Line::where('name', $lineName)->where('plant_id', $plantId)->first();
if (!$line)
{
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '{$lineName}' not found for the plant!"
'status_description' => "Line Name '{$lineName}' not found for the plant!",
], 400);
}
$lineId = $line->id;//no_of_operation
$lineId = $line->id; // no_of_operation
$lineWorkGroup1Id = $line->work_group1_id;
$lineWorkGroup2Id = $line->work_group2_id;
if ($line->no_of_operation == null || $line->no_of_operation == '' || $line->no_of_operation == 0 || !is_numeric($line->no_of_operation))
{
if ($line->no_of_operation == null || $line->no_of_operation == '' || $line->no_of_operation == 0 || ! is_numeric($line->no_of_operation)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Group work center not found for the plant & line!"
'status_description' => 'Group work center not found for the plant & line!',
], 400);
}
@@ -146,26 +135,22 @@ class MachineController extends Controller
$lineWorkGroupIds = [];
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$curWorkGroupId = $line->{"work_group{$i}_id"};
if (in_array($curWorkGroupId, $lineWorkGroupIds))
{
if (in_array($curWorkGroupId, $lineWorkGroupIds)) {
continue;
}
else
{
} else {
$lineWorkGroupIds[] = $curWorkGroupId;
}
$test[] = [
'group_work_center' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->name ?? "",
'operation_number' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->operation_number ?? "",
'work_centers' => Machine::where('plant_id', $plantId)->where('work_group_master_id', $curWorkGroupId)->orderBy('work_center')->pluck('work_center')->toArray() ?? [],
'group_work_center' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->name ?? '',
'operation_number' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->operation_number ?? '',
'work_centers' => Machine::where('plant_id', $plantId)->where('work_group_master_id', $curWorkGroupId)->orderBy('work_center')->pluck('work_center')->toArray() ?? [],
];
}
if($lineWorkGroupIds)
{
if ($lineWorkGroupIds) {
return response()->json([
'machines' => $test
'machines' => $test,
]);
}
// $machines = Machine::with('plant')->with('workGroupMaster')->orderBy('plant_id')->get();

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use Filament\Notifications\Notification;
use Illuminate\Http\Request;
use Mpdf\Mpdf;
use Mpdf\QrCode\Output;
@@ -20,11 +21,11 @@ class PalletController extends Controller
public function downloadReprintQrPdf($palletNo)
{
$qrCode = new QrCode($palletNo);
$output = new Output\Png();
$output = new Output\Png;
$qrBinary = $output->output($qrCode, 100);
$qrBase64 = base64_encode($qrBinary);
return '
return '
<html>
<head>
<style>
@@ -39,10 +40,10 @@ class PalletController extends Controller
<table class="sticker-table">
<tr>
<td class="qr-cell">
<img class="qr" src="data:image/png;base64,' . $qrBase64 . '" alt="QR" />
<img class="qr" src="data:image/png;base64,'.$qrBase64.'" alt="QR" />
</td>
<td class="text-cell">
' . htmlspecialchars($palletNo) . '
'.htmlspecialchars($palletNo).'
</td>
</tr>
</table>
@@ -73,26 +74,182 @@ class PalletController extends Controller
// $mpdf->Output('qr-label.pdf', 'I');
}
public function downloadQrPdf($palletNo)
public function downloadReprintProcess($plant, $item, $process_order, $coil_number, $name)
{
$qrCode = new QrCode($palletNo);
$output = new Output\Png();
// dd($plant,$item,$process_order,$coil_number);
$processOrder = \App\Models\ProcessOrder::where('plant_id', $plant)
->where('item_id', $item)
->where('process_order', $process_order)
->where('coil_number', $coil_number)
->first();
if (! $processOrder) {
return response()->json(['error' => 'Process order not found'], 404);
}
$receivedQuantity = $processOrder->received_quantity;
$machineName = $processOrder->machine_name;
$user = $processOrder->created_by;
$icode = \App\Models\Item::find($item);
$pCode = \App\Models\Plant::find($plant);
$plCode = $pCode->code;
if (! $plCode) {
Notification::make()
->title('Unknown Plant')
->body('Plant not found.')
->warning()
->send();
}
if (! $icode) {
Notification::make()
->title('Unknown Item')
->body('Item not found.')
->warning()
->send();
}
$itCode = $icode->code;
$itemAgaPlant = \App\Models\Item::where('code', $itCode)
->where('plant_id', $plant)
->first();
if (! $itemAgaPlant) {
Notification::make()
->title('Unknown Item')
->body("Item not found against plant code $plCode.")
->warning()
->send();
} else {
$itemDescription = $itemAgaPlant->description;
}
$nowDT = now()->format('d-m-Y H:i:s');
// Build QR content
$qrContent = "{$receivedQuantity}|{$itCode}|{$process_order}-{$coil_number}";
$qrCode = new QrCode($qrContent);
$output = new Output\Png;
$qrBinary = $output->output($qrCode, 100);
$qrBase64 = base64_encode($qrBinary);
$htmlBlock = '
return '
<html>
<head>
<style>
@page {
size: 60mm 30mm;
margin: 0;
}
body {
margin: 0;
padding: 0;
width: 60mm;
font-size: 9pt;
font-family: "DejaVu Sans Condensed", "FreeSans", sans-serif;
}
.sticker-table {
width: 60mm;
border-collapse: collapse;
page-break-inside: avoid;
}
.text-cell {
text-align: left;
vertical-align: top;
font-size: 9pt;
padding-left: 2mm;
padding-top: 2mm; /* was 6mm ❌ */
font-weight: bold;
line-height: 1.1; /* IMPORTANT */
white-space: nowrap;
width: 40mm;
}
.qr-cell {
width: 20mm;
text-align: center;
vertical-align: middle;
}
.lbl {
display: inline-block;
width: 11mm;
font-weight: bold;
}
.text-cell b {
font-size: 10pt; /* was 12pt ❌ */
font-weight: bold;
}
img.qr {
width: 12mm;
height: 12mm;
display: block;
margin: auto;
}
</style>
</head>
<body>
<table class="sticker-table">
<tr>
<td class="text-cell">
<span class="lbl">D/T</span>: '.htmlspecialchars($nowDT).'<br>
<span class="lbl">OP ID</span>: '.htmlspecialchars($user).'<br>
<span class="lbl">PO NO</span>: '.htmlspecialchars($process_order).'<br>
<span class="lbl">M/C</span>: '.htmlspecialchars($itCode).'<br>
<span class="lbl">DES</span>: '.htmlspecialchars($itemDescription).'<br>
<span class="lbl">WGT</span>: <b>'.htmlspecialchars($receivedQuantity).' KGS</b><br>
<span class="lbl">MAC</span>: '.htmlspecialchars($machineName).'
</td>
<td class="qr-cell">
<img class="qr" src="data:image/png;base64,'.$qrBase64.'" alt="QR" />
</td>
</tr>
</table>
<script>
window.onload = function () {
window.print();
setTimeout(function () { window.close(); }, 500);
};
</script>
</body>
</html>
';
}
public function downloadQrPdf($palletNo)
{
$qrCode = new QrCode($palletNo);
$output = new Output\Png;
$qrBinary = $output->output($qrCode, 100);
$qrBase64 = base64_encode($qrBinary);
$htmlBlock = '
<table class="sticker-table">
<tr>
<td class="qr-cell">
<img class="qr" src="data:image/png;base64,' . $qrBase64 . '" alt="QR" />
<img class="qr" src="data:image/png;base64,'.$qrBase64.'" alt="QR" />
</td>
<td class="text-cell">
' . htmlspecialchars($palletNo) . '
'.htmlspecialchars($palletNo).'
</td>
</tr>
</table>';
return '
return '
<html>
<head>
<style>
@@ -104,7 +261,7 @@ class PalletController extends Controller
</style>
</head>
<body>
' . $htmlBlock . $htmlBlock . '
'.$htmlBlock.$htmlBlock.'
<script>
window.onload = function () {
window.print();

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Models\GrMaster;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\User;
@@ -667,11 +668,14 @@ class PdfController extends Controller
$plantId = $plant->id;
$itemCode = $data['item_code'] ?? '';
$lineName = $data['line_name'] ?? '';
$coilNo = $data['coil_number'] ?? '';
$orderQty = $data['order_quantity'] ?? 0;
$receivedQty = $data['received_quantity'] ?? 0;
$scrapQty = $data['scrap_quantity'] ?? 0;
$sfgNo = $data['sfg_number'] ?? '';
$machineId = $data['machine_id'] ?? '';
$rework = $data['rework'] ?? '';
$createdBy = $data['created_by'] ?? '';
// $validated = $request->validate([
@@ -701,6 +705,35 @@ class PdfController extends Controller
], 404);
}
if ($lineName == null || $lineName == '' || ! $lineName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name can't be empty!",
], 404);
}
$line = Line::where('name', $lineName)->first();
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name '{$lineName}' not found!",
], 404);
}
$lineNamePlant = Line::where('name', $lineName)
->where('plant_id', $plantId)
->first();
if (! $lineNamePlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name '{$lineName}' not found for the plant code '{$plantCode}'!",
], 404);
}
$lineNamePlantId = $lineNamePlant->id;
if ($coilNo == null || $coilNo == '') {
return response()->json([
'status_code' => 'ERROR',
@@ -806,18 +839,6 @@ class PdfController extends Controller
], 404);
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' with coil number '{$coilNo}' already exist for the plant code '{$plantCode}'!",
], 404);
}
$alreadyReceived = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
@@ -839,25 +860,98 @@ class PdfController extends Controller
], 404);
}
try {
ProcessOrder::Create(
[
'plant_id' => $plantId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'created_by' => $createdBy,
]
);
if ($rework == null || $rework == '' || ! $rework) {
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Inserted Successfully',
]);
'status_code' => 'ERROR',
'status_description' => "Rework can't be empty!",
], 404);
}
if($rework != 'Yes' && $rework != 'No'){
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework value should be either 'Yes' or 'No'!",
], 404);
}
else if ($rework == 'No')
{
if($scrapQty != 0){
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Scrap Quanity value should be '0'!",
], 404);
}
}
try
{
if ($rework == 'Yes')
{
$updated = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineNamePlantId)
->where('coil_number', $coilNo)
->update([
// 'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
// 'sfg_number' => $sfgNo,
// 'machine_name' => $machineId,
'rework_status' => 1,
'updated_by' => $createdBy,
'updated_at' => now(),
]);
if ($updated == 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'No matching record found for rework coil number!',
], 404);
}
else
{
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Updated Successfully (Rework)',
]);
}
}
else
{
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' with coil number '{$coilNo}' already exist for the plant code '{$plantCode}'!",
], 404);
}
ProcessOrder::Create(
[
'plant_id' => $plantId,
'line_id' => $lineNamePlantId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'rework_status' => 0,
'created_by' => $createdBy,
]
);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Inserted Successfully',
]);
}
} catch (\Exception $e) {
return response()->json([
'status_code' => 'ERROR',
@@ -866,6 +960,65 @@ class PdfController extends Controller
}
}
public function storeLaserPdf(Request $request){
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 404);
}
$workflowId = $request->header('work_flow_id');
if (!$workflowId) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "work_flow_id can't be empty!",
], 404);
}
if (! $request->hasFile('pdf_file')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'No PDF file provided!',
], 404);
}
// $file = $request->file('pdf_file');
// $filename = $file->getClientOriginalName();
// $filePath = $file->storeAs(
// 'uploads/LaserDocs',
// $filename,
// 'local'
// );
$filename = $workflowId . '.pdf';
$filePath = 'uploads/LaserDocs/' . $filename;
if (Storage::disk('local')->exists($filePath)) {
Storage::disk('local')->delete($filePath);
}
Storage::disk('local')->putFileAs(
'uploads/LaserDocs',
$filename,
'local'
);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Laser document pdf file replaced successfully!',
], 200);
}
/**
* Display the specified resource.
*/

View File

@@ -2,6 +2,8 @@
namespace App\Http\Controllers;
use App\Models\DriverMaster;
use App\Models\VehicleMaster;
use Illuminate\Http\Request;
use Str;
use Illuminate\Support\Facades\Schema;
@@ -19,10 +21,21 @@ class SapFileController extends Controller
/**
* Store a newly created resource in storage.
*/
// public function store(Request $request)
// {
// //
// }
public function store(Request $request)
{
$request->validate([
'name' => 'required|string',
'identification1' => 'nullable|string',
'identification2' => 'nullable|string',
'identification3' => 'nullable|string',
'contact_number' => 'nullable|string',
'alternate_number' => 'nullable|string',
]);
DriverMaster::create($request->all());
return response()->json(['success' => true]);
}
public function getSapData(Request $request)
{
@@ -145,40 +158,6 @@ class SapFileController extends Controller
], 500);
}
// $table = 'class_characteristics';
// $columns = Schema::getColumnListing($table); // returns lowercase column names
// $rows = [];
// foreach ($lines as $line) {
// $values = str_getcsv($line); // split by comma
// $row = [];
// foreach ($columns as $index => $column) {
// $value = $values[$index] ?? null; // if missing, set null
// if ($value === '') $value = null; // empty string -> null
// $row[$column] = $value;
// }
// $rows[] = $row;
// }
// return response()->json([
// 'status' => 'DEBUG_ROWS',
// 'rows_sample' => array_slice($rows, 0, 5),
// ]);
// Insert into database
// foreach ($rows as $row) {
// \App\Models\ClassCharacteristic::create($row);
// }
// return response()->json([
// 'status' => 'SUCCESS',
// 'rows_imported' => count($rows),
// ]);
// Prepare arrays
// $serialNumbers = [];
// $remainingRows = [];
@@ -251,7 +230,7 @@ class SapFileController extends Controller
if (!empty($invalidSerials)) {
return response()->json([
'status' => 'ERROR',
'status_description' => 'Some serial numbers are invalid (less than 13 characters)',
'status_description' => 'serial numbers are invalid (less than 13 characters)',
'invalid_serials' => $invalidSerials
], 400);
}

View File

@@ -4,7 +4,7 @@ namespace App\Http\Controllers;
use App\Models\Plant;
use App\Models\User;
//use Carbon\Carbon;
// use Carbon\Carbon;
use Hash;
use Illuminate\Http\Request;
@@ -29,72 +29,65 @@ class UserController extends Controller
/**
* Display the specified resource.
*/
//show(string $id)
// show(string $id)
public function get_testing_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$header_user = $request->header('User-Name');
$header_pass = $request->header('User-Pass');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$header_user = $request->header('User-Name');
$header_pass = $request->header('User-Pass');
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
if (!$header_user)
{
if (! $header_user) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid user name found!'
'status_description' => 'Invalid user name found!',
], 400);
}
else if (!$header_pass)
{
} elseif (! $header_pass) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid password found!'
'status_description' => 'Invalid password found!',
], 400);
}
$existUser = User::where('name', $header_user)->first();
$existPlant = "All Plants";
$existPlant = 'All Plants';
if (!$existUser)
{
if (! $existUser) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Unknown user name found!'
'status_description' => 'Unknown user name found!',
], 400);
}
else {
} else {
$codeExist = Plant::where('id', $existUser->plant_id)->first();
if ($codeExist) {
$existPlant = $codeExist->code;
}
}
// Retrieve the user by email
//$user = User::where('email', $email)->first();
// $user = User::where('email', $email)->first();
if (Hash::check($header_pass, $existUser->password)) {
return response()->json([
'created_at' => $existUser->created_at->format('Y-m-d H:i:s') ?? "",
'updated_at' => $existUser->updated_at->format('Y-m-d H:i:s') ?? "",
'requested_at' => now()->format('Y-m-d H:i:s') ?? "", //Carbon::now(config('app.timezone'))->format('Y-m-d H:i:s') ?? "",
'plant' => (String)$existPlant ?? "",
'email' => $existUser->email ?? "",
'roles' => $existUser->roles()->pluck('name')->toArray()
'created_at' => $existUser->created_at->format('Y-m-d H:i:s') ?? '',
'updated_at' => $existUser->updated_at->format('Y-m-d H:i:s') ?? '',
'requested_at' => now()->format('Y-m-d H:i:s') ?? '', // Carbon::now(config('app.timezone'))->format('Y-m-d H:i:s') ?? "",
'plant' => (string) $existPlant ?? '',
'email' => $existUser->email ?? '',
'roles' => $existUser->roles()->pluck('name')->toArray(),
], 200);
} else {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Password does not match!'
'status_description' => 'Password does not match!',
], 400);
}

View File

@@ -114,6 +114,7 @@ class InvoicePendingReasonImport implements ToCollection
continue;
}
// dd($row['document_number'], bin2hex($row['document_number']));
$this->validRows[] = [
'plant_id' => $plantId,

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Jobs;
use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
class SendApprover1MailJob implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct(public RequestCharacteristic $request) {
}
/**
* Execute the job.
*/
public function handle()
{
// Already approved? stop
if (!is_null($this->request->approver_status1)) return;
if ($this->request->approver1_mail_sent) return;
$approver = CharacteristicApproverMaster::where('plant_id', $this->request->plant_id)
->where('machine_id', $this->request->machine_id)
->first();
if (! $approver || ! $approver->mail1) return;
Mail::to($approver->mail1)
->queue(new CharacteristicApprovalMail(
$this->request,
$approver->name1,
1
));
$this->request->update(['approver1_mail_sent' => 1]);
SendApprover2MailJob::dispatch($this->request)
->delay(now()->addMinutes(5));
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Jobs;
use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
class SendApprover2MailJob implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
// public function __construct()
// {
// //
// }
/**
* Execute the job.
*/
public function __construct(public RequestCharacteristic $request) {}
public function handle()
{
// If approver-1 approved → STOP
if (!is_null($this->request->approver_status1)) return;
// If approver-2 already approved → STOP
if (!is_null($this->request->approver_status2)) return;
if ($this->request->approver2_mail_sent) return;
$approver = CharacteristicApproverMaster::where('plant_id', $this->request->plant_id)
->where('machine_id', $this->request->machine_id)
->first();
if (! $approver || ! $approver->mail2) return;
Mail::to($approver->mail2)
->queue(new CharacteristicApprovalMail(
$this->request,
$approver->name2,
2
));
$this->request->update(['approver2_mail_sent' => 1]);
// Schedule Approver-3 after 5 minutes
SendApprover3MailJob::dispatch($this->request)
->delay(now()->addMinutes(5));
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Jobs;
use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
class SendApprover3MailJob implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
// public function __construct()
// {
// //
// }
/**
* Execute the job.
*/
public function __construct(public RequestCharacteristic $request) {}
public function handle()
{
if (
!is_null($this->request->approver_status1) ||
!is_null($this->request->approver_status2) ||
!is_null($this->request->approver_status3)
) {
return;
}
if ($this->request->approver3_mail_sent) return;
$approver = CharacteristicApproverMaster::where('plant_id', $this->request->plant_id)
->where('machine_id', $this->request->machine_id)
->first();
if (! $approver || ! $approver->mail3) return;
Mail::to($approver->mail3)
->queue(new CharacteristicApprovalMail(
$this->request,
$approver->name3,
3
));
$this->request->update(['approver3_mail_sent' => 1]);
}
}

View File

@@ -13,23 +13,41 @@ class GuardPatrolEntryDataTable extends Component
// public $date;
public $newNameFound;
public $guardName;
public $checkPointName;
public $startTime;
public $endTime;
public $start;
public $finish;
public $begin;
public $end;
public $labTime;
public $minDiff;
public $seqNoCnt = 0;
public $seqNo = 0;
public $isSequenced = true;
public $sequences = [];
public $seqTime;
public $seqTimes = [];
public $startSeqCheckPoints = [];
public $records = [];
protected $listeners = [
@@ -61,9 +79,9 @@ class GuardPatrolEntryDataTable extends Component
$this->seqTimes = [];
$this->startSeqCheckPoints = [];
if (!$plantId || !$date)
{
if (! $plantId || ! $date) {
$this->records = [];
return;
}
@@ -73,20 +91,19 @@ class GuardPatrolEntryDataTable extends Component
$this->startSeqCheckPoints[$i] = CheckPointTime::with('checkPointNames1')->with('checkPointNames2')->where('sequence_number', $i)->where('plant_id', $plantId)->first();
}
$this->sequences = array_fill(1, $this->seqNoCnt, "X");
$this->sequences = array_fill(1, $this->seqNoCnt, 'X');
$this->seqTimes = array_fill(1, $this->seqNoCnt, null);
$hasSingleGuard = GuardPatrolEntry::whereDate('patrol_time', $date)->where('plant_id', $plantId)->orderBy('patrol_time', 'asc')->get();
$checking = 0;
$records = GuardPatrolEntry::with('guardNames')->with('checkPointNames')->whereDate('patrol_time', $date)->where('plant_id', $plantId)->orderBy('patrol_time', 'asc')->get(); //desc Carbon::parse($record->patrol_time)->toTimeString()
foreach ($records as $index => $record) { //foreach ($startSeqCheckPoints as $seq => $checkpoint)
$records = GuardPatrolEntry::with('guardNames')->with('checkPointNames')->whereDate('patrol_time', $date)->where('plant_id', $plantId)->orderBy('patrol_time', 'asc')->get(); // desc Carbon::parse($record->patrol_time)->toTimeString()
foreach ($records as $index => $record) { // foreach ($startSeqCheckPoints as $seq => $checkpoint)
$checking++;
$guardName = $record->guardNames ? $record->guardNames->name : null;
$checkPointName = $record->checkPointNames ? $record->checkPointNames->name : null;
if ($this->guardName != $guardName || $this->newNameFound) {//if ($this->newNameFound) {
if ($this->guardName)
{
if ($this->guardName != $guardName || $this->newNameFound) {// if ($this->newNameFound) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
@@ -105,27 +122,25 @@ class GuardPatrolEntryDataTable extends Component
$this->seqTimes = array_fill(1, $this->seqNoCnt, null);
$this->guardName = $guardName;
$this->startTime = Carbon::parse($record->patrol_time)->toTimeString(); //"2025-06-01 00:07:12"
$this->startTime = Carbon::parse($record->patrol_time)->toTimeString(); // "2025-06-01 00:07:12"
$this->start = Carbon::parse($record->patrol_time);
$this->endTime = Carbon::parse($record->patrol_time)->toTimeString(); //"2025-06-01 00:07:12"
$this->endTime = Carbon::parse($record->patrol_time)->toTimeString(); // "2025-06-01 00:07:12"
$this->finish = Carbon::parse($record->patrol_time);
$this->begin = Carbon::parse($record->patrol_time);
$this->end = Carbon::parse($record->patrol_time);
$this->labTime = (int)$this->start->diffInMinutes($this->finish);
$this->minDiff = (int)$this->begin->diffInMinutes($this->end);
$this->seqTime = $this->begin->toTimeString(). " - " . $this->end->toTimeString();
$this->labTime = (int) $this->start->diffInMinutes($this->finish);
$this->minDiff = (int) $this->begin->diffInMinutes($this->end);
$this->seqTime = $this->begin->toTimeString().' - '.$this->end->toTimeString();
$this->seqNo = 0;
$this->newNameFound = false;
$this->isSequenced = true;
}
else if ($this->guardName == $guardName && $this->start && $this->begin)
{
$this->endTime = Carbon::parse($record->patrol_time)->toTimeString(); //"2025-06-01 00:07:12"
} elseif ($this->guardName == $guardName && $this->start && $this->begin) {
$this->endTime = Carbon::parse($record->patrol_time)->toTimeString(); // "2025-06-01 00:07:12"
$this->finish = Carbon::parse($record->patrol_time);
$this->end = Carbon::parse($record->patrol_time);
$this->labTime = (int)$this->start->diffInMinutes($this->finish);
$this->minDiff = (int)$this->begin->diffInMinutes($this->end);
$this->seqTime = $this->begin->toTimeString(). " - " . $this->end->toTimeString();
$this->labTime = (int) $this->start->diffInMinutes($this->finish);
$this->minDiff = (int) $this->begin->diffInMinutes($this->end);
$this->seqTime = $this->begin->toTimeString().' - '.$this->end->toTimeString();
$this->begin = Carbon::parse($record->patrol_time);
// $this->seqNo = 0;
}
@@ -133,19 +148,16 @@ class GuardPatrolEntryDataTable extends Component
$this->seqNo++;
if ($this->seqNo == 1) {
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo]->checkPointNames1->name) {//"STP BACKSIDE"
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo]->checkPointNames1->name) {// "STP BACKSIDE"
$this->isSequenced = true;
$this->sequences = array_fill(1, $this->seqNoCnt, "X");
}
else {
$this->sequences = array_fill(1, $this->seqNoCnt, 'X');
} else {
$this->isSequenced = false;
$this->sequences = array_fill(1, $this->seqNoCnt, "X");
$this->sequences = array_fill(1, $this->seqNoCnt, 'X');
}
if (($index+1) == count($hasSingleGuard))
{
if ($this->guardName)
{
if (($index + 1) == count($hasSingleGuard)) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
@@ -161,26 +173,37 @@ class GuardPatrolEntryDataTable extends Component
$this->records[] = $recordData;
}
}
}
else if ($this->seqNo >= ($this->seqNoCnt+1)) {
$this->seqTimes[$this->seqNo-1] = $this->seqTime;
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo-1]->checkPointNames2->name) {//"D 72 END"
} elseif ($this->seqNo >= ($this->seqNoCnt + 1)) {
$this->seqTimes[$this->seqNo - 1] = $this->seqTime;
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo - 1]->checkPointNames2->name) {// "D 72 END"
if ($this->isSequenced) {
$this->sequences[$this->seqNo-1] = $this->minDiff;
$this->sequences[$this->seqNo - 1] = $this->minDiff;
}
}
else {
} else {
$this->isSequenced = false;
}
$this->newNameFound = true;
if ($hasSingleGuard->unique('guard_name_id')->count() == 1)
{
if (($this->seqNoCnt+1) == count($hasSingleGuard))
{
//dd("Has 1 Guard and single patrol round (".($this->seqNoCnt+1).") is present");
if ($this->guardName)
{
if ($hasSingleGuard->unique('guard_name_id')->count() == 1) {
if (($this->seqNoCnt + 1) == count($hasSingleGuard)) {
// dd("Has 1 Guard and single patrol round (".($this->seqNoCnt+1).") is present");
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
'end_time' => $this->endTime,
'lap_time' => $this->labTime,
];
for ($i = 1; $i <= $this->seqNoCnt; $i++) {
$recordData["Sequence_$i"] = $this->sequences[$i];
$recordData["Sequence_Time_$i"] = $this->seqTimes[$i];
}
$this->records[] = $recordData;
}
} elseif (($index + 1) == count($hasSingleGuard)) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
@@ -196,30 +219,8 @@ class GuardPatrolEntryDataTable extends Component
$this->records[] = $recordData;
}
}
else if (($index+1) == count($hasSingleGuard))
{
if ($this->guardName)
{
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
'end_time' => $this->endTime,
'lap_time' => $this->labTime,
];
for ($i = 1; $i <= $this->seqNoCnt; $i++) {
$recordData["Sequence_$i"] = $this->sequences[$i];
$recordData["Sequence_Time_$i"] = $this->seqTimes[$i];
}
$this->records[] = $recordData;
}
}
}
else if (($index+1) == count($hasSingleGuard))
{
if ($this->guardName)
{
} elseif (($index + 1) == count($hasSingleGuard)) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
@@ -235,26 +236,36 @@ class GuardPatrolEntryDataTable extends Component
$this->records[] = $recordData;
}
}
}
else // if ($this->seqNo >= 2) {
{
$this->seqTimes[$this->seqNo-1] = $this->seqTime;
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo]->checkPointNames1->name) {//"CANTEEN"
} else { // if ($this->seqNo >= 2) {
$this->seqTimes[$this->seqNo - 1] = $this->seqTime;
if ($checkPointName == $this->startSeqCheckPoints[$this->seqNo]->checkPointNames1->name) {// "CANTEEN"
if ($this->isSequenced) {
$this->sequences[$this->seqNo-1] = $this->minDiff;
$this->sequences[$this->seqNo - 1] = $this->minDiff;
}
}
else {
} else {
$this->isSequenced = false;
}
if ($hasSingleGuard->unique('guard_name_id')->count() == 1)
{
if ($this->seqNo == count($hasSingleGuard))
{
//dd("Has 1 Guard and single patrol round (".($this->seqNoCnt+1).") is present");
if ($this->guardName)
{
if ($hasSingleGuard->unique('guard_name_id')->count() == 1) {
if ($this->seqNo == count($hasSingleGuard)) {
// dd("Has 1 Guard and single patrol round (".($this->seqNoCnt+1).") is present");
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
'end_time' => $this->endTime,
'lap_time' => $this->labTime,
];
for ($i = 1; $i <= $this->seqNoCnt; $i++) {
$recordData["Sequence_$i"] = $this->sequences[$i];
$recordData["Sequence_Time_$i"] = $this->seqTimes[$i];
}
$this->records[] = $recordData;
}
} elseif (($index + 1) == count($hasSingleGuard)) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
@@ -270,30 +281,8 @@ class GuardPatrolEntryDataTable extends Component
$this->records[] = $recordData;
}
}
else if (($index+1) == count($hasSingleGuard))
{
if ($this->guardName)
{
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,
'end_time' => $this->endTime,
'lap_time' => $this->labTime,
];
for ($i = 1; $i <= $this->seqNoCnt; $i++) {
$recordData["Sequence_$i"] = $this->sequences[$i];
$recordData["Sequence_Time_$i"] = $this->seqTimes[$i];
}
$this->records[] = $recordData;
}
}
}
else if (($index+1) == count($hasSingleGuard))
{
if ($this->guardName)
{
} elseif (($index + 1) == count($hasSingleGuard)) {
if ($this->guardName) {
$recordData = [
'guard_name' => $this->guardName,
'start_time' => $this->startTime,

View File

@@ -37,7 +37,8 @@ class SerialValidationData extends Component
'refreshEmptyInvoice' => 'loadEmptyData',
'refreshInvoiceData' => 'loadData',
'refreshMaterialInvoiceData' => 'loadMaterialData',
'openCapacitorModal' => 'showCapacitorInputBox',
'focusCapacitor' => 'focusCapacitorInput'
//'openCapacitorModal' => 'showCapacitorInputBox',
];
public $capacitorInput = '';
@@ -48,6 +49,8 @@ class SerialValidationData extends Component
public $panel_box_serial_number;
public $itemcode;
public string $currentItemCode = '';
public string $currentSerialNumber = '';
@@ -64,6 +67,11 @@ class SerialValidationData extends Component
// // $this->showCapacitorInput = false;
// }
public function focusCapacitorInput($itemCode)
{
$this->dispatch('focus-capacitor-input', itemCode: $itemCode);
}
public function loadCompletedData($invoiceNumber, $plantId, $isSerial)
{

View File

@@ -0,0 +1,115 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\URL;
use Illuminate\Mail\Mailables\Attachment;
use Storage;
class CharacteristicApprovalMail extends Mailable
{
use Queueable, SerializesModels;
public $request;
public $approverName;
public $level;
public $pdfPath;
public $tableData;
/**
* Create a new message instance.
*/
public function __construct($request, $approverName, $level, $pdfPath = null, $characteristics = [])
{
$this->request = $request;
$this->approverName = $approverName;
$this->level = $level;
$this->pdfPath = $pdfPath;
$this->tableData = $characteristics;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Characteristic Approval Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.characteristic-approval',
with: [
'company' => 'CRI Digital Manufacturing Solutions',
'greeting' => 'Dear ' . $this->approverName . ',',
'request' => $this->request,
'tableData' => $this->tableData,
'approveUrl' => $this->approveUrl(),
'holdUrl' => $this->holdUrl(),
'rejectUrl' => $this->rejectUrl(),
'wishes' => 'Thanks & Regards,<br>CRI Digital Manufacturing Solutions',
]
);
}
protected function approveUrl()
{
return URL::signedRoute('characteristic.approve', [
'id' => $this->request->id,
'level' => $this->level
]);
}
protected function holdUrl()
{
return URL::signedRoute('characteristic.hold', [
'id' => $this->request->id,
'level' => $this->level
]);
}
protected function rejectUrl()
{
return URL::signedRoute('characteristic.reject', [
'id' => $this->request->id,
'level' => $this->level
]);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
if (! $this->pdfPath) {
return [];
}
if (! Storage::disk('local')->exists($this->pdfPath)) {
return [];
}
return [
Attachment::fromStorageDisk(
'local',
$this->pdfPath
)->as(basename($this->pdfPath)),
];
}
}

View File

@@ -9,26 +9,27 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class InvoiceDataValidation extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $fillable = [
"plant_id",
"distribution_channel_desc",
"customer_code",
"document_number",
"document_date",
"customer_trade_name",
"customer_location",
"location",
"created_at",
"created_by",
"updated_by",
"updated_at"
'plant_id',
'distribution_channel_desc',
'customer_code',
'document_number',
'document_date',
'customer_trade_name',
'customer_location',
'location',
'remark',
'created_at',
'created_by',
'updated_by',
'updated_at',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

@@ -12,6 +12,7 @@ class ProcessOrder extends Model
protected $fillable = [
'plant_id',
'line_id',
'item_id',
'process_order',
'coil_number',
@@ -19,6 +20,8 @@ class ProcessOrder extends Model
'received_quantity',
'sfg_number',
'machine_name',
'scrap_quantity',
'rework_status',
'created_at',
'created_by',
'updated_by',
@@ -30,7 +33,12 @@ class ProcessOrder extends Model
return $this->belongsTo(Plant::class);
}
public function item()
public function line(): BelongsTo
{
return $this->belongsTo(Line::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class, 'item_id');
}

View File

@@ -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 process_orders
ADD COLUMN line_id BIGINT DEFAULT NULL,
ADD CONSTRAINT process_orders_line_id_fkey
FOREIGN KEY (line_id) REFERENCES lines(id);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,29 @@
<?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
{
DB::statement("
ALTER TABLE process_orders
ADD COLUMN scrap_quantity NUMERIC(10,3)
");
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -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 process_orders
ADD COLUMN rework_status INT NOT NULL DEFAULT (0)
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Action Already Taken</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f6f8;
margin: 0;
padding: 0;
}
.container {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.card {
background: #ffffff;
width: 420px;
padding: 30px;
border-radius: 8px;
text-align: center;
box-shadow: 0 6px 20px rgba(0,0,0,0.1);
}
.icon {
font-size: 50px;
margin-bottom: 10px;
color: #ff9800;
}
h2 {
margin: 10px 0;
color: #333;
}
.status {
margin-top: 15px;
padding: 10px;
border-radius: 6px;
font-weight: bold;
font-size: 16px;
}
.status.Approved {
background-color: #e8f5e9;
color: #2e7d32;
}
.status.Hold {
background-color: #fff3e0;
color: #ef6c00;
}
.status.Rejected {
background-color: #fdecea;
color: #c62828;
}
.note {
margin-top: 15px;
font-size: 14px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="icon">⚠️</div>
<h2>Action Already Taken</h2>
<div class="status {{ $status }}">
Status: {{ $status }}
</div>
<p class="note">
This request has already been processed.<br>
No further action is required.
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<title>Request On Hold</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; margin:0; padding:0;">
<table width="100%" cellpadding="0" cellspacing="0" style="padding: 20px 0;">
<tr>
<td align="center">
<!-- Card container -->
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border: 1px solid #e0e0e0;">
<tr>
<td style="padding: 30px; text-align: center;">
<!-- Header -->
<div style="font-size: 40px;">🟠</div>
<h2 style="color: #FF8800; margin: 10px 0 20px; font-size: 24px;">Request On Hold</h2>
<!-- Message -->
<p style="font-size: 16px; color: #555555; line-height: 1.5;">
Your request has been temporarily put on hold.
</p>
<!-- Remark Textbox -->
<div style="margin-top: 20px; text-align: left;">
<label for="remark" style="font-size: 14px; color: #333;">Remark <span style="color:red;">*</span></label>
<textarea id="remark" style="width:100%; height:100px; padding:10px; margin-top:5px; border:1px solid #ddd; border-radius:5px;"></textarea>
<div id="remarkError" style="color:red; font-size:12px; display:none; margin-top:5px;">
Remark is mandatory.
</div>
</div>
<!-- Buttons -->
<div style="margin-top: 20px;">
{{-- <button onclick="holdRequest()" style="padding: 10px 20px; margin-right: 10px; background-color:#FF8800; color:#fff; border:none; border-radius:5px; cursor:pointer;">
Hold
</button> --}}
<input type="hidden" id="requestId" value="{{ request()->query('id') }}">
<input type="hidden" id="level" value="{{ request()->query('level') }}">
<button onclick="saveRemark()" style="padding: 10px 20px; background-color:#4CAF50; color:#fff; border:none; border-radius:5px; cursor:pointer;">
Save Remark
</button>
</div>
</td>
</tr>
<!-- Footer -->
<tr>
<td style="padding: 15px; text-align: center; font-size: 12px; color: #999999;">
CRI Digital Manufacturing Solutions<br>
&copy; 2026 All Rights Reserved
</td>
</tr>
</table>
</td>
</tr>
</table>
<script>
function saveRemark() {
const remark = document.getElementById("remark").value.trim();
const id = document.getElementById("requestId").value;
const level = document.getElementById("level").value;
fetch('/characteristic/hold-save', {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
id: id,
level: level,
remark: remark
})
})
.then(res => {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.json();
})
.then(data => {
alert('Hold saved successfully!');
window.location.href = "/approval/hold-success";
})
.catch(err => {
console.error(err);
alert('Error saving hold!');
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<title>Request On Hold</title>
</head>
<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; margin:0; padding:0;">
<table width="100%" cellpadding="0" cellspacing="0" style="padding: 20px 0;">
<tr>
<td align="center">
<!-- Card container -->
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border: 1px solid #e0e0e0;">
<tr>
<td style="padding: 30px; text-align: center;">
<!-- Header -->
<div style="font-size: 40px;">🟠</div>
<h2 style="color: #FF8800; margin: 10px 0 20px; font-size: 24px;">Request On Hold</h2>
<!-- Message -->
<p style="font-size: 16px; color: #555555; line-height: 1.5;">
Your request has been temporarily put on hold.
</p>
</td>
</tr>
<!-- Footer -->
<tr>
<td style="padding: 15px; text-align: center; font-size: 12px; color: #999999;">
CRI Digital Manufacturing Solutions<br>
&copy; 2026 All Rights Reserved
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<title>Request On Reject</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; margin:0; padding:0;">
<table width="100%" cellpadding="0" cellspacing="0" style="padding: 20px 0;">
<tr>
<td align="center">
<!-- Card container -->
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border: 1px solid #e0e0e0;">
<tr>
<td style="padding: 30px; text-align: center;">
<!-- Header -->
<div style="font-size: 40px;">🟠</div>
<h2 style="color: #FF0000; margin: 10px 0 20px; font-size: 24px;">Request On Reject</h2>
<!-- Message -->
<p style="font-size: 16px; color: #555555; line-height: 1.5;">
Your request has been temporarily put on reject.
</p>
<!-- Remark Textbox -->
<div style="margin-top: 20px; text-align: left;">
<label for="remark" style="font-size: 14px; color: #333;">Remark <span style="color:red;">*</span></label>
<textarea id="remark" style="width:100%; height:100px; padding:10px; margin-top:5px; border:1px solid #ddd; border-radius:5px;"></textarea>
<div id="remarkError" style="color:red; font-size:12px; display:none; margin-top:5px;">
Remark is mandatory.
</div>
</div>
<!-- Buttons -->
<div style="margin-top: 20px;">
{{-- <button onclick="holdRequest()" style="padding: 10px 20px; margin-right: 10px; background-color:#FF8800; color:#fff; border:none; border-radius:5px; cursor:pointer;">
Hold
</button> --}}
<input type="hidden" id="requestId" value="{{ request()->query('id') }}">
<input type="hidden" id="level" value="{{ request()->query('level') }}">
<button onclick="saveRemark()" style="padding: 10px 20px; background-color:#4CAF50; color:#fff; border:none; border-radius:5px; cursor:pointer;">
Save Remark
</button>
</div>
</td>
</tr>
<!-- Footer -->
<tr>
<td style="padding: 15px; text-align: center; font-size: 12px; color: #999999;">
CRI Digital Manufacturing Solutions<br>
&copy; 2026 All Rights Reserved
</td>
</tr>
</table>
</td>
</tr>
</table>
<script>
function saveRemark() {
const remark = document.getElementById("remark").value.trim();
const id = document.getElementById("requestId").value;
const level = document.getElementById("level").value;
fetch('/characteristic/reject-save', {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
id: id,
level: level,
remark: remark
})
})
.then(res => {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.json();
})
.then(data => {
alert('Reject saved successfully!');
window.location.href = "/approval/reject-success";
})
.catch(err => {
console.error(err);
alert('Error saving reject!');
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title>Rejected</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f6f6f6;
padding: 20px;
}
.card {
background: #ffffff;
padding: 20px;
max-width: 500px;
margin: 50px auto;
border-radius: 6px;
text-align: center;
box-shadow: 0 0 10px rgba(0,0,0,.1);
}
.rejected {
color: red;
font-size: 20px;
font-weight: bold;
}
.footer {
font-size: 12px;
color: #999999;
text-align: center;
margin-top: 20px;
}
a.button {
display: inline-block;
margin-top: 15px;
padding: 10px 20px;
background-color: red;
color: #ffffff;
text-decoration: none;
border-radius: 5px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="card">
<div class="rejected"> Rejected Successfully</div>
<p>The rejection has been recorded.</p>
<p>You may now close this tab.</p>
<!-- Footer -->
<div class="footer">
CRI Digital Manufacturing Solutions<br>
&copy; 2026 All Rights Reserved
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<title>Approval Recorded</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f6f6f6;
padding: 20px;
}
.card {
background: #ffffff;
padding: 20px;
max-width: 500px;
margin: 50px auto;
border-radius: 6px;
text-align: center;
box-shadow: 0 0 10px rgba(0,0,0,.1);
}
.success {
color: green;
font-size: 18px;
font-weight: bold;
}
.footer {
font-size: 12px;
color: #999999;
text-align: center;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="card">
<div class="success"> Approval Successful</div>
<p>Your action has been recorded.</p>
<p>You may now close this tab.</p>
<!-- Footer -->
<div class="footer">
CRI Digital Manufacturing Solutions<br>
&copy; 2026 All Rights Reserved
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{{-- <title>Invoice Data Report</title> --}}
</head>
<body>
<div style="text-align: center; font-weight: bold;">
{{ $company }}
</div>
<br>
<p>{!! $greeting !!}</p>
<table border="1" width="50%" cellpadding="6" cellspacing="0">
<tr>
<th width="30%">Title</th>
<th width="40%">Details</th>
</tr>
<tr>
<td>Requested DateTime</td>
<td>{{ $request->created_at->format('d-m-Y H:i:s') }}</td>
</tr>
<tr>
<td>Plant</td>
<td>{{ $request->plant->name ?? $request->plant_id }}</td>
</tr>
<tr>
<td>Item Code</td>
<td>{{ $request->item->code ?? $request->code }}</td>
</tr>
<tr>
<td>Job Number</td>
<td>{{ $request->aufnr }}</td>
</tr>
</table>
<br>
<table border="1" width="50%" cellpadding="6" cellspacing="0">
<tr>
<th>Characteristics Name</th>
<th>SAP Value</th>
<th>Update Value</th>
<th>WorkFlow ID</th>
</tr>
@forelse ($tableData as $char)
<tr>
{{-- <td>{{ $char['characteristic_name'] ?? '-' }}</td> --}}
<td>{{ strtoupper($char['characteristic_name'] ?? '-') }}</td>
<td>{{ $char['current_value'] ?? '-' }}</td>
<td>{{ $char['update_value'] ?? '-' }}</td>
<td>{{ $char['work_flow_id'] ?? '-' }}</td>
</tr>
@empty
<tr>
<td colspan="4">No Characteristics Found</td>
</tr>
@endforelse
</table>
<br>
<table border="1" width="50%" cellpadding="6" cellspacing="0">
<tr>
<th>Approver Name</th>
<th>Approve Status</th>
</tr>
<tr>
<td>{{ $approverName }}</td>
<td style="text-align: center;">
<a href="{{ $approveUrl }}">Approve</a> |
<a href="{{ $holdUrl }}">Hold</a> |
<a href="{{ $rejectUrl }}">Reject</a>
</td>
</tr>
</table>
<p>{!! $wishes !!}</p>
</div>
</body>
</html>