1
0
forked from poc/pds

111 Commits

Author SHA1 Message Date
dhanabalan
8813567f0b Add missing created_at and updated_at fields to fillable attributes in ProductionQuantity model 2025-09-09 19:03:13 +05:30
dhanabalan
ffa2b1f783 Remove redundant 'asc' parameter from created_at orderBy in QualityValidationResource table query 2025-09-09 18:01:19 +05:30
dhanabalan
e29c16c79a Add sorting by created_at in QualityValidationResource table query 2025-09-09 17:55:53 +05:30
dhanabalan
4d516e955c added created_at and updated_at column in quality validation model 2025-09-09 10:56:22 +05:30
dhanabalan
b0d73dbbc6 Add searchable functionality to line name column in QualityValidationResource table 2025-09-09 10:39:20 +05:30
dhanabalan
37c91afe25 Rename subassembly_code to mot_subassembly_code in get_motor_master method for clarity 2025-09-09 10:23:58 +05:30
dhanabalan
77064399cd Update example header for line column in ConfigurationImporter 2025-09-09 08:41:22 +05:30
dhanabalan
3398a60d1b Update label for laser part validation input in StickerMasterResource 2025-09-06 16:25:52 +05:30
dhanabalan
65aafbeb65 Add required validation to load rate input in StickerMasterResource resource 2025-09-06 16:16:35 +05:30
dhanabalan
ad72d38193 Update plant column references in ConfigurationExporter and ConfigurationImporter to use 'code' instead of 'name' 2025-09-06 11:30:07 +05:30
dhanabalan
cac91722c3 Refactor form schema in StickerMasterResource for improved clarity and organization 2025-09-05 17:27:24 +05:30
dhanabalan
bb2b81d0f2 updated header name for leak current limit in motor testing master 2025-09-05 14:41:27 +05:30
dhanabalan
2150f6098f Added required isi model column for motor testing importer and exporter 2025-09-05 14:32:47 +05:30
dhanabalan
a0a1e87440 Added subassembly code to motor master output in TestingPanelController 2025-09-05 14:03:54 +05:30
dhanabalan
8da3c746b9 Added sub assembly column in import and export 2025-09-05 09:35:06 +05:30
dhanabalan
d05623f920 Added subassembly code in resource page of motor testing master 2025-09-05 09:33:16 +05:30
dhanabalan
e3d29cba81 Added subassembly code in model file in motor testing master 2025-09-05 09:31:06 +05:30
dhanabalan
5cbae18532 Added subassembly code column motor testing master 2025-09-05 09:28:50 +05:30
dhanabalan
7e688683d7 corrected bundle logic for invoice quantity 2025-08-27 08:37:21 +05:30
dhanabalan
ab5a8c0874 Removed unwanted column in bundle data in invoice mail 2025-08-26 19:06:51 +05:30
dhanabalan
19e1f12f5d Refactor invoice report generation to include quantity metrics and enhance email content structure 2025-08-26 18:08:06 +05:30
dhanabalan
e57962f023 Merge branch 'master' of ssh://172.31.31.31:2222/poc/pds 2025-08-26 18:01:43 +05:30
dhanabalan
c5a730b71d Added roles column in view reports and Refactor User table columns for improved sorting and searching functionality 2025-08-26 17:57:16 +05:30
root
967a429595 Merge branch 'master' of https://git.iotsignin.com/poc/pds 2025-08-26 16:35:02 +05:30
root
7f0d138383 WIP: local changes before pull 2025-08-26 16:21:53 +05:30
dhanabalan
d5c0303be4 Merge branch 'master' of ssh://172.31.31.31:2222/poc/pds 2025-08-26 16:10:31 +05:30
dhanabalan
c2f9b77e1f Create motor_testing_masters table with comprehensive fields for motor testing data 2025-08-26 16:09:10 +05:30
3053098cfb Updated file name to work migration functionality in order 2025-08-26 10:32:46 +00:00
a5ded4a20a Added plant column with BIGINT type and its default value as 0 2025-08-26 10:25:05 +00:00
dhanabalan
d419973ab5 Add getRedirectUrl method to resource creation classes for consistent redirection 2025-08-26 15:44:51 +05:30
dhanabalan
86e458037f Removed unnecessary lines in alert_mail_rules table 2025-08-25 20:09:24 +05:30
dhanabalan
e6ba543589 Added roles on UserExporter and UserImporter for consistency and enhanced functionality 2025-08-25 17:00:00 +05:30
dhanabalan
1cee8dc71d Enhance item description field to auto-populate based on selected item ID 2025-08-25 12:17:49 +05:30
dhanabalan
3a009543ea Update MachineResource refine line selection logic 2025-08-25 11:43:09 +05:30
dhanabalan
d4045b7b0f Update validation for line stop code to require a minimum length of 3 characters 2025-08-22 14:47:01 +05:30
dhanabalan
a831f6e787 Testing 2025-08-21 18:07:08 +05:30
dhanabalan
b399141c7e Add UserExporter and UserImporter classes with export/import functionality 2025-08-21 17:07:34 +05:30
dhanabalan
8fd2212ec4 Refactor PermissionSeeder to update permissions for user, plant, and block views 2025-08-21 16:32:32 +05:30
dhanabalan
e6f78c60d5 Fix email address for admin in UserSeeder 2025-08-21 16:07:43 +05:30
dhanabalan
a3a421af88 Added logic in quality validation screen to scan capacitor qr code in part validation 5 2025-08-21 14:06:23 +05:30
dhanabalan
d4eeee7d05 Refactor root redirect logic to simplify default behavior 2025-08-20 19:53:01 +05:30
dhanabalan
bd17af8945 Update root redirect logic to handle specific host 2025-08-20 19:49:28 +05:30
dhanabalan
95f1e09304 Added policy file for eb reading 2025-08-12 17:27:36 +05:30
dhanabalan
fc42e7db6c Add TempLiveReadingResource files from qds branch 2025-08-12 17:21:22 +05:30
dhanabalan
0d3e58e7af Add EbReadingImporter and EbReadingExporter from qds branch 2025-08-12 17:18:02 +05:30
dhanabalan
658d7cb42c Add EbReadingResource related files from qds branch 2025-08-12 17:14:40 +05:30
dhanabalan
679d532b17 Add EbReading.php model file from qds branch 2025-08-12 17:07:54 +05:30
dhanabalan
50ddd51f04 Add eb_readings migration from qds branch 2025-08-12 16:52:39 +05:30
dhanabalan
dc9f929fa2 Update sequences column logic in guard patrol entry table for accurate display 2025-08-07 10:50:00 +05:30
dhanabalan
e58dbfbebd Added sticker reprint updated logic and added blade file 2025-08-07 09:25:25 +05:30
dhanabalan
15af1edb8f Rename identification fields to Aadhar Number and PAN Number for clarity 2025-08-07 09:20:53 +05:30
dhanabalan
705cc8c3a4 Added blank line for improved readability 2025-08-05 12:09:44 +05:30
dhanabalan
6e61f83e3a Validate production order length to be between 7 and 14 digits in both ProductionQuantityImporter and QualityValidationImporter 2025-08-05 12:03:49 +05:30
dhanabalan
197184e2ed Refactor Invoice Validation Logic and Update UI for Serial and Material Invoices
- Improved conditional checks for invoice processing in InvoiceValidationResource on completion (or pending).
- Enhanced notifications for completed scanning processes for both serial and material invoices.
- Updated CreateInvoiceValidation page to pass invoice type to serial and material invoice on completion (or pending).
- Modified InvoiceDataTable to include a new property for serial/material invoice handling.
- Adjusted Blade view to dynamically display the correct title and messages based on invoice type (serial/material).
2025-08-05 12:00:26 +05:30
dhanabalan
d6c77bd6c3 Enhance production order validation to require numeric values with 7 to 14 digits across multiple resources 2025-08-04 19:35:50 +05:30
dhanabalan
68d4240ab0 Add removed all line for production line stop count and production order count 2025-08-04 18:23:51 +05:30
dhanabalan
68ba8fa89d Added Serial Invoice Api for invoice validation 2025-08-04 12:26:49 +05:30
dhanabalan
8c84e48f8e Refactor pallet number generation to include LocatorInvoiceValidation for improved uniqueness 2025-08-02 12:49:26 +05:30
dhanabalan
2e7859656a Disablked the delete at for export page 2025-07-31 18:21:11 +05:30
dhanabalan
4bfbebb254 Added No column for all resource tables page 2025-07-31 18:16:51 +05:30
dhanabalan
1ea00b6901 Added device name column for mfm parameter resource and import and export 2025-07-31 18:14:02 +05:30
dhanabalan
5084aa9c0e Added import and export in device master resource page 2025-07-31 18:05:06 +05:30
dhanabalan
c844a23556 Added device master importer and exporter 2025-07-31 18:04:21 +05:30
dhanabalan
76649651f1 Added line type column in production mail table 2025-07-31 17:32:26 +05:30
dhanabalan
e15c866078 Add column for table line type 2025-07-31 17:26:00 +05:30
dhanabalan
04af1c7c34 modified names of live reading for view page 2025-07-31 17:22:00 +05:30
dhanabalan
8871389fe3 chngaed name of edit live readings page 2025-07-31 17:20:32 +05:30
dhanabalan
ec2fd4d3ca modifiednavigation names for live readings page 2025-07-31 17:18:44 +05:30
dhanabalan
5c1f77796f Arranged text input box for mfm parameter page 2025-07-31 17:09:16 +05:30
dhanabalan
530bca4c4b Added required for trend line analysis page 2025-07-31 17:07:02 +05:30
dhanabalan
ccceff9edc Added required for trend chart analysis chart page 2025-07-31 17:05:22 +05:30
dhanabalan
c53f40d8a0 Added module for trend line analysis chart 2025-07-31 17:02:56 +05:30
dhanabalan
6b67d94476 Added permissions for ems trend line and trend chart page 2025-07-31 16:59:12 +05:30
dhanabalan
b2d2ab7e05 Added trend line analysis page and blade file 2025-07-31 16:57:51 +05:30
dhanabalan
573b02a97a Added trend line chart analysis chart page 2025-07-31 16:57:08 +05:30
dhanabalan
96a5dacf95 Add trend chart analysis page and blade file 2025-07-31 16:56:01 +05:30
dhanabalan
58cdcec6ed Added trend chart analysis chart file 2025-07-31 16:52:58 +05:30
dhanabalan
c67e8fcc59 Added device master logic for mfm parameter controller 2025-07-31 16:43:53 +05:30
dhanabalan
d5588e0b25 modified logic for mfm parameter resource page 2025-07-31 16:43:07 +05:30
dhanabalan
9ff7f88840 modified logic for mfm meter resource file 2025-07-31 16:42:36 +05:30
dhanabalan
03e53e0bb1 Added mfm parameter exporter file 2025-07-31 16:41:13 +05:30
dhanabalan
33b2b6399d Added mfm meter importer and exporter file 2025-07-31 16:38:23 +05:30
dhanabalan
2437bdf85f added column device_master_id for mfm_parameter model file 2025-07-31 16:35:51 +05:30
dhanabalan
f51aea626b Added foreign key device_master_id for mfm_parameter table 2025-07-31 16:33:58 +05:30
dhanabalan
77129cb70b Added mfm meter model file 2025-07-31 16:30:59 +05:30
dhanabalan
bb462a6c45 Added foreign and unique key for mfm_meters table 2025-07-31 16:30:04 +05:30
dhanabalan
9a2a6bdd9b Add device master policy file 2025-07-31 16:21:14 +05:30
dhanabalan
0a414a6804 Added device master resource file 2025-07-31 16:18:25 +05:30
dhanabalan
f4bb7a7a78 Added device master model file 2025-07-31 16:17:35 +05:30
dhanabalan
8aad6cf1e6 Add device master migration file 2025-07-31 16:14:47 +05:30
dhanabalan
3b18411141 Added logic for invoice report for daily report 2025-07-31 15:00:03 +05:30
dhanabalan
162eaa0c9c added unwanted line 2025-07-31 13:59:14 +05:30
dhanabalan
d5f55fbf98 added commented line for git checking 2025-07-31 13:58:18 +05:30
dhanabalan
cf5cfac555 Removed unwanted lines for production send report 2025-07-31 13:53:41 +05:30
dhanabalan
7bf2e8182b Updated QR validation functionality to allow with and without item code 2025-07-31 12:26:16 +05:30
dhanabalan
216b62f8bf Added notification for missing invoice type in filter options 2025-07-31 12:22:23 +05:30
dhanabalan
cad7f19ab5 Added invoice_type radio filter and scanned_status select filter to Invoice Validation 2025-07-31 08:53:40 +05:30
dhanabalan
ca9695c922 Added operator_id and scanned_status filter fields to Invoice validaitons resources and Alignment changed in filter option for Production Quantity / Quality Validation 2025-07-30 15:18:26 +05:30
dhanabalan
d1f9a3176f Added operator_id field to ProductionQuantity and QualityValidation in report filter 2025-07-30 12:32:17 +05:30
dhanabalan
0b9d0f9995 modified size of the qr code of scan pallet 2025-07-29 18:02:42 +05:30
dhanabalan
897aa77217 Modified qr code size for pallet 2025-07-29 15:52:44 +05:30
dhanabalan
000533ef7c Added scan pallet print pdf 2025-07-29 15:36:29 +05:30
dhanabalan
a78cb75bdd Added reprint for scan pallet 2025-07-29 13:56:30 +05:30
dhanabalan
ab769d2287 Added 2 copies of pallet number print for scan pallet 2025-07-29 13:26:13 +05:30
dhanabalan
0bde54cf1a removed logic against the production order 2025-07-29 11:47:26 +05:30
dhanabalan
48942307e1 modified sticker reprint controller logic 2025-07-29 11:46:44 +05:30
dhanabalan
8c5f2b5b39 commented production order text input box as mandatory 2025-07-29 11:35:13 +05:30
dhanabalan
b1df9f8b87 Added production sticker reprint page 2025-07-29 11:33:28 +05:30
dhanabalan
c0d13db2f3 Added created_at, updated_at, email while data response with roles 2025-07-28 18:33:15 +05:30
dhanabalan
b4bf170c89 Added kiosk for scan pallet 2025-07-28 18:10:54 +05:30
dhanabalan
b0d2132e25 Refactor QR code PDF generation to improve layout and add automatic print functionality 2025-07-28 18:01:50 +05:30
115 changed files with 8163 additions and 1512 deletions

View File

