Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c070c9763e | ||
|
|
2116ea422e | ||
|
|
acc98ad876 | ||
|
|
45898b2fa2 | ||
|
|
390e013ccb | ||
|
|
dc9f929fa2 | ||
|
|
e58dbfbebd | ||
|
|
15af1edb8f | ||
|
|
705cc8c3a4 | ||
|
|
6e61f83e3a | ||
|
|
197184e2ed | ||
|
|
d6c77bd6c3 | ||
|
|
68d4240ab0 | ||
|
|
68ba8fa89d | ||
|
|
8c84e48f8e | ||
|
|
2e7859656a | ||
|
|
4bfbebb254 | ||
|
|
1ea00b6901 | ||
|
|
5084aa9c0e | ||
|
|
c844a23556 | ||
|
|
76649651f1 | ||
|
|
e15c866078 | ||
|
|
04af1c7c34 | ||
|
|
8871389fe3 | ||
|
|
ec2fd4d3ca | ||
|
|
5c1f77796f | ||
|
|
530bca4c4b | ||
|
|
ccceff9edc | ||
|
|
c53f40d8a0 | ||
|
|
6b67d94476 | ||
|
|
b2d2ab7e05 | ||
|
|
573b02a97a | ||
|
|
96a5dacf95 | ||
|
|
58cdcec6ed | ||
|
|
c67e8fcc59 | ||
|
|
d5588e0b25 | ||
|
|
9ff7f88840 | ||
|
|
03e53e0bb1 | ||
|
|
33b2b6399d | ||
|
|
2437bdf85f | ||
|
|
f51aea626b | ||
|
|
77129cb70b | ||
|
|
bb462a6c45 | ||
|
|
9a2a6bdd9b | ||
|
|
0a414a6804 | ||
|
|
f4bb7a7a78 | ||
|
|
8aad6cf1e6 | ||
|
|
3b18411141 | ||
|
|
162eaa0c9c | ||
|
|
d5f55fbf98 | ||
|
|
cf5cfac555 | ||
|
|
7bf2e8182b | ||
|
|
216b62f8bf | ||
|
|
cad7f19ab5 | ||
|
|
ca9695c922 | ||
|
|
d1f9a3176f | ||
|
|
0b9d0f9995 | ||
|
|
897aa77217 | ||
|
|
000533ef7c | ||
|
|
a78cb75bdd | ||
|
|
ab769d2287 | ||
|
|
0bde54cf1a | ||
|
|
48942307e1 | ||
|
|
8c5f2b5b39 | ||
|
|
b1df9f8b87 | ||
|
|
c0d13db2f3 | ||
|
|
b4bf170c89 | ||
|
|
b0d2132e25 |
30
.github/workflows/pint.yaml
vendored
30
.github/workflows/pint.yaml
vendored
@@ -1,30 +0,0 @@
|
||||
name: Laravel Pint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Reinstall system libraries to ensure compatibility
|
||||
- name: Ensure system libraries are up-to-date
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --reinstall --yes git libc6
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.3"
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --no-interaction --prefer-dist --no-progress
|
||||
|
||||
# Run pint in test mode, check only files different from master branch
|
||||
- name: Run Laravel Pint in test mode
|
||||
run: vendor/bin/pint --test --diff=master
|
||||
@@ -280,8 +280,8 @@ class SendInvoiceReport extends Command
|
||||
|
||||
$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,6 +293,16 @@ class SendInvoiceReport extends Command
|
||||
: [$plantIdArg];
|
||||
|
||||
$no = 1;
|
||||
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;
|
||||
|
||||
@@ -193,6 +193,9 @@ class SendProductionReport extends Command
|
||||
// ];
|
||||
// }
|
||||
// }
|
||||
//..
|
||||
|
||||
//.
|
||||
|
||||
foreach ($plants as $plant)
|
||||
{
|
||||
@@ -204,7 +207,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 +223,7 @@ class SendProductionReport extends Command
|
||||
'no' => $no++,
|
||||
'plant' => $plant->name,
|
||||
'line' => $line->name,
|
||||
'type' => $line->type,
|
||||
'targetQuantity' => $targetQuantity,
|
||||
'productionQuantity' => $productionQuantity,
|
||||
];
|
||||
|
||||
54
app/Filament/Exports/DeviceMasterExporter.php
Normal file
54
app/Filament/Exports/DeviceMasterExporter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
140
app/Filament/Exports/EbReadingExporter.php
Normal file
140
app/Filament/Exports/EbReadingExporter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
54
app/Filament/Exports/MfmMeterExporter.php
Normal file
54
app/Filament/Exports/MfmMeterExporter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
92
app/Filament/Exports/MfmReadingExporter.php
Normal file
92
app/Filament/Exports/MfmReadingExporter.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\MfmReading;
|
||||
use Filament\Actions\Exports\ExportColumn;
|
||||
use Filament\Actions\Exports\Exporter;
|
||||
use Filament\Actions\Exports\Models\Export;
|
||||
|
||||
class MfmReadingExporter extends Exporter
|
||||
{
|
||||
protected static ?string $model = MfmReading::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('mfmMeter.name')
|
||||
->label('MFM METER NAME'),
|
||||
ExportColumn::make('apparent_energy_received')
|
||||
->label('APPARENT ENERGY RECEIVED'),
|
||||
ExportColumn::make('reactive_energy_received')
|
||||
->label('REACTIVE ENERGY RECEIVED'),
|
||||
ExportColumn::make('active_energy_received')
|
||||
->label('ACTIVE ENERGY RECEIVED'),
|
||||
ExportColumn::make('active_power_r')
|
||||
->label('ACTIVE POWER R'),
|
||||
ExportColumn::make('active_power_y')
|
||||
->label('ACTIVE POWER Y'),
|
||||
ExportColumn::make('active_power_b')
|
||||
->label('ACTIVE POWER B'),
|
||||
ExportColumn::make('active_power_total')
|
||||
->label('ACTIVE POWER TOTAL'),
|
||||
ExportColumn::make('voltage_ry')
|
||||
->label('VOLTAGE RY'),
|
||||
ExportColumn::make('voltage_yb')
|
||||
->label('VOLTAGE YB'),
|
||||
ExportColumn::make('voltage_br')
|
||||
->label('VOLTAGE BR'),
|
||||
ExportColumn::make('current_r')
|
||||
->label('CURRENT R'),
|
||||
ExportColumn::make('current_y')
|
||||
->label('CURRENT Y'),
|
||||
ExportColumn::make('current_b')
|
||||
->label('CURRENT B'),
|
||||
ExportColumn::make('current_n')
|
||||
->label('CURRENT N'),
|
||||
ExportColumn::make('voltage_r_n')
|
||||
->label('VOLTAGE R N'),
|
||||
ExportColumn::make('voltage_y_n')
|
||||
->label('VOLTAGE Y N'),
|
||||
ExportColumn::make('voltage_b_n')
|
||||
->label('VOLTAGE B N'),
|
||||
ExportColumn::make('frequency')
|
||||
->label('FREQUENCY'),
|
||||
ExportColumn::make('power_factor_r')
|
||||
->label('POWER FACTOR R'),
|
||||
ExportColumn::make('power_factor_y')
|
||||
->label('POWER FACTOR Y'),
|
||||
ExportColumn::make('power_factor_b')
|
||||
->label('POWER FACTOR B'),
|
||||
ExportColumn::make('power_factor_total')
|
||||
->label('POWER FACTOR TOTAL'),
|
||||
ExportColumn::make('created_at')
|
||||
->label('CREATED AT'),
|
||||
ExportColumn::make('updated_at')
|
||||
->label('UPDATED AT'),
|
||||
ExportColumn::make('deleted_at')
|
||||
->label('DELETED AT')
|
||||
->enabledByDefault(false),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getCompletedNotificationBody(Export $export): string
|
||||
{
|
||||
$body = 'Your mfm 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;
|
||||
}
|
||||
}
|
||||
51
app/Filament/Exports/TempLiveReadingExporter.php
Normal file
51
app/Filament/Exports/TempLiveReadingExporter.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\TempLiveReading;
|
||||
use Filament\Actions\Exports\ExportColumn;
|
||||
use Filament\Actions\Exports\Exporter;
|
||||
use Filament\Actions\Exports\Models\Export;
|
||||
|
||||
class TempLiveReadingExporter extends Exporter
|
||||
{
|
||||
protected static ?string $model = TempLiveReading::class;
|
||||
|
||||
public static function getColumns(): array
|
||||
{
|
||||
static $rowNumber = 0;
|
||||
return [
|
||||
ExportColumn::make('no')
|
||||
->label('NO')
|
||||
->state(function ($record) use (&$rowNumber) {
|
||||
return ++$rowNumber;
|
||||
}),
|
||||
ExportColumn::make('plant.name')
|
||||
->label('PLANT'),
|
||||
ExportColumn::make('mfmMeter.name')
|
||||
->label('MFM METER NAME'),
|
||||
ExportColumn::make('register_data')
|
||||
->label('REGISTER DATA'),
|
||||
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 temp live 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;
|
||||
}
|
||||
}
|
||||
70
app/Filament/Imports/DeviceMasterImporter.php
Normal file
70
app/Filament/Imports/DeviceMasterImporter.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?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')
|
||||
->example('172.31.76.67')
|
||||
->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;
|
||||
}
|
||||
}
|
||||
243
app/Filament/Imports/EbReadingImporter.php
Normal file
243
app/Filament/Imports/EbReadingImporter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
72
app/Filament/Imports/MfmMeterImporter.php
Normal file
72
app/Filament/Imports/MfmMeterImporter.php
Normal 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('devicemaster')
|
||||
->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;
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
|
||||
186
app/Filament/Imports/MfmReadingImporter.php
Normal file
186
app/Filament/Imports/MfmReadingImporter.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Imports;
|
||||
|
||||
use App\Models\MfmReading;
|
||||
use Filament\Actions\Imports\ImportColumn;
|
||||
use Filament\Actions\Imports\Importer;
|
||||
use Filament\Actions\Imports\Models\Import;
|
||||
|
||||
class MfmReadingImporter extends Importer
|
||||
{
|
||||
protected static ?string $model = MfmReading::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('mfmMeter')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Mfm Meter Name')
|
||||
->example('Display SSB')
|
||||
->label('Display SSB')
|
||||
->relationship(resolveUsing:'name')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('apparent_energy_received')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Apparent Energy Received')
|
||||
->example('1084610')
|
||||
->label('Apparent Energy Received')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('reactive_energy_received')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Reactive Energy Received')
|
||||
->example('347496.9')
|
||||
->label('Reactive Energy Received')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('active_energy_received')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Active Energy Received')
|
||||
->example('611717.1')
|
||||
->label('Active Energy Received')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('active_power_r')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Active Power R')
|
||||
->example('3.974')
|
||||
->label('Active Power R')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('active_power_y')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Active Power Y')
|
||||
->example('0.796')
|
||||
->label('Active Power Y')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('active_power_b')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Active Power B')
|
||||
->example('1.397')
|
||||
->label('Active Power B')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('active_power_total')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Active Power Total')
|
||||
->example('6.433')
|
||||
->label('Active Power Total')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_ry')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage RY')
|
||||
->example('413.308')
|
||||
->label('Voltage RY')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_yb')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage YB')
|
||||
->example('415.305')
|
||||
->label('Voltage YB')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_br')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage BR')
|
||||
->example('415.216')
|
||||
->label('Voltage BR')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('current_r')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Current R')
|
||||
->example('17.446')
|
||||
->label('Current R')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('current_y')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Current Y')
|
||||
->example('4.801')
|
||||
->label('Current Y')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('current_b')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Current B')
|
||||
->example('7.04')
|
||||
->label('Current B')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('current_n')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Current N')
|
||||
->example('14.063')
|
||||
->label('Current N')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_r_n')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage R N')
|
||||
->example('237.898')
|
||||
->label('Voltage R N')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_y_n')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage Y N')
|
||||
->example('239.518')
|
||||
->label('Voltage Y N')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('voltage_b_n')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Voltage B N')
|
||||
->example('240.798')
|
||||
->label('Voltage B N')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('frequency')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Frequency')
|
||||
->example('50.228')
|
||||
->label('Frequency')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('power_factor_r')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Power Factor R')
|
||||
->example('0.988')
|
||||
->label('Power Factor R')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('power_factor_y')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Power Factor Y')
|
||||
->example('0.764')
|
||||
->label('Power Factor Y')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('power_factor_b')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Power Factor B')
|
||||
->example('0.849')
|
||||
->label('Power Factor B')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('power_factor_total')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Power Factor Total')
|
||||
->example('0.919')
|
||||
->label('Power Factor Total')
|
||||
->rules(['required']),
|
||||
];
|
||||
}
|
||||
|
||||
public function resolveRecord(): ?MfmReading
|
||||
{
|
||||
// return MfmReading::firstOrNew([
|
||||
// // Update existing records, matching them by `$this->data['column_name']`
|
||||
// 'email' => $this->data['email'],
|
||||
// ]);
|
||||
|
||||
return new MfmReading();
|
||||
}
|
||||
|
||||
public static function getCompletedNotificationBody(Import $import): string
|
||||
{
|
||||
$body = 'Your mfm 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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
66
app/Filament/Imports/TempLiveReadingImporter.php
Normal file
66
app/Filament/Imports/TempLiveReadingImporter.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Imports;
|
||||
|
||||
use App\Models\TempLiveReading;
|
||||
use Filament\Actions\Imports\ImportColumn;
|
||||
use Filament\Actions\Imports\Importer;
|
||||
use Filament\Actions\Imports\Models\Import;
|
||||
|
||||
class TempLiveReadingImporter extends Importer
|
||||
{
|
||||
protected static ?string $model = TempLiveReading::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('mfmMeter')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Mfm Meter Name')
|
||||
->example('Display SSB')
|
||||
->label('Mfm Meter Name')
|
||||
->relationship(resolveUsing:'name')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('register_data')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Register Data')
|
||||
->example('65165,5646,561,561')
|
||||
->label('Register Data')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('created_by')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Created By')
|
||||
->example('Admin')
|
||||
->label('Created By')
|
||||
->rules(['required']),
|
||||
];
|
||||
}
|
||||
|
||||
public function resolveRecord(): ?TempLiveReading
|
||||
{
|
||||
// return TempLiveReading::firstOrNew([
|
||||
// // Update existing records, matching them by `$this->data['column_name']`
|
||||
// 'email' => $this->data['email'],
|
||||
// ]);
|
||||
|
||||
return new TempLiveReading();
|
||||
}
|
||||
|
||||
public static function getCompletedNotificationBody(Import $import): string
|
||||
{
|
||||
$body = 'Your temp live 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;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ class Dashboard extends \Filament\Pages\Dashboard
|
||||
{
|
||||
return 'Production Line Count';
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
$widgets = [];
|
||||
|
||||
@@ -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}";
|
||||
|
||||
@@ -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;
|
||||
|
||||
1448
app/Filament/Pages/StickerReprint.php
Normal file
1448
app/Filament/Pages/StickerReprint.php
Normal file
File diff suppressed because it is too large
Load Diff
131
app/Filament/Pages/TrendChartAnalys.php
Normal file
131
app/Filament/Pages/TrendChartAnalys.php
Normal 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');
|
||||
}
|
||||
}
|
||||
129
app/Filament/Pages/TrendLineAnalysis.php
Normal file
129
app/Filament/Pages/TrendLineAnalysis.php
Normal 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');
|
||||
}
|
||||
}
|
||||
151
app/Filament/Resources/DeviceMasterResource.php
Normal file
151
app/Filament/Resources/DeviceMasterResource.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?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;
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
443
app/Filament/Resources/EbReadingResource.php
Normal file
443
app/Filament/Resources/EbReadingResource.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?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;
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -74,6 +75,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 +133,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
'scanned_quantity'=> $scanMQuan,
|
||||
]);
|
||||
|
||||
if ($totQuan === $scanMQuan)
|
||||
if ($totQuan == $scanMQuan)
|
||||
{
|
||||
Notification::make()
|
||||
->title("Completed: Material Invoice")
|
||||
@@ -134,7 +151,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 +164,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 +202,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 +407,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 +416,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 +437,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 +469,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 +478,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 +498,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 +507,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 +539,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 +548,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 +581,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 +590,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($excelCode === $code && is_numeric($excelMatQty)) {
|
||||
if ($excelCode == $code && is_numeric($excelMatQty)) {
|
||||
$totalExcelQty += $excelMatQty;
|
||||
}
|
||||
}
|
||||
@@ -669,7 +686,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
}
|
||||
}
|
||||
|
||||
if ($inserted > 0 || $oldQuan !== $newQuan)
|
||||
if ($inserted > 0 || $oldQuan != $newQuan)
|
||||
{
|
||||
Notification::make()
|
||||
->title("Material invoice successfully updatad.")
|
||||
@@ -695,13 +712,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 +792,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 +810,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 +821,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 +863,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 +1104,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 +1155,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
}
|
||||
}
|
||||
|
||||
if ($inserted > 0 || $oldQuan !== $newQuan)
|
||||
if ($inserted > 0 || $oldQuan != $newQuan)
|
||||
{
|
||||
Notification::make()
|
||||
->title("Serial invoice successfully updated.")
|
||||
@@ -1165,13 +1182,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 +1300,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 +1343,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
|
||||
foreach ($rows as $index => $row)
|
||||
{
|
||||
if ($index === 0) continue;
|
||||
if ($index == 0) continue;
|
||||
|
||||
$materialCode = trim($row[0]);
|
||||
|
||||
@@ -1365,7 +1382,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
}
|
||||
}
|
||||
|
||||
if($invoiceType === 'M')
|
||||
if($invoiceType == 'M')
|
||||
{
|
||||
$invalidMatCodes = [];
|
||||
$materialCodes = [];
|
||||
@@ -1375,7 +1392,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 +1595,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 +1604,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 +1659,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 +1668,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 +1694,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 +1703,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 +1728,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 +1737,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 +1776,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 +1822,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
}
|
||||
}
|
||||
}
|
||||
else if($invoiceType === 'S')
|
||||
else if($invoiceType == 'S')
|
||||
{
|
||||
$invalidMatCodes = [];
|
||||
$materialCodes = [];
|
||||
@@ -1817,7 +1834,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 +2094,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 +2140,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 +2218,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 +2272,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
{
|
||||
if ($totMQuan > 0)
|
||||
{
|
||||
if ($totQuan === $scanMQuan)
|
||||
if ($totQuan == $scanMQuan)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Completed: Material Invoice')
|
||||
@@ -2282,7 +2299,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 +2776,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 +2803,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 +2821,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($totQuan === $scanSQuan)
|
||||
if ($totQuan == $scanSQuan)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Completed: Serial Invoice')
|
||||
@@ -2831,7 +2848,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 +3021,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
]);
|
||||
return;
|
||||
}
|
||||
else if($hadMotorQr === $hasMotorQr)
|
||||
else if($hadMotorQr == $hasMotorQr)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Duplicate: Motor QR')
|
||||
@@ -3027,7 +3044,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 +3055,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 +3084,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
'scanned_quantity'=> $scannedQuantity,
|
||||
]);
|
||||
|
||||
if($totQuan === $scannedQuantity)
|
||||
if($totQuan == $scannedQuantity)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Completed: Serial Invoice')
|
||||
@@ -3085,7 +3102,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 +3131,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
]);
|
||||
return;
|
||||
}
|
||||
else if($hadPumpQr === $hasPumpQr)
|
||||
else if($hadPumpQr == $hasPumpQr)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Duplicate: Pump QR')
|
||||
@@ -3137,7 +3154,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 +3165,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 +3194,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
'scanned_quantity'=> $scannedQuantity,
|
||||
]);
|
||||
|
||||
if($totQuan === $scannedQuantity)
|
||||
if($totQuan == $scannedQuantity)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Completed: Serial Invoice')
|
||||
@@ -3195,7 +3212,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 +3243,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
]);
|
||||
return;
|
||||
}
|
||||
else if($hadCapacitorQr === '1' && $hasCapacitorQr)
|
||||
else if($hadCapacitorQr == '1' && $hasCapacitorQr)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Duplicate: Capacitor QR')
|
||||
@@ -3285,7 +3302,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
]);
|
||||
return;
|
||||
}
|
||||
else if($hadPumpSetQr === $hasPumpSetQr)
|
||||
else if($hadPumpSetQr == $hasPumpSetQr)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Duplicate: Pump Set QR')
|
||||
@@ -3308,7 +3325,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 +3336,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 +3365,7 @@ class CreateInvoiceValidation extends CreateRecord
|
||||
'scanned_quantity'=> $scannedQuantity,
|
||||
]);
|
||||
|
||||
if($totQuan === $scannedQuantity)
|
||||
if($totQuan == $scannedQuantity)
|
||||
{
|
||||
Notification::make()
|
||||
->title('Completed: Serial Invoice')
|
||||
@@ -3366,7 +3383,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
|
||||
{
|
||||
|
||||
@@ -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');
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Exports\MfmReadingExporter;
|
||||
use App\Filament\Imports\MfmReadingImporter;
|
||||
use App\Filament\Resources\MfmReadingResource\Pages;
|
||||
use App\Filament\Resources\MfmReadingResource\RelationManagers;
|
||||
use App\Models\MfmReading;
|
||||
@@ -12,6 +14,9 @@ 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;
|
||||
|
||||
class MfmReadingResource extends Resource
|
||||
{
|
||||
@@ -60,11 +65,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()
|
||||
@@ -193,6 +201,18 @@ class MfmReadingResource extends Resource
|
||||
Tables\Actions\ForceDeleteBulkAction::make(),
|
||||
Tables\Actions\RestoreBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->headerActions([
|
||||
ImportAction::make()
|
||||
->importer(MfmReadingImporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view import mfm reading');
|
||||
}),
|
||||
ExportAction::make()
|
||||
->exporter(MfmReadingExporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view export mfm reading');
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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'];
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
@@ -9,4 +9,9 @@ use Filament\Resources\Pages\CreateRecord;
|
||||
class CreateTempLiveReading extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TempLiveReadingResource::class;
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Create Live Readings';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,9 @@ class EditTempLiveReading extends EditRecord
|
||||
Actions\RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Edit Live Readings';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,9 @@ class ListTempLiveReadings extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Live Readings';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,9 @@ class ViewTempLiveReading extends ViewRecord
|
||||
Actions\EditAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'View Live Readings';
|
||||
}
|
||||
}
|
||||
|
||||
553
app/Filament/Widgets/TrendChartAnalysis.php
Normal file
553
app/Filament/Widgets/TrendChartAnalysis.php
Normal 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';
|
||||
}
|
||||
}
|
||||
206
app/Filament/Widgets/TrendLineChart.php
Normal file
206
app/Filament/Widgets/TrendLineChart.php
Normal 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';
|
||||
}
|
||||
}
|
||||
90
app/Http/Controllers/ChatbotController.php
Normal file
90
app/Http/Controllers/ChatbotController.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Gemini\Laravel\Facades\Gemini;
|
||||
|
||||
class ChatbotController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
// public function handleMessage(Request $request)
|
||||
// {
|
||||
// $request->validate(['message' => 'required|string']);
|
||||
// $userMessage = $request->input('message');
|
||||
|
||||
// try {
|
||||
// $result = Gemini::geminiPro()->generateContent($userMessage);
|
||||
// $reply = $result->text() ?? 'Sorry, no response from Gemini AI.';
|
||||
// } catch (\Exception $e) {
|
||||
// \Log::error('Gemini API Exception: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
|
||||
// if (config('app.debug')) {
|
||||
// return response()->json(['reply' => 'Error: ' . $e->getMessage()], 500);
|
||||
// }
|
||||
// return response()->json(['reply' => 'Error communicating with Gemini AI. Please try again later.'], 500);
|
||||
// }
|
||||
|
||||
// return response()->json(['reply' => $reply]);
|
||||
// }
|
||||
|
||||
// public function handleMessage(Request $request)
|
||||
// {
|
||||
// $request->validate([
|
||||
// 'message' => 'required|string'
|
||||
// ]);
|
||||
|
||||
// $apiKey = env('GEMINI_API_KEY'); // Put this in .env
|
||||
|
||||
// $response = Http::withHeaders([
|
||||
// 'Content-Type' => 'application/json',
|
||||
// 'x-goog-api-key' => $apiKey
|
||||
// ])->post('https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent', [
|
||||
// 'contents' => [
|
||||
// ['parts' => [['text' => $request->message]]]
|
||||
// ]
|
||||
// ]);
|
||||
|
||||
// if ($response->successful()) {
|
||||
// return response()->json([
|
||||
// 'reply' => $response->json()['candidates'][0]['content']['parts'][0]['text'] ?? 'No response.'
|
||||
// ]);
|
||||
// }
|
||||
|
||||
// return response()->json(['reply' => 'Failed to fetch response.'], 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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
824
app/Http/Controllers/InvoiceValidationController.php
Normal file
824
app/Http/Controllers/InvoiceValidationController.php
Normal file
@@ -0,0 +1,824 @@
|
||||
<?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
|
||||
{
|
||||
|
||||
$plantCode = $request->header('plant-code');
|
||||
$invoiceNo = $request->header('invoice-number');
|
||||
$lineQuan = $request->header('line-quantity');
|
||||
|
||||
if (!$plantCode) {
|
||||
return response()->json([
|
||||
'status_code' => 'ERROR',
|
||||
'status_description' => "Plant Code value can't be empty"
|
||||
], 404);
|
||||
}
|
||||
|
||||
$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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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,10 +46,138 @@ 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->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;}
|
||||
// .qr-cell { width: 14mm;}
|
||||
// .text-cell { text-align: left; vertical-align: middle; font-size: 22pt; padding-left: 1mm; padding-top: 2mm; white-space: nowrap; font-weight: bold; }
|
||||
// img.qr { width: 19mm; height: 19mm; display: block; margin-left: -2mm;}
|
||||
// </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');
|
||||
// }
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
|
||||
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>';
|
||||
|
||||
$html = '
|
||||
<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: 0mm; 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: 16mm; height: 16mm; display: block; margin-left: -2mm;}
|
||||
</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],
|
||||
@@ -57,17 +185,12 @@ class PalletController extends Controller
|
||||
'margin_right' => 0,
|
||||
'margin_top' => 0,
|
||||
'margin_bottom' => 0,
|
||||
'tempDir' => '/var/www/storage/mpdf-tmp',
|
||||
// 'tempDir' => '/var/www/storage/mpdf-tmp',
|
||||
]);
|
||||
|
||||
$mpdf->WriteHTML($html);
|
||||
$mpdf->Output('qr-label.pdf', 'I');
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
|
||||
277
app/Http/Controllers/ProductionStickerReprintController.php
Normal file
277
app/Http/Controllers/ProductionStickerReprintController.php
Normal 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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
27
app/Models/DeviceMaster.php
Normal file
27
app/Models/DeviceMaster.php
Normal 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
69
app/Models/EbReading.php
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
106
app/Policies/DeviceMasterPolicy.php
Normal file
106
app/Policies/DeviceMasterPolicy.php
Normal 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');
|
||||
}
|
||||
}
|
||||
106
app/Policies/EbReadingPolicy.php
Normal file
106
app/Policies/EbReadingPolicy.php
Normal 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');
|
||||
}
|
||||
}
|
||||
@@ -86,4 +86,9 @@ return [
|
||||
|
||||
'livewire_loading_delay' => 'default',
|
||||
|
||||
// 'assets' => [
|
||||
// 'app.js', // or your filament.js file
|
||||
// ],
|
||||
|
||||
|
||||
];
|
||||
|
||||
84
config/sanctum.php
Normal file
84
config/sanctum.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Stateful Domains
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Requests from the following domains / hosts will receive stateful API
|
||||
| authentication cookies. Typically, these should include your local
|
||||
| and production domains which access your API via a frontend SPA.
|
||||
|
|
||||
*/
|
||||
|
||||
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
||||
'%s%s',
|
||||
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
||||
Sanctum::currentApplicationUrlWithPort(),
|
||||
// Sanctum::currentRequestHost(),
|
||||
))),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array contains the authentication guards that will be checked when
|
||||
| Sanctum is trying to authenticate a request. If none of these guards
|
||||
| are able to authenticate the request, Sanctum will use the bearer
|
||||
| token that's present on an incoming request for authentication.
|
||||
|
|
||||
*/
|
||||
|
||||
'guard' => ['web'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expiration Minutes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value controls the number of minutes until an issued token will be
|
||||
| considered expired. This will override any values set in the token's
|
||||
| "expires_at" attribute, but first-party sessions are not affected.
|
||||
|
|
||||
*/
|
||||
|
||||
'expiration' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Token Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Sanctum can prefix new tokens in order to take advantage of numerous
|
||||
| security scanning initiatives maintained by open source platforms
|
||||
| that notify developers if they commit tokens into repositories.
|
||||
|
|
||||
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
||||
|
|
||||
*/
|
||||
|
||||
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When authenticating your first-party SPA with Sanctum you may need to
|
||||
| customize some of the middleware Sanctum uses while processing the
|
||||
| request. You may change the middleware listed below as required.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
|
||||
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
|
||||
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
|
||||
],
|
||||
|
||||
];
|
||||
@@ -35,4 +35,8 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
'gemini' => [
|
||||
'key' => env('GEMINI_API_KEY'),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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) {
|
||||
// //
|
||||
// });
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$sql = <<<'SQL'
|
||||
ALTER TABLE mfm_parameters
|
||||
ADD COLUMN device_master_id BIGINT NOT NULL,
|
||||
ADD CONSTRAINT mfm_parameters_device_master_id_fkey
|
||||
FOREIGN KEY (device_master_id) REFERENCES device_masters(id);
|
||||
SQL;
|
||||
|
||||
DB::statement($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Schema::table('mfm_parameters', function (Blueprint $table) {
|
||||
// //
|
||||
// });
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?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 eb_readings (
|
||||
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
|
||||
plant_id BIGINT NOT NULL,
|
||||
|
||||
lcd_segment_check TEXT DEFAULT NULL,
|
||||
meter_serial_no TEXT DEFAULT NULL,
|
||||
eb_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
ph_seq_of_volt TEXT DEFAULT NULL,
|
||||
ph_assoc_conn_check TEXT DEFAULT NULL,
|
||||
instantaneous_ph_volt TEXT DEFAULT NULL,
|
||||
instantaneous_curr TEXT DEFAULT NULL,
|
||||
instantaneous_freq TEXT DEFAULT NULL,
|
||||
instantaneous_kw_with_sign TEXT DEFAULT NULL,
|
||||
instantaneous_kva TEXT DEFAULT NULL,
|
||||
instantaneous_kv_ar TEXT DEFAULT NULL,
|
||||
instantaneous_pf_with_sign TEXT DEFAULT NULL,
|
||||
rd_with_elapsed_time_kva TEXT DEFAULT NULL,
|
||||
cum_active_import_energy TEXT DEFAULT NULL,
|
||||
tod1_active_energy_6_9 TEXT DEFAULT NULL,
|
||||
tod2_active_energy_18_21 TEXT DEFAULT NULL,
|
||||
tod3_active_energy_21_22 TEXT DEFAULT NULL,
|
||||
tod4_active_energy_5_6_9_18 TEXT DEFAULT NULL,
|
||||
tod5_active_energy_22_5 TEXT DEFAULT NULL,
|
||||
cum_reac_lag_energy TEXT DEFAULT NULL,
|
||||
cum_reac_lead_energy TEXT DEFAULT NULL,
|
||||
cum_appar_energy TEXT DEFAULT NULL,
|
||||
tod1_appar_energy_6_9 TEXT DEFAULT NULL,
|
||||
tod2_appar_energy_18_21 TEXT DEFAULT NULL,
|
||||
tod3_appar_energy_21_22 TEXT DEFAULT NULL,
|
||||
tod4_appar_energy_5_6_9_18 TEXT DEFAULT NULL,
|
||||
tod5_appar_energy_22_5 TEXT DEFAULT NULL,
|
||||
avg_pow_factor TEXT DEFAULT NULL,
|
||||
avg_freq_15min_last_ip TEXT DEFAULT NULL,
|
||||
net_kv_arh_high TEXT DEFAULT NULL,
|
||||
net_kv_arh_low TEXT DEFAULT NULL,
|
||||
cum_md_kva TEXT DEFAULT NULL,
|
||||
present_md_kva TEXT DEFAULT NULL,
|
||||
present_md_kva_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
tod1_md_kva_6_9 TEXT DEFAULT NULL,
|
||||
tod2_md_kva_18_21 TEXT DEFAULT NULL,
|
||||
tod3_md_kva_21_22 TEXT DEFAULT NULL,
|
||||
tod4_md_kva_5_6_9_18 TEXT DEFAULT NULL,
|
||||
tod5_md_kva_22_5 TEXT DEFAULT NULL,
|
||||
total_pow_off_hours TEXT DEFAULT NULL,
|
||||
programming_count TEXT DEFAULT NULL,
|
||||
last_occ_res_event_type TEXT DEFAULT NULL,
|
||||
last_occ_res_event_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
tamper_count TEXT DEFAULT NULL,
|
||||
reset_count TEXT DEFAULT NULL,
|
||||
last_md_reset_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
electrician_sign TEXT DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMP,
|
||||
updated_by TEXT NULL,
|
||||
|
||||
FOREIGN KEY (plant_id) REFERENCES plants (id)
|
||||
|
||||
);
|
||||
SQL;
|
||||
|
||||
DB::statement($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('eb_readings');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
// Enable TimescaleDB extension
|
||||
DB::statement('CREATE EXTENSION IF NOT EXISTS timescaledb;');
|
||||
|
||||
DB::statement('ALTER TABLE mfm_readings ADD PRIMARY KEY (id, created_at);');
|
||||
|
||||
// Create hypertable partitioned by created_at
|
||||
DB::statement("
|
||||
SELECT create_hypertable(
|
||||
'mfm_readings',
|
||||
'created_at',
|
||||
chunk_time_interval => interval '1 day',
|
||||
if_not_exists => TRUE
|
||||
);
|
||||
");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Schema::table('mfm_readings', function (Blueprint $table) {
|
||||
// //
|
||||
// });
|
||||
}
|
||||
};
|
||||
@@ -141,6 +141,8 @@ class PermissionSeeder extends Seeder
|
||||
Permission::updateOrCreate(['name' => 'view guard patrol hourly count dashboard']);
|
||||
Permission::updateOrCreate(['name' => 'view invoice serial quantity dashboard']);
|
||||
Permission::updateOrCreate(['name' => 'create production sticker reprint page']);
|
||||
Permission::updateOrCreate(['name' => 'view ems trend line analysis dashboard']);
|
||||
Permission::updateOrCreate(['name' => 'view ems trend chart analysis dashboard']);
|
||||
|
||||
|
||||
//Send To Sap Permissions
|
||||
|
||||
22
finance-news-today.txt
Normal file
22
finance-news-today.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
Markets & Economy:
|
||||
|
||||
* The Reserve Bank of India (RBI) has kept the repo rate unchanged at 5.5% and maintained its GDP growth forecast at 6.5%.
|
||||
* The RBI has lowered its inflation forecast for the 2026 fiscal year to 3.1%.
|
||||
* India's foreign exchange reserves have decreased by $9 billion to $689 billion.
|
||||
* The rupee has seen a rise of 15 paise, reaching 87.73 against the U.S. dollar in early trading.
|
||||
* In the U.K., the services sector has experienced its most significant drop in orders in nearly three years.
|
||||
|
||||
Corporate News:
|
||||
|
||||
* Intel is reportedly facing challenges with a crucial manufacturing process for its upcoming PC chip.
|
||||
* Shareholders are suing Elon Musk, alleging that he made exaggerated claims about Tesla's Robotaxi.
|
||||
* News Corp has issued a warning that Donald Trump's AI is using content from his book, "The Art of the Deal."
|
||||
* Chinese automakers, including BYD, saw significant increases in their U.K. sales in July.
|
||||
|
||||
Global Trade:
|
||||
|
||||
* There are concerns about the potential impact of tariffs proposed by Donald Trump on the Indian economy.
|
||||
|
||||
Other News:
|
||||
|
||||
* Central GST officers in India have uncovered significant tax evasion amounting to approximately Rs 7.08 lakh crore over the past five fiscal years.
|
||||
6
public/C:\Users\Admin\Downloads
Normal file
6
public/C:\Users\Admin\Downloads
Normal file
@@ -0,0 +1,6 @@
|
||||
SIZE 60 mm,40 mm
|
||||
GAP 3 mm,0 mm
|
||||
CLS
|
||||
QRCODE 40,100,M,4,A,0,M2,"HelloWorld123"
|
||||
TEXT 200,100,"3",0,1,1,"HelloWorld123"
|
||||
PRINT 1
|
||||
44
public/index.html
Normal file
44
public/index.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Chart.js Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myChart"></canvas>
|
||||
|
||||
<!-- Load Chart.js and plugins -->
|
||||
<script src="js/chart.min.js"></script>
|
||||
<script src="js/chartjs-plugin-datalabels.min.js"></script>
|
||||
<script src="js/chartjs-plugin-annotation.min.js"></script>
|
||||
|
||||
<!-- Your chart initialization code -->
|
||||
<script>
|
||||
const ctx = document.getElementById('myChart').getContext('2d');
|
||||
new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['Red', 'Blue', 'Yellow'],
|
||||
datasets: [{
|
||||
label: '# of Votes',
|
||||
data: [12, 19, 3]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
datalabels: {
|
||||
// plugin options
|
||||
},
|
||||
annotation: {
|
||||
// plugin options
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
4
public/js/filament-chart-js-plugins.js
Normal file
4
public/js/filament-chart-js-plugins.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// import ChartDataLabels from 'chartjs-plugin-datalabels'
|
||||
|
||||
// window.filamentChartJsPlugins ??= []
|
||||
// window.filamentChartJsPlugins.push(ChartDataLabels)
|
||||
1
resources/css/filament/admin/theme.css
Normal file
1
resources/css/filament/admin/theme.css
Normal file
@@ -0,0 +1 @@
|
||||
@import '../../../../vendor/filament/filament/resources/css/theme.css';
|
||||
@@ -1 +1,3 @@
|
||||
import './bootstrap';
|
||||
|
||||
|
||||
|
||||
86
resources/views/chatbot.blade.php
Normal file
86
resources/views/chatbot.blade.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Gemini Chat</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 40px;
|
||||
}
|
||||
#chat-box {
|
||||
border: 1px solid #ccc;
|
||||
padding: 15px;
|
||||
height: 300px;
|
||||
overflow-y: scroll;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.user, .bot {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.user {
|
||||
text-align: right;
|
||||
color: blue;
|
||||
}
|
||||
.bot {
|
||||
text-align: left;
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Gemini Chat</h2>
|
||||
<div id="chat-box"></div>
|
||||
<textarea id="prompt" rows="3" cols="60" placeholder="Type your message here..."></textarea><br>
|
||||
<button onclick="sendPrompt()">Send</button>
|
||||
|
||||
<script>
|
||||
async function getGeminiResponse(prompt) {
|
||||
try {
|
||||
const res = await fetch('http://172.31.31.51:8000/api/chatbot/message', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ message: prompt })
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text();
|
||||
console.error(`Server returned ${res.status}:`, errorText);
|
||||
throw new Error(`HTTP error! Status: ${res.status}`);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
return data.reply || "Sorry, no response.";
|
||||
} catch (e) {
|
||||
console.error('Fetch error:', e);
|
||||
return "Error fetching response.";
|
||||
}
|
||||
}
|
||||
|
||||
async function sendPrompt() {
|
||||
const promptInput = document.getElementById('prompt');
|
||||
const prompt = promptInput.value.trim();
|
||||
if (!prompt) return;
|
||||
|
||||
appendMessage('user', prompt);
|
||||
promptInput.value = '';
|
||||
|
||||
const reply = await getGeminiResponse(prompt);
|
||||
appendMessage('bot', reply);
|
||||
}
|
||||
|
||||
function appendMessage(sender, text) {
|
||||
const chatBox = document.getElementById('chat-box');
|
||||
const message = document.createElement('div');
|
||||
message.className = sender;
|
||||
message.textContent = text;
|
||||
chatBox.appendChild(message);
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
72
resources/views/filament/pages/sticker-reprint.blade.php
Normal file
72
resources/views/filament/pages/sticker-reprint.blade.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
|
||||
{{-- Heading label --}}
|
||||
<h2 class="text-xl font-semibold text-gray-800">
|
||||
STICKER RE-PRINT
|
||||
</h2>
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{-- {{ $this->filtersForm($this->form) }} --}}
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- <input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/> --}}
|
||||
<div class="mb-4">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const scanInput = document.getElementById('qr-scan-input');
|
||||
if (!scanInput) return;
|
||||
|
||||
scanInput.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
const value = scanInput.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
Livewire.dispatch('handleQrScan', { value: value });
|
||||
scanInput.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
window.addEventListener('open-pdf', event => {
|
||||
const pdfUrl = event.detail.url;
|
||||
const win = window.open(pdfUrl, '_blank');
|
||||
if (!win) {
|
||||
console.warn('Popup blocked. Please allow popups for this site.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ItemOverview::class)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
11
resources/views/filament/pages/trend-chart-analys.blade.php
Normal file
11
resources/views/filament/pages/trend-chart-analys.blade.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
10
resources/views/filament/pages/trend-line-analysis.blade.php
Normal file
10
resources/views/filament/pages/trend-line-analysis.blade.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,8 @@
|
||||
<button
|
||||
type="button"
|
||||
wire:click="updateInvoice"
|
||||
class="px-2 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Update Invoice
|
||||
</button>
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
<th rowspan="2" class="border px-4 py-2" style="width: 60px;">Patrol Round</th>
|
||||
<th rowspan="2" class="border px-4 py-2">Guard Name</th>
|
||||
<th colspan="3" class="border px-4 py-2">Patrol</th>
|
||||
<th colspan="{{ $seqNoCnt }}" class="border px-4 py-2">Sequences</th>
|
||||
@php
|
||||
$newSeqNoCnt = $seqNoCnt+1;
|
||||
@endphp
|
||||
<th colspan="{{ $newSeqNoCnt }}" class="border px-4 py-2">Sequences</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="border px-4 py-2">Start Time</th>
|
||||
@@ -23,7 +26,10 @@
|
||||
$seqTitle = $checkpoint->checkPointNames1->name . " - " . $checkpoint->checkPointNames2->name;
|
||||
}
|
||||
@endphp
|
||||
<th class="border px-4 py-2" title="{{ $seqTitle }}">{{ $seq }}</th>
|
||||
@if ($seq == 1)
|
||||
<th class="border px-4 py-2" style="" title="">1</th>
|
||||
@endif
|
||||
<th class="border px-4 py-2" title="{{ $seqTitle }}">{{ $seq + 1 }}</th>
|
||||
@empty
|
||||
<th class="border px-4 py-2" title="Sequences not found!">0</th>
|
||||
@endforelse
|
||||
@@ -38,6 +44,7 @@
|
||||
<td class="border px-4 py-2" title="Start Time">{{ $record['start_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="End Time">{{ $record['end_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="Lap Time">{{ $record['lap_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="">0</td>
|
||||
{{-- <td class="border px-4 py-2" style="{{ $bgStyle1 }}" title="<?php echo htmlspecialchars($seqTitle1); ?>">{{ $actualVal1 }}</td> --}}
|
||||
@foreach($startSeqCheckPoints as $seq => $checkpoint)
|
||||
@php
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-bold text-gray-800">INVOICE DATA TABLE</h2>
|
||||
<h2 class="text-lg font-bold text-gray-800">
|
||||
@if ($hasSearched)
|
||||
SERIAL INVOICE DATA TABLE
|
||||
@elseif ($materialInvoice)
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@else
|
||||
@if ($completedInvoice)
|
||||
@if ($isSerial)
|
||||
SERIAL INVOICE DATA TABLE
|
||||
@else
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@endif
|
||||
@else
|
||||
INVOICE DATA TABLE
|
||||
@endif
|
||||
@endif
|
||||
</h2>
|
||||
<div class="mt-2">
|
||||
<hr class="border-t-2 border-gray-300">
|
||||
</div>
|
||||
@@ -10,7 +26,13 @@
|
||||
{{-- Modal for completed invoice--}}
|
||||
@if ($completedInvoice)
|
||||
<div class="text-center text-red-500">
|
||||
<p>Completed the scanning process for invoice number <strong>{{ $invoiceNumber }}</strong>.</p>
|
||||
<p>
|
||||
@if ($isSerial)
|
||||
Completed the scanning process for serial invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@else
|
||||
Completed the scanning process for material invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Plant</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Line</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Target Quantity</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Line Type</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -71,6 +72,7 @@
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['line'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['targetQuantity'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['type'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['productionQuantity'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
94
resources/views/print-qr.blade.php
Normal file
94
resources/views/print-qr.blade.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@media print {
|
||||
@page {
|
||||
size: 60mm 14mm;
|
||||
margin: -1mm;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 60mm;
|
||||
height: 14mm;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.serial {
|
||||
text-align: left;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.desc-row {
|
||||
font-weight: normal;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
table, td, tr
|
||||
{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
margin: 0;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.po-number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
img.qr {
|
||||
width: 13mm;
|
||||
height: 13mm;
|
||||
padding-left: 2mm;
|
||||
padding-top: 1mm;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="print-container"></div>
|
||||
|
||||
<script>
|
||||
const copies = {{ $copies }};
|
||||
const qrBase64 = @json($qrBase64);
|
||||
const serial = @json($serial);
|
||||
const productionOrder = @json($productionOrder);
|
||||
const description = @json($item->description);
|
||||
|
||||
const htmlBlock = `
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<img class="qr" src="data:image/png;base64,${qrBase64}" alt="QR" />
|
||||
</td>
|
||||
<td>
|
||||
<pre><span class="serial">${serial}</span><span class="po-number">${productionOrder}</span><br><span class="desc-row">${description}</span></pre>
|
||||
</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(() => {
|
||||
window.close();
|
||||
}, 500);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
0
resources/views/vendor/filament/components/layouts/app.blade.php
vendored
Normal file
0
resources/views/vendor/filament/components/layouts/app.blade.php
vendored
Normal file
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\ChatbotController;
|
||||
use App\Http\Controllers\InvoiceValidationController;
|
||||
use App\Http\Controllers\MachineController;
|
||||
use App\Http\Controllers\MfmParameterController;
|
||||
use App\Http\Controllers\ModuleChartController;
|
||||
@@ -82,6 +84,8 @@ Route::get('sticker/get-master-type-data', [StickerMasterController::class, 'get
|
||||
|
||||
Route::get('/download-qr-pdf/{palletNo}', [PalletController::class, 'downloadQrPdf'])->name('download-qr-pdf');
|
||||
|
||||
Route::get('/download-reprint-qr-pdf/{palletNo}', [PalletController::class, 'downloadReprintQrPdf'])->name('download-reprint-qr-pdf');
|
||||
|
||||
Route::get('/download-qr1-pdf/{palletNo}', [ProductionStickerReprintController::class, 'downloadQrPdf'])->name('download-qr1-pdf');
|
||||
|
||||
//Production Dashboard Controller
|
||||
@@ -129,3 +133,12 @@ Route::get('get/module-guard-name/data', [ModuleGuardNameController::class, 'get
|
||||
Route::get('get/mfm-parameter/data', [MfmParameterController::class, 'get_mfm_parameter']);
|
||||
|
||||
Route::get('get/mfm-parameterid/data', [MfmParameterController::class, 'get_mfm_parameterid']);
|
||||
|
||||
//Invoice Validation Controller
|
||||
|
||||
Route::post('serial-invoice/store-data', [InvoiceValidationController::class, 'serialInvoice']);
|
||||
|
||||
Route::post('material-invoice/store-data', [InvoiceValidationController::class, 'materialInvoice']);
|
||||
|
||||
Route::post('/chatbot/message', [ChatbotController::class, 'handleMessage']);
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ use Illuminate\Support\Facades\Route;
|
||||
return redirect('/admin');
|
||||
});
|
||||
|
||||
Route::get('/chatbot', function () {
|
||||
return view('chatbot');
|
||||
});
|
||||
|
||||
|
||||
// Route::get('/scheduler', function() {
|
||||
// Artisan::call('schedule:run');
|
||||
// });
|
||||
|
||||
Reference in New Issue
Block a user