@@ -30,258 +30,17 @@ class SendInvoiceReport extends Command
* Execute the console command.
*/
// public function handle()
// {
// $schedule = $this->argument('schedule_type');
// $plantid = $this->argument('plant');
// $mailRules = \App\Models\AlertMailRule::where('module', 'InvoiceValidation')->get()->groupBy('rule_name');
// $startDate = now()->setTime(8, 0, 0);
// $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
// $plants = InvoiceValidation::select('plant_id')->distinct()->pluck('plant_id');
// $serialTableData = [];
// $materialTableData = [];
// $bundleTableData = [];
// $noSerial = 1;
// $noMaterial = 1;
// $noBundle = 1;
// foreach ($plants as $plantId) {
// $plant = Plant::find($plantId);
// $plantName = $plant ? $plant->name : $plantId;
// //..Serial Invoice
// $totalSerialCount = InvoiceValidation::where('plant_id', $plantId)
// ->whereNull('quantity')
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedSerialCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->whereNull('quantity')
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END)"
// )
// ->count();
// $serialTableData[] = [
// 'no' => $noSerial++,
// 'plant' => $plantName,
// 'totalInvoice' => $totalSerialCount,
// 'scannedInvoice' => $scannedSerialCount,
// ];
// //..Individual Invoice
// $TotalMatCount = InvoiceValidation::where('plant_id', $plantId)
// ->where('quantity', 1)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedMatCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->where('quantity', 1)
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)"
// )
// ->count();
// $materialTableData[] = [
// 'no' => $noMaterial++,
// 'plant' => $plantName,
// 'totalInvoice' => $TotalMatCount,
// 'scannedInvoice' => $scannedMatCount,
// ];
// //..BUndle Invoice
// $totalBundleCount = InvoiceValidation::where('plant_id', $plantId)
// ->where('quantity', '>', 1)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedBundleCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->where('quantity', '>', 1)
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)"
// )
// ->count();
// $bundleTableData[] = [
// 'no' => $noBundle++,
// 'plant' => $plantName,
// 'totalInvoice' => $totalBundleCount,
// 'scannedInvoice' => $scannedBundleCount,
// ];
// }
// // Send to SerialInvoiceMail recipients
// if ($mailRules->has('SerialInvoiceMail')) {
// $emails = $mailRules['SerialInvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test($serialTableData, [], []));
// }
// }
// // Send to MaterialInvoiceMail recipients (material + bundle table)
// if ($mailRules->has('MaterialInvoiceMail')) {
// $emails = $mailRules['MaterialInvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test([], $materialTableData, $bundleTableData));
// }
// }
// // Send to InvoiceMail recipients (all three tables)
// if ($mailRules->has('InvoiceMail')) {
// $emails = $mailRules['InvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test($serialTableData, $materialTableData, $bundleTableData));
// }
// }
// //$this->info(json_encode($materialTableData));
// }
// public function handle()
// {
// $schedule = $this->argument('schedule_type');
// $plantId = $this->argument('plant');
// $mailRules = \App\Models\AlertMailRule::where('module', 'InvoiceValidation')->get()->groupBy('rule_name');
// $startDate = now()->setTime(8, 0, 0);
// $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
// $serialTableData = [];
// $materialTableData = [];
// $bundleTableData = [];
// $plant = Plant::find($plantId);
// $plantName = $plant ? $plant->name : $plantId;
// // Serial Invoice
// $totalSerialCount = InvoiceValidation::where('plant_id', $plantId)
// ->whereNull('quantity')
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedSerialCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->whereNull('quantity')
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END)"
// )
// ->count();
// $serialTableData[] = [
// 'no' => 1,
// 'plant' => $plantName,
// 'totalInvoice' => $totalSerialCount,
// 'scannedInvoice' => $scannedSerialCount,
// ];
// // Individual Material Invoice
// $TotalMatCount = InvoiceValidation::where('plant_id', $plantId)
// ->where('quantity', 1)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedMatCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->where('quantity', 1)
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)"
// )
// ->count();
// $materialTableData[] = [
// 'no' => 1,
// 'plant' => $plantName,
// 'totalInvoice' => $TotalMatCount,
// 'scannedInvoice' => $scannedMatCount,
// ];
// // Bundle Invoice
// $totalBundleCount = InvoiceValidation::where('plant_id', $plantId)
// ->where('quantity', '>', 1)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->distinct('invoice_number')
// ->count('invoice_number');
// $scannedBundleCount = InvoiceValidation::select('invoice_number')
// ->where('plant_id', $plantId)
// ->where('quantity', '>', 1)
// ->whereBetween('updated_at', [$startDate, $endDate])
// ->groupBy('invoice_number')
// ->havingRaw(
// "COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)"
// )
// ->count();
// $bundleTableData[] = [
// 'no' => 1,
// 'plant' => $plantName,
// 'totalInvoice' => $totalBundleCount,
// 'scannedInvoice' => $scannedBundleCount,
// ];
// // Send to SerialInvoiceMail recipients
// if ($mailRules->has('SerialInvoiceMail')) {
// $emails = $mailRules['SerialInvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test($serialTableData, [], []));
// }
// }
// // Send to MaterialInvoiceMail recipients (material + bundle table)
// if ($mailRules->has('MaterialInvoiceMail')) {
// $emails = $mailRules['MaterialInvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test([], $materialTableData, $bundleTableData));
// }
// }
// // Send to InvoiceMail recipients (all three tables)
// if ($mailRules->has('InvoiceMail')) {
// $emails = $mailRules['InvoiceMail']->pluck('email')->unique()->toArray();
// foreach ($emails as $email) {
// Mail::to($email)->send(new test($serialTableData, $materialTableData, $bundleTableData));
// }
// }
// // $this->table(
// // ['No', 'Plant', 'Total Invoice', 'Scanned Invoice'],
// // $serialTableData
// // );
// }
public function handle()
{
$schedule = $this->argument('schedule_type');
//$scheduleType = $this->argument('scheduleType');
$plantIdArg = (int) $this->argument('plant'); // can be 0 for all plants
$mailRules = \App\Models\AlertMailRule::where('module', 'InvoiceValidation')->get()->groupBy('rule_name');
$startDate = now()->setTime(8, 0, 0);
$endDate = now()->copy()->addDay()->setTime(8, 0, 0);
// $startDate = now()->setTime(8, 0, 0);
// $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
$serialTableData = [];
$materialTableData = [];
@@ -293,7 +52,18 @@ class SendInvoiceReport extends Command
: [$plantIdArg];
$no = 1;
foreach ($plantIds as $plantId) {
if (strtolower($schedule) == 'daily')
{
$startDate = now()->subDay()->setTime(8, 0, 0);
$endDate = now()->setTime(8, 0, 0);
}
else
{
$startDate = now()->setTime(8, 0, 0);
$endDate = now()->copy()->addDay()->setTime(8, 0, 0);
}
foreach ($plantIds as $plantId)
{
$plant = Plant::find($plantId);
$plantName = $plant ? $plant->name : $plantId;
@@ -312,11 +82,27 @@ class SendInvoiceReport extends Command
->havingRaw("COUNT(*) = SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END)")
->count();
$serialInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('quantity', null)
->whereBetween('created_at', [$startDate, $endDate])
->count();
$scannedInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('scanned_status', 'Scanned')
->where(function($query) {
$query->whereNull('quantity')
->orWhere('quantity', 0);
})
->whereBetween('updated_at', [$startDate, $endDate])
->count();
$serialTableData[] = [
'no' => $no,
'plant' => $plantName,
'totalInvoice' => $totalSerialCount,
'scannedInvoice' => $scannedSerialCount,
'totalInvoiceQuan' => $serialInvoiceQuan,
'scannedInvoiceQuan' => $scannedInvoiceQuan,
];
// Material Invoice
@@ -334,11 +120,25 @@ class SendInvoiceReport extends Command
->havingRaw("COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)")
->count();
$totalMatInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('quantity', 1)
->whereBetween('created_at', [$startDate, $endDate])
->count();
$scannedMatInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('quantity', 1)
->whereNotNull('serial_number')
->where('serial_number','!=', '')
->whereBetween('updated_at', [$startDate, $endDate])
->count();
$materialTableData[] = [
'no' => $no,
'plant' => $plantName,
'totalInvoice' => $totalMatCount,
'scannedInvoice' => $scannedMatCount,
'totalInvoiceQuan' => $totalMatInvoiceQuan,
'scannedInvoiceQuan' => $scannedMatInvoiceQuan,
];
// Bundle Invoice
@@ -356,29 +156,49 @@ class SendInvoiceReport extends Command
->havingRaw("COUNT(*) = SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END)")
->count();
$totalBundleInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('quantity', '>', 1)
->whereBetween('created_at', [$startDate, $endDate])
->count();
$scannedBundleInvoiceQuan = InvoiceValidation::where('plant_id', $plantId)
->where('quantity', '>', 1)
->whereNotNull('serial_number')
->where('serial_number','!=', '')
->whereBetween('updated_at', [$startDate, $endDate])
->count();
$bundleTableData[] = [
'no' => $no,
'plant' => $plantName,
'totalInvoice' => $totalBundleCount,
'scannedInvoice' => $scannedBundleCount,
'totalInvoiceQuan' => $totalBundleInvoiceQuan,
'scannedInvoiceQuan' => $scannedBundleInvoiceQuan,
];
$no++;
}
$mail = new test($serialTableData, $materialTableData, $bundleTableData, $schedule);
$contentVars = $mail->content()->with;
$this->info($contentVars['greeting'] ?? 'Invoice Report');
// Send to SerialInvoiceMail recipients
if ($mailRules->has('SerialInvoiceMail')) {
$emails = $mailRules['SerialInvoiceMail']->pluck('email')->unique()->toArray();
foreach ($emails as $email) {
Mail::to($email)->send(new test($serialTableData, [], []));
Mail::to($email)->send(new test($serialTableData, [], [], $schedule));
}
}
// Send to MaterialInvoiceMail recipients (material + bundle table)
if ($mailRules->has('MaterialInvoiceMail')) {
$emails = $mailRules['MaterialInvoiceMail']->pluck('email')->unique()->toArray();
foreach ($emails as $email) {
Mail::to($email)->send(new test([], $materialTableData, $bundleTableData));
Mail::to($email)->send(new test([], $materialTableData, $bundleTableData, $schedule));
}
}
@@ -386,19 +206,21 @@ class SendInvoiceReport extends Command
if ($mailRules->has('InvoiceMail')) {
$emails = $mailRules['InvoiceMail']->pluck('email')->unique()->toArray();
foreach ($emails as $email) {
Mail::to($email)->send(new test($serialTableData, $materialTableData, $bundleTableData));
Mail::to($email)->send(new test($serialTableData, $materialTableData, $bundleTableData, $schedule));
}
}
// Show preview in console
$this->info('--- Serial Invoice Table ---');
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice'], $serialTableData);
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice','TotalInvoice Quantity', 'ScannedInvoice Quantity'], $serialTableData);
$this->info('--- Material Invoice Table ---');
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice'], $materialTableData);
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice','TotalInvoice Quantity', 'ScannedInvoice Quantity'], $materialTableData);
$this->info('--- Bundle Invoice Table ---');
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice'], $bundleTableData);
$this->table(['#', 'Plant', 'Total Invoice', 'Scanned Invoice','TotalInvoice Quantity', 'ScannedInvoice Quantity'], $bundleTableData);
$this->info($contentVars['wishes'] ?? '');
}

View File

@@ -33,77 +33,6 @@ class SendProductionReport extends Command
* Execute the console command.
*/
// public function handle()
// {
// $scheduleType = $this->argument('schedule_type');
// $plantId = $this->argument('plant');
// $mailRules = \App\Models\AlertMailRule::where('module', 'ProductionQuantities')
// ->where('rule_name', 'ProductionMail')
// ->where('plant', $plantId)
// ->where('schedule_type', $scheduleType)
// ->get();
// $emails = $mailRules->pluck('email')->unique()->toArray();
// $plant = Plant::find($plantId);
// if (!$plant) {
// $this->error("Invalid plant ID: $plantId");
// return;
// }
// $lines = Line::where('plant_id', $plantId)->get();
// $startDate = now()->setTime(8, 0, 0);
// $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
// $PlanstartDate = now()->setTime(8, 0, 0);
// $planendDate = now()->copy()->addDay()->setTime(7, 59, 00);
// $tableData = [];
// $no = 1;
// foreach ($lines as $line) {
// $lineId = $line->id;
// $lineName = $line->name;
// $targetQuantity = ProductionPlan::where('plant_id', $plantId)
// ->where('line_id', $lineId)
// ->whereBetween('created_at', [$PlanstartDate, $planendDate])
// ->sum('plan_quantity');
// $productionQuantity = ProductionQuantity::where('plant_id', $plantId)
// ->where('line_id', $lineId)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->count();
// $tableData[] = [
// 'no' => $no++,
// 'plant' => $plant->name,
// 'line' => $lineName,
// 'targetQuantity' => $targetQuantity,
// 'productionQuantity' => $productionQuantity,
// ];
// }
// // $this->table(
// // ['No', 'Plant', 'Line', 'Target Quantity', 'Production Quantity'],
// // $tableData
// // );
// if (!empty($emails)) {
// foreach ($emails as $email) {
// Mail::to($email)->send(new ProductionMail($tableData));
// }
// } else {
// $this->info('No recipients found for ProductionMailAlert.');
// }
// $this->info("Production report sent to " . count($emails) . " recipient(s).");
// }
public function handle()
{
$scheduleType = $this->argument('schedule_type');
@@ -146,53 +75,7 @@ class SendProductionReport extends Command
$tableData = [];
$no = 1;
// foreach ($plants as $plant) {
// $lines = Line::where('plant_id', $plant->id)->get();
// foreach ($lines as $line) {
// $targetQuantity = ProductionPlan::where('plant_id', $plant->id)
// ->where('line_id', $line->id)
// ->whereBetween('created_at', [$PlanstartDate, $planendDate])
// ->sum('plan_quantity');
// $productionQuantity = ProductionQuantity::where('plant_id', $plant->id)
// ->where('line_id', $line->id)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->count();
// $tableData[] = [
// 'no' => $no++,
// 'plant' => $plant->name,
// 'line' => $line->name,
// 'targetQuantity' => $targetQuantity,
// 'productionQuantity' => $productionQuantity,
// ];
// }
// }
// $fgTableData = []; // store FG Line related data
// foreach ($plants as $plant) {
// // ✅ Only get FG Lines
// $fgLines = Line::where('plant_id', $plant->id)
// ->where('type', 'FG Line')
// ->get();
// foreach ($fgLines as $line) {
// $validationCount = \App\Models\QualityValidation::where('plant_id', $plant->id)
// ->where('line_id', $line->id)
// ->whereBetween('created_at', [$startDate, $endDate])
// ->count();
// $fgTableData[] = [
// 'no' => $no++,
// 'plant' => $plant->name,
// 'line' => $line->name,
// 'targetQuantity' => $targetQuantity,
// 'productionQuantity' => $validationCount,
// ];
// }
// }
//.
foreach ($plants as $plant)
{
@@ -204,7 +87,7 @@ class SendProductionReport extends Command
->whereBetween('created_at', [$PlanstartDate, $planendDate])
->sum('plan_quantity');
if (strtolower($line->type) === 'fg line') {
if (strtolower($line->type) == 'fg line') {
$productionQuantity = \App\Models\QualityValidation::where('plant_id', $plant->id)
->where('line_id', $line->id)
->whereBetween('created_at', [$startDate, $endDate])
@@ -220,6 +103,7 @@ class SendProductionReport extends Command
'no' => $no++,
'plant' => $plant->name,
'line' => $line->name,
'type' => $line->type,
'targetQuantity' => $targetQuantity,
'productionQuantity' => $productionQuantity,
];
@@ -228,20 +112,38 @@ class SendProductionReport extends Command
///$this->table(['No', 'Plant', 'Line', 'Target Quantity', 'Production Quantity'], $fgTableData);
//$this->table(['No', 'Plant', 'Line', 'Target Quantity', 'Production Quantity'], $fgTableData);
$this->table(['No', 'Plant', 'Line', 'Target Quantity', 'Production Quantity'], $tableData);
// $this->table(['No', 'Plant', 'Line', 'Target Quantity', 'Production Quantity'], $tableData);
// if (!empty($emails)) {
// foreach ($emails as $email) {
// Mail::to($email)->send(new ProductionMail($tableData));
// }
// } else {
// $this->info('No recipients found for ProductionMailAlert.');
// }
// $this->info("Production report sent to " . count($emails) . " recipient(s).");
// Preview in console
$mail = new ProductionMail($scheduleType, $tableData);
$contentVars = $mail->content()->with;
$this->info($contentVars['greeting'] ?? 'Production Report');
$this->table(
['No', 'Plant', 'Line', 'Type', 'Target Quantity', 'Production Quantity'],
$tableData
);
$this->info($contentVars['wishes'] ?? '');
// Send mails
if (!empty($emails)) {
foreach ($emails as $email) {
Mail::to($email)->send(new ProductionMail($tableData));
Mail::to($email)->send(new ProductionMail($scheduleType, $tableData));
}
$this->info("Production report sent to " . count($emails) . " recipient(s).");
} else {
$this->info('No recipients found for ProductionMailAlert.');
$this->warn('No recipients found for ProductionMailAlert.');
}
$this->info("Production report sent to " . count($emails) . " recipient(s).");
}
}

View File

@@ -22,7 +22,7 @@ class ConfigurationExporter extends Exporter
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
ExportColumn::make('plant.code')
->label('PLANT'),
ExportColumn::make('line.name')
->label('LINE'),

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Filament\Exports;
use App\Models\DeviceMaster;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class DeviceMasterExporter extends Exporter
{
protected static ?string $model = DeviceMaster::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.name')
->label('PLANT'),
ExportColumn::make('name')
->label('DEVICE NAME'),
ExportColumn::make('mac_address')
->label('MAC ADDRESS'),
ExportColumn::make('ip_address')
->label('IP ADDRESS'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your device 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,140 @@
<?php
namespace App\Filament\Exports;
use App\Models\EbReading;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class EbReadingExporter extends Exporter
{
protected static ?string $model = EbReading::class;
static $rowNumber = 0;
public static function getColumns(): array
{
return [
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('lcd_segment_check')
->label('LCD SEGMENT CHECK'),
ExportColumn::make('meter_serial_no')
->label('METER SERIAL NO'),
ExportColumn::make('eb_date_time')
->label('EB DATE TIME'),
ExportColumn::make('ph_seq_of_volt')
->label('PH SEQ OF VOLT'),
ExportColumn::make('ph_assoc_conn_check')
->label('PH ASSOC CONN CHECK'),
ExportColumn::make('instantaneous_ph_volt')
->label('INSTANTANEOUS PH VOLT'),
ExportColumn::make('instantaneous_curr')
->label('INSTANTANEOUS CURR'),
ExportColumn::make('instantaneous_freq')
->label('INSTANTANEOUS FREQ'),
ExportColumn::make('instantaneous_kw_with_sign')
->label('INSTANTANEOUS KW WITH SIGN'),
ExportColumn::make('instantaneous_kva')
->label('INSTANTANEOUS KVA'),
ExportColumn::make('instantaneous_kv_ar')
->label('INSTANTANEOUS KV AR'),
ExportColumn::make('instantaneous_pf_with_sign')
->label('INSTANTANEOUS PF WITH SIGN'),
ExportColumn::make('rd_with_elapsed_time_kva')
->label('RD WITH ELAPSED TIME KVA'),
ExportColumn::make('cum_active_import_energy')
->label('CUM ACTIVE IMPORT ENERGY'),
ExportColumn::make('tod1_active_energy_6_9')
->label('TOD1 ACTIVE ENERGY 6-9'),
ExportColumn::make('tod2_active_energy_18_21')
->label('TOD2 ACTIVE ENERGY 18-21'),
ExportColumn::make('tod3_active_energy_21_22')
->label('TOD3 ACTIVE ENERGY 21-22'),
ExportColumn::make('tod4_active_energy_5_6_9_18')
->label('TOD4 ACTIVE ENERGY 5-6-9-18'),
ExportColumn::make('tod5_active_energy_22_5')
->label('TOD5 ACTIVE ENERGY 22-5'),
ExportColumn::make('cum_reac_lag_energy')
->label('CUM REAC LAG ENERGY'),
ExportColumn::make('cum_reac_lead_energy')
->label('CUM REAC LEAD ENERGY'),
ExportColumn::make('cum_appar_energy')
->label('CUM APPAR ENERGY'),
ExportColumn::make('tod1_appar_energy_6_9')
->label('TOD1 APPAR ENERGY 6-9'),
ExportColumn::make('tod2_appar_energy_18_21')
->label('TOD2 APPAR ENERGY 18-21'),
ExportColumn::make('tod3_appar_energy_21_22')
->label('TOD3 APPAR ENERGY 21-22'),
ExportColumn::make('tod4_appar_energy_5_6_9_18')
->label('TOD4 APPAR ENERGY 5-6-9-18'),
ExportColumn::make('tod5_appar_energy_22_5')
->label('TOD5 APPAR ENERGY 22-5'),
ExportColumn::make('avg_pow_factor')
->label('AVG POW FACTOR'),
ExportColumn::make('avg_freq_15min_last_ip')
->label('AVG FREQ 15MIN LAST IP'),
ExportColumn::make('net_kv_arh_high')
->label('NET KV ARH HIGH'),
ExportColumn::make('net_kv_arh_low')
->label('NET KV ARH LOW'),
ExportColumn::make('cum_md_kva')
->label('CUM MD KVA'),
ExportColumn::make('present_md_kva')
->label('PRESENT MD KVA'),
ExportColumn::make('present_md_kva_date_time')
->label('PRESENT MD KVA DATE TIME'),
ExportColumn::make('tod1_md_kva_6_9')
->label('TOD1 MD KVA 6-9'),
ExportColumn::make('tod2_md_kva_18_21')
->label('TOD2 MD KVA 18-21'),
ExportColumn::make('tod3_md_kva_21_22')
->label('TOD3 MD KVA 21-22'),
ExportColumn::make('tod4_md_kva_5_6_9_18')
->label('TOD4 MD KVA 5-6-9-18'),
ExportColumn::make('tod5_md_kva_22_5')
->label('TOD5 MD KVA 22-5'),
ExportColumn::make('total_pow_off_hours')
->label('TOTAL POW OFF HOURS'),
ExportColumn::make('programming_count')
->label('PROGRAMMING COUNT'),
ExportColumn::make('last_occ_res_event_type')
->label('LAST OCC RES EVENT TYPE'),
ExportColumn::make('last_occ_res_event_date_time')
->label('LAST OCC RES EVENT DATE TIME'),
ExportColumn::make('tamper_count')
->label('TAMPER COUNT'),
ExportColumn::make('reset_count')
->label('RESET COUNT'),
ExportColumn::make('last_md_reset_date_time')
->label('LAST MD RESET DATE TIME'),
ExportColumn::make('electrician_sign')
->label('ELECTRICIAN SIGN'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->enabledByDefault(false),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your eb reading 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,54 @@
<?php
namespace App\Filament\Exports;
use App\Models\MfmMeter;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class MfmMeterExporter extends Exporter
{
protected static ?string $model = MfmMeter::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.name')
->label('PLANT'),
ExportColumn::make('device.name')
->label('DEVICE NAME'),
ExportColumn::make('sequence')
->label('SEQUENCE'),
ExportColumn::make('name')
->label('NAME'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
ExportColumn::make('created_by')
->label('CREATED BY'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your mfm meter 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

@@ -13,20 +13,40 @@ class MfmParameterExporter extends Exporter
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('id')
->label('ID'),
ExportColumn::make('plant.name'),
ExportColumn::make('name'),
ExportColumn::make('register_id'),
ExportColumn::make('identifier'),
ExportColumn::make('byte_to_convert'),
ExportColumn::make('type_to_convert'),
ExportColumn::make('decimal_to_display'),
ExportColumn::make('created_at'),
ExportColumn::make('updated_at'),
ExportColumn::make('deleted_at'),
ExportColumn::make('mfmMeter.name'),
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('deviceName.name')
->label('Device Name'),
ExportColumn::make('name')
->label('NAME'),
ExportColumn::make('mfmMeter.name')
->label('MFM METER'),
ExportColumn::make('register_id')
->label('REGISTER ID'),
ExportColumn::make('identifier')
->label('IDENTIFIER'),
ExportColumn::make('byte_to_convert')
->label('BYTE TO CONVERT'),
ExportColumn::make('type_to_convert')
->label('TYPE TO CONVERT'),
ExportColumn::make('decimal_to_display')
->label('DECIMAL TO DISPLAY'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
];
}

View File

@@ -28,6 +28,8 @@ class MotorTestingMasterExporter extends Exporter
->label('CATEGORY'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('subassembly_code')
->label('SUBASSEMBLY CODE'),
ExportColumn::make('item.description')
->label('DESCRIPTION'),
ExportColumn::make('isi_model')
@@ -69,9 +71,9 @@ class MotorTestingMasterExporter extends Exporter
ExportColumn::make('res_br_ul')
->label('RESISTANCE BR UL'),
ExportColumn::make('lock_volt_limit')
->label('LOCK VOLT Limit'),
->label('LOCK VOLT LIMIT'),
ExportColumn::make('leak_cur_limit')
->label('Leak CURRENT Limit'),
->label('LEAK CURRENT LIMIT'),
ExportColumn::make('lock_cur_ll')
->label('LOCK CURRENT LL'),
ExportColumn::make('lock_cur_ul')

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Filament\Exports;
use App\Models\User;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class UserExporter extends Exporter
{
protected static ?string $model = User::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('name')
->label('NAME'),
ExportColumn::make('email')
->label('E-MAIL'),
ExportColumn::make('password')
->label('PASSWORD'),
ExportColumn::make('roles')
->label('ROLES')
->state(function ($record) {
// Assuming Spatie\Permission: roles() relationship
return $record->roles->pluck('name')->join(', ');
}),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your user 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

@@ -41,15 +41,15 @@ class ConfigurationImporter extends Importer
ImportColumn::make('line')
->requiredMapping()
->relationship(resolveUsing: 'name')
->exampleHeader('Plant')
->exampleHeader('Line')
->example(['4 inch pump line'])
->label('Line')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->relationship(resolveUsing: 'name')
->relationship(resolveUsing: 'code')
->exampleHeader('Plant')
->example(['Ransar Industries-I'])
->example(['1000'])
->label('Plant')
->rules(['required']),
];

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Filament\Imports;
use App\Models\DeviceMaster;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class DeviceMasterImporter extends Importer
{
protected static ?string $model = DeviceMaster::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('name')
->requiredMapping()
->exampleHeader('Device Name')
->label('Device Name')
->rules(['required']),
ImportColumn::make('mac_address')
->requiredMapping()
->exampleHeader('MAC Address')
->example('00:1A:2B:3C:4D:5E')
->label('MAC Address')
->rules(['required', 'mac_address']),
ImportColumn::make('ip_address')
->requiredMapping()
->exampleHeader('IP Address')
->label('IP Address')
->rules(['required', 'ip']),
ImportColumn::make('created_by')
->requiredMapping()
->exampleHeader('Created By')
->example('Admin')
->label('Created By')
->rules(['required']),
];
}
public function resolveRecord(): ?DeviceMaster
{
// return DeviceMaster::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new DeviceMaster();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your device master 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

@@ -0,0 +1,243 @@
<?php
namespace App\Filament\Imports;
use App\Models\EbReading;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class EbReadingImporter extends Importer
{
protected static ?string $model = EbReading::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('lcd_segment_check')
->label('LCD Segment Check')
->example('Ok')
->exampleHeader('LCD Segment Check'),
ImportColumn::make('meter_serial_no')
->label('Meter Serial No')
->example('572880')
->exampleHeader('Meter Serial No'),
ImportColumn::make('eb_date_time')
->label('EB Date Time')
->example('2025-08-05 08:32:58')
->exampleHeader('EB Date Time')
->requiredMapping()
->rules(['required', 'datetime']),
ImportColumn::make('ph_seq_of_volt')
->label('Phase Sequence of Volt')
->example('RYB')
->exampleHeader('Phase Sequence of Volt'),
ImportColumn::make('ph_assoc_conn_check')
->example('GOOD')
->exampleHeader('Phase Associated Connection Check')
->label('Phase Associated Connection Check'),
ImportColumn::make('instantaneous_ph_volt')
->exampleHeader('Instantaneous Phase Volt')
->example('64.35,64.91,64.93')
->label('Instantaneous Phase Volt'),
ImportColumn::make('instantaneous_curr')
->exampleHeader('Instantaneous Current')
->example('1.02,1.00,0.94')
->label('Instantaneous Current'),
ImportColumn::make('instantaneous_freq')
->exampleHeader('Instantaneous Frequency')
->example('50.07')
->label('Instantaneous Frequency'),
ImportColumn::make('instantaneous_kw_with_sign')
->exampleHeader('Instantaneous KW with Sign')
->example('0.176')
->label('Instantaneous KW with Sign'),
ImportColumn::make('instantaneous_kva')
->exampleHeader('Instantaneous KVA')
->example('0.176')
->label('Instantaneous KVA'),
ImportColumn::make('instantaneous_kv_ar')
->exampleHeader('Instantaneous KV AR')
->example('0.02')
->label('Instantaneous KV AR'),
ImportColumn::make('instantaneous_pf_with_sign')
->exampleHeader('Instantaneous PF with Sign')
->example('0.99')
->label('Instantaneous PF with Sign'),
ImportColumn::make('rd_with_elapsed_time_kva')
->exampleHeader('RD with Elapsed Time KVA')
->example('0.047')
->label('RD with Elapsed Time KVA'),
ImportColumn::make('cum_active_import_energy')
->exampleHeader('Cumulative Active Import Energy')
->example('13246.46')
->label('Cumulative Active Import Energy'),
ImportColumn::make('tod1_active_energy_6_9')
->exampleHeader('TOD1 Active Energy 6-9')
->example('1367.75')
->label('TOD1 Active Energy 6-9'),
ImportColumn::make('tod2_active_energy_18_21')
->exampleHeader('TOD2 Active Energy 18-21')
->example('1759.08')
->label('TOD2 Active Energy 18-21'),
ImportColumn::make('tod3_active_energy_21_22')
->exampleHeader('TOD3 Active Energy 21-22')
->example('457.67')
->label('TOD3 Active Energy 21-22'),
ImportColumn::make('tod4_active_energy_5_6_9_18')
->exampleHeader('TOD4 Active Energy 5-6-9-18')
->example('6253.85')
->label('TOD4 Active Energy 5-6-9-18'),
ImportColumn::make('tod5_active_energy_22_5')
->exampleHeader('TOD5 Active Energy 22-5')
->example('3408.11')
->label('TOD5 Active Energy 22-5'),
ImportColumn::make('cum_reac_lag_energy')
->exampleHeader('Cumulative Reactive Lag Energy')
->example('685.11')
->label('Cumulative Reactive Lag Energy'),
ImportColumn::make('cum_reac_lead_energy')
->exampleHeader('Cumulative Reactive Lead Energy')
->example('426.1')
->label('Cumulative Reactive Lead Energy'),
ImportColumn::make('cum_appar_energy')
->exampleHeader('Cumulative Apparent Energy')
->example('13306.57')
->label('Cumulative Apparent Energy'),
ImportColumn::make('tod1_appar_energy_6_9')
->exampleHeader('TOD1 Apparent Energy 6-9')
->example('1374.63')
->label('TOD1 Apparent Energy 6-9'),
ImportColumn::make('tod2_appar_energy_18_21')
->exampleHeader('TOD2 Apparent Energy 18-21')
->example('1766.61')
->label('TOD2 Apparent Energy 18-21'),
ImportColumn::make('tod3_appar_energy_21_22')
->exampleHeader('TOD3 Apparent Energy 21-22')
->example('459.47')
->label('TOD3 Apparent Energy 21-22'),
ImportColumn::make('tod4_appar_energy_5_6_9_18')
->exampleHeader('TOD4 Apparent Energy 5-6-9-18')
->example('6283.28')
->label('TOD4 Apparent Energy 5-6-9-18'),
ImportColumn::make('tod5_appar_energy_22_5')
->exampleHeader('TOD5 Apparent Energy 22-5')
->example('3422.56')
->label('TOD5 Apparent Energy 22-5'),
ImportColumn::make('avg_pow_factor')
->exampleHeader('Average Power Factor')
->example('0.98')
->label('Average Power Factor'),
ImportColumn::make('avg_freq_15min_last_ip')
->exampleHeader('Average Frequency 15min Last IP')
->example('50')
->label('Average Frequency 15min Last IP'),
ImportColumn::make('net_kv_arh_high')
->exampleHeader('Net KV ARH High')
->example('2.99')
->label('Net KV ARH High'),
ImportColumn::make('net_kv_arh_low')
->exampleHeader('Net KV ARH Low')
->example('143.14')
->label('Net KV ARH Low'),
ImportColumn::make('cum_md_kva')
->exampleHeader('Cumulative MD KVA')
->example('43.816')
->label('Cumulative MD KVA'),
ImportColumn::make('present_md_kva')
->exampleHeader('Present MD KVA')
->example('0.379')
->label('Present MD KVA'),
ImportColumn::make('present_md_kva_date_time')
->label('Present MD KVA Date Time')
->exampleHeader('Present MD KVA Date Time')
->example('2025-08-05 08:32:58')
->requiredMapping()
->rules(['required', 'datetime']),
ImportColumn::make('tod1_md_kva_6_9')
->exampleHeader('TOD1 MD KVA 6-9')
->example('0.282')
->label('TOD1 MD KVA 6-9'),
ImportColumn::make('tod2_md_kva_18_21')
->exampleHeader('TOD2 MD KVA 18-21')
->example('0.268')
->label('TOD2 MD KVA 18-21'),
ImportColumn::make('tod3_md_kva_21_22')
->exampleHeader('TOD3 MD KVA 21-22')
->example('0')
->label('TOD3 MD KVA 21-22'),
ImportColumn::make('tod4_md_kva_5_6_9_18')
->exampleHeader('TOD4 MD KVA 5-6-9-18')
->example('0.379')
->label('TOD4 MD KVA 5-6-9-18'),
ImportColumn::make('tod5_md_kva_22_5')
->exampleHeader('TOD5 MD KVA 22-5')
->example('0.379')
->label('TOD5 MD KVA 22-5'),
ImportColumn::make('total_pow_off_hours')
->exampleHeader('Total Power Off Hours')
->example('6480.56')
->label('Total Power Off Hours'),
ImportColumn::make('programming_count')
->exampleHeader('Programming Count')
->example('3')
->label('Programming Count'),
ImportColumn::make('last_occ_res_event_type')
->exampleHeader('Last Occurrence/Reset Event Type')
->example('-')
->label('Last Occurrence/Reset Event Type'),
ImportColumn::make('last_occ_res_event_date_time')
->label('Last Occurrence/Reset Event Date Time')
->example('2025-08-05 08:32:58')
->exampleHeader('Last Occurrence/Reset Event Date Time')
->requiredMapping()
->rules(['required', 'datetime']),
ImportColumn::make('tamper_count')
->exampleHeader('Tamper Count')
->example('24')
->label('Tamper Count'),
ImportColumn::make('reset_count')
->exampleHeader('Reset Count')
->example('108')
->label('Reset Count'),
ImportColumn::make('last_md_reset_date_time')
->exampleHeader('Last MD Reset Date Time')
->example('2025-08-05 08:32:58')
->label('Last MD Reset Date Time')
->requiredMapping()
->rules(['required', 'datetime']),
ImportColumn::make('electrician_sign')
->exampleHeader('Electrician Sign')
->example('Admin')
->label('Electrician Sign'),
];
}
public function resolveRecord(): ?EbReading
{
// return EbReading::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new EbReading();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your eb reading 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

@@ -35,7 +35,7 @@ class LineStopImporter extends Importer
public function resolveRecord(): ?LineStop
{
$warnMsg = [];
if (Str::length($this->data['code']) < 6 || !ctype_alnum($this->data['code'])) {
if (Str::length($this->data['code']) < 3 || !ctype_alnum($this->data['code'])) {
$warnMsg[] = "Invalid line stop code found";
}
if (Str::length($this->data['reason']) < 5) {

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Filament\Imports;
use App\Models\MfmMeter;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class MfmMeterImporter extends Importer
{
protected static ?string $model = MfmMeter::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('Device Name')
->requiredMapping()
->exampleHeader('Device Name')
->example('REG001')
->label('Device Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('sequence')
->requiredMapping()
->exampleHeader('Sequence')
->example('1')
->label('Sequence')
->rules(['required']),
ImportColumn::make('name')
->requiredMapping()
->exampleHeader('Meter Name')
->example('Display SSB')
->label('Meter Name')
->rules(['required']),
ImportColumn::make('created_by')
->requiredMapping()
->exampleHeader('Created By')
->example('Admin')
->label('Created By')
->rules(['required']),
];
}
public function resolveRecord(): ?MfmMeter
{
// return MfmMeter::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new MfmMeter();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your mfm meter 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

@@ -21,6 +21,13 @@ class MfmParameterImporter extends Importer
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('deviceName')
->requiredMapping()
->exampleHeader('Device Name')
->example('REG001')
->label('Device Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('mfmMeter')
->requiredMapping()
->exampleHeader('Mfm Meter Sequence')

View File

@@ -22,7 +22,14 @@ class MotorTestingMasterImporter extends Importer
->label('Item Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('subassembly_code')
->requiredMapping()
->exampleHeader('SubAssembly Code')
->example(['123456'])
->label('SubAssembly Code')
->rules(['required']),
ImportColumn::make('isi_model')
->requiredMapping()
->boolean()
->exampleHeader('ISI Model')
->example(['Y','N','Y'])
@@ -144,8 +151,8 @@ class MotorTestingMasterImporter extends Importer
->rules(['required']),
ImportColumn::make('leak_cur_limit')
->requiredMapping()
->exampleHeader('Leakage Current Limit')
->label('Leakage Current Limit')
->exampleHeader('Leak Current Limit')
->label('Leak Current Limit')
->example(['50','50','50'])
->rules(['required']),
ImportColumn::make('lock_cur_ll')

View File

@@ -130,7 +130,7 @@ class ProductionQuantityImporter extends Importer
if (Str::length($this->data['serial_number']) < 9 || !ctype_alnum($this->data['serial_number'])) {
$warnMsg[] = "Invalid serial number found";
}
if (Str::length($this->data['production_order']) > 0 && (Str::length($this->data['production_order']) < 7 || !is_numeric($this->data['production_order']))) {
if (Str::length($this->data['production_order']) > 0 && (Str::length($this->data['production_order']) < 7 || Str::length($this->data['production_order']) > 14 || !is_numeric($this->data['production_order']))) {
$warnMsg[] = "Invalid production order found";
}

View File

@@ -206,7 +206,7 @@ class QualityValidationImporter extends Importer
$warnMsg[] = "Sticker item code not found";
}
if (!is_numeric($this->data['production_order']) || Str::length($this->data['production_order']) < 7) {
if (!is_numeric($this->data['production_order']) || Str::length($this->data['production_order']) < 7 || Str::length($this->data['production_order']) > 14) {
$warnMsg[] = "Invalid production order found";
}

View File

@@ -0,0 +1,114 @@
<?php
namespace App\Filament\Imports;
use App\Models\User;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Spatie\Permission\Models\Role;
use Str;
class UserImporter extends Importer
{
protected static ?string $model = User::class;
public static function getColumns(): array
{
return [
ImportColumn::make('name')
->requiredMapping()
->exampleHeader('Name')
->example('RAW00001')
->label('Name')
->rules(['required']),//, 'max:255'
ImportColumn::make('email')
->requiredMapping()
->exampleHeader('E-mail')
->example('RAW00001@cripumps.com')
->label('E-mail')
->rules(['required', 'email']),//, 'max:255'
ImportColumn::make('password')
->requiredMapping()
->exampleHeader('Password')
->example('RAW00001')
->label('Password')
->rules(['required']),//, 'max:255'
ImportColumn::make('roles')
->requiredMapping()
->exampleHeader('Roles')
->example('Employee')
->label('Roles')
->rules(['nullable', 'string']), // Optional roles
];
}
public function resolveRecord(): ?User
{
$warnMsg = [];
if (Str::length($this->data['name']) < 1) {
$warnMsg[] = "User name not found!";
}
// || !is_numeric($this->data['code']) || !preg_match('/^[1-9]\d{3,}$/', $this->data['code'])
if (Str::length($this->data['email']) < 5) {
$warnMsg[] = "Invalid email found!";
}
if (Str::length($this->data['password']) < 3) {
$warnMsg[] = "Invalid password found!";
}
// Validate roles if provided
$roles = [];
if (!empty($this->data['roles'])) {
$roles = collect(explode(',', $this->data['roles']))
->map(fn($role) => trim($role))
->filter()
->toArray();
foreach ($roles as $roleName) {
if (!Role::where('name', $roleName)->exists()) {
$warnMsg[] = "Role : '{$roleName}' does not exist!";
}
}
}
else {
$warnMsg[] = "User roles not found!";
}
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$user = User::updateOrCreate([
'email' => $this->data['email'],
],
[
'name' => $this->data['name'],
'password' => $this->data['password'],
]);
// Assign roles
if (!empty($roles)) {
$user->syncRoles($roles);
}
return null;
// return User::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
//return new User();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your user 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

@@ -53,6 +53,7 @@ class Dashboard extends \Filament\Pages\Dashboard
{
return 'Production Line Count';
}
public function getWidgets(): array
{
$widgets = [];

View File

@@ -726,13 +726,27 @@ class PalletFromLocator extends Page implements HasForms
$month = now()->format('m');
$prefix = "EP-{$year}{$month}";
$lastPallet = PalletValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first(); //->where('plant_id', $plantId)
$lastPallet1 = PalletValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first(); //->where('plant_id', $plantId)
$lastPallet2 = LocatorInvoiceValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first();
$newNumber = '001'; // $lastPallet ? str_pad(intval(substr($lastPallet->pallet_number, -3)) + 1, 3, '0', STR_PAD_LEFT) : '001';
if ($lastPallet) {
$serialPart = substr($lastPallet->pallet_number, strlen($prefix));
if ($lastPallet1 && $lastPallet2) {
$serialPart1 = substr($lastPallet1->pallet_number, strlen($prefix));
$serialPart2 = substr($lastPallet2->pallet_number, strlen($prefix));
if (intval($serialPart1) > intval($serialPart2)) {
$newNumber = str_pad(intval($serialPart1) + 1, strlen($serialPart1), '0', STR_PAD_LEFT);
} else {
$newNumber = str_pad(intval($serialPart2) + 1, strlen($serialPart2), '0', STR_PAD_LEFT);
}
}
else if ($lastPallet1) {
$serialPart1 = substr($lastPallet1->pallet_number, strlen($prefix));
// OR
// $serialPart = str_replace($prefix, '', $lastPallet->pallet_number);
$newNumber = str_pad(intval($serialPart) + 1, strlen($serialPart), '0', STR_PAD_LEFT);
$newNumber = str_pad(intval($serialPart1) + 1, strlen($serialPart1), '0', STR_PAD_LEFT);
}
else if ($lastPallet2) {
$serialPart2 = substr($lastPallet2->pallet_number, strlen($prefix));
$newNumber = str_pad(intval($serialPart2) + 1, strlen($serialPart2), '0', STR_PAD_LEFT);
}
$newPalletNumber = "{$prefix}{$newNumber}";

View File

@@ -320,23 +320,44 @@ class ProductionQuantityPage extends Page implements HasForms
->hintColor('danger'),
TextInput::make('production_order')
->label('Production Order')
->reactive()
->required()
//->columnSpan(1)
->columnSpan(['default' => 1, 'sm' => 1])
->afterStateUpdated(function ($state, callable $get, callable $set): void {
$set('item_code', null);
$set('item_id', null);
// $set('item_description', null);
$set('serial_number', null);
$set('validationError', null);
$this->prodOrder = $state;
return;
// if (empty($state)) {
// }
}),
->label('Production Order')
->reactive()
->required()
->minLength(7)
->maxLength(14)
//->columnSpan(1)
->columnSpan(['default' => 1, 'sm' => 1])
->afterStateUpdated(function ($state, callable $get, callable $set): void {
if(!is_numeric($get('production_order')) || !preg_match('/^[1-9][0-9]{6,13}$/', $get('production_order')))
{
$set('productionError', "Must be a numeric value with 7 to 14 digits.");
$set('production_order', null);
$set('item_code', null);
$set('item_id', null);
// $set('item_description', null);
$set('serial_number', null);
$set('validationError', null);
$this->prodOrder = null;
}
else
{
$set('productionError', null);
$set('production_order', $state);
$set('item_code', null);
$set('item_id', null);
// $set('item_description', null);
$set('serial_number', null);
$set('validationError', null);
$this->prodOrder = $state;
// if (empty($state)) {
// }
}
})
->extraAttributes(fn ($get) => [
'class' => $get('productionError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('productionError') ? $get('productionError') : null)
->hintColor('danger'),
// TextInput::make('item_code')
// ->label('Item Code')
@@ -592,7 +613,7 @@ class ProductionQuantityPage extends Page implements HasForms
->send();
return;
}
else if (!preg_match('/^[1-9][0-9]{6,}$/', $this->prodOrder))
else if (!preg_match('/^[1-9][0-9]{6,13}$/', $this->prodOrder))
{
$this->form->fill([
'plant_id'=> $this->pId,
@@ -611,7 +632,7 @@ class ProductionQuantityPage extends Page implements HasForms
Notification::make()
->title('Invalid Production Order')
->body("Must contain at least 7 digits.<br>Must start with a non-zero digit.")
->body("Must be a numeric value with 7 to 14 digits.<br>Must start with a non-zero digit.")
->danger()
->send();
return;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
<?php
namespace App\Filament\Pages;
use App\Filament\Widgets\TrendChartAnalysis;
use App\Models\MfmMeter;
use Filament\Pages\Page;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use App\Models\Plant;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Forms\Components\DateTimePicker;
use Illuminate\Support\Facades\Auth;
class TrendChartAnalys extends Page
{
use HasFiltersForm;
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.trend-chart-analys';
protected static ?string $navigationGroup = 'EMS DashBoard';
// use HasFiltersForm;
public function mount(): void
{
session()->forget(['selected_plant', 'selected_meter', 'from_datetime', 'to_datetime', 'parameter']);
$this->filtersForm->fill([
'selected_plant' => null,
'selected_meter' => null,
'from_datetime' => null,
'to_datetime' => null,
'parameter' => null,
]);
}
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
DateTimePicker::make('from_datetime')
->label('From DateTime')
->required()
->before('to_datetime')
->reactive()
->afterStateUpdated(function ($state) {
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
session(['from_datetime' => $formatted]);
}),
DateTimePicker::make('to_datetime')
->label('To DateTime')
->required()
->after('from_datetime')
->reactive()
->afterStateUpdated(function ($state) {
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
session(['to_datetime' => $formatted]);
}),
Select::make('plant')
->options(Plant::pluck('name', 'id'))
->label('Select Plant')
->reactive()
->required()
->afterStateUpdated(function ($state, callable $set) {
session(['selected_plant' => $state]);
// When plant changes, also reset meter_name
$set('meter_name', null);
session(['selected_meter' => null]);
// dd($state);
}),
Select::make('meter_name')
->options(function ($get) {
$plantId = $get('plant');
// Return meter name/id pairs from mfm_meters where plant_id matches selected plant
return $plantId ? MfmMeter::where('plant_id', $plantId)->pluck('name', 'id') : [];
})
->label('Select Meter')
->reactive()
->required()
->afterStateUpdated(function ($state) {
session(['selected_meter' => $state]);
}),
Select::make('parameter')
->options([
'Phase Voltage' => 'Phase Voltage',
'Line Voltage' => 'Line Voltage',
'Current' => 'Current',
'Active Power' => 'Active Power',
'Power Factor' => 'Power Factor',
'Units' => 'Units',
])
->label('Select Parameter')
->reactive()
->required()
->afterStateUpdated(function ($state) {
session(['parameter' => $state]);
}),
])
->columns(5);
}
public static function getNavigationLabel(): string
{
return 'Trend Chart Analysis';
}
public function getHeading(): string
{
return 'Trend Chart Analysis';
}
public function getWidgets(): array
{
$widgets = [];
if (TrendChartAnalysis::canView()) {
$widgets[] = TrendChartAnalysis::class;
}
return $widgets;
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view ems trend chart analysis dashboard');
}
}

View File

@@ -0,0 +1,129 @@
<?php
namespace App\Filament\Pages;
use App\Filament\Widgets\TrendLineChart;
use Filament\Pages\Page;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use App\Models\Plant;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Forms\Components\DateTimePicker;
use App\Models\MfmMeter;
use Illuminate\Support\Facades\Auth;
class TrendLineAnalysis extends Page
{
use HasFiltersForm;
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.trend-line-analysis';
protected static ?string $navigationGroup = 'EMS DashBoard';
public function mount(): void
{
session()->forget(['selected_plant', 'selected_meter', 'from_datetime', 'to_datetime', 'parameter']);
$this->filtersForm->fill([
'selected_plant' => null,
'selected_meter' => null,
'from_datetime' => null,
'to_datetime' => null,
'parameter' => null,
]);
}
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
DateTimePicker::make('from_datetime')
->label('From DateTime')
->required()
->before('to_datetime')
->reactive()
->afterStateUpdated(function ($state) {
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
session(['from_datetime' => $formatted]);
}),
DateTimePicker::make('to_datetime')
->label('To DateTime')
->required()
->after('from_datetime')
->reactive()
->afterStateUpdated(function ($state) {
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
session(['to_datetime' => $formatted]);
}),
Select::make('plant')
->options(Plant::pluck('name', 'id'))
->label('Select Plant')
->reactive()
->required()
->afterStateUpdated(function ($state, callable $set) {
session(['selected_plant' => $state]);
// When plant changes, also reset meter_name
$set('meter_name', null);
session(['selected_meter' => null]);
// dd($state);
}),
Select::make('meter_name')
->options(function ($get) {
$plantId = $get('plant');
// Return meter name/id pairs from mfm_meters where plant_id matches selected plant
return $plantId ? MfmMeter::where('plant_id', $plantId)->pluck('name', 'id') : [];
})
->label('Select Meter')
->reactive()
->required()
->afterStateUpdated(function ($state) {
session(['selected_meter' => $state]);
}),
Select::make('parameter')
->options([
'Phase Voltage' => 'Phase Voltage',
'Line Voltage' => 'Line Voltage',
'Current' => 'Current',
'Active Power' => 'Active Power',
'Power Factor' => 'Power Factor',
'Units' => 'Units',
])
->label('Select Parameter')
->reactive()
->required()
->afterStateUpdated(function ($state) {
session(['parameter' => $state]);
}),
])
->columns(5);
}
// public static function getNavigationLabel(): string
// {
// return 'Trend Chart Analysis';
// }
// public function getHeading(): string
// {
// return 'Trend Chart Analysis';
// }
public function getWidgets(): array
{
$widgets = [];
if (TrendLineChart::canView()) {
$widgets[] = TrendLineChart::class;
}
return $widgets;
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view ems trend line analysis dashboard');
}
}

View File

@@ -12,11 +12,15 @@ class CreateAlertMailRule extends CreateRecord
protected function mutateFormDataBeforeCreate(array $data): array
{
if ($data['is_active']) {
$data['plant'] = 0;
}
return $data;
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateBlock extends CreateRecord
{
protected static string $resource = BlockResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateCompany extends CreateRecord
{
protected static string $resource = CompanyResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateConfiguration extends CreateRecord
{
protected static string $resource = ConfigurationResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\DeviceMasterExporter;
use App\Filament\Imports\DeviceMasterImporter;
use App\Filament\Resources\DeviceMasterResource\Pages;
use App\Filament\Resources\DeviceMasterResource\RelationManagers;
use App\Models\DeviceMaster;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
class DeviceMasterResource extends Resource
{
protected static ?string $model = DeviceMaster::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Power House';
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required(),
Forms\Components\TextInput::make('name')
->label('Device Name')
->required(),
Forms\Components\TextInput::make('mac_address')
->label('MAC Address'),
Forms\Components\TextInput::make('ip_address')
->label('IP Address'),
Forms\Components\Hidden::make('created_by')
->default(Filament::auth()->user()?->name),
])
->columns(4),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('name')
->label('Device Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('mac_address')
->label('MAC Address')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('ip_address')
->label('IP Address')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(DeviceMasterImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import device master');
}),
ExportAction::make()
->exporter(DeviceMasterExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export device master');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListDeviceMasters::route('/'),
'create' => Pages\CreateDeviceMaster::route('/create'),
'view' => Pages\ViewDeviceMaster::route('/{record}'),
'edit' => Pages\EditDeviceMaster::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Filament\Resources\DeviceMasterResource\Pages;
use App\Filament\Resources\DeviceMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateDeviceMaster extends CreateRecord
{
protected static string $resource = DeviceMasterResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\DeviceMasterResource\Pages;
use App\Filament\Resources\DeviceMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditDeviceMaster extends EditRecord
{
protected static string $resource = DeviceMasterResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\DeviceMasterResource\Pages;
use App\Filament\Resources\DeviceMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListDeviceMasters extends ListRecords
{
protected static string $resource = DeviceMasterResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\DeviceMasterResource\Pages;
use App\Filament\Resources\DeviceMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewDeviceMaster extends ViewRecord
{
protected static string $resource = DeviceMasterResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -0,0 +1,443 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\EbReadingExporter;
use App\Filament\Imports\EbReadingImporter;
use App\Filament\Resources\EbReadingResource\Pages;
use App\Filament\Resources\EbReadingResource\RelationManagers;
use App\Models\EbReading;
use App\Models\Plant;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
use Filament\Facades\Filament;
use Filament\Tables\Filters\Filter;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\DateTimePicker;
class EbReadingResource extends Resource
{
protected static ?string $model = EbReading::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Power House';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->required(),
Forms\Components\TextInput::make('lcd_segment_check')
->label('LCD Segment Check'),
Forms\Components\TextInput::make('meter_serial_no')
->label('Meter Serial No'),
Forms\Components\DateTimePicker::make('eb_date_time')
->required()
->label('EB Date Time'),
Forms\Components\TextInput::make('ph_seq_of_volt')
->label('PH Sequence of Volt'),
Forms\Components\TextInput::make('ph_assoc_conn_check')
->label('PH Association Connection Check'),
Forms\Components\TextInput::make('instantaneous_ph_volt')
->label('Instantaneous PH Volt'),
Forms\Components\TextInput::make('instantaneous_curr')
->label('Instantaneous Current'),
Forms\Components\TextInput::make('instantaneous_freq')
->label('Instantaneous Frequency'),
Forms\Components\TextInput::make('instantaneous_kw_with_sign')
->label('Instantaneous KW with Sign'),
Forms\Components\TextInput::make('instantaneous_kva')
->label('Instantaneous KVA'),
Forms\Components\TextInput::make('instantaneous_kv_ar')
->label('Instantaneous KV AR'),
Forms\Components\TextInput::make('instantaneous_pf_with_sign')
->label('Instantaneous PF with Sign'),
Forms\Components\TextInput::make('rd_with_elapsed_time_kva')
->label('RD with Elapsed Time KVA'),
Forms\Components\TextInput::make('cum_active_import_energy')
->label('Cumulative Active Import Energy'),
Forms\Components\TextInput::make('tod1_active_energy_6_9')
->label('TOD1 Active Energy 6-9'),
Forms\Components\TextInput::make('tod2_active_energy_18_21')
->label('TOD2 Active Energy 18-21'),
Forms\Components\TextInput::make('tod3_active_energy_21_22')
->label('TOD3 Active Energy 21-22'),
Forms\Components\TextInput::make('tod4_active_energy_5_6_9_18')
->label('TOD4 Active Energy 5-6-9-18'),
Forms\Components\TextInput::make('tod5_active_energy_22_5')
->label('TOD5 Active Energy 22-5'),
Forms\Components\TextInput::make('cum_reac_lag_energy')
->label('Cumulative Reactive Lag Energy'),
Forms\Components\TextInput::make('cum_reac_lead_energy')
->label('Cumulative Reactive Lead Energy'),
Forms\Components\TextInput::make('cum_appar_energy')
->label('Cumulative Apparent Energy'),
Forms\Components\TextInput::make('tod1_appar_energy_6_9')
->label('TOD1 Apparent Energy 6-9'),
Forms\Components\TextInput::make('tod2_appar_energy_18_21')
->label('TOD2 Apparent Energy 18-21'),
Forms\Components\TextInput::make('tod3_appar_energy_21_22')
->label('TOD3 Apparent Energy 21-22'),
Forms\Components\TextInput::make('tod4_appar_energy_5_6_9_18')
->label('TOD4 Apparent Energy 5-6-9-18'),
Forms\Components\TextInput::make('tod5_appar_energy_22_5')
->label('TOD5 Apparent Energy 22-5'),
Forms\Components\TextInput::make('avg_pow_factor')
->label('Average Power Factor'),
Forms\Components\TextInput::make('avg_freq_15min_last_ip')
->label('Average Frequency 15min Last IP'),
Forms\Components\TextInput::make('net_kv_arh_high')
->label('Net KV ARH High'),
Forms\Components\TextInput::make('net_kv_arh_low')
->label('Net KV ARH Low'),
Forms\Components\TextInput::make('cum_md_kva')
->label('Cumulative MD KVA'),
Forms\Components\TextInput::make('present_md_kva')
->label('Present MD KVA'),
Forms\Components\DateTimePicker::make('present_md_kva_date_time')
->label('Present MD KVA Date Time')
->required(),
Forms\Components\TextInput::make('tod1_md_kva_6_9')
->label('TOD1 MD KVA 6-9'),
Forms\Components\TextInput::make('tod2_md_kva_18_21')
->label('TOD2 MD KVA 18-21'),
Forms\Components\TextInput::make('tod3_md_kva_21_22')
->label('TOD3 MD KVA 21-22'),
Forms\Components\TextInput::make('tod4_md_kva_5_6_9_18')
->label('TOD4 MD KVA 5-6-9-18'),
Forms\Components\TextInput::make('tod5_md_kva_22_5')
->label('TOD5 MD KVA 22-5'),
Forms\Components\TextInput::make('total_pow_off_hours')
->label('Total Power Off Hours'),
Forms\Components\TextInput::make('programming_count')
->label('Programming Count'),
Forms\Components\TextInput::make('last_occ_res_event_type')
->label('Last Occurrence/Reset Event Type'),
Forms\Components\DateTimePicker::make('last_occ_res_event_date_time')
->label('Last Occurrence/Reset Event Date Time')
->required(),
Forms\Components\TextInput::make('tamper_count')
->label('Tamper Count'),
Forms\Components\TextInput::make('reset_count')
->label('Reset Count'),
Forms\Components\DateTimePicker::make('last_md_reset_date_time')
->label('Last MD Reset Date Time')
->required(),
Forms\Components\Hidden::make('electrician_sign')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->alignCenter()
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('lcd_segment_check')
->alignCenter()
->label('LCD Segment Check'),
Tables\Columns\TextColumn::make('meter_serial_no')
->alignCenter()
->label('Meter Serial No'),
Tables\Columns\TextColumn::make('eb_date_time')
->alignCenter()
->label('EB Date Time'),
Tables\Columns\TextColumn::make('ph_seq_of_volt')
->alignCenter()
->label('PH Sequence of Volt'),
Tables\Columns\TextColumn::make('ph_assoc_conn_check')
->alignCenter()
->label('PH Association Connection Check'),
Tables\Columns\TextColumn::make('instantaneous_ph_volt')
->alignCenter()
->label('Instantaneous PH Volt'),
Tables\Columns\TextColumn::make('instantaneous_curr')
->alignCenter()
->label('Instantaneous Current'),
Tables\Columns\TextColumn::make('instantaneous_freq')
->alignCenter()
->label('Instantaneous Frequency'),
Tables\Columns\TextColumn::make('instantaneous_kw_with_sign')
->alignCenter()
->label('Instantaneous KW with Sign'),
Tables\Columns\TextColumn::make('instantaneous_kva')
->alignCenter()
->label('Instantaneous KVA'),
Tables\Columns\TextColumn::make('instantaneous_kv_ar')
->alignCenter()
->label('Instantaneous KV AR'),
Tables\Columns\TextColumn::make('instantaneous_pf_with_sign')
->alignCenter()
->label('Instantaneous PF with Sign'),
Tables\Columns\TextColumn::make('rd_with_elapsed_time_kva')
->alignCenter()
->label('RD with Elapsed Time KVA'),
Tables\Columns\TextColumn::make('cum_active_import_energy')
->alignCenter()
->label('Cumulative Active Import Energy'),
Tables\Columns\TextColumn::make('tod1_active_energy_6_9')
->alignCenter()
->label('TOD1 Active Energy 6-9'),
Tables\Columns\TextColumn::make('tod2_active_energy_18_21')
->alignCenter()
->label('TOD2 Active Energy 18-21'),
Tables\Columns\TextColumn::make('tod3_active_energy_21_22')
->alignCenter()
->label('TOD3 Active Energy 21-22'),
Tables\Columns\TextColumn::make('tod4_active_energy_5_6_9_18')
->alignCenter()
->label('TOD4 Active Energy 5-6-9-18'),
Tables\Columns\TextColumn::make('tod5_active_energy_22_5')
->alignCenter()
->label('TOD5 Active Energy 22-5'),
Tables\Columns\TextColumn::make('cum_reac_lag_energy')
->alignCenter()
->label('Cumulative Reactive Lag Energy'),
Tables\Columns\TextColumn::make('cum_reac_lead_energy')
->alignCenter()
->label('Cumulative Reactive Lead Energy'),
Tables\Columns\TextColumn::make('cum_appar_energy')
->alignCenter()
->label('Cumulative Apparent Energy'),
Tables\Columns\TextColumn::make('tod1_appar_energy_6_9')
->alignCenter()
->label('TOD1 Apparent Energy 6-9'),
Tables\Columns\TextColumn::make('tod2_appar_energy_18_21')
->alignCenter()
->label('TOD2 Apparent Energy 18-21'),
Tables\Columns\TextColumn::make('tod3_appar_energy_21_22')
->alignCenter()
->label('TOD3 Apparent Energy 21-22'),
Tables\Columns\TextColumn::make('tod4_appar_energy_5_6_9_18')
->alignCenter()
->label('TOD4 Apparent Energy 5-6-9-18'),
Tables\Columns\TextColumn::make('tod5_appar_energy_22_5')
->alignCenter()
->label('TOD5 Apparent Energy 22-5'),
Tables\Columns\TextColumn::make('avg_pow_factor')
->alignCenter()
->label('Average Power Factor'),
Tables\Columns\TextColumn::make('avg_freq_15min_last_ip')
->alignCenter()
->label('Average Frequency 15min Last IP'),
Tables\Columns\TextColumn::make('net_kv_arh_high')
->alignCenter()
->label('Net KV ARH High'),
Tables\Columns\TextColumn::make('net_kv_arh_low')
->alignCenter()
->label('Net KV ARH Low'),
Tables\Columns\TextColumn::make('cum_md_kva')
->alignCenter()
->label('Cumulative MD KVA'),
Tables\Columns\TextColumn::make('present_md_kva')
->alignCenter()
->label('Present MD KVA'),
Tables\Columns\TextColumn::make('present_md_kva_date_time')
->alignCenter()
->label('Present MD KVA Date Time'),
Tables\Columns\TextColumn::make('tod1_md_kva_6_9')
->alignCenter()
->label('TOD1 MD KVA 6-9'),
Tables\Columns\TextColumn::make('tod2_md_kva_18_21')
->alignCenter()
->label('TOD2 MD KVA 18-21'),
Tables\Columns\TextColumn::make('tod3_md_kva_21_22')
->alignCenter()
->label('TOD3 MD KVA 21-22'),
Tables\Columns\TextColumn::make('tod4_md_kva_5_6_9_18')
->alignCenter()
->label('TOD4 MD KVA 5-6-9-18'),
Tables\Columns\TextColumn::make('tod5_md_kva_22_5')
->alignCenter()
->label('TOD5 MD KVA 22-5'),
Tables\Columns\TextColumn::make('total_pow_off_hours')
->alignCenter()
->label('Total Power Off Hours'),
Tables\Columns\TextColumn::make('programming_count')
->alignCenter()
->label('Programming Count'),
Tables\Columns\TextColumn::make('last_occ_res_event_type')
->alignCenter()
->label('Last Occurrence/Reset Event Type'),
Tables\Columns\TextColumn::make('last_occ_res_event_date_time')
->alignCenter()
->label('Last Occurrence/Reset Event Date Time'),
Tables\Columns\TextColumn::make('tamper_count')
->alignCenter()
->label('Tamper Count'),
Tables\Columns\TextColumn::make('reset_count')
->alignCenter()
->label('Reset Count'),
Tables\Columns\TextColumn::make('last_md_reset_date_time')
->alignCenter()
->label('Last MD Reset Date Time'),
Tables\Columns\TextColumn::make('electrician_sign')
->alignCenter()
->label('Created By'),
Tables\Columns\TextColumn::make('created_at')
->alignCenter()
->label('Created At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
// ->filters([
// Tables\Filters\TrashedFilter::make(),
// ])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select Plant')
->nullable()
->options(function () {
return Plant::pluck('name', 'id');
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('electrician_sign', null);
}),
TextInput::make('electrician_sign')
->label('Created By'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['electrician_sign'])) {
return $query->whereRaw('1 = 0');
}
if (!empty($data['Plant'])) {
$query->where('plant_id', $data['Plant']);
}
if (!empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (!empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
if (!empty($data['electrician_sign'])) {
$query->where('electrician_sign', $data['electrician_sign']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (!empty($data['Plant'])) {
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
}
if (!empty($data['electrician_sign'])) {
$indicators[] = 'Created By: ' . $data['electrician_sign'];
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
if (!empty($data['created_to'])) {
$indicators[] = 'To: ' . $data['created_to'];
}
return $indicators;
})
])
->filtersFormMaxHeight('280px')
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(EbReadingImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import eb reading');
}),
ExportAction::make()
->exporter(EbReadingExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export eb reading');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListEbReadings::route('/'),
'create' => Pages\CreateEbReading::route('/create'),
'view' => Pages\ViewEbReading::route('/{record}'),
'edit' => Pages\EditEbReading::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Filament\Resources\EbReadingResource\Pages;
use App\Filament\Resources\EbReadingResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateEbReading extends CreateRecord
{
protected static string $resource = EbReadingResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\EbReadingResource\Pages;
use App\Filament\Resources\EbReadingResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditEbReading extends EditRecord
{
protected static string $resource = EbReadingResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\EbReadingResource\Pages;
use App\Filament\Resources\EbReadingResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListEbReadings extends ListRecords
{
protected static string $resource = EbReadingResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\EbReadingResource\Pages;
use App\Filament\Resources\EbReadingResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewEbReading extends ViewRecord
{
protected static string $resource = EbReadingResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -73,14 +73,14 @@ class GuardNameResource extends Resource
->ignore($get('id'));
}),
Forms\Components\TextInput::make('identification1')
->label('Identification-1')
->label('Aadhar Number')
->required()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('created_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('identification2')
->label('Identification-2')
->label('PAN Number')
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('created_by', Filament::auth()->user()?->name);

View File

@@ -17,6 +17,7 @@ use Filament\Forms;
use Filament\Forms\Components\Actions\Action as ActionsAction;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Radio;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
@@ -147,16 +148,16 @@ class InvoiceValidationResource extends Resource
->reactive()
->hidden(fn (callable $get) => ($get('invoice_number') == null || $get('update_invoice') == '0') || !empty($get('serial_number')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
if(!$get('plant_id'))
if (!$get('plant_id'))
{
$set('update_invoice', null);
return;
}
if($get('update_invoice') === "1")
if ($get('update_invoice') == "1")
{
$totQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->where('plant_id', $get('plant_id'))->count();
if($totQuan <= 0)
if ($totQuan <= 0)
{
$set('update_invoice', null);
return;
@@ -166,9 +167,9 @@ class InvoiceValidationResource extends Resource
$scanMQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $get('plant_id'))->count();
$scanSQuan = InvoiceValidation::where('invoice_number', $get('invoice_number'))->where('scanned_status', 'Scanned')->where('plant_id', $get('plant_id'))->count();
if($totMQuan > 0)
if ($totMQuan > 0)
{
if ($totQuan === $scanMQuan)
if ($totQuan == $scanMQuan)
{
$set('update_invoice', null);
return;
@@ -176,7 +177,7 @@ class InvoiceValidationResource extends Resource
}
else
{
if ($totQuan === $scanSQuan)
if ($totQuan == $scanSQuan)
{
$set('update_invoice', null);
return;
@@ -342,15 +343,57 @@ class InvoiceValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
// /home/iot-dev/projects/pds/storage/app/private/uploads/temp/3RA0018735.xlsx
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->count();
if ($totQuan > 0)
{
$scanSQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->count();
if ($totQuan == $scanSQuan)
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
Notification::make()
->title("Serial invoice number : '$originalNameOnly' already completed the scanning process for plant : '$plantName'.")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
else
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
// $plantCode = $invoiceFirst ? (String)$invoiceFirst->plant->code : null;
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
$invoicePlantId = $invoiceFirst->plant_id;
if ($plantId != $invoicePlantId)
{
Notification::make()
->title("Serial invoice number : '$originalNameOnly' already exists for plant : '$plantName'.<br>Choose the valid 'Plant' to proceed!")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
}
}
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count();
$scanSQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
if($totQuan == $scanSQuan && $totQuan > 0)
if ($totQuan > 0 && $totQuan == $scanSQuan)
{
Notification::make()
->title('Serial invoice already completed the scanning process for selected plant.')
->danger()
->send();
->title('Serial invoice already completed the scanning process for selected plant.')
->danger()
->send();
if ($disk->exists($path))
{
@@ -363,7 +406,7 @@ class InvoiceValidationResource extends Resource
{
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
if ((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
@@ -387,7 +430,7 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
@@ -398,19 +441,17 @@ class InvoiceValidationResource extends Resource
if (!empty($materialCode))
{
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
if (Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
}
else
{
if (empty($serialNumber)) {
$missingSerials[] = $materialCode;
}
else if(Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber))
else if (Str::length($serialNumber) < 9 || !ctype_alnum($serialNumber))
{
$invalidSerialCodes[] = $serialNumber;
}
@@ -452,7 +493,6 @@ class InvoiceValidationResource extends Resource
}
return;
}
else if (!empty($uniqueMissingSerials)) {
Notification::make()
->title('Missing Serial Numbers')
@@ -478,7 +518,7 @@ class InvoiceValidationResource extends Resource
else if (!empty($duplicateSerialCodes)) {
Notification::make()
->title('Duplicate Serial Numbers')
->body('The following serial numbers are already exist in database:<br>' . implode(', ', $duplicateSerialCodes))
->body('The following serial numbers are already exist in imported excel:<br>' . implode(', ', $duplicateSerialCodes))
->danger()
->send();
if ($disk->exists($path)) {
@@ -531,30 +571,30 @@ class InvoiceValidationResource extends Resource
// Check which codes have a material_type set (not null)
$invalidCodes = $matchedItems
->filter(fn ($sticker) => !empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
->filter(fn ($sticker) => !empty($sticker->material_type)) //filter invalid
->pluck('item.code')
->toArray();
if (count($invalidCodes) > 10)
{
Notification::make()
->title('Invalid item codes found')
->body('' . count($invalidCodes) . 'item codes found have material type.')
->danger()
->send();
->title('Invalid item codes found')
->body('' . count($invalidCodes) . 'item codes found have material type.')
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
else if(count($invalidCodes) > 0)
else if (count($invalidCodes) > 0)
{
Notification::make()
->title('Invalid item codes found')
->body('Material invoice Item Codes found : ' . implode(', ', $invalidCodes))
->danger()
->send();
->title('Invalid item codes found')
->body('Material invoice Item Codes found : ' . implode(', ', $invalidCodes))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
@@ -566,7 +606,7 @@ class InvoiceValidationResource extends Resource
// Save full file path to session
session(['uploaded_invoice_path' => $fullPath]);
Notification::make()
->title('Serial invoice imported successfully.')
->title('Serial invoice imported successfully.')
->success()
->send();
}
@@ -602,7 +642,6 @@ class InvoiceValidationResource extends Resource
->visible(fn (Get $get) => !empty($get('plant_id')))
->directory('uploads/temp'),
])
->action(function (array $data) {
$uploadedFile = $data['invoice_material'];
@@ -619,10 +658,52 @@ class InvoiceValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->count();
if ($totQuan > 0)
{
$scanMQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->count();
if ($totQuan == $scanMQuan)
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
Notification::make()
->title("Material invoice number : '$originalNameOnly' already completed the scanning process for plant : '$plantName'.")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
else
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $originalNameOnly)->first();
// $plantCode = $invoiceFirst ? (String)$invoiceFirst->plant->code : null;
$plantName = $invoiceFirst ? (String)$invoiceFirst->plant->name : null;
$invoicePlantId = $invoiceFirst->plant_id;
if ($plantId != $invoicePlantId)
{
Notification::make()
->title("Material invoice number : '$originalNameOnly' already exists for plant : '$plantName'.<br>Choose the valid 'Plant' to proceed!")
->danger()
->send();
if ($disk->exists($path))
{
$disk->delete($path);
}
return;
}
}
}
$totQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->where('plant_id', $plantId)->count();
$scanMQuan = InvoiceValidation::where('invoice_number', $originalNameOnly)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
if($totQuan == $scanMQuan && $totQuan > 0)
if ($totQuan > 0 && $totQuan == $scanMQuan)
{
Notification::make()
->title('Material invoice already completed the scanning process for selected plant.')
@@ -638,7 +719,7 @@ class InvoiceValidationResource extends Resource
{
$rows = Excel::toArray(null, $fullPath)[0];
if((count($rows) - 1) <= 0)
if ((count($rows) - 1) <= 0)
{
Notification::make()
->title('Records Not Found')
@@ -661,7 +742,7 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$materialQuantity = trim($row[1]);
@@ -671,13 +752,13 @@ class InvoiceValidationResource extends Resource
}
if (!empty($materialCode)) {
if(Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
if (Str::length($materialCode) < 6 || !ctype_alnum($materialCode))
{
$invalidMatCodes[] = $materialCode;
}
else
{
if($materialQuantity == 0)
if ($materialQuantity == 0)
{
$invalidMaterialQuan[] = $materialCode;
}
@@ -685,7 +766,7 @@ class InvoiceValidationResource extends Resource
{
$missingQuantities[] = $materialCode;
}
else if(!is_numeric($materialQuantity))
else if (!is_numeric($materialQuantity))
{
$invalidMatQuan[] = $materialCode;
}
@@ -820,7 +901,7 @@ class InvoiceValidationResource extends Resource
}
return;
}
else if(count($invalidCodes) > 0)
else if (count($invalidCodes) > 0)
{
$invalidCodes = array_unique($invalidCodes);
Notification::make()
@@ -851,29 +932,29 @@ class InvoiceValidationResource extends Resource
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
if ($totalExcelQty === 0) {
if ($totalExcelQty == 0) {
$zeroQtyCodes[] = $code;
} elseif (!is_numeric($totalExcelQty)) {
$nonNumericQtyCodes[] = $code; // Here you may want to check divisibility condition too
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty !== 0) {
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty != 0) {
$notDivisibleCodes[] = $code;
}
}
}
$showValidationNotification = function(array $codes, string $message) {
if (count($codes) === 0) return;
if (count($codes) == 0) return;
$uniqueCodes = array_unique($codes);
$codeList = implode(', ', $uniqueCodes);
@@ -929,6 +1010,16 @@ class InvoiceValidationResource extends Resource
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Radio::make('invoice_type')
->label('Type ?')
->boolean()
->options([
'Serial' => 'Serial',
'Material' => 'Material'
])
->default('Serial')
->inlineLabel(false)
->inline(),
Select::make('Plant')
->label('Select Plant')
->nullable()
@@ -938,6 +1029,7 @@ class InvoiceValidationResource extends Resource
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('sticker_master_id', null);
$set('operator_id', null);
}),
TextInput::make('invoice_number')
->label('Invoice Number')
@@ -962,6 +1054,31 @@ class InvoiceValidationResource extends Resource
})
->searchable()
->reactive(),
Select::make('scanned_status')
->label('Scanned Status')
->nullable()
->options([
'Scanned' => 'Scanned',
'Pending' => 'Pending',
])
->searchable()
->reactive(),
Select::make('operator_id')
->label('Created By')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId)
{
return InvoiceValidation::whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
else
{
return InvoiceValidation::where('plant_id', $plantId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
})
->searchable()
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
@@ -975,10 +1092,46 @@ class InvoiceValidationResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['invoice_number']) && empty($data['serial_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['sticker_master_id'])) {
if (empty($data['invoice_type']) || (empty($data['Plant']) && empty($data['invoice_number']) && empty($data['serial_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['operator_id']) && empty($data['scanned_status']) && empty($data['sticker_master_id']))) {
if (empty($data['invoice_type']))
{
Notification::make()
->title('Please, choose invoice type to filter.')
->danger()
->send();
}
return $query->whereRaw('1 = 0');
}
if ($data['invoice_type'] == 'Serial') {
$query->whereNull('quantity');
if (!empty($data['scanned_status'])) {
if ($data['scanned_status'] == 'Scanned') {
$query->whereNotNull('scanned_status')->where('scanned_status', '!=', '');
} elseif ($data['scanned_status'] == 'Pending') {
//$query->whereNull('scanned_status')->orWhere('scanned_status', '');
$query->where(function ($query) use ($data) {
// if (empty($data['scanned_status']) || $data['scanned_status'] == 'Pending') {
$query->whereNull('scanned_status')->orWhere('scanned_status', '!=', 'Scanned');
// }
});
}
}
} elseif ($data['invoice_type'] == 'Material') {
$query->whereNotNull('quantity');//->where('quantity', '>', 0)
if (!empty($data['scanned_status'])) {
if ($data['scanned_status'] == 'Scanned') {
$query->whereNotNull('serial_number')->where('serial_number', '!=', '');
} elseif ($data['scanned_status'] == 'Pending') {
$query->where(function ($query) use ($data) {
$query->whereNull('serial_number')->orWhere('serial_number', '=', '');
});
}
}
}
if (!empty($data['Plant'])) { //$plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
}
@@ -999,6 +1152,10 @@ class InvoiceValidationResource extends Resource
$query->where('created_at', '<=', $data['created_to']);
}
if (!empty($data['operator_id'])) {
$query->where('operator_id', $data['operator_id']);
}
if (!empty($data['sticker_master_id'])) {
$stickerMasterIds = StickerMaster::where('item_id', $data['sticker_master_id'])
->pluck('id')
@@ -1024,6 +1181,15 @@ class InvoiceValidationResource extends Resource
$indicators[] = 'Serial Number: ' . $data['serial_number'];
}
if (!empty($data['sticker_master_id'])) {
$itemCode = Item::find($data['sticker_master_id'])->code ?? 'Unknown';
$indicators[] = 'Item Code: ' . $itemCode;
}
if (!empty($data['operator_id'])) {
$indicators[] = 'Created By: ' . $data['operator_id'];
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
@@ -1032,9 +1198,8 @@ class InvoiceValidationResource extends Resource
$indicators[] = 'To: ' . $data['created_to'];
}
if (!empty($data['sticker_master_id'])) {
$itemCode = Item::find($data['sticker_master_id'])->code ?? 'Unknown';
$indicators[] = 'Item Code: ' . $itemCode;
if (!empty($data['scanned_status'])) {
$indicators[] = 'Scanned Status: ' . $data['scanned_status'];
}
return $indicators;

View File

@@ -8,6 +8,7 @@ use App\Imports\ExcelImport;
use App\Livewire\InvoiceDataTable;
use App\Models\InvoiceValidation;
use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use Filament\Facades\Filament;
use Filament\Pages\Concerns\ExposesTableToWidgets;
@@ -60,6 +61,11 @@ class CreateInvoiceValidation extends CreateRecord
];
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
public function processInvoice($invoiceNumber)
{
$invoiceNumber = trim($invoiceNumber);
@@ -74,6 +80,22 @@ class CreateInvoiceValidation extends CreateRecord
$this->plantId = $plantId;
$plant = Plant::find($plantId);
if ($plant)
{
$plantCode = $plant->code;
}
else
{
$plantCode = null;
}
//..GET SERIAL INVOICE API
//..
$updateStatus = $this->form->getState()['update_invoice'] ?? null;
$this->invoiceNumber = trim($this->form->getState()['invoice_number']) ?? $invoiceNumber;
@@ -116,7 +138,7 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scanMQuan,
]);
if ($totQuan === $scanMQuan)
if ($totQuan == $scanMQuan)
{
Notification::make()
->title("Completed: Material Invoice")
@@ -134,7 +156,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false);
}
else
{
@@ -147,7 +169,7 @@ class CreateInvoiceValidation extends CreateRecord
// $this->dispatch( (!empty($hasRecords) && $hasRecords) ? 'refreshMaterialInvoiceData' : 'refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId); //$this->invoiceNumber
$this->dispatch('refreshMaterialInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
if($updateStatus === '1')
if($updateStatus == '1')
{
//'Material invoice update in progress...';
$filename = $invoiceNumber . '.xlsx';
@@ -185,7 +207,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$materialQuantity = trim($row[1]);
@@ -390,7 +412,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -399,16 +421,16 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
if ($totalExcelQty === 0) {
if ($totalExcelQty == 0) {
$zeroQtyCodes[] = $code;
} elseif (!is_numeric($totalExcelQty)) {
$nonNumericQtyCodes[] = $code; // Here you may want to check divisibility condition too
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty !== 0) {
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty != 0) {
$notDivisibleCodes[] = $code;
}
}
@@ -420,7 +442,7 @@ class CreateInvoiceValidation extends CreateRecord
}
$showValidationNotification = function(array $codes, string $message) {
if (count($codes) === 0) return;
if (count($codes) == 0) return;
$uniqueCodes = array_unique($codes);
$codeList = implode(', ', $uniqueCodes);
@@ -452,7 +474,7 @@ class CreateInvoiceValidation extends CreateRecord
$inserted = 0;
foreach ($matchedItems as $sticker)
{
if ($newQuan === -1 && !$hasQuanTyp)
if ($newQuan == -1 && !$hasQuanTyp)
{
InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) {
$query->whereNull('serial_number')->orWhere('serial_number', '');
@@ -461,7 +483,7 @@ class CreateInvoiceValidation extends CreateRecord
$newQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->count();
}
else if ($newQuan === -1 && $hasQuanTyp)
else if ($newQuan == -1 && $hasQuanTyp)
{
InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->where(function($query) {
$query->whereNull('serial_number')->orWhere('serial_number', '');
@@ -481,7 +503,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -490,7 +512,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
@@ -522,7 +544,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -531,7 +553,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
@@ -564,7 +586,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -573,7 +595,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty;
}
}
@@ -669,7 +691,7 @@ class CreateInvoiceValidation extends CreateRecord
}
}
if ($inserted > 0 || $oldQuan !== $newQuan)
if ($inserted > 0 || $oldQuan != $newQuan)
{
Notification::make()
->title("Material invoice successfully updatad.")
@@ -695,13 +717,13 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
if ($totalQuantity == $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false);
}
else
{
@@ -775,7 +797,7 @@ class CreateInvoiceValidation extends CreateRecord
//$hasRecords = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('plant_id', $plantId)->first()->stickerMasterRelation->material_type ?? null;
// $this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
if ($totQuan === $scanSQuan)
if ($totQuan == $scanSQuan)
{
Notification::make()
->title("Completed: Serial Invoice")
@@ -793,7 +815,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{
@@ -804,7 +826,7 @@ class CreateInvoiceValidation extends CreateRecord
->send();
$this->dispatch('refreshInvoiceData', invoiceNumber: $invoiceNumber, plantId: $plantId);
if($updateStatus === '1')
if($updateStatus == '1')
{
$filename = $invoiceNumber . '.xlsx';
$directory = 'uploads/temp';
@@ -846,7 +868,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
@@ -1087,7 +1109,7 @@ class CreateInvoiceValidation extends CreateRecord
$inserted = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) // Skip header;
if ($index == 0) // Skip header;
{
InvoiceValidation::where('invoice_number', $invoiceNumber)
->where(function($query) {
@@ -1138,7 +1160,7 @@ class CreateInvoiceValidation extends CreateRecord
}
}
if ($inserted > 0 || $oldQuan !== $newQuan)
if ($inserted > 0 || $oldQuan != $newQuan)
{
Notification::make()
->title("Serial invoice successfully updated.")
@@ -1165,13 +1187,13 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
if ($totalQuantity == $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{
@@ -1283,7 +1305,7 @@ class CreateInvoiceValidation extends CreateRecord
$uploadedFilename = pathinfo($fullPath, PATHINFO_FILENAME);
// Compare with invoice number
if ($uploadedFilename !== $invoiceNumber) {
if ($uploadedFilename != $invoiceNumber) {
Notification::make()
->title("Uploaded file name does not match the invoice number.")
->danger()
@@ -1326,7 +1348,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue;
if ($index == 0) continue;
$materialCode = trim($row[0]);
@@ -1365,7 +1387,7 @@ class CreateInvoiceValidation extends CreateRecord
}
}
if($invoiceType === 'M')
if($invoiceType == 'M')
{
$invalidMatCodes = [];
$materialCodes = [];
@@ -1375,7 +1397,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$materialQuantity = trim($row[1]);
@@ -1578,7 +1600,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -1587,23 +1609,23 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
if ($totalExcelQty === 0) {
if ($totalExcelQty == 0) {
$zeroQtyCodes[] = $code;
} elseif (!is_numeric($totalExcelQty)) {
$nonNumericQtyCodes[] = $code; // Here you may want to check divisibility condition too
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty !== 0) {
} elseif ($bundleQty != 0 && $totalExcelQty % $bundleQty != 0) {
$notDivisibleCodes[] = $code;
}
}
}
$showValidationNotification = function(array $codes, string $message) {
if (count($codes) === 0) return;
if (count($codes) == 0) return;
$uniqueCodes = array_unique($codes);
$codeList = implode(', ', $uniqueCodes);
@@ -1642,7 +1664,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -1651,7 +1673,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
@@ -1677,7 +1699,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -1686,7 +1708,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
@@ -1711,7 +1733,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$excelCode = trim($row[0]);
$excelMatQty = trim($row[1]);
@@ -1720,7 +1742,7 @@ class CreateInvoiceValidation extends CreateRecord
continue;
}
if ($excelCode === $code && is_numeric($excelMatQty)) {
if ($excelCode == $code && is_numeric($excelMatQty)) {
$totalExcelQty += $excelMatQty; // Sum up the quantities
}
}
@@ -1759,13 +1781,13 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
if ($totalQuantity == $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false);
}
else
{
@@ -1805,7 +1827,7 @@ class CreateInvoiceValidation extends CreateRecord
}
}
}
else if($invoiceType === 'S')
else if($invoiceType == 'S')
{
$invalidMatCodes = [];
$materialCodes = [];
@@ -1817,7 +1839,7 @@ class CreateInvoiceValidation extends CreateRecord
foreach ($rows as $index => $row)
{
if ($index === 0) continue; // Skip header
if ($index == 0) continue; // Skip header
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
@@ -2077,7 +2099,7 @@ class CreateInvoiceValidation extends CreateRecord
$inserted = 0;
foreach ($rows as $index => $row)
{
if ($index === 0) continue;
if ($index == 0) continue;
$materialCode = trim($row[0]);
$serialNumber = trim($row[1]);
@@ -2123,13 +2145,13 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if ($totalQuantity === $scannedQuantity)
if ($totalQuantity == $scannedQuantity)
{
if ($disk->exists($filePath)) {
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{
@@ -2201,9 +2223,9 @@ class CreateInvoiceValidation extends CreateRecord
{
$totalQuantity = InvoiceValidation::where('invoice_number', $this->invoiceNumber)->where('plant_id', $this->plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $this->invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $this->plantId)->count();
if ($totalQuantity === $scannedQuantity)
if ($totalQuantity == $scannedQuantity)
{
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $this->invoiceNumber, plantId: $this->plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $this->invoiceNumber, plantId: $this->plantId, isSerial: true);
}
else
{
@@ -2255,7 +2277,7 @@ class CreateInvoiceValidation extends CreateRecord
{
if ($totMQuan > 0)
{
if ($totQuan === $scanMQuan)
if ($totQuan == $scanMQuan)
{
Notification::make()
->title('Completed: Material Invoice')
@@ -2282,7 +2304,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false);
return;
}
else
@@ -2759,7 +2781,7 @@ class CreateInvoiceValidation extends CreateRecord
$scannedMQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->whereNotNull('serial_number')->where('serial_number', '!=', '')->where('plant_id', $plantId)->count();
if($totQuan === $scannedMQuantity)
if($totQuan == $scannedMQuantity)
{
Notification::make()
->title('Completed: Material Invoice')
@@ -2786,7 +2808,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: false);
}
else
{
@@ -2804,7 +2826,7 @@ class CreateInvoiceValidation extends CreateRecord
}
else
{
if ($totQuan === $scanSQuan)
if ($totQuan == $scanSQuan)
{
Notification::make()
->title('Completed: Serial Invoice')
@@ -2831,7 +2853,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
return;
}
else
@@ -3004,7 +3026,7 @@ class CreateInvoiceValidation extends CreateRecord
]);
return;
}
else if($hadMotorQr === $hasMotorQr)
else if($hadMotorQr == $hasMotorQr)
{
Notification::make()
->title('Duplicate: Motor QR')
@@ -3027,7 +3049,7 @@ class CreateInvoiceValidation extends CreateRecord
$packCnt = 1;
$scanCnt = 1;
$record->motor_scanned_status = 1;
//if($hadPumpQr === $hasPumpQr && $hadPumpSetQr === $hasPumpSetQr)
//if($hadPumpQr == $hasPumpQr && $hadPumpSetQr == $hasPumpSetQr)
if($hasPumpQr || $hasPumpSetQr || $hasCapacitorQr)
{
$packCnt = $hasPumpQr ? $packCnt + 1 : $packCnt;
@@ -3038,7 +3060,7 @@ class CreateInvoiceValidation extends CreateRecord
$scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt;
if($packCnt === $scanCnt)
if($packCnt == $scanCnt)
{
$record->scanned_status = 'Scanned';
}
@@ -3067,7 +3089,7 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if($totQuan === $scannedQuantity)
if($totQuan == $scannedQuantity)
{
Notification::make()
->title('Completed: Serial Invoice')
@@ -3085,7 +3107,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{
@@ -3114,7 +3136,7 @@ class CreateInvoiceValidation extends CreateRecord
]);
return;
}
else if($hadPumpQr === $hasPumpQr)
else if($hadPumpQr == $hasPumpQr)
{
Notification::make()
->title('Duplicate: Pump QR')
@@ -3137,7 +3159,7 @@ class CreateInvoiceValidation extends CreateRecord
$packCnt = 1;
$scanCnt = 1;
$record->pump_scanned_status = 1;
// if($hadMotorQr === $hasMotorQr && $hadPumpSetQr === $hasPumpSetQr && ($hadCapacitorQr === '1' && $hasCapacitorQr))
// if($hadMotorQr == $hasMotorQr && $hadPumpSetQr == $hasPumpSetQr && ($hadCapacitorQr == '1' && $hasCapacitorQr))
if($hasMotorQr || $hasPumpSetQr || $hasCapacitorQr)
{
$packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt;
@@ -3148,7 +3170,7 @@ class CreateInvoiceValidation extends CreateRecord
$scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt;
if($packCnt === $scanCnt)
if($packCnt == $scanCnt)
{
$record->scanned_status = 'Scanned';
}
@@ -3177,7 +3199,7 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if($totQuan === $scannedQuantity)
if($totQuan == $scannedQuantity)
{
Notification::make()
->title('Completed: Serial Invoice')
@@ -3195,7 +3217,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{
@@ -3226,7 +3248,7 @@ class CreateInvoiceValidation extends CreateRecord
]);
return;
}
else if($hadCapacitorQr === '1' && $hasCapacitorQr)
else if($hadCapacitorQr == '1' && $hasCapacitorQr)
{
Notification::make()
->title('Duplicate: Capacitor QR')
@@ -3285,7 +3307,7 @@ class CreateInvoiceValidation extends CreateRecord
]);
return;
}
else if($hadPumpSetQr === $hasPumpSetQr)
else if($hadPumpSetQr == $hasPumpSetQr)
{
Notification::make()
->title('Duplicate: Pump Set QR')
@@ -3308,7 +3330,7 @@ class CreateInvoiceValidation extends CreateRecord
$packCnt = 1;
$scanCnt = 1;
$record->scanned_status_set = 1;
// if($hadMotorQr === $hasMotorQr && $hadPumpQr === $hasPumpQr && ($hadCapacitorQr === '1' && $hasCapacitorQr))
// if($hadMotorQr == $hasMotorQr && $hadPumpQr == $hasPumpQr && ($hadCapacitorQr == '1' && $hasCapacitorQr))
if($hasMotorQr || $hasPumpQr || $hasCapacitorQr)
{
$packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt;
@@ -3319,7 +3341,7 @@ class CreateInvoiceValidation extends CreateRecord
$scanCnt = $hadPumpQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadCapacitorQr ? $scanCnt + 1: $scanCnt;
if($packCnt === $scanCnt)
if($packCnt == $scanCnt)
{
$record->scanned_status = 'Scanned';
}
@@ -3348,7 +3370,7 @@ class CreateInvoiceValidation extends CreateRecord
'scanned_quantity'=> $scannedQuantity,
]);
if($totQuan === $scannedQuantity)
if($totQuan == $scannedQuantity)
{
Notification::make()
->title('Completed: Serial Invoice')
@@ -3366,7 +3388,7 @@ class CreateInvoiceValidation extends CreateRecord
//$fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
}
else
{

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateItem extends CreateRecord
{
protected static string $resource = ItemResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateLine extends CreateRecord
{
protected static string $resource = LineResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateLineStop extends CreateRecord
{
protected static string $resource = LineStopResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -21,7 +21,9 @@ class CreateLocatorInvoiceValidation extends CreateRecord
protected static string $view = 'filament.resources.pallet-validation-resource.pages.create-locator-invoice-validation';
public $plantId;
public $invoice_number;
public $pallet_number;
public $serial_number, $snoCount;
@@ -29,8 +31,13 @@ class CreateLocatorInvoiceValidation extends CreateRecord
public $locator_number;
public array $matchedSerialNumbersForRemoval = [];
public bool $showRemoveSerialsModal = false;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
public function processinvoiceSNo()
{

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateLocator extends CreateRecord
{
protected static string $resource = LocatorResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -71,9 +71,7 @@ class MachineResource extends Resource
return [];
}
return Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
return Line::where('plant_id', $get('plant_id'))->where('no_of_operation', '>', 0)->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->line_id;
@@ -87,13 +85,13 @@ class MachineResource extends Resource
}
else
{
$grpWrkCnr = Line::find($lineId)->group_work_center;
if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
{
$set('mLineError', 'Please select a group work center line.');
$set('line_id', null);
return;
}
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
// $set('mLineError', 'Please select a group work center line.');
// $set('line_id', null);
// return;
// }
$set('mLineError', null);
}
})

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateMachine extends CreateRecord
{
protected static string $resource = MachineResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -2,8 +2,11 @@
namespace App\Filament\Resources;
use App\Filament\Exports\MfmMeterExporter;
use App\Filament\Imports\MfmMeterImporter;
use App\Filament\Resources\MfmMeterResource\Pages;
use App\Filament\Resources\MfmMeterResource\RelationManagers;
use App\Models\DeviceMaster;
use App\Models\MfmMeter;
use Filament\Facades\Filament;
use Filament\Forms;
@@ -14,6 +17,8 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
class MfmMeterResource extends Resource
{
@@ -32,6 +37,18 @@ class MfmMeterResource extends Resource
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->label('Plant')
->reactive()
->required(),
Forms\Components\Select::make('device_master_id')
//->relationship('device', 'name')
->options(function ($get) {
$plantId = $get('plant_id');
if (!$plantId) {
return [];
}
return DeviceMaster::where('plant_id', $plantId)->pluck('name', 'id');
})
->label('Device Name')
->required(),
Forms\Components\TextInput::make('sequence')
->required(),
@@ -49,13 +66,20 @@ class MfmMeterResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->sortable(),
Tables\Columns\TextColumn::make('devicemaster.name')
->label('Device Name')
->sortable(),
Tables\Columns\TextColumn::make('sequence')
->label('Sequence')
->sortable(),
@@ -91,6 +115,18 @@ class MfmMeterResource extends Resource
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(MfmMeterImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import mfm meter');
}),
ExportAction::make()
->exporter(MfmMeterExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export mfm meter');
}),
]);
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateMfmMeter extends CreateRecord
{
protected static string $resource = MfmMeterResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -36,6 +36,10 @@ class MfmParameterResource extends Resource
->label('Plant')
->relationship('plant', 'name')
->required(),
Forms\Components\Select::make('device_master_id')
->label('Device Master')
->relationship('deviceName', 'name')
->required(),
Forms\Components\Select::make('mfm_meter_id')
->label('Mfm Meter')
->relationship('mfmMeter', 'sequence')
@@ -61,7 +65,7 @@ class MfmParameterResource extends Resource
->default(1)
->required(),
])
->columns(8),
->columns(3),
]);
}
@@ -69,14 +73,22 @@ class MfmParameterResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('deviceName.name')
->label('Device Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('mfmMeter.name')
->label('Sequence')
->alignCenter()

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateMfmParameter extends CreateRecord
{
protected static string $resource = MfmParameterResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -60,11 +60,14 @@ class MfmReadingResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->alignCenter()
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateMfmReading extends CreateRecord
{
protected static string $resource = MfmReadingResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateModuleList extends CreateRecord
{
protected static string $resource = ModuleListResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -28,9 +28,9 @@ class MotorTestingMasterResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Master Entries';
protected static ?string $navigationGroup = 'Testing Panel';
protected static ?int $navigationSort = 12;
protected static ?int $navigationSort = 1;
public static function form(Form $form): Form
{
@@ -61,6 +61,11 @@ class MotorTestingMasterResource extends Resource
])
->hint(fn ($get) => $get('mTmError') ? $get('mTmError') : null)
->hintColor('danger'),
Forms\Components\TimePicker::make('routine_test_time')
->label('Routine Test Time')
->default('00:40:00')
->required()
->reactive(),
Forms\Components\Select::make('item_id')
->label('Item Code')
//->relationship('item', 'name')
@@ -82,11 +87,40 @@ class MotorTestingMasterResource extends Resource
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TimePicker::make('routine_test_time')
->label('Routine Test Time')
->default('00:40:00')
Forms\Components\TextInput::make('subassembly_code')
->label('Subassembly Code')
->required()
->reactive(),
->placeholder('Scan the valid code')
->reactive()
->alphaNum()
->minLength(6)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('subassembly_code');
// Ensure `linestop_id` is not cleared
if (!$code) {
$set('iCodeError', 'Scan the valid Subassembly Code.');
return;
}
else
{
if (strlen($code) < 6) {
$set('iCodeError', 'Subassembly code must be at least 6 digits.');
return;
}
else if (!preg_match('/^[a-zA-Z0-9]{6,}$/', $code)) {
$set('code',null);
$set('iCodeError', 'Subassembly code must contain only alpha-numeric characters.');
return;
}
$set('iCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iCodeError') ? $get('iCodeError') : null)
->hintColor('danger'),
Forms\Components\Select::make('isi_model')
->label('ISI Model')
->options([
@@ -296,6 +330,11 @@ class MotorTestingMasterResource extends Resource
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('subassembly_code')
->label('SubAssembly Code')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.description')
->label('Model')
->alignCenter()

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateMotorTestingMaster extends CreateRecord
{
protected static string $resource = MotorTestingMasterResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -7,6 +7,7 @@ use App\Filament\Imports\PalletValidationImporter;
use App\Filament\Resources\PalletValidationResource\Pages;
use App\Filament\Resources\PalletValidationResource\RelationManagers;
use App\Models\Item;
use App\Models\LocatorInvoiceValidation;
use App\Models\PalletValidation;
use App\Models\Plant;
use App\Models\StickerMaster;
@@ -89,13 +90,29 @@ class PalletValidationResource extends Resource
$month = now()->format('m');
$prefix = "EP-{$year}{$month}";
$lastPallet = PalletValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first(); //->where('plant_id', $plantId)
$lastPallet1 = PalletValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first(); //->where('plant_id', $plantId)
$lastPallet2 = LocatorInvoiceValidation::where('pallet_number', 'like', "{$prefix}%")->orderByDesc('pallet_number')->first();
$newNumber = '001'; // $lastPallet ? str_pad(intval(substr($lastPallet->pallet_number, -3)) + 1, 3, '0', STR_PAD_LEFT) : '001';
if ($lastPallet) {
$serialPart = substr($lastPallet->pallet_number, strlen($prefix));
if ($lastPallet1 && $lastPallet2) {
$serialPart1 = substr($lastPallet1->pallet_number, strlen($prefix));
$serialPart2 = substr($lastPallet2->pallet_number, strlen($prefix));
if (intval($serialPart1) > intval($serialPart2)) {
$newNumber = str_pad(intval($serialPart1) + 1, strlen($serialPart1), '0', STR_PAD_LEFT);
} else {
$newNumber = str_pad(intval($serialPart2) + 1, strlen($serialPart2), '0', STR_PAD_LEFT);
}
}
else if ($lastPallet1) {
$serialPart1 = substr($lastPallet1->pallet_number, strlen($prefix));
// OR
// $serialPart = str_replace($prefix, '', $lastPallet->pallet_number);
$newNumber = str_pad(intval($serialPart) + 1, strlen($serialPart), '0', STR_PAD_LEFT);
$newNumber = str_pad(intval($serialPart1) + 1, strlen($serialPart1), '0', STR_PAD_LEFT);
}
else if ($lastPallet2) {
$serialPart2 = substr($lastPallet2->pallet_number, strlen($prefix));
// OR
// $serialPart = str_replace($prefix, '', $lastPallet->pallet_number);
$newNumber = str_pad(intval($serialPart2) + 1, strlen($serialPart2), '0', STR_PAD_LEFT);
}
$newPalletNumber = "{$prefix}{$newNumber}";
@@ -521,7 +538,7 @@ class PalletValidationResource extends Resource
])
->action(function (array $data) {
$selectedPalletNumber = $data['pallet_list'];
return redirect()->route('download-qr-pdf', ['palletNo' => $selectedPalletNumber]);
return redirect()->route('download-reprint-qr-pdf', ['palletNo' => $selectedPalletNumber]);
})
->visible(function() {

View File

@@ -14,17 +14,22 @@ use Illuminate\View\View;
class CreatePalletValidation extends CreateRecord
{
public $plantId;
public $pallet_number;
public $palletNo;
public $pendingPallet;
public $snoCount = 0;
public $pallet_number_locked = false;
public $serial_number;
protected static string $view = 'filament.resources.pallet-validation-resource.pages.create-pallet-validation';
protected static string $resource = PalletValidationResource::class;
protected static string $view = 'filament.resources.pallet-validation-resource.pages.create-pallet-validation';
protected static string $resource = PalletValidationResource::class;
protected $listeners = [
'updateSnoQuantity' => 'handleUpdateSnoQuantity',
@@ -32,6 +37,10 @@ class CreatePalletValidation extends CreateRecord
public ?array $data = null;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
public function processPalletSNo()
{

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreatePlant extends CreateRecord
{
protected static string $resource = PlantResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -319,8 +319,10 @@ class ProductionQuantityResource extends Resource
->label('Production Order')
->reactive()
->required()
->minLength(7)
->maxLength(14)
->columnSpan(2)
// ->rules(['regex:/^[1-9][0-9]{6,}$/'])
//->rules(['regex:/^[1-9][0-9]{6,}$/'])
// ->disabled(function ($get) {
// return $get('item_code');
// })
@@ -332,15 +334,35 @@ class ProductionQuantityResource extends Resource
return $latestProduction ? $latestProduction->production_order : null;
})
->afterStateUpdated(function ($state, callable $get, callable $set): void {
$set('item_code', null);
$set('item_id', null);
// $set('item_description', null);
$set('serial_number', null);
$set('validationError', null);
return;
// if (empty($state)) {
// }
}),
if(!is_numeric($get('production_order')) || !preg_match('/^[1-9][0-9]{6,13}$/', $get('production_order')))
{
$set('item_code', null);
$set('item_id', null);
$set('serial_number', null);
$set('production_order', null);
$set('prodOrdError', "Must be a numeric value with 7 to 14 digits.");
$set('validationError', null);
return;
}
else
{
$set('item_code', null);
$set('item_id', null);
// $set('item_description', null);
$set('serial_number', null);
$set('production_order', $state);
$set('prodOrdError', null);
$set('validationError', null);
return;
// if (empty($state)) {
// }
}
})
->extraAttributes(fn ($get) => [
'class' => $get('prodOrdError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('prodOrdError') ? $get('prodOrdError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('item_code')
->label('Item Code')
// ->required()
@@ -1035,6 +1057,7 @@ class ProductionQuantityResource extends Resource
$set('Shift', null);
$set('Item', null);
$set('sap_msg_status', null);
$set('operator_id', null);
}),
//line
@@ -1050,7 +1073,10 @@ class ProductionQuantityResource extends Resource
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
})
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('operator_id', null);
}),
//block
Select::make('Block')
@@ -1067,6 +1093,7 @@ class ProductionQuantityResource extends Resource
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Shift', null);
$set('operator_id', null);
}),
//shift
@@ -1085,7 +1112,10 @@ class ProductionQuantityResource extends Resource
->where('block_id', $blockId)
->pluck('name', 'id');
})
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('operator_id', null);
}),
TextInput::make('production_order')
->label('Production Order')
@@ -1133,6 +1163,37 @@ class ProductionQuantityResource extends Resource
// ->options(QualityValidation::whereNotNull('sap_msg_status')->select('sap_msg_status')->distinct()->pluck('sap_msg_status', 'sap_msg_status'))
->reactive(),
Select::make('operator_id')
->label('Created By')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$lineId = $get('Line');
$shiftId = $get('Shift');
if (!$plantId && !$lineId && !$shiftId)
{
return ProductionQuantity::whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
else if ($plantId && !$lineId && !$shiftId)
{
return ProductionQuantity::where('plant_id', $plantId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
else if ($plantId && $lineId && !$shiftId)
{
return ProductionQuantity::where('plant_id', $plantId)->where('line_id', $lineId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
else if ($plantId && !$lineId && $shiftId)
{
return ProductionQuantity::where('plant_id', $plantId)->where('shift_id', $shiftId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
else// if ($plantId && $lineId && $shiftId)
{
return ProductionQuantity::where('plant_id', $plantId)->where('line_id', $lineId)->where('shift_id', $shiftId)->whereNotNull('operator_id')->select('operator_id')->distinct()->pluck('operator_id', 'operator_id');
}
})
->searchable()
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
@@ -1146,7 +1207,7 @@ class ProductionQuantityResource extends Resource
->native(false),
])
->query(function ($query, array $data) {
if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['production_order']) && empty($data['serial_number']) && empty($data['Item']) && empty($data['sap_msg_status']) && empty($data['created_from']) && empty($data['created_to'])) {
if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['production_order']) && empty($data['serial_number']) && empty($data['Item']) && empty($data['operator_id']) && empty($data['sap_msg_status']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -1178,6 +1239,10 @@ class ProductionQuantityResource extends Resource
$query->where('sap_msg_status', $data['sap_msg_status']);
}
if (!empty($data['operator_id'])) {
$query->where('operator_id', $data['operator_id']);
}
if ($from = $data['created_from'] ?? null) {
$query->where('created_at', '>=', $from);
}
@@ -1185,6 +1250,7 @@ class ProductionQuantityResource extends Resource
if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $to);
}
// return $query;
})
->indicateUsing(function (array $data) {
@@ -1218,6 +1284,10 @@ class ProductionQuantityResource extends Resource
$indicators[] = 'SAP Message Status: ' . $data['sap_msg_status'];
}
if (!empty($data['operator_id'])) {
$indicators[] = 'Created By: ' . $data['operator_id'];
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}

View File

@@ -335,7 +335,7 @@ class CreateProductionQuantity extends CreateRecord
->send();
return;
}
else if (!preg_match('/^[1-9][0-9]{6,}$/', $this->prodOrder))
else if (!preg_match('/^[1-9][0-9]{6,13}$/', $this->prodOrder))
{
$this->form->fill([
'plant_id'=> $this->pId,
@@ -354,7 +354,7 @@ class CreateProductionQuantity extends CreateRecord
Notification::make()
->title('Invalid Production Order')
->body("Must contain at least 7 digits.<br>Must start with a non-zero digit.")
->body("Must be a numeric value with 7 to 14 digits.<br>Must start with a non-zero digit.")
->danger()
->seconds(2)
->send();

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,11 @@ class CreateReworkLocatorInvoiceValidation extends CreateRecord
protected static string $resource = ReworkLocatorInvoiceValidationResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
public function processInvoiceRework($invoiceNo)
{
$plantId = $this->form->getState()['plant'];

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateShift extends CreateRecord
{
protected static string $resource = ShiftResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -3,12 +3,12 @@
namespace App\Filament\Resources;
use App\Filament\Exports\StickerMasterExporter;
use App\Filament\Imports\ShiftImporter;
//use App\Filament\Imports\ShiftImporter;
use App\Filament\Imports\StickerMasterImporter;
use App\Filament\Resources\StickerMasterResource\Pages;
use App\Filament\Resources\StickerMasterResource\RelationManagers;
//use App\Filament\Resources\StickerMasterResource\RelationManagers;
use App\Models\StickerMaster;
use Closure;
//use Closure;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
@@ -18,6 +18,7 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
// use Illuminate\Validation\Rule;
@@ -35,383 +36,401 @@ class StickerMasterResource extends Resource
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->reactive()
->nullable()
->default(function () {
return optional(StickerMaster::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => !empty($get('id'))) //disable in edit if user try to change
->afterStateUpdated(fn (callable $set) =>
$set('item_id', null) & //when plant changed remove all the data which is in text input box
$set('item_description', null) &
$set('item_error', null) &
$set('panel_box_code', null) &
$set('load_rate', null) &
$set('bundle_quantity', null) &
$set('material_type', null) &
$set('part_validation1', null) &
$set('part_validation2', null) &
$set('part_validation3', null) &
$set('part_validation4', null) &
$set('part_validation5', null) &
$set('laser_part_validation1', null) &
$set('laser_part_validation2', null) &
$set('serial_number_motor', false) &
$set('serial_number_pump', false) &
$set('serial_number_pumpset', false) &
$set('pack_slip_motor', false) &
$set('pack_slip_pump', false) &
$set('pack_slip_pumpset', false) &
$set('name_plate_motor', false) &
$set('name_plate_pump', false) &
$set('name_plate_pumpset', false) &
$set('tube_sticker_motor', false) &
$set('tube_sticker_pump', false) &
$set('tube_sticker_pumpset', false) &
$set('warranty_card', false)
)
->required(),
->schema([
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->reactive()
->nullable()
->default(function () {
return optional(StickerMaster::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => !empty($get('id'))) //disable in edit if user try to change
->afterStateUpdated(fn (callable $set) =>
$set('item_id', null) & //when plant changed remove all the data which is in text input box
$set('item_description', null) &
$set('item_error', null) &
$set('panel_box_code', null) &
$set('load_rate', null) &
$set('bundle_quantity', null) &
$set('material_type', null) &
$set('part_validation1', null) &
$set('part_validation2', null) &
$set('part_validation3', null) &
$set('part_validation4', null) &
$set('part_validation5', null) &
$set('laser_part_validation1', null) &
$set('laser_part_validation2', null) &
$set('serial_number_motor', false) &
$set('serial_number_pump', false) &
$set('serial_number_pumpset', false) &
$set('pack_slip_motor', false) &
$set('pack_slip_pump', false) &
$set('pack_slip_pumpset', false) &
$set('name_plate_motor', false) &
$set('name_plate_pump', false) &
$set('name_plate_pumpset', false) &
$set('tube_sticker_motor', false) &
$set('tube_sticker_pump', false) &
$set('tube_sticker_pumpset', false) &
$set('warranty_card', false)
)
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
Forms\Components\Select::make('item_id')
->label('Item Code')
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id')
->toArray();
})
// ->rule(function (callable $get) {
// return Rule::unique('items', 'code')
// ->where('plant_id', $get('plant_id'))
// ->ignore($get('id')); // Ignore current record during updates
// })
->required()
->nullable()
->searchable()
->reactive()
// ->disabled(fn (Get $get) => !empty($get('id')))
->live(debounce: 500) // Enable live updates
->afterStateUpdated(function ($state, callable $set, callable $get) {
return \App\Models\Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id')
->toArray();
})
// ->rule(function (callable $get) {
// return Rule::unique('items', 'code')
// ->where('plant_id', $get('plant_id'))
// ->ignore($get('id')); // Ignore current record during updates
// })
->required()
->nullable()
->searchable()
->reactive()
// ->disabled(fn (Get $get) => !empty($get('id')))
->live(debounce: 500) // Enable live updates
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$itemId = $get('item_id');
$plantId = $get('plant_id');
$itemId = $get('item_id');
//If plant_id is changed or empty, reset everything
if (blank($plantId)) {
$set('item_id', null);
$set('item_error', null);
$set('item_description', null);
return;
}
//If plant_id is changed or empty, reset everything
if (blank($plantId)) {
$set('item_id', null);
$set('item_error', null);
$set('item_description', null);
return;
}
if (blank($itemId)) {
$set('item_error', null);
$set('item_description', null);
return;
}
if (blank($itemId)) {
$set('item_error', null);
$set('item_description', null);
return;
}
$availableItems = \App\Models\Item::where('plant_id', $plantId)->exists();
if (!$availableItems) {
$set('item_error', null);
return;
}
$availableItems = \App\Models\Item::where('plant_id', $plantId)->exists();
if (!$availableItems) {
$set('item_error', null);
return;
}
// Ensure `item_id` is not cleared
if (!$plantId || !$itemId) {
$set('item_description', null);
return;
}
// Ensure `item_id` is not cleared
if (!$plantId || !$itemId) {
$set('item_description', null);
return;
}
// Check if item exists for the selected plant
$item = \App\Models\Item::where('plant_id', $plantId)
->where('id', $itemId)
->first();
// Check if item exists for the selected plant
$item = \App\Models\Item::where('plant_id', $plantId)
->where('id', $itemId)
->first();
if ($item) {
$set('item_description', $item->description);
} else {
$set('item_description', null);
}
if ($item) {
$set('item_description', $item->description);
} else {
$set('item_description', null);
}
$duplicateSticker = StickerMaster::where('plant_id', $plantId)
->where('item_id', $itemId)
->exists();
if(!$get('id'))
{
$set('item_error', $duplicateSticker ? 'Item Code already exists for the selected plant.' : null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('item_error') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('item_error') ? $get('item_error') : null)
->hintColor('danger'),
$duplicateSticker = StickerMaster::where('plant_id', $plantId)
->where('item_id', $itemId)
->exists();
if(!$get('id'))
{
$set('item_error', $duplicateSticker ? 'Item Code already exists for the selected plant.' : null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('item_error') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('item_error') ? $get('item_error') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('item_description')
->label('Description')
->required()
->afterStateHydrated(function ($component, $state, Get $get, Set $set) {
if ($get('id')) {
$itemId = StickerMaster::where('id', $get('id'))->first()?->item_id;
if ($itemId) {
$item = \App\Models\Item::where('id', $itemId)->first()?->description;
if ($item) {
$set('item_description', $item);
} else {
$set('item_description', null);
}
} else {
$set('item_description', null);
}
}
})
->reactive()
->readOnly(true),
Forms\Components\TextInput::make('part_validation1')
->label('Part Validation 1')
->nullable(),
Forms\Components\TextInput::make('item_description')
->label('Description')
->required()
->reactive()
->readOnly(true),
Forms\Components\TextInput::make('part_validation2')
->label('Part Validation 2')
->nullable(),
Forms\Components\TextInput::make('part_validation1')
->nullable(),
Forms\Components\TextInput::make('part_validation3')
->label('Part Validation 3')
->nullable(),
Forms\Components\TextInput::make('part_validation2')
->nullable(),
Forms\Components\TextInput::make('part_validation4')
->label('Part Validation 4')
->nullable(),
Forms\Components\TextInput::make('part_validation3')
->nullable(),
Forms\Components\TextInput::make('part_validation5')
->label('Part Validation 5 (Capacitor QR)')
->nullable(),
Forms\Components\TextInput::make('part_validation4')
->nullable(),
Forms\Components\TextInput::make('laser_part_validation1')
->label('Laser Part Validation 1')
->nullable(),
Forms\Components\TextInput::make('part_validation5')
->nullable(),
Forms\Components\TextInput::make('laser_part_validation2')
->label('Laser Part Validation 2')
->nullable(),
Forms\Components\TextInput::make('laser_part_validation1')
->nullable(),
Forms\Components\TextInput::make('panel_box_code')
->label('Panel Box Code')
->readOnly(fn (callable $get) => $get('material_type'))
->nullable(),
Forms\Components\TextInput::make('laser_part_validation2')
->nullable(),
Forms\Components\TextInput::make('load_rate')
->label('Load Rate')
->default(0)
->required()
->disabled(function ($get) {
return $get('material_type');
})
->integer(),
Forms\Components\TextInput::make('panel_box_code')
->label('Panel Box Code')
->readOnly(fn (callable $get) => $get('material_type'))
->nullable(),
Forms\Components\Select::make('material_type')
->label('Material Type')
->options([
'1' => 'Individual',
'2' => 'Bundle',
'3' => 'Quantity',
])
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
Forms\Components\TextInput::make('load_rate')
->label('Load Rate')
->default(0)
->disabled(function ($get) {
return $get('material_type');
})
->integer()
->nullable(),
if ($state)
{
$set('panel_box_code', null);
$set('load_rate', 0);
}
if ($state !== "2")
{
$set('bundle_quantity', null);
}
else
{
$set('bundle_quantity', 2);
}
//$plantId = $get('plant_id');
})
->nullable(),
Forms\Components\Select::make('material_type')
->label('Material Type')
->options([
'1' => 'Individual',
'2' => 'Bundle',
'3' => 'Quantity',
])
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
Forms\Components\TextInput::make('bundle_quantity')
->label('Bundle Quantity')
->integer()
->readOnly(fn (callable $get) => $get('material_type') !== "2")
->nullable()
->minValue(2)
->reactive()
->afterStateUpdated(function ($state, callable $set,callable $get) {
if($get('material_type') !== "2")
{
$set('bundle_quantity', null);
}
else if ($get('bundle_quantity') < 2)
{
$set('bundle_quantity', 2);
}
}),
if ($state)
{
$set('panel_box_code', null);
$set('load_rate', 0);
}
Forms\Components\Checkbox::make('serial_number_motor')
->reactive()
->disabled(function ($get) {
return $get('serial_number_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_motor', false);
}
})
->dehydrateStateUsing(fn ($state): mixed => $state ? $state : null),
if ($state !== "2")
{
$set('bundle_quantity', null);
}
else
{
$set('bundle_quantity', 2);
}
//$plantId = $get('plant_id');
})
->nullable(),
Forms\Components\Checkbox::make('serial_number_pump')
->reactive()
->disabled(function ($get) {
return $get('serial_number_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\TextInput::make('bundle_quantity')
->label('Bundle Quantity')
->integer()
->readOnly(fn (callable $get) => $get('material_type') !== "2")
->nullable()
->minValue(2)
->reactive()
->afterStateUpdated(function ($state, callable $set,callable $get) {
if($get('material_type') !== "2")
{
$set('bundle_quantity', null);
}
else if ($get('bundle_quantity') < 2)
{
$set('bundle_quantity', 2);
}
}),
Forms\Components\Checkbox::make('serial_number_pumpset')
->reactive()
->disabled(function ($get) {
return $get('serial_number_motor') || $get('serial_number_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_motor', false);
$set('serial_number_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('serial_number_motor')
->reactive()
->disabled(function ($get) {
return $get('serial_number_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_motor', false);
}
})
->dehydrateStateUsing(fn ($state): mixed => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_motor')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('serial_number_pump')
->reactive()
->disabled(function ($get) {
return $get('serial_number_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_pump')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('serial_number_pumpset')
->reactive()
->disabled(function ($get) {
return $get('serial_number_motor') || $get('serial_number_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('serial_number_pumpset'))
{
$set('serial_number_motor', false);
$set('serial_number_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_pumpset')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_motor') || $get('pack_slip_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_motor', false);
$set('pack_slip_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_motor')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_motor')
->reactive()
->disabled(function ($get) {
return $get('name_plate_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_pump')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_pump')
->reactive()
->disabled(function ($get) {
return $get('name_plate_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('pack_slip_pumpset')
->reactive()
->disabled(function ($get) {
return $get('pack_slip_motor') || $get('pack_slip_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('pack_slip_pumpset'))
{
$set('pack_slip_motor', false);
$set('pack_slip_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_pumpset')
->reactive()
->disabled(function ($get) {
return $get('name_plate_motor') || $get('name_plate_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_motor', false);
$set('name_plate_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_motor')
->reactive()
->disabled(function ($get) {
return $get('name_plate_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('tube_sticker_motor')
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_pump')
->reactive()
->disabled(function ($get) {
return $get('name_plate_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('tube_sticker_pump')
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('name_plate_pumpset')
->reactive()
->disabled(function ($get) {
return $get('name_plate_motor') || $get('name_plate_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('name_plate_pumpset'))
{
$set('name_plate_motor', false);
$set('name_plate_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('tube_sticker_pumpset')
->nullable()
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_motor') || $get('tube_sticker_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_motor', false);
$set('tube_sticker_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null), //to pass null value
Forms\Components\Checkbox::make('tube_sticker_motor')
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_motor', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('warranty_card')
->nullable()
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('tube_sticker_pump')
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_pumpset');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\Checkbox::make('tube_sticker_pumpset')
->nullable()
->reactive()
->disabled(function ($get) {
return $get('tube_sticker_motor') || $get('tube_sticker_pump');
})
->afterStateUpdated(function ($state, callable $set,callable $get) {
if ($get('tube_sticker_pumpset'))
{
$set('tube_sticker_motor', false);
$set('tube_sticker_pump', false);
}
})
->dehydrateStateUsing(fn ($state) => $state ? $state : null), //to pass null value
Forms\Components\Checkbox::make('warranty_card')
->nullable()
->dehydrateStateUsing(fn ($state) => $state ? $state : null),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
]);
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
]);
}
public static function table(Table $table): Table
@@ -424,13 +443,13 @@ class StickerMasterResource extends Resource
// ->numeric()
// ->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()

View File

@@ -21,4 +21,9 @@ class CreateStickerMaster extends CreateRecord
]);
}
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -2,6 +2,8 @@
namespace App\Filament\Resources;
use App\Filament\Exports\TempLiveReadingExporter;
use App\Filament\Imports\TempLiveReadingImporter;
use App\Filament\Resources\TempLiveReadingResource\Pages;
use App\Filament\Resources\TempLiveReadingResource\RelationManagers;
use App\Models\MfmMeter;
@@ -15,6 +17,9 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
class TempLiveReadingResource extends Resource
{
@@ -62,10 +67,14 @@ class TempLiveReadingResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->numeric()
->sortable(),
@@ -104,6 +113,18 @@ class TempLiveReadingResource extends Resource
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(TempLiveReadingImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import temp live reading');
}),
ExportAction::make()
->exporter(TempLiveReadingExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export temp live reading');
}),
]);
}
@@ -113,6 +134,16 @@ class TempLiveReadingResource extends Resource
//
];
}
public static function getNavigationLabel(): string
{
return 'Live Readings';
}
public static function getHeading(): string
{
return 'Live Readings';
}
public static function getPages(): array
{

View File

@@ -9,4 +9,14 @@ use Filament\Resources\Pages\CreateRecord;
class CreateTempLiveReading extends CreateRecord
{
protected static string $resource = TempLiveReadingResource::class;
public function getHeading(): string
{
return 'Create Live Readings';
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -19,4 +19,9 @@ class EditTempLiveReading extends EditRecord
Actions\RestoreAction::make(),
];
}
public function getHeading(): string
{
return 'Edit Live Readings';
}
}

View File

@@ -16,4 +16,9 @@ class ListTempLiveReadings extends ListRecords
Actions\CreateAction::make(),
];
}
public function getHeading(): string
{
return 'Live Readings';
}
}

View File

@@ -16,4 +16,9 @@ class ViewTempLiveReading extends ViewRecord
Actions\EditAction::make(),
];
}
public function getHeading(): string
{
return 'View Live Readings';
}
}

View File

@@ -2,13 +2,18 @@
namespace App\Filament\Resources;
use App\Filament\Exports\UserExporter;
use App\Filament\Imports\UserImporter;
use App\Filament\Resources\UserResource\Pages;
use App\Filament\Resources\UserResource\RelationManagers;
use App\Models\User;
use Filament\Facades\Filament;
use Filament\Forms;
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\Model;
@@ -80,6 +85,7 @@ class UserResource extends Resource
// ->label('ID')
// ->numeric()
// ->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
@@ -91,18 +97,23 @@ class UserResource extends Resource
Tables\Columns\TextColumn::make('name')
->label('User Name')
->alignCenter()
->sortable()
->searchable(),
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('email')
->label('Email')
->alignCenter()
->sortable()
->searchable(),
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('email_verified_at')
->label('Email Verified At')
->dateTime()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('roles.name')
->label('Roles')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
@@ -134,6 +145,18 @@ class UserResource extends Resource
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(UserImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import user');
}),
ExportAction::make()
->exporter(UserExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export user');
}),
]);
}

View File

@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -0,0 +1,553 @@
<?php
namespace App\Filament\Widgets;
use App\Models\MfmReading;
use Carbon\Carbon;
use Filament\Widgets\ChartWidget;
use Filament\Support\RawJs;
class TrendChartAnalysis extends ChartWidget
{
protected static ?string $heading = 'Trend Chart Analysis';
protected static ?string $maxHeight = '420px';
protected int|string|array $columnSpan = 12;
// Add a property to receive filters from parent or externally
protected function getData(): array
{
$fromDatetime = session('from_datetime');
$toDatetime = session('to_datetime');
$selectedPlant = session('selected_plant');
$meterId = session('selected_meter');
$parameter = session('parameter');
if (empty($fromDatetime) || empty($toDatetime) || empty($selectedPlant) || empty($meterId) || empty($parameter)) {
return [
'labels' => [],
'datasets' => [],
];
}
$fromDateTime = Carbon::parse($fromDatetime);
$toDateTime = Carbon::parse($toDatetime);
if ($fromDateTime->gt($toDateTime) || $fromDateTime->gt(now()) || $toDateTime->gt(now())) {
return [
'labels' => [],
'datasets' => [],
];
}
$durationHours = $fromDateTime->diffInHours($toDateTime);
//dd($durationHours);
if ($durationHours < 1 || $durationHours > 24) {
return [
'labels' => [],
'datasets' => [],
];
}
$intervalCount = $durationHours > 12 ? 12 : 10;
$intervalMinutes = $durationHours > 12 ? 120 : floor(($durationHours * 60) / $intervalCount);
$labels = [];
if ($parameter == 'Phase Voltage') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$voltageRYSummary = $dataAggregation('voltage_ry');
$voltageYBSummary = $dataAggregation('voltage_yb');
$voltageBRSummary = $dataAggregation('voltage_br');
$frequencySummary = $dataAggregation('frequency');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'Voltage RY Min', 'Voltage RY Max', 'Voltage RY Avg',
'Voltage YB Min', 'Voltage YB Max', 'Voltage YB Avg',
'Voltage BR Min', 'Voltage BR Max', 'Voltage BR Avg',
'Frequency Min', 'Frequency Max', 'Frequency Avg',
];
// Ordered data values matching labels above
$dataValues = [
$voltageRYSummary['min'], $voltageRYSummary['max'], $voltageRYSummary['avg'],
$voltageYBSummary['min'], $voltageYBSummary['max'], $voltageYBSummary['avg'],
$voltageBRSummary['min'], $voltageBRSummary['max'], $voltageBRSummary['avg'],
$frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else if ($parameter == 'Line Voltage') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$voltageRNSummary = $dataAggregation('voltage_r_n');
$voltageYNSummary = $dataAggregation('voltage_y_n');
$voltageBNSummary = $dataAggregation('voltage_b_n');
$frequencySummary = $dataAggregation('frequency');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'Voltage RN Min', 'Voltage RN Max', 'Voltage RN Avg',
'Voltage YN Min', 'Voltage YN Max', 'Voltage YN Avg',
'Voltage BN Min', 'Voltage BN Max', 'Voltage BN Avg',
'Frequency Min', 'Frequency Max', 'Frequency Avg',
];
// Ordered data values matching labels above
$dataValues = [
$voltageRNSummary['min'], $voltageRNSummary['max'], $voltageRNSummary['avg'],
$voltageYNSummary['min'], $voltageYNSummary['max'], $voltageYNSummary['avg'],
$voltageBNSummary['min'], $voltageBNSummary['max'], $voltageBNSummary['avg'],
$frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else if ($parameter == 'Current') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$curR = $dataAggregation('current_r');
$curY = $dataAggregation('current_y');
$curB = $dataAggregation('current_b');
$curN = $dataAggregation('current_n');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'Current R Min', 'Current R Max', 'Current R Avg',
'Current Y Min', 'Current Y Max', 'Current Y Avg',
'Current B Min', 'Current B Max', 'Current B Avg',
'Current N Min', 'Current N Max', 'Current N Avg',
];
// Ordered data values matching labels above
$dataValues = [
$curR['min'], $curR['max'], $curR['avg'],
$curY['min'], $curY['max'], $curY['avg'],
$curB['min'], $curB['max'], $curB['avg'],
$curN['min'], $curN['max'], $curN['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else if ($parameter == 'Active Power') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$activePowR = $dataAggregation('active_power_r');
$activePowY = $dataAggregation('active_power_y');
$activePowB = $dataAggregation('active_power_b');
$activePowTot = $dataAggregation('active_power_total');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'ActivePow R Min', 'ActivePow R Max', 'ActivePow R Avg',
'ActivePow Y Min', 'ActivePow Y Max', 'ActivePow Y Avg',
'ActivePow B Min', 'ActivePow B Max', 'ActivePow B Avg',
'ActivePow Tot Min', 'ActivePow Tot Max', 'ActivePow Tot Avg',
];
// Ordered data values matching labels above
$dataValues = [
$activePowR['min'], $activePowR['max'], $activePowR['avg'],
$activePowY['min'], $activePowY['max'], $activePowY['avg'],
$activePowB['min'], $activePowB['max'], $activePowB['avg'],
$activePowTot['min'], $activePowTot['max'], $activePowTot['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else if ($parameter == 'Power Factor') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$powFacR = $dataAggregation('power_factor_r');
$powFacY = $dataAggregation('power_factor_y');
$powFacB = $dataAggregation('power_factor_b');
$powFacTot = $dataAggregation('power_factor_total');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'PowerFac R Min', 'PowerFac R Max', 'PowerFac R Avg',
'PowerFac Y Min', 'PowerFac Y Max', 'PowerFac Y Avg',
'PowerFac B Min', 'PowerFac B Max', 'PowerFac B Avg',
'PowerFac Tot Min', 'PowerFac Tot Max', 'PowerFac Tot Avg',
];
// Ordered data values matching labels above
$dataValues = [
$powFacR['min'], $powFacR['max'], $powFacR['avg'],
$powFacY['min'], $powFacY['max'], $powFacY['avg'],
$powFacB['min'], $powFacB['max'], $powFacB['avg'],
$powFacTot['min'], $powFacTot['max'], $powFacTot['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else if ($parameter == 'Units') {
// Helper function to get min, max, avg for a column with PostgreSQL casting
$dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
$min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
$avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
->where('mfm_meter_id', $meterId)
->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
return [
'min' => round($min ?? 0, 2),
'max' => round($max ?? 0, 2),
'avg' => round($avg ?? 0, 2),
];
};
// Get aggregated data for all relevant columns
$appEneRec = $dataAggregation('apparent_energy_received');
$reaEneRec = $dataAggregation('reactive_energy_received');
$actEneRec = $dataAggregation('active_energy_received');
// Labels for each bar on X-axis (min, max, avg per column)
$labels = [
'AppEneRec Min', 'AppEneRec Max', 'AppEneRec Avg',
'ReaEneRec Min', 'ReaEneRec Max', 'ReaEneRec Avg',
'ActEneRec Min', 'ActEneRec Max', 'ActEneRec Avg',
];
// Ordered data values matching labels above
$dataValues = [
$appEneRec['min'], $appEneRec['max'], $appEneRec['avg'],
$reaEneRec['min'], $reaEneRec['max'], $reaEneRec['avg'],
$actEneRec['min'], $actEneRec['max'], $actEneRec['avg'],
];
// Colors by aggregation type: Min - yellow, Max - green, Avg - blue
$aggregationColors = [
'rgba(204, 163, 0, 0.8)', // Darker yellow (Min)
'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max)
'rgba(30, 90, 140, 0.8)', // Darker blue (Avg)
];
// Each set of 3 bars per column repeats the colors: min, max, avg
$backgroundColorArray = [];
foreach (range(1, 4) as $group) { // 4 column groups
foreach ($aggregationColors as $color) {
$backgroundColorArray[] = $color;
}
}
// Construct chart data structure
return [
'labels' => $labels,
'datasets' => [
[
'label' => 'Phase Voltage & Frequency Stats',
// Bar values array: 12 bars total (4 groups × 3 stats each)
'data' => $dataValues,
'backgroundColor' => $backgroundColorArray,
'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
'borderWidth' => 1,
],
],
];
}
else
{
$data = [];
$labels = [];
$currentStart = $fromDateTime->copy();
return [
'labels' => $labels,
'datasets' => [
[
'label' => ucfirst(str_replace('_', ' ', $parameter)),
'data' => $data,
'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
'borderColor' => 'rgba(75, 192, 192, 1)',
'fill' => false,
'tension' => 0.3,
'pointRadius' => 5,
'pointHoverRadius' => 7,
],
],
];
}
}
protected function getOptions(): array
{
return [
'plugins' => [
'datalabels' => [
'anchor' => 'start',
'align' => 'start',
'offset' => -15,
'color' => '#000',
'font' => [
'weight' => 'bold',
],
'formatter' => RawJs::make('function(value) {
return value;
}'),
],
],
'scales' => [
'y' => [
'beginAtZero' => true,
'ticks' => [
'stepSize' => 1,
],
],
],
];
}
protected function getType(): string
{
return 'bar';
}
}

View File

@@ -0,0 +1,206 @@
<?php
namespace App\Filament\Widgets;
use App\Models\MfmReading;
use Carbon\Carbon;
use Filament\Widgets\ChartWidget;
class TrendLineChart extends ChartWidget
{
protected static ?string $heading = 'Trend Line Analysis';
protected static ?string $maxHeight = '420px';
protected int|string|array $columnSpan = 12;
protected function getData(): array
{
$fromDatetime = session('from_datetime');
$toDatetime = session('to_datetime');
$selectedPlant = session('selected_plant');
$meterId = session('selected_meter');
$parameter = session('parameter');
if (empty($fromDatetime) || empty($toDatetime) || empty($selectedPlant) || empty($meterId) || empty($parameter)) {
return [
'labels' => [],
'datasets' => [],
];
}
$fromDateTime = Carbon::parse($fromDatetime);
$toDateTime = Carbon::parse($toDatetime);
if ($fromDateTime->gt($toDateTime) || $fromDateTime->gt(now()) || $toDateTime->gt(now())) {
return [
'labels' => [],
'datasets' => [],
];
}
$durationHours = $fromDateTime->diffInHours($toDateTime);
if ($durationHours < 1 || $durationHours > 24) {
return [
'labels' => [],
'datasets' => [],
];
}
$intervalCount = $durationHours > 12 ? 12 : 10;
$intervalMinutes = $durationHours > 12 ? 120 : floor(($durationHours * 60) / $intervalCount);
$labels = [];
$columnMap = [];
$datasetColors = [];
$dataSeries = [];
// Determine columns and labels based on selected parameter
switch ($parameter) {
case 'Phase Voltage':
$columnMap = [
'voltage_ry' => 'Voltage RY Max',
'voltage_yb' => 'Voltage YB Max',
'voltage_br' => 'Voltage BR Max',
'frequency' => 'Frequency Max',
];
$datasetColors = [
'voltage_ry' => 'rgba(255, 99, 132, 1)', // red
'voltage_yb' => 'rgba(54, 162, 235, 1)', // blue
'voltage_br' => 'rgba(255, 206, 86, 1)', // yellow
'frequency' => 'rgba(75, 192, 192, 1)', // teal
];
break;
case 'Line Voltage':
$columnMap = [
'voltage_r_n' => 'Voltage R-N Max',
'voltage_y_n' => 'Voltage Y-N Max',
'voltage_b_n' => 'Voltage B-N Max',
'frequency' => 'Frequency Max',
];
$datasetColors = [
'voltage_r_n' => 'rgba(153, 102, 255, 1)', // purple
'voltage_y_n' => 'rgba(255, 159, 64, 1)', // orange
'voltage_b_n' => 'rgba(0, 200, 83, 1)', // green
'frequency' => 'rgba(75, 192, 192, 1)', // teal
];
break;
case 'Current':
$columnMap = [
'current_r' => 'Current R Max',
'current_y' => 'Current Y Max',
'current_b' => 'Current B Max',
'current_n' => 'Current N Max ',
];
$datasetColors = [
'current_r' => 'rgba(153, 102, 255, 1)', // purple
'current_y' => 'rgba(255, 159, 64, 1)', // orange
'current_b' => 'rgba(0, 200, 83, 1)', // green
'current_n' => 'rgba(75, 192, 192, 1)', // teal
];
break;
case 'Active Power':
$columnMap = [
'active_power_r' => 'Active Pow R Max',
'active_power_y' => 'Active Pow Y Max',
'active_power_b' => 'Active Pow B Max',
'active_power_total' => 'Active Pow Tot Max ',
];
$datasetColors = [
'active_power_r' => 'rgba(153, 102, 255, 1)', // purple
'active_power_y' => 'rgba(255, 159, 64, 1)', // orange
'active_power_b' => 'rgba(0, 200, 83, 1)', // green
'active_power_total' => 'rgba(75, 192, 192, 1)', // teal
];
break;
case 'Power Factor':
$columnMap = [
'power_factor_r' => 'Power Fac R Max',
'power_factor_y' => 'Power Fac Y Max',
'power_factor_b' => 'Power Fac B Max',
'power_factor_total' => 'Power Fac Tot Max ',
];
$datasetColors = [
'power_factor_r' => 'rgba(153, 102, 255, 1)', // purple
'power_factor_y' => 'rgba(255, 159, 64, 1)', // orange
'power_factor_b' => 'rgba(0, 200, 83, 1)', // green
'power_factor_total' => 'rgba(75, 192, 192, 1)', // teal
];
break;
case 'Units':
$columnMap = [
'apparent_energy_received' => 'AppEneRec Max',
'reactive_energy_received' => 'ReacEneRec Max',
'active_energy_received' => 'ActiveEneRec Max',
];
$datasetColors = [
'apparent_energy_received' => 'rgba(153, 102, 255, 1)', // purple
'reactive_energy_received' => 'rgba(255, 159, 64, 1)', // orange
'active_energy_received' => 'rgba(0, 200, 83, 1)', // green
];
break;
default:
return [
'labels' => [],
'datasets' => [],
];
}
// Initialize empty arrays for each data series
foreach ($columnMap as $column => $label) {
$dataSeries[$column] = [];
}
$current = $fromDateTime->copy();
while ($current < $toDateTime) {
$next = $current->copy()->addMinutes($intervalMinutes);
$selectParts = [];
foreach ($columnMap as $column => $label) {
$selectParts[] = "MAX({$column}::double precision) as {$column}";
}
$readings = MfmReading::where('mfm_meter_id', $meterId)
->whereBetween('created_at', [$current, $next])
->selectRaw(implode(', ', $selectParts))
->first();
$labels[] = $current->format('H:i');
foreach ($columnMap as $column => $label) {
$dataSeries[$column][] = round($readings->{$column} ?? 0, 2);
}
$current = $next;
}
// Construct dataset array
$datasets = [];
foreach ($columnMap as $column => $label) {
$datasets[] = [
'label' => $label,
'data' => $dataSeries[$column],
'borderColor' => $datasetColors[$column],
'backgroundColor' => str_replace('1)', '0.2)', $datasetColors[$column]),
'fill' => false,
'tension' => 0.1,
];
}
return [
'labels' => $labels,
'datasets' => $datasets,
];
}
protected function getType(): string
{
return 'line';
}
}

View File

@@ -0,0 +1,811 @@
<?php
namespace App\Http\Controllers;
use App\Models\InvoiceValidation;
use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use Illuminate\Http\Request;
use Str;
class InvoiceValidationController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function serialInvoice(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!'
], 403);
}
try
{
$data = $request->all();
if (!isset($data['plant_code']) || trim($data['plant_code']) == '')
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
], 400);
}
else if (Str::length($data['plant_code']) < 4 || !is_numeric($data['plant_code']) || !preg_match('/^[1-9]\d{3,}$/', $data['plant_code']))
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
], 400);
}
$plant = Plant::where('code', $data['plant_code'])->first();
if (!$plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Plant not found!'
], 400);
}
$plantId = $plant->id;
if (!isset($data['item_codes']) || !is_array($data['item_codes']) || count($data['item_codes']) == 0)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'item_codes is required and must be a non-empty array!'
], 400);
}
//..Checking invoice number for empty or invalid length
$invoiceNumber = $data['invoice_number'] ?? null;
if (!$invoiceNumber || trim($invoiceNumber) == '')
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'invoice_number is required!'
], 400);
}
else if (strlen(trim($invoiceNumber)) < 7)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'invoice number must contain at least 7 alphanumeric characters.'
], 400);
}
//..Checking item codes for invalid length
$invalidItem = [];
foreach ($data['item_codes'] as $item) {
if (!isset($item['item_code']) || strlen(trim($item['item_code'])) < 6) {
$invalidItem[] = $item['item_code'] ?? '(missing item_code)';
}
}
if (!empty($invalidItem)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item codes have invalid length (less than 6 characters)',
'invalid_item_codes' => $invalidItem
], 400);
}
//..Checking item codes for invalid characters
$invalidItemCodes = [];
foreach ($data['item_codes'] as $item)
{
$itemCode = $item['item_code'] ?? '';
$trimmedCode = trim($itemCode);
if ($trimmedCode == '' || !ctype_alnum($trimmedCode))
{
$invalidItemCodes[] = $item;
}
}
if (!empty($invalidItemCodes)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item_code(s) contain invalid characters (only alphanumeric allowed).',
'invalid_item_codes' => array_map(function($item) {
return $item['item_code'] ?? '(missing item_code)';
}, $invalidItemCodes)
], 400);
}
//..Checking serial numbers for length less than 9 characters
$invalidSerials = [];
foreach ($data['item_codes'] as $item) {
if (isset($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
if (strlen(trim($serial)) < 9)
{
$invalidSerials[] = $serial;
}
}
}
}
if (!empty($invalidSerials)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following serial numbers have invalid length (less than 9 characters)',
'invalid_serial_numbers' => $invalidSerials
], 400);
}
//..Checking serial numbers for invalid characters
$invalidSerialNumbers = [];
foreach ($data['item_codes'] as $item) {
if (isset($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
$trimmedSerial = trim($serial);
if ($trimmedSerial == '' || !ctype_alnum($trimmedSerial)) {
$invalidSerialNumbers[] = $serial;
}
}
}
}
if (!empty($invalidSerialNumbers)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following serial number(s) contain invalid characters (only alphanumeric allowed).',
'invalid_serial_numbers' => $invalidSerialNumbers
], 400);
}
//Duplicate item code within json payload
$duplicateItemCode = [];
$seenCodes = [];
foreach ($data['item_codes'] as $item)
{
$code = $item['item_code'] ?? null;
if ($code == null) {
continue;
}
if (in_array($code, $seenCodes))
{
if (!in_array($code, array_column($duplicateItemCode, 'item_code'))) {
$duplicateItemCode[] = $item;
}
}
else
{
$seenCodes[] = $code;
}
}
if (!empty($duplicateItemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Duplicate item_code found in request payload.",
'duplicate_item_codes' => array_map(function($item) {
return $item['item_code'] ?? '(missing item_code)';
}, $duplicateItemCode)
], 400);
}
//Duplicate serial numbers within all item_codes
$duplicateSno = [];
$seenSerials = [];
foreach ($data['item_codes'] as $item)
{
if (isset($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
if (in_array($serial, $seenSerials)) {
if (!in_array($serial, $duplicateSno)) {
$duplicateSno[] = $serial;
}
} else {
$seenSerials[] = $serial;
}
}
}
}
if (!empty($duplicateSno)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Duplicate serial number found in request payload.",
'duplicate_serial_numbers' => $duplicateSno
], 400);
}
//..Checking invoice number against plant in invoice validation table
$totQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->count();
if ($totQuan > 0)
{
$scanSQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->count();
if ($totQuan == $scanSQuan)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Serial invoice number : '$invoiceNumber' completed the scanning process. Scan the next 'Serial Invoice' to proceed!",
], 400);
}
else
{
$invoiceFirst = InvoiceValidation::with('plant')->where('invoice_number', $invoiceNumber)->first();
$plantCode = $invoiceFirst ? (String)$invoiceFirst->plant->code : null;
if ($data['plant_code'] != $plantCode)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Serial invoice number : '$invoiceNumber' already exists for plant code : '$plantCode'. Pass the valid 'Plant Code' proceed!",
], 400);
}
}
}
//In item codes array serial numbers not exists
$snoNotExist = [];
foreach ($data['item_codes'] as $item)
{
if (!isset($item['item_code']) || !isset($item['serial_numbers']) || !is_array($item['serial_numbers']))
{
//$snoNotExist[] = $item;
$snoNotExist[] = $item['item_code'] ?? '(missing item_code)';
}
}
if(!empty($snoNotExist)){
return response()->json([
'status_code' => 'ERROR',
'status_description' => "item_codes array must have an item_code and an array of serial_numbers below item code doesn't have serial number array.",
'item_codes' => $snoNotExist
], 400);
}
$notFoundItemCodes = [];
foreach ($data['item_codes'] as $item)
{
$itemRecord = Item::where('code', $item['item_code'])->first();
if (!$itemRecord) {
$notFoundItemCodes[] = $item['item_code'];
}
else
{
$itemId = $itemRecord->id;
}
}
if (!empty($notFoundItemCodes)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in items table",
'item_codes' =>$notFoundItemCodes
], 400);
}
//..Checking Item Code aginst Plant in items table
$plant = Plant::find($plantId);
$notFouItePlant = [];
foreach ($data['item_codes'] as $item)
{
$itemRec = Item::where('code', $item['item_code'])
->where('plant_id', $plantId)
->first();
if (!$itemRec) {
$notFouItePlant[] = $item['item_code'];
}
}
if (!empty($notFouItePlant)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in items table for plant '" . ($plant ? $plant->name : 'Unknown'). "'",
'item_codes' => $notFouItePlant
], 400);
}
$notFouItemCodesStiMas = [];
foreach ($data['item_codes'] as $item) {
$itemRecord = Item::where('code', $item['item_code'])->first();
if ($itemRecord) {
$itemId = $itemRecord->id;
$stickerMasterRecord = StickerMaster::where('item_id', $itemId)->first();
if (!$stickerMasterRecord) {
$notFouItemCodesStiMas[] = $item['item_code'];
}
}
else
{
$notFouItemCodesStiMas[] = $item['item_code'];
}
}
if (!empty($notFouItemCodesStiMas)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item code(s) were not found in sticker master table',
'item_codes' => $notFouItemCodesStiMas
], 400);
}
//..Checking Item Code in sticker master table aginst Plant
$notFouIteStickerPlant = [];
foreach ($data['item_codes'] as $item)
{
$stickerMasterRec = StickerMaster::where('item_id', $itemId)
->where('plant_id', $plantId)
->first();
if (!$stickerMasterRec) {
$notFouIteStickerPlant[] = $item['item_code'];
}
}
if (!empty($notFouIteStickerPlant)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in sticker master table for plant'" . ($plant ? $plant->name : 'Unknown'). "'",
'item_codes' => $notFouIteStickerPlant
], 400);
}
$invalidSerialMasType = [];
foreach ($data['item_codes'] as $item) {
$itemRecord = Item::where('code', $item['item_code'])->first();
$itemId = $itemRecord->id;
$stickerMaster = StickerMaster::where('item_id', $itemId)
->where('plant_id', $plantId)
->whereNotNull('material_type')
->where('material_type', '!=', 0)
->first();
if ($stickerMaster) {
$invalidSerialMasType[] = $item['item_code'];
}
}
if (!empty($invalidSerialMasType)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item code(s) not belongs to serial invoice type in sticker master table',
'item_codes' => $invalidSerialMasType
], 400);
}
if ($totQuan > 0)
{
$scanSQuan = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
$allSerialNumbers = [];
foreach ($data['item_codes'] as $item) {
if (isset($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
$allSerialNumbers[] = $serial;
}
}
}
// Check database for existing serial numbers for this plant
$existingSerials = InvoiceValidation::where('plant_id', $plantId)
->where('invoice_number', '!=', $invoiceNumber)
->whereIn('serial_number', $allSerialNumbers)
->pluck('serial_number')
->toArray();
if (!empty($existingSerials)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'serial numbers already exist for this plant in database.',
'duplicate_serial_numbers' => $existingSerials,
], 400);
}
InvoiceValidation::where('invoice_number', $invoiceNumber)
->where(function($query) {
$query->whereNull('motor_scanned_status')->orWhere('motor_scanned_status', '');
})
->where(function($query) {
$query->whereNull('pump_scanned_status')->orWhere('pump_scanned_status', '');
})
->where(function($query) {
$query->whereNull('capacitor_scanned_status')->orWhere('capacitor_scanned_status', '');
})
->where(function($query) {
$query->whereNull('scanned_status_set')->orWhere('scanned_status_set', '');
})
->where(function($query) {
$query->whereNull('scanned_status')->orWhere('scanned_status', '');
})
->forceDelete(); //->delete();
try
{
foreach ($data['item_codes'] as $item)
{
$stickerMasterId = $stickerMasterRecord->id;
if (!isset($item['serial_numbers']) || !is_array($item['serial_numbers'])) {
continue;
}
foreach ($item['serial_numbers'] as $serial)
{
$exists = InvoiceValidation::where('invoice_number', $invoiceNumber)
->where('serial_number', $serial)
->first();
if ($exists)
{
$exists->updated_at = now();
$exists->save();
continue;
}
else
{
InvoiceValidation::create([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'item_code' => $item['item_code'],
'serial_number' => $serial,
'sticker_master_id' => $stickerMasterId,
'updated_at' => now(),
]);
}
}
}
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Serial Invoice imported successfully!'
], 200);
}
catch (\Exception $e) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Failed to insert one or more serial invoice records: ' . $e->getMessage(),
], 500);
}
}
else
{
$allSerialNumbers = [];
foreach ($data['item_codes'] as $item) {
if (isset($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial)
{
$allSerialNumbers[] = $serial;
}
}
}
// Check database for existing serial numbers for this plant
$existingSerials = InvoiceValidation::where('plant_id', $plantId)
->whereIn('serial_number', $allSerialNumbers)
->pluck('serial_number')
->toArray();
if (!empty($existingSerials)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'serial numbers already exist for this plant in database.',
'duplicate_serial_numbers' => $existingSerials,
], 400);
}
//..
try
{
foreach ($data['item_codes'] as $item)
{
$stickerMasterId = $stickerMasterRecord->id;
foreach ($item['serial_numbers'] as $serial)
{
InvoiceValidation::create([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'item_code' => $item['item_code'],
'serial_number' => $serial,
'sticker_master_id' => $stickerMasterId,
]);
}
}
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Serial Invoice imported successfully!'
], 200);
}
catch (\Exception $e)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Failed to insert one or more serial invoice records: ' . $e->getMessage(),
], 500);
}
}
}
catch (\Exception $e)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => $e->getMessage(),
], 500);
}
}
public function materialInvoice(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!'
], 403);
}
try
{
$data = $request->all();
if (!isset($data['plant_code']) || trim($data['plant_code']) == '')
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
], 400);
}
else if (Str::length($data['plant_code']) < 4 || !is_numeric($data['plant_code']) || !preg_match('/^[1-9]\d{3,}$/', $data['plant_code']))
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
], 400);
}
$plant = Plant::where('code', $data['plant_code'])->first();
if (!$plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Plant not found!'
], 400);
}
$plantId = $plant->id;
$invoiceNumber = $data['invoice_number'] ?? null;
if (!$invoiceNumber || trim($invoiceNumber) == '')
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'invoice_number is required!'
], 400);
}
else if (strlen(trim($invoiceNumber)) < 7)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'invoice number must contain at least 7 alphanumeric characters.'
], 400);
}
//..Checking item codes for invalid length
$invalidItem = [];
foreach ($data['item_codes'] as $item) {
if (!isset($item['item_code']) || strlen(trim($item['item_code'])) < 6) {
$invalidItem[] = $item['item_code'] ?? '(missing item_code)';
}
}
if (!empty($invalidItem)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item codes have invalid length (less than 6 characters)',
'invalid_item_codes' => $invalidItem
], 400);
}
//..Checking item codes for invalid characters
$invalidItemCodes = [];
foreach ($data['item_codes'] as $item)
{
$itemCode = $item['item_code'] ?? '';
$trimmedCode = trim($itemCode);
if ($trimmedCode == '' || !ctype_alnum($trimmedCode))
{
$invalidItemCodes[] = $item;
}
}
if (!empty($invalidItemCodes)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item_code(s) contain invalid characters (only alphanumeric allowed).',
'invalid_item_codes' => array_map(function($item) {
return $item['item_code'] ?? '(missing item_code)';
}, $invalidItemCodes)
], 400);
}
//..Checking item codes in items table
$notFoundItemCodes = [];
foreach ($data['item_codes'] as $item)
{
$itemRecord = Item::where('code', $item['item_code'])->first();
if (!$itemRecord) {
$notFoundItemCodes[] = $item['item_code'];
}
}
$itemId = $itemRecord->id;
if (!empty($notFoundItemCodes)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in items table",
'item_codes' =>$notFoundItemCodes
], 400);
}
//..Checking Item Code in sticker master table
$notFouItemCodesStiMas = [];
foreach ($data['item_codes'] as $item)
{
$stickerMasterRecord = StickerMaster::where('item_id', $itemId)->first();
if (!$stickerMasterRecord) {
$notFouItemCodesStiMas[] = $item['item_code'];
}
}
if (!empty($notFouItemCodesStiMas)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item code(s) were not found in sticker master table',
'item_codes' => $notFouItemCodesStiMas
], 400);
}
//..Checking Item Code aginst Plant in items table
$plant = Plant::find($plantId);
$notFouItePlant = [];
foreach ($data['item_codes'] as $item)
{
$itemRec = Item::where('code', $item['item_code'])
->where('plant_id', $plantId)
->first();
if (!$itemRec) {
$notFouItePlant[] = $item['item_code'];
}
}
if (!empty($notFouItePlant)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in items table for plant '" . ($plant ? $plant->name : 'Unknown'). "'",
'item_codes' => $notFouItePlant
], 400);
}
//..Checking Item Code in sticker master table aginst Plant
$notFouIteStickerPlant = [];
foreach ($data['item_codes'] as $item)
{
$stickerMasterRec = StickerMaster::where('item_id', $itemId)
->where('plant_id', $plantId)
->first();
if (!$stickerMasterRec) {
$notFouIteStickerPlant[] = $item['item_code'];
}
}
if (!empty($notFouIteStickerPlant)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The following item code(s) were not found in sticker master table for plant'" . ($plant ? $plant->name : 'Unknown'). "'",
'item_codes' => $notFouIteStickerPlant
], 400);
}
$invalidMaterialType = [];
foreach ($data['item_codes'] as $item) {
$itemRecord = Item::where('code', $item['item_code'])->first();
$itemId = $itemRecord->id;
$stickerMaster = StickerMaster::where('item_id', $itemId)
->where('plant_id', $plantId)
->where(function($query) {
$query->whereNull('material_type')
->orWhere('material_type', 0);
})
->first();
if ($stickerMaster) {
$invalidMaterialType[] = $item['item_code'];
}
}
if (!empty($invalidMaterialType)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'The following item code(s) belongs to seial invoice type in sticker master table',
'item_codes' => $invalidMaterialType
], 400);
}
foreach ($data['item_codes'] as $item)
{
$quantity = isset($item['item_quantity']) ? (int)$item['item_quantity'] : null;
InvoiceValidation::create([
'plant_id' => $plantId,
'item_code' => $item['item_code'],
'item_quantity' => $quantity,
'created_at' => now(),
'updated_at' => now(),
]);
}
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Invoice validation records inserted successfully.'
], 200);
}
catch (\Exception $e)
{
return response()->json([
'status_code' => 'ERROR',
'status_description' => $e->getMessage(),
], 500);
}
}
/**
* 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

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\DeviceMaster;
use App\Models\MfmMeter;
use App\Models\MfmParameter;
use App\Models\Plant;
@@ -95,6 +96,7 @@ class MfmParameterController extends Controller
$plantCode = $request->header('plant-code');
$mfmParameterSeq = $request->header('mfm-meter-sequence');
$deviceName = $request->header('device-name');
if (!$plantCode) {
return response()->json([
@@ -108,9 +110,17 @@ class MfmParameterController extends Controller
'status_description' => "Mfm Parameter sequence value can't be empty"
], 404);
}
else if (!$deviceName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Device name value can't be empty"
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
$device = DeviceMaster::where('name', $deviceName)->first();
if (!$plant)
{
return response()->json([
@@ -118,9 +128,11 @@ class MfmParameterController extends Controller
'status_description' => "Plant Code '{$plantCode}' not found!"
], 404);
}
// Find mfm_meter by sequence and plant_id
$mfmMeter = MfmMeter::where('sequence', trim($mfmParameterSeq))
->where('plant_id', $plant->id)
->where('device_master_id', $device->id)
->first();
if (!$mfmMeter) {
@@ -133,6 +145,7 @@ class MfmParameterController extends Controller
// Now fetch mfm_parameters for this plant and meter
$mfmParameters = MfmParameter::where('plant_id', $plant->id)
->where('mfm_meter_id', $mfmMeter->id)
->where('device_master_id', $device->id)
->get(['register_id', 'byte_to_convert', 'type_to_convert', 'decimal_to_display']);
$transformed = $mfmParameters->map(function ($item) {
@@ -159,7 +172,7 @@ class MfmParameterController extends Controller
if ($transformed->isEmpty()) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "No MFM parameters found for the specified plant and meter."
'status_description' => "No MFM parameters found for the specified plant,meter and device name."
], 404);
}

View File

@@ -128,10 +128,17 @@ class ModulePlantLineController extends Controller
], 404);
}
if (strtolower(trim($chartName)) != 'production hourly count') {
$normalizedChartName = strtolower(trim($chartName));
if ($normalizedChartName != 'production order count' && $normalizedChartName != 'production hourly count' && $normalizedChartName != 'production line stop count') {
array_unshift($nonFgLines, 'All Lines');
}
// if (strtolower(trim($chartName)) != 'production hourly count') {
// array_unshift($nonFgLines, 'All Lines');
// }
// Add "All Lines" to beginning and "FG Lines" at the end
// array_unshift($nonFgLines, 'All Lines');
// $nonFgLines[] = 'FG Line';

View File

@@ -17,23 +17,23 @@ class PalletController extends Controller
//
}
public function downloadQrPdf($palletNo)
public function downloadReprintQrPdf($palletNo)
{
$qrCode = new QrCode($palletNo);
$output = new Output\Png();
$qrBinary = $output->output($qrCode, 100);
$qrBase64 = base64_encode($qrBinary);
$html = '
return '
<html>
<head>
<style>
body { margin: 0; padding: 0; width: 60mm; height: 14mm; font-size: 10pt; font-family: DejaVu Sans, sans-serif; }
.sticker-table { width: 60mm; height: 14mm; border-collapse: collapse; }
.qr-cell { width: 14mm; text-align: left; vertical-align: middle; padding-left: 6mm; padding-top: 2mm; }
.text-cell { text-align: left; vertical-align: middle; font-size: 15pt; padding-left: 4mm; padding-top: 2mm; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: bold; }
img.qr { width: 18mm; height: 18mm; display: block; }
</style>
<style>
body { margin: 0; padding: 0; width: 60mm; height: auto; font-size: 10pt; font-family: DejaVu Sans, sans-serif; }
.sticker-table { width: 60mm; height: 14mm; border-collapse: collapse; page-break-after: always; }
.qr-cell { width: 14mm; text-align: right; vertical-align: bottom; padding-left: 0mm; padding-top: 0mm; }
.text-cell { text-align: left; vertical-align: middle; font-size: 20pt; padding-left: 1mm; padding-top: 2mm; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: bold; }
img.qr { width: 19mm; height: 19mm; display: block; }
</style>
</head>
<body>
<table class="sticker-table">
@@ -46,23 +46,89 @@ class PalletController extends Controller
</td>
</tr>
</table>
<script>
window.onload = function () {
window.print();
setTimeout(function () {
window.close();
}, 500); // Wait 0.5 seconds before closing
};
</script>
</body>
</html>
';
$mpdf = new Mpdf([
'mode' => 'utf-8',
'format' => [60, 14],
'margin_left' => 0,
'margin_right' => 0,
'margin_top' => 0,
'margin_bottom' => 0,
'tempDir' => '/var/www/storage/mpdf-tmp',
]);
// $mpdf = new Mpdf([
// 'mode' => 'utf-8',
// 'format' => [60, 14],
// 'margin_left' => 0,
// 'margin_right' => 0,
// 'margin_top' => 0,
// 'margin_bottom' => 0,
// // 'tempDir' => '/var/www/storage/mpdf-tmp',
// ]);
$mpdf->WriteHTML($html);
$mpdf->Output('qr-label.pdf', 'I');
exit;
// $mpdf->WriteHTML($html);
// // Output PDF to browser for printing
// $mpdf->Output('qr-label.pdf', 'I');
}
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" />
</td>
<td class="text-cell">
' . htmlspecialchars($palletNo) . '
</td>
</tr>
</table>';
return '
<html>
<head>
<style>
body { margin: 0; padding: 0; width: 60mm; height: auto; font-size: 10pt; font-family: DejaVu Sans, sans-serif; }
.sticker-table { width: 60mm; height: 14mm; border-collapse: collapse; page-break-after: always; }
.qr-cell { width: 14mm; text-align: right; vertical-align: bottom; padding-left: -8mm; padding-top: 0mm; }
.text-cell { text-align: left; vertical-align: middle; font-size: 22pt; padding-left: 1mm; padding-top: 2mm; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: bold; }
img.qr { width: 19mm; height: 19mm; display: block; }
</style>
</head>
<body>
' . $htmlBlock . $htmlBlock . '
<script>
window.onload = function () {
window.print();
setTimeout(function () {
window.close();
}, 1000); // Wait 1 second before closing
};
</script>
</body>
</html>';
// $mpdf = new Mpdf([
// 'mode' => 'utf-8',
// 'format' => [60, 14],
// 'margin_left' => 0,
// 'margin_right' => 0,
// 'margin_top' => 0,
// 'margin_bottom' => 0,
// // 'tempDir' => '/var/www/storage/mpdf-tmp',
// ]);
// $mpdf->WriteHTML($html);
// // Output PDF to browser for printing
// $mpdf->Output('qr-label.pdf', 'I');
}
/**

View File

@@ -0,0 +1,277 @@
<?php
namespace App\Http\Controllers;
use App\Models\Item;
use App\Models\ProductionQuantity;
use App\Models\StickerMaster;
use Illuminate\Http\Request;
use Mpdf\Mpdf;
use Mpdf\QrCode\Output;
use Mpdf\QrCode\QrCode;
class ProductionStickerReprintController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
// public function downloadQrPdf($palletNo)
// {
// $parts = explode('|', $palletNo);
// $itemCode = trim($parts[0]);
// $serial = isset($parts[1]) ? trim($parts[1]) : null;
// // Retrieve the item record by item code
// $item = Item::where('code', $itemCode)->first();
// if (!$item) {
// abort(404, "Item with code {$itemCode} not found.");
// }
// $itemId = $item->id;
// $production = ProductionQuantity::where('item_id', $itemId)
// ->where('serial_number', $serial)
// ->first();
// if (!$production) {
// abort(404, "Production data for item code '{$itemCode}' with serial '{$serial}' not found.");
// }
// $productionOrder = $production->production_order;
// $qrCode = new QrCode($palletNo);
// $output = new Output\Png();
// $qrBinary = $output->output($qrCode, 100);
// $qrBase64 = base64_encode($qrBinary);
// $sticker = StickerMaster::where('item_id', $itemId)->first();
// // Decide number of copies
// $copies = 1;
// if ($sticker) {
// if ($sticker->serial_number_pump == 1) {
// // If pump is selected (regardless of motor), 2 copies
// $copies = 2;
// } elseif ($sticker->serial_number_motor == 1) {
// // Only motor selected, 1 copy
// $copies = 1;
// }
// }
// return '
// <html>
// <head>
// <style>
// body {
// margin: 0;
// padding: 0;
// width: 100mm;
// height: 14mm;
// font-size: 10pt;
// font-family: Arial Narrow, Arial, sans-serif;
// }
// .sticker-table {
// width: 100mm;
// height: 14mm;
// }
// .text-cell {
// margin: 0;
// padding: 0;
// text-align: left;
// font-size: 14pt;
// font-weight: normal;
// line-height: 1.2;
// }
// .text-row {
// font-weight: bold;
// font-size: 9pt;
// }
// .serial {
// text-align: left;
// }
// .po-number {
// text-align: right;
// white-space: nowrap;
// }
// .desc-row {
// font-weight: normal;
// font-size: 8pt;
// }
// .qr-cell {
// width: 14mm;
// text-align: left;
// padding-left: 0mm;
// padding-top: 0mm;
// }
// img.qr {
// width: 20mm;
// height: 20mm;
// }
// </style>
// </head>
// <body>
// <div id="print-container"></div>
// <script>
// const copies = ' . $copies . ';
// const htmlBlock = `
// <table class="sticker-table">
// <tr>
// <td class="qr-cell">
// <img class="qr" src="data:image/png;base64,' . $qrBase64 . '" alt="QR" />
// </td>
// <td class="text-cell">
// <div class="text-row">
// <pre><span class="serial">' . htmlspecialchars($serial) . '</span> <span class="po-number">' . htmlspecialchars($productionOrder) . '</span></pre>
// </div>
// <div class="desc-row">
// ' . htmlspecialchars($item->description) . '
// </div>
// </td>
// </tr>
// </table>
// `;
// const container = document.getElementById("print-container");
// for (let i = 0; i < copies; i++) {
// container.insertAdjacentHTML("beforeend", htmlBlock);
// }
// window.onload = function () {
// window.print();
// setTimeout(function () {
// window.close();
// }, 500);
// };
// </script>
// </body>
// </html>
// ';
// //Get sticker master data
// // $sticker = StickerMaster::where('item_id', $itemId)->first();
// // //Decide number of copies
// // $copies = 1; // default
// // if ($sticker) {
// // if ($sticker->serial_number_motor == 1) {
// // $copies = 1;
// // } elseif (is_null($sticker->serial_number_motor) && $sticker->serial_number_pump == 1) {
// // $copies = 2;
// // }
// // }
// // $mpdf = new Mpdf([
// // 'mode' => 'utf-8',
// // 'format' => [60, 14],
// // 'margin_left' => 0,
// // 'margin_right' => 0,
// // 'margin_top' => 0,
// // 'margin_bottom' => 0,
// // ]);
// // for ($i = 0; $i < $copies; $i++) {
// // $mpdf->WriteHTML($html);
// // if ($i < $copies - 1) {
// // $mpdf->AddPage();
// // }
// // }
// // $mpdf->Output('qr-label.pdf', 'I');
// // exit;
// }
/**
* Store a newly created resource in storage.
*/
public function downloadQrPdf($palletNo)
{
$parts = explode('|', $palletNo);
$itemCode = trim($parts[0]);
$serial = isset($parts[1]) ? trim($parts[1]) : null;
$item = Item::where('code', $itemCode)->first();
$itemId= $item->id;
if (!$item) {
abort(404, "Item with code {$itemCode} not found.");
}
$production = ProductionQuantity::where('item_id', $item->id)
->where('serial_number', $serial)
->first();
if (!$production) {
abort(404, "Production data for item code '{$itemCode}' with serial '{$serial}' not found.");
}
$productionOrder = $production->production_order ?? '';
if ($item->category == 'Submersible Motor')
{
$copies = 1;
}
elseif ($item->category == 'Submersible Pump')
{
$copies = 2;
}
// 5. Generate QR Code (base64)
$qrCode = new QrCode($palletNo);
$output = new Output\Png();
$qrBinary = $output->output($qrCode, 100); // 100 = size
$qrBase64 = base64_encode($qrBinary);
// 6. Return view
return view('print-qr', [
'qrBase64' => $qrBase64,
'serial' => $serial,
'productionOrder' => $productionOrder,
'item' => $item,
'copies'=> $copies,
]);
}
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

@@ -458,6 +458,7 @@ class TestingPanelController extends Controller
}
$output = [
"mot_subassembly_code" => $motorTestingMaster->subassembly_code ?? "",
"mot_model_name" => $description,
"mot_non_isi_model" => $motorTestingMaster->isi_model ? "0" :"1",
"mot_phase" => $motorTestingMaster->phase ?? "",
@@ -488,7 +489,7 @@ class TestingPanelController extends Controller
"mot_noload_pow_ll" => $motorTestingMaster->noload_pow_ll ?? "",
"mot_noload_pow_ul" => $motorTestingMaster->noload_pow_ul ?? "",
"mot_noload_spd_ll" => $motorTestingMaster->noload_spd_ll ?? "",
"mot_noload_spd_ul" => $motorTestingMaster->noload_spd_ul ?? "",
"mot_noload_spd_ul" => $motorTestingMaster->noload_spd_ul ?? ""
];
return response()->json($output, 200);

View File

@@ -81,6 +81,9 @@ class UserController extends Controller
//$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'),
'email' => $existUser->email,
'roles' => $existUser->roles()->pluck('name')->toArray()
], 200);
} else {

View File

@@ -19,6 +19,8 @@ class InvoiceDataTable extends Component
public bool $completedInvoice = false;
public bool $isSerial = false;
public bool $emptyInvoice = false;
public bool $hasSearched = false;
@@ -49,11 +51,12 @@ class InvoiceDataTable extends Component
public string $currentSerialNumber = '';
public function loadCompletedData($invoiceNumber, $plantId)
public function loadCompletedData($invoiceNumber, $plantId, $isSerial)
{
$this->plantId = $plantId;
$this->invoiceNumber = $invoiceNumber;
$this->completedInvoice = true;
$this->isSerial = $isSerial;
$this->emptyInvoice = false;
$this->hasSearched = false;
$this->materialInvoice = false;
@@ -64,8 +67,8 @@ class InvoiceDataTable extends Component
{
$this->plantId = $plantId;
$this->invoiceNumber = $invoiceNumber;
$this->emptyInvoice = true;
$this->completedInvoice = false;
$this->emptyInvoice = true;
$this->hasSearched = false;
$this->materialInvoice = false;
// $this->showCapacitorInput = false;
@@ -75,9 +78,10 @@ class InvoiceDataTable extends Component
{
$this->plantId = $plantId;
$this->invoiceNumber = $invoiceNumber;
$this->hasSearched = true;
$this->emptyInvoice = false;
$this->completedInvoice = false;
$this->isSerial = true;
$this->emptyInvoice = false;
$this->hasSearched = true;
$this->materialInvoice = false;
// $this->showCapacitorInput = false;
@@ -113,10 +117,11 @@ class InvoiceDataTable extends Component
{
$this->plantId = $plantId;
$this->invoiceNumber = $invoiceNumber;
$this->materialInvoice = true;
$this->emptyInvoice = false;
$this->completedInvoice = false;
$this->isSerial = false;
$this->emptyInvoice = false;
$this->hasSearched = false;
$this->materialInvoice = true;
// $this->showCapacitorInput = false;
//->where('serial_number', '!=', '')
@@ -171,13 +176,12 @@ class InvoiceDataTable extends Component
$this->currentSerialNumber = $serialNumber;
$this->showCapacitorInput = true;
// $this->capacitorInput = '';
$this->emptyInvoice = false;
$this->completedInvoice = false;
$this->isSerial = true;
$this->emptyInvoice = false;
$this->hasSearched = false;
$this->materialInvoice = false;
$this->dispatch('focus-capacitor-input');
$this->dispatch('focus-capacitor-input');
}
public function cancelCapacitorInput()
@@ -330,7 +334,7 @@ class InvoiceDataTable extends Component
->success()
->seconds(2)
->send();
$this->loadCompletedData($matchingValidation->invoice_number, $matchingValidation->plant_id);
$this->loadCompletedData($matchingValidation->invoice_number, $matchingValidation->plant_id, true);
}
else
{

View File

@@ -2,6 +2,7 @@
namespace App\Mail;
use DateTime;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
@@ -14,12 +15,14 @@ class ProductionMail extends Mailable
use Queueable, SerializesModels;
public $tableData;
public $scheduleType;
/**
* Create a new message instance.
*/
public function __construct($tableData = [])
public function __construct($scheduleType,$tableData = [])
{
$this->scheduleType = $scheduleType;
$this->tableData = $tableData ?? [];
}
@@ -36,19 +39,57 @@ class ProductionMail extends Mailable
/**
* Get the message content definition.
*/
// public function content(): Content
// {
// return new Content(
// view: 'mail.production_report',
// with: [
// 'company' => "CRI Digital Manufacturing Solutions",
// 'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached production report status details for the 'Target Quantity' and 'Production Quantity' count,",
// // 'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached production report status details for the 'Target Quantity' and 'Production Quantity' count,<br>" . $reportPeriod,
// 'tableData' => $this->tableData,
// 'wishes' => "Thanks & Regards,<br>CRI Digital Manufacturing Solutions"
// ],
// );
// }
public function content(): Content
{
return new Content(
$greeting = "Dear Sir/Madam,<br><br>Kindly find the attached production report status details for the 'Target Quantity' and 'Production Quantity' count,";
if ($this->scheduleType == 'Daily') {
$fromDate = (new DateTime('yesterday 08:00'))->format('d/m/Y H:i') . ':000';
$toDate = (new DateTime('today 07:59'))->format('d/m/Y H:i') . ':999';
$reportPeriod = "The following report presents results from: $fromDate to $toDate.";
$greeting .= $reportPeriod;
}
if ($this->scheduleType == 'Hourly') {
$now = now();
$fromHour = $now->copy()->subHour()->format('H:i:s');
$toHour = $now->format('H:i:s');
$reportDate = $now->format('d/m/Y');
$greeting .= "The following report presents results from: $reportDate, $fromHour to $toHour.";
}
if ($this->scheduleType == 'Live') {
$now = now();
$fromMinute = $now->copy()->subMinute()->format('d/m/Y H:i:s');
$toMinute = $now->format('d/m/Y H:i:s');
$greeting .= "The following report presents results from: $fromMinute to $toMinute.";
}
return new Content(
view: 'mail.production_report',
with: [
'company' => "CRI Digital Manufacturing Solutions",
'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached production report status details for the 'Target Quantity' and 'Production Quantity' count,",
'greeting' => $greeting,
'tableData' => $this->tableData,
'wishes' => "Thanks & Regards,<br>CRI Digital Manufacturing Solutions"
],
);
}
/**
* Get the attachments for the message.
*

View File

@@ -2,6 +2,7 @@
namespace App\Mail;
use DateTime;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
@@ -16,16 +17,16 @@ class test extends Mailable
public $materialTableData;
public $bundleTableData;
public $schedule;
/**
* Create a new message instance.
*/
// public function __construct($tableData = [])
// {
// $this->tableData = $tableData ?? [];
// }
public function __construct($serialTableData, $materialTableData, $bundleTableData)
public function __construct($serialTableData, $materialTableData, $bundleTableData, $schedule)
{
$this->schedule = $schedule;
$this->serialTableData = $serialTableData;
$this->materialTableData = $materialTableData;
$this->bundleTableData = $bundleTableData;
@@ -44,18 +45,54 @@ class test extends Mailable
/**
* Get the message content definition.
*/
// public function content(): Content
// {
// return new Content(
// view: 'mail.test_mail',
// with: [
// 'company' => "CRI Digital Manufacturing Solutions",
// 'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached invoice status details for the 'Total Number of Invoices' and 'Scanned Number of Invoices' count,",
// //'tableData' => $this->tableData,
// 'serialTableData' => $this->serialTableData,
// 'materialTableData' => $this->materialTableData,
// 'bundleTableData' => $this->bundleTableData,
// 'wishes' => "Thanks & Regards,<br>CRI Digital Manufacturing Solutions"
// ],
// );
// }
public function content(): Content
{
$greeting = "Dear Sir/Madam,<br><br>Kindly find the attached invoice status details for the 'Total Number of Invoices' and 'Scanned Number of Invoices' count,";
if ($this->schedule == 'Daily') {
$fromDate = (new DateTime('yesterday 08:00'))->format('d/m/Y H:i') . ':000';
$toDate = (new DateTime('today 07:59'))->format('d/m/Y H:i') . ':999';
$reportPeriod = "The following report presents results from: $fromDate to $toDate.";
//$greeting .= $reportPeriod;
$greeting .= "<br><br>$reportPeriod";
}
if ($this->schedule == 'Hourly') {
$now = now();
$fromHour = $now->copy()->subHour()->format('H:i:s');
$toHour = $now->format('H:i:s');
$reportDate = $now->format('d/m/Y');
$greeting .= "The following report presents results from: $reportDate, $fromHour to $toHour.";
}
if ($this->schedule == 'Live') {
$now = now();
$fromMinute = $now->copy()->subMinute()->format('d/m/Y H:i:s');
$toMinute = $now->format('d/m/Y H:i:s');
$greeting .= "The following report presents results from: $fromMinute to $toMinute.";
}
return new Content(
view: 'mail.test_mail',
// with: [
// 'name' => "CRI Digital Manufacturing Solutions<br><br>Dear Sir/Madam,<br><br> Kindly find the attached invoice status details for the 'Total Number Of Invoices' and 'Scanned Number Of Invoices' count,",
// 'tableData' => $this->tableData,
// 'wishes' => "Thanks & Regards<br><br>CRI Digital Manufacturing Solutions"
// ],
with: [
with: [
'company' => "CRI Digital Manufacturing Solutions",
'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached invoice status details for the 'Total Number of Invoices' and 'Scanned Number of Invoices' count,",
'greeting' => $greeting,
//'greeting' => "Dear Sir/Madam,<br><br>Kindly find the attached invoice status details for the 'Total Number of Invoices' and 'Scanned Number of Invoices' count,",
//'tableData' => $this->tableData,
'serialTableData' => $this->serialTableData,
'materialTableData' => $this->materialTableData,

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class DeviceMaster extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'name',
'mac_address',
'ip_address',
'created_at',
'updated_at',
'created_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

69
app/Models/EbReading.php Normal file
View File

@@ -0,0 +1,69 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class EbReading extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'lcd_segment_check',
'meter_serial_no',
'eb_date_time',
'ph_seq_of_volt',
'ph_assoc_conn_check',
'instantaneous_ph_volt',
'instantaneous_curr',
'instantaneous_freq',
'instantaneous_kw_with_sign',
'instantaneous_kva',
'instantaneous_kv_ar',
'instantaneous_pf_with_sign',
'rd_with_elapsed_time_kva',
'cum_active_import_energy',
'tod1_active_energy_6_9',
'tod2_active_energy_18_21',
'tod3_active_energy_21_22',
'tod4_active_energy_5_6_9_18',
'tod5_active_energy_22_5',
'cum_reac_lag_energy',
'cum_reac_lead_energy',
'cum_appar_energy',
'tod1_appar_energy_6_9',
'tod2_appar_energy_18_21',
'tod3_appar_energy_21_22',
'tod4_appar_energy_5_6_9_18',
'tod5_appar_energy_22_5',
'avg_pow_factor',
'avg_freq_15min_last_ip',
'net_kv_arh_high',
'net_kv_arh_low',
'cum_md_kva',
'present_md_kva',
'present_md_kva_date_time',
'tod1_md_kva_6_9',
'tod2_md_kva_18_21',
'tod3_md_kva_21_22',
'tod4_md_kva_5_6_9_18',
'tod5_md_kva_22_5',
'total_pow_off_hours',
'programming_count',
'last_occ_res_event_type',
'last_occ_res_event_date_time',
'tamper_count',
'reset_count',
'last_md_reset_date_time',
'electrician_sign',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

@@ -13,6 +13,7 @@ class MfmMeter extends Model
protected $fillable = [
'plant_id',
'device_master_id',
'sequence',
'name',
'created_at',
@@ -24,4 +25,9 @@ class MfmMeter extends Model
{
return $this->belongsTo(Plant::class);
}
public function devicemaster(): BelongsTo
{
return $this->belongsTo(DeviceMaster::class, 'device_master_id');
}
}

View File

@@ -13,6 +13,7 @@ class MfmParameter extends Model
protected $fillable = [
'plant_id',
'mfm_meter_id',
'device_master_id',
'name',
'register_id',
'identifier',
@@ -33,4 +34,9 @@ class MfmParameter extends Model
{
return $this->belongsTo(MfmMeter::class, 'mfm_meter_id');
}
public function deviceName(): BelongsTo
{
return $this->belongsTo(DeviceMaster::class, 'device_master_id');
}
}

View File

@@ -13,6 +13,7 @@ class MotorTestingMaster extends Model
protected $fillable = [
'plant_id',
'item_id',
'subassembly_code',
'isi_model',
'phase',
'kw',

View File

@@ -22,6 +22,12 @@ class ProductionQuantity extends Model
"serial_number",
"production_order",
"operator_id",
// "success_status",
// "no_of_employee",
// "list_of_employee",
"created_at",
"updated_at"
];
public function plant(): BelongsTo

View File

@@ -35,6 +35,8 @@ class QualityValidation extends Model
'part_validation5',
'operator_id',
'uom',
'created_at',
'updated_at',
'serial_number',
'sap_msg_status',
'sap_msg_description',

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\DeviceMaster;
use App\Models\User;
class DeviceMasterPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any DeviceMaster');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('view DeviceMaster');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create DeviceMaster');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('update DeviceMaster');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('delete DeviceMaster');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any DeviceMaster');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('restore DeviceMaster');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any DeviceMaster');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('replicate DeviceMaster');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder DeviceMaster');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, DeviceMaster $devicemaster): bool
{
return $user->checkPermissionTo('force-delete DeviceMaster');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any DeviceMaster');
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\EbReading;
use App\Models\User;
class EbReadingPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any EbReading');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('view EbReading');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create EbReading');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('update EbReading');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('delete EbReading');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any EbReading');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('restore EbReading');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any EbReading');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('replicate EbReading');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder EbReading');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, EbReading $ebreading): bool
{
return $user->checkPermissionTo('force-delete EbReading');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any EbReading');
}
}

View File

@@ -70,7 +70,6 @@ return new class extends Migration
DB::statement($sql);
}
/**
* Reverse the migrations.
*/

View File

@@ -15,6 +15,8 @@ return new class extends Migration
CREATE TABLE alert_mail_rules (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant BIGINT NOT NULL DEFAULT(0),
module TEXT NOT NULL,
rule_name TEXT NOT NULL,
@@ -27,6 +29,7 @@ return new class extends Migration
created_by TEXT NOT NULL,
updated_by TEXT NOT NULL
);
SQL;

View File

@@ -0,0 +1,45 @@
<?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'
CREATE TABLE device_masters (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
name TEXT NOT NULL,
mac_address TEXT DEFAULT NULL,
ip_address TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP,
created_by TEXT NULL,
UNIQUE (name, plant_id),
FOREIGN KEY (plant_id) REFERENCES plants (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('device_masters');
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE mfm_meters
ADD COLUMN device_master_id BIGINT NOT NULL,
ADD CONSTRAINT mfm_meters_device_master_id_fkey
FOREIGN KEY (device_master_id) REFERENCES device_masters(id);
SQL;
DB::statement($sql);
$sql1 = <<<'SQL'
ALTER TABLE mfm_meters
ADD UNIQUE (plant_id, device_master_id, name);
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('mfm_meters', function (Blueprint $table) {
// //
// });
}
};

Some files were not shown because too many files have changed in this diff Show More