29 Commits

Author SHA1 Message Date
a6b8a5c0cc Merge pull request 'Added CustomerPoMaster importer and exporter' (#381) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #381
2026-02-24 07:43:26 +00:00
dhanabalan
8dabfb1fa5 Added CustomerPoMaster importer and exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Successful in 3m13s
Laravel Larastan / larastan (pull_request) Failing after 3m42s
2026-02-24 13:13:09 +05:30
c6714b195e Merge pull request 'ranjith-dev' (#380) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #380
2026-02-24 07:41:03 +00:00
dhanabalan
3bdcc15c18 Added customer po policy file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 2m50s
Laravel Larastan / larastan (pull_request) Failing after 4m6s
2026-02-24 13:10:25 +05:30
dhanabalan
2696e9633c Added customer po resource pages
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-02-24 13:08:12 +05:30
dhanabalan
d46819a79d Added customer po master model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-02-24 13:06:01 +05:30
dhanabalan
6321d3c8db Added customer po master migration file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-02-24 13:05:10 +05:30
d392fe9c78 Merge pull request 'Changed logic in invoice in transit import page' (#379) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Reviewed-on: #379
2026-02-23 13:09:02 +00:00
dhanabalan
79e6d498d9 Changed logic in invoice in transit import page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Laravel Pint / pint (pull_request) Successful in 2m36s
Laravel Larastan / larastan (pull_request) Failing after 3m36s
2026-02-23 18:38:47 +05:30
eccc6342c0 Merge pull request 'Added updated_by name if not exist on importer' (#378) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Reviewed-on: #378
2026-02-23 10:14:54 +00:00
dhanabalan
543ce2fc81 Added updated_by name if not exist on importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 2m46s
Laravel Larastan / larastan (pull_request) Failing after 4m1s
2026-02-23 15:44:36 +05:30
dbc9a02669 Merge pull request 'Added rework_status value validation on importer' (#377) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #377
2026-02-23 10:12:08 +00:00
dhanabalan
dc0bf9a9a7 Added rework_status value validation on importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m36s
Laravel Larastan / larastan (pull_request) Failing after 4m2s
2026-02-23 15:41:36 +05:30
837b936b51 Merge pull request 'Added rework coil number warning message on import' (#376) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #376
2026-02-23 10:03:25 +00:00
dhanabalan
5afc8afa1a Added rework coil number warning message on import
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Larastan / larastan (pull_request) Failing after 3m44s
Laravel Pint / pint (pull_request) Successful in 3m43s
2026-02-23 15:33:03 +05:30
528914e2d0 Merge pull request 'Commented created_at and updated_at column when line not found' (#375) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Reviewed-on: #375
2026-02-23 09:51:46 +00:00
dhanabalan
84f5ee7f7e Commented created_at and updated_at column when line not found
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m36s
Laravel Larastan / larastan (pull_request) Failing after 3m36s
2026-02-23 15:21:22 +05:30
bb94206a1e Merge pull request 'Added created_by value if not exist' (#374) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #374
2026-02-23 09:43:42 +00:00
dhanabalan
25ed37f50d Added created_by value if not exist
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 3m39s
Laravel Larastan / larastan (pull_request) Failing after 3m52s
2026-02-23 15:06:48 +05:30
d7f758b584 Merge pull request 'Update process order logic on importer' (#373) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #373
2026-02-23 09:29:25 +00:00
dhanabalan
a1f3bc555e Update process order logic on importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 3m32s
Laravel Larastan / larastan (pull_request) Failing after 3m49s
2026-02-23 14:58:17 +05:30
85bfb99273 Merge pull request 'Removed label name of item code in table list' (#372) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Reviewed-on: #372
2026-02-23 09:25:04 +00:00
dhanabalan
6010cf5998 Removed label name of item code in table list
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m45s
Laravel Larastan / larastan (pull_request) Failing after 3m52s
2026-02-23 14:54:49 +05:30
2f2faa3019 Merge pull request 'Added category in production target page and added in livewire table' (#371) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #371
2026-02-23 09:15:23 +00:00
dhanabalan
f818a8c44b Added category in production target page and added in livewire table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 4m2s
Laravel Larastan / larastan (pull_request) Failing after 5m16s
2026-02-23 14:44:59 +05:30
d72f4c89fd Merge pull request 'Changed logic in calender blade file' (#370) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 24s
Reviewed-on: #370
2026-02-23 04:19:05 +00:00
dhanabalan
b698493e1a Changed logic in calender blade file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m36s
Laravel Larastan / larastan (pull_request) Failing after 3m24s
2026-02-23 09:48:48 +05:30
4c07abe394 Merge pull request 'Updated line label on report view' (#369) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #369
2026-02-23 04:04:59 +00:00
dhanabalan
9fd451bbda Updated line label on report view
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 3m26s
Laravel Larastan / larastan (pull_request) Failing after 3m37s
2026-02-23 09:33:24 +05:30
18 changed files with 977 additions and 147 deletions

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Filament\Exports;
use App\Models\CustomerPoMaster;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class CustomerPoMasterExporter extends Exporter
{
protected static ?string $model = CustomerPoMaster::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('customer_po')
->label('CUSTOMER PO'),
ExportColumn::make('customer_name')
->label('CUSTOMER NAME'),
ExportColumn::make('quantity')
->label('QUANTITY'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your customer po master export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.';
}
return $body;
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace App\Filament\Imports;
use App\Models\CustomerPoMaster;
use App\Models\Item;
use App\Models\Plant;
use App\Models\User;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Facades\Filament;
use Str;
class CustomerPoMasterImporter extends Importer
{
protected static ?string $model = CustomerPoMaster::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('Item Code')
->example('630214')
->label('Item Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('customer_po')
->requiredMapping()
->exampleHeader('Customer PO')
->example('1JA0029512')
->label('Customer PO')
->rules(['required']),
ImportColumn::make('customer_name')
->requiredMapping()
->exampleHeader('Customer Name')
->example('KANKARIA MACHINERY STORE')
->label('Customer Name')
->rules(['required']),
ImportColumn::make('quantity')
->requiredMapping()
->exampleHeader('Quantity')
->example('5')
->label('Quantity')
->rules(['required']),
// ImportColumn::make('created_by')
// ->requiredMapping()
// ->exampleHeader('Created By')
// ->example('Admin')
// ->label('Created By')
// ->rules(['required']),
];
}
public function resolveRecord(): ?CustomerPoMaster
{
$warnMsg = [];
$plantCod = $this->data['plant'];
$plant = null;
$item = null;
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found';
} else {
$item = Item::where('code', $this->data['item'])->where('plant_id', $plant->id)->first();
}
if (! $item) {
$warnMsg[] = 'Item not found';
}
}
if (Str::length($this->data['customer_po']) < 9) {
$warnMsg[] = 'Invalid Customer PO number found';
}
if (empty($this->data['customer_po'])) {
$warnMsg[] = 'Customer PO cannot be empty.';
}
// $user = User::where('name', $this->data['created_by'])->first();
// if (! $user) {
// $warnMsg[] = 'User not found';
// }
$user = Filament::auth()->user();
$operatorName = $user->name;
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
//else { // if (empty($warnMsg))
// $grMaster = GrMaster::where('plant_id', $plant->id)
// ->where('serial_number', $this->data['serial_number'])
// ->latest()
// ->first();
// if ($grMaster) {
// throw new RowImportFailedException('Serial number already exist!');
// }
// }
CustomerPoMaster::updateOrCreate([
'plant_id' => $plant->id,
'item_id' => $item->id,
'customer_po' => $this->data['customer_po'],
'customer_name' => $this->data['customer_name'],
'quantity' => $this->data['quantity'] ?? null,
'created_by' => $operatorName,
]);
return null;
// return new CustomerPoMaster();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your customer po master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
if ($failedRowsCount = $import->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
}
return $body;
}
}

View File

@@ -142,13 +142,12 @@ class ProcessOrderImporter extends Importer
if ($recQuan == null || $recQuan == '') {
$recQuan = 0;
}
if ($reworkStatus == null || $reworkStatus = '') {
if ($reworkStatus == null || $reworkStatus = '' || $reworkStatus == 0 || $reworkStatus = '0') {
$reworkStatus = 0;
}
if ($createdBy == null || $createdBy == '') {
$createdBy = Filament::auth()->user()?->name;
$updatedBy = $createdBy;
} elseif ($reworkStatus == 1 || $reworkStatus = '1') {
$reworkStatus = 1;
} else {
$warnMsg[] = 'Invalid rework status found';
}
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
@@ -209,21 +208,16 @@ class ProcessOrderImporter extends Importer
$lineId = null;
}
if ($createdBy != null && $createdBy != '') {
if ($plantId) {
$user = User::where('name', $createdBy)->first();
// $user = User::where('name', $this->data['created_by'])->first();
// if (! $user) {
// $warnMsg[] = 'User not found';
// }
$userPlant = User::where('name', $createdBy)->where('plant_id', $plantId)->first();
if (! $user) {
$warnMsg[] = 'Created By user name not found!';
} elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
$warnMsg[] = "Created By user '{$createdBy}' not found for Plant '{$plantCod}'!";
} elseif (! $user->hasRole(['Super Admin', 'Process Quality Manager', 'Process Manager', 'Process Supervisor', 'Process Employee'])) {
$warnMsg[] = 'Created By user does not have rights!';
}
}
$updatedBy = Filament::auth()->user()?->name;
if (! $createdBy) {
$createdBy = Filament::auth()->user()->name;
$updatedBy = Filament::auth()->user()->name;
} elseif (! $updatedBy) {
$updatedBy = Filament::auth()->user()->name;
}
if (! empty($warnMsg)) {
@@ -280,9 +274,10 @@ class ProcessOrderImporter extends Importer
->where('coil_number', $coilNo)
->first();
if (! $existing && $coilNo == '0' || $coilNo == 0) {
if (! $existing && ($coilNo == '0' || $coilNo == 0)) {
ProcessOrder::create([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => $itemId,
'process_order' => $processOrder,
'coil_number' => '0',
@@ -297,8 +292,8 @@ class ProcessOrderImporter extends Importer
[
'plant_id' => $plantId,
'line_id' => $lineId,
'process_order' => $processOrder,
'item_id' => $itemId,
'process_order' => $processOrder,
'coil_number' => $coilNo,
'order_quantity' => $orderQuan,
'received_quantity' => $recQuan,
@@ -306,13 +301,17 @@ class ProcessOrderImporter extends Importer
'sfg_number' => $sfgNo,
'machine_name' => $machineName,
'rework_status' => $reworkStatus,
'created_at' => $createdAt,
'updated_at' => $updatedAt,
// 'created_at' => $createdAt,
// 'updated_at' => $updatedAt,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]
);
} else {// $coilNo = '0'
if ($existing->rework_status == 1 && $reworkStatus == 0) {
throw new RowImportFailedException('Rework coil number already exist for the given Plant and Process Order!');
}
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
@@ -324,7 +323,7 @@ class ProcessOrderImporter extends Importer
// 'machine_name' => $machineId,
'rework_status' => $reworkStatus,
'updated_by' => $updatedBy,
'updated_at' => $updatedAt,
// 'updated_at' => $updatedAt,
]);
}
}

View File

@@ -31,47 +31,6 @@ class ProductionTarget extends Page
->schema([
Section::make('')
->schema([
Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->reactive()
// ->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
// dd($state);
$set('line_id', null);
$set('year', null);
$set('month', null);
$this->dispatch('loadData',$state, '', '', '');
}),
Select::make('line_id')
->label('Line')
->required()
->relationship('line', 'name')
// ->searchable()
->columnSpan(1)
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$set('year', null);
$set('month', null);
$this->dispatch('loadData',$plantId, $state, '', '');
}),
Select::make('year')
->label('Year')
->reactive()
@@ -97,9 +56,13 @@ class ProductionTarget extends Page
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('month', null);
$set('plant_id', null);
$set('line_id', null);
$set('category', null);
$plantId = $get('plant_id');
$lineId = $get('line_id');
$this->dispatch('loadData',$plantId, $lineId, $state, '');
// $this->dispatch('loadData',$plantId, $lineId, $state, '');
$this->dispatch('loadData',$state, '', '', '', '');
}),
Select::make('month')
@@ -121,23 +84,86 @@ class ProductionTarget extends Page
'12' => 'December',
])
->required()
->afterStateUpdated(function ($state, callable $get) {
->afterStateUpdated(function ($state, callable $get, $set) {
$set('plant_id', null);
$set('line_id', null);
$set('category', null);
$year = $get('year');
$this->dispatch('loadData',$year, $state, '', '', '');
// $plantId = $get('plant_id');
// $lineId = $get('line_id');
// // $month = $get('month');
// $year = $get('year');
// $month = (int) $get('month');
// if (!$month) {
// return;
// }
// $this->dispatch('loadData', $plantId, $lineId, $month, $year);
}),
Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->reactive()
// ->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
// dd($state);
$set('line_id', null);
$set('category', null);
$this->dispatch('loadData',$state, '', '', '', '');
}),
Select::make('line_id')
->label('Line')
->required()
->relationship('line', 'name')
// ->searchable()
->columnSpan(1)
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$lineId = $get('line_id');
// $month = $get('month');
$year = $get('year');
$month = (int) $get('month');
$this->dispatch('loadData',$year, $month, $plantId, $lineId, '');
}),
if (!$month) {
return;
}
$this->dispatch('loadData', $plantId, $lineId, $month, $year);
TextInput::make('category')
->label('Category')
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$lineId = $get('line_id');
// $month = $get('month');
$year = $get('year');
$month = (int) $get('month');
$category = $get('category');
$this->dispatch('loadData',$year, $month, $plantId, $lineId, $category);
}),
])
->columns(4)
->columns(5)
]);
}

View File

@@ -0,0 +1,176 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\CustomerPoMasterExporter;
use App\Filament\Imports\CustomerPoMasterImporter;
use App\Filament\Resources\CustomerPoMasterResource\Pages;
use App\Filament\Resources\CustomerPoMasterResource\RelationManagers;
use App\Models\CustomerPoMaster;
use App\Models\Item;
use App\Models\Plant;
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\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
class CustomerPoMasterResource extends Resource
{
protected static ?string $model = CustomerPoMaster::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->reactive()
->relationship('plant', 'name')
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
->reactive()
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
return [];
}
return Item::where('plant_id', $plantId)->pluck('code', 'id');
})
->required(),
Forms\Components\TextInput::make('customer_po')
->label('Customer PO'),
Forms\Components\TextInput::make('customer_name')
->label('Customer Name'),
Forms\Components\TextInput::make('quantity')
->label('Quantity'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->default(Filament::auth()->user()?->name),
]);
}
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('item.code')
->label('Item Code')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('customer_po')
->label('Customer PO')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('customer_name')
->label('Customer Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('quantity')
->label('Quantity')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->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()
->label('Import Customer PO')
->color('warning')
->importer(CustomerPoMasterImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import customer po master');
}),
ExportAction::make()
->label('Export Customer PO')
->color('warning')
->exporter(CustomerPoMasterExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export customer po master');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCustomerPoMasters::route('/'),
'create' => Pages\CreateCustomerPoMaster::route('/create'),
'view' => Pages\ViewCustomerPoMaster::route('/{record}'),
'edit' => Pages\EditCustomerPoMaster::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\CustomerPoMasterResource\Pages;
use App\Filament\Resources\CustomerPoMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCustomerPoMaster extends CreateRecord
{
protected static string $resource = CustomerPoMasterResource::class;
}

View File

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

View File

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

View File

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

View File

@@ -446,7 +446,7 @@ class GrMasterResource extends Resource
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item Code')
->label('Item')
->searchable()
->alignCenter()
->sortable(),

View File

@@ -351,12 +351,12 @@ class InvoiceInTransitResource extends Resource
if (empty($transportName)) {
$invalidTransportName[] = "Row {$index}";
}
if (empty($LRBAWNo)) {
$invalidLRBLAWNo[] = "Row {$index}";
}
if (empty($LRBAWDt)) {
$invalidLRBLAWDt[] = "Row {$index}";
}
// if (empty($LRBAWNo)) {
// $invalidLRBLAWNo[] = "Row {$index}";
// }
// if (empty($LRBAWDt)) {
// $invalidLRBLAWDt[] = "Row {$index}";
// }
if (empty($pendingDays)) {
$invalidPenDay[] = "Row {$index}";
}
@@ -367,50 +367,56 @@ class InvoiceInTransitResource extends Resource
$invalidPlaCoFound[] = $plantCode;
}
if($LRBAWNo){
if(strlen($LRBAWNo) < 2){
$invalidLRBLAWNo[] = $LRBAWNo;
}
}
$plant = Plant::where('code', $plantCode)->first();
// $plantId = $plant->id;
}
if (! empty($invalidPlantCode) || ! empty($invalidRecPlant) || ! empty($invalidRecPlantName) || ! empty($invalidInvNo) || ! empty($invalidInvDt) || ! empty($invalidICode) || ! empty($invalidDesc) || ! empty($invalidQty) || ($invalidTransportName) || ! empty($invalidLRBLAWNo) || ! empty($invalidLRBLAWDt) || ! empty($invalidPenDay)) {
if (! empty($invalidPlantCode) || ! empty($invalidRecPlant) || ! empty($invalidRecPlantName) || ! empty($invalidInvNo) || ! empty($invalidInvDt) || ! empty($invalidICode) || ! empty($invalidDesc) || ! empty($invalidQty) || ($invalidTransportName) || ! empty($invalidPenDay)) {
$errorMsg = '';
if (! empty($invalidPlantCode)) {
$errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidPlantCode).'<br>';
$errorMsg .= 'Missing Receiving Plant Code in rows: '.implode(', ', $invalidPlantCode).'<br>';
}
if (! empty($invalidRecPlant)) {
$errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidRecPlant).'<br>';
$errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidRecPlant).'<br>';
}
if (! empty($invalidRecPlantName)) {
$errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidRecPlantName).'<br>';
$errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidRecPlantName).'<br>';
}
if (! empty($invalidInvNo)) {
$errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidInvNo).'<br>';
$errorMsg .= 'Missing Invoice Number in rows: '.implode(', ', $invalidInvNo).'<br>';
}
if (! empty($invalidInvDt)) {
$errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidInvDt).'<br>';
$errorMsg .= 'Missing Invoice Dates in rows: '.implode(', ', $invalidInvDt).'<br>';
}
if (! empty($invalidICode)) {
$errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidICode).'<br>';
$errorMsg .= 'Missing Item Code in rows: '.implode(', ', $invalidICode).'<br>';
}
if (! empty($invalidDesc)) {
$errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidDesc).'<br>';
$errorMsg .= 'Missing Item Description in rows: '.implode(', ', $invalidDesc).'<br>';
}
if (! empty($invalidQty)) {
$errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidQty).'<br>';
$errorMsg .= 'Missing Quantity in rows: '.implode(', ', $invalidQty).'<br>';
}
if (! empty($invalidTransportName)) {
$errorMsg .= 'Missing Receiving Plant in rows: '.implode(', ', $invalidTransportName).'<br>';
}
if (! empty($invalidLRBLAWNo)) {
$errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidLRBLAWNo).'<br>';
}
if (! empty($invalidLRBLAWDt)) {
$errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidLRBLAWDt).'<br>';
$errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidTransportName).'<br>';
}
// if (! empty($invalidLRBLAWNo)) {
// $errorMsg .= 'Missing Receiving Plant Name in rows: '.implode(', ', $invalidLRBLAWNo).'<br>';
// }
// if (! empty($invalidLRBLAWDt)) {
// $errorMsg .= 'Missing Transit Days in rows: '.implode(', ', $invalidLRBLAWDt).'<br>';
// }
if (! empty($invalidPenDay)) {
$errorMsg .= 'Missing Transport Name in rows: '.implode(', ', $invalidPenDay).'<br>';
$errorMsg .= 'Missing Pending Days in rows: '.implode(', ', $invalidPenDay).'<br>';
}
Notification::make()
@@ -454,19 +460,30 @@ class InvoiceInTransitResource extends Resource
return;
}
if (! empty($invalidLRBLAWNo)) {
$invalidLRBLAWNo = array_unique($invalidLRBLAWNo);
Notification::make()
->title('Invalid LR/BL/AW Number')
->body('LR/BL/AW Number should contain length minimum 2 digits:<br>'.implode(', ', $invalidLRBLAWNo))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
$mandatoryColumns = 23;
$firstRow = $rows[0] ?? [];
if (count($firstRow) < $mandatoryColumns) {
Notification::make()
->title('Invalid Excel Format')
->body('Few columns not found. Columns A to W are mandatory.')
->danger()
->persistent()
->send();
return;
}
@@ -530,7 +547,7 @@ class InvoiceInTransitResource extends Resource
if (! empty($OBDDate)) {
if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $OBDDate)) {
[$day, $month, $year] = preg_split('/[-\/]/', $OBDDate);
$formattedDate = "{$year}-{$month}-{$day}";
$formatted = "{$year}-{$month}-{$day}";
} elseif (is_numeric($OBDDate)) {
$formatted = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($OBDDate)->format('Y-m-d');
} else {
@@ -540,6 +557,16 @@ class InvoiceInTransitResource extends Resource
$formatted = null;
}
$rowNumber = $index + 1;
if ($LRBAWNo == '' || $LRBAWDt == '') {
// $missedInvoices[] = $invoiceNo;
// $missedInvoices[$invoiceNo][] = $index + 1;
// continue;
$key = $invoiceNo ?: 'Row '.$rowNumber;
$missedInvoices[$key][$rowNumber] = true;
continue;
}
$inserted = InvoiceInTransit::create([
'plant_id' => $plant->id,
'receiving_plant' => $receivingPlant,
@@ -567,10 +594,28 @@ class InvoiceInTransitResource extends Resource
'created_by' => $operatorName,
]);
}
$formattedMissed = [];
if (!empty($missedInvoices)) {
$formattedMissed = array_map(
fn($rows, $invoice) =>
$invoice . ' (Row: ' . implode(', ', array_keys($rows)) . ')',
$missedInvoices,
array_keys($missedInvoices)
);
}
if ($inserted) {
$message = "Invoice in transit uploaded successfully!";
if (!empty($formattedMissed)) {
$message .= "\n\nSkipped Invoices (Missing LR/Date):\n"
. implode("\n", $formattedMissed);
}
Notification::make()
->title('Upload Success')
->body('Invoice in transit uploaded successfully!')
->title('Upload Completed')
->body($message)
->success()
->send();

View File

@@ -48,6 +48,7 @@ class ProductionPlanResource extends Resource
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required()
// ->nullable()
@@ -79,6 +80,7 @@ class ProductionPlanResource extends Resource
->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id')
->label('Line')
->relationship('line', 'name')
->required()
// ->nullable()
@@ -437,7 +439,7 @@ class ProductionPlanResource extends Resource
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('line.name')
->label('Plant')
->label('Line')
->alignCenter()
->sortable()
->searchable(),

View File

@@ -26,6 +26,7 @@ class ProductionTargetPlan extends Component
protected $listeners = [
'loadData' => 'loadProductionData',
'loadCategoryData' => 'loadProductionDataCategory',
'loadData1' => 'exportProductionData',
];
@@ -175,7 +176,7 @@ class ProductionTargetPlan extends Component
public function loadProductionData($plantId, $lineId, $month, $year)
public function loadProductionData($year, $month, $plantId, $lineId, $category)
{
if (!$plantId || !$lineId || !$month || !$year) {
$this->records = [];
@@ -195,6 +196,9 @@ class ProductionTargetPlan extends Component
->where('production_plans.line_id', $lineId)
->whereMonth('production_plans.created_at', $month)
->whereYear('production_plans.created_at', $year)
->when($category, function ($query) use ($category) {
$query->where('items.category', $category);
})
->select(
'production_plans.item_id',
'production_plans.plant_id',
@@ -203,6 +207,7 @@ class ProductionTargetPlan extends Component
'production_plans.working_days',
'production_plans.leave_dates',
'items.code as item_code',
'items.category as category',
'items.description as item_description',
'lines.name as line_name',
'lines.line_capacity as line_capacity',
@@ -229,6 +234,11 @@ class ProductionTargetPlan extends Component
->where('line_id', $lineId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->when($category, function ($query) use ($category) {
$query->whereHas('item', function ($q) use ($category) {
$q->where('category', $category);
});
})
->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
->get()
->groupBy(fn($row) =>
@@ -249,7 +259,7 @@ class ProductionTargetPlan extends Component
$lineCapacity = (float) ($row['line_capacity'] ?? 0);
$dailyLineCapacity = (float) ($row['line_capacity'] ?? 0);
$row['category'] = $row['category'] ?? '-';
$row['daily_line_capacity'] = [];
$row['daily_target_dynamic'] = [];
$row['produced_quantity'] = [];
@@ -291,6 +301,122 @@ class ProductionTargetPlan extends Component
}
// public function loadProductionDataCategory($year, $month, $plantId, $lineId, $category)
// {
// if (!$plantId || !$lineId || !$month || !$year || !$category) {
// $this->records = [];
// $this->dates = [];
// $this->leaveDates = [];
// return;
// }
// $dates = $this->getMonthDates($month, $year);
// $this->dates = $dates;
// $plans = ProductionPlan::query()
// ->join('items', 'items.id', '=', 'production_plans.item_id')
// ->join('lines', 'lines.id', '=', 'production_plans.line_id')
// ->join('plants', 'plants.id', '=', 'production_plans.plant_id')
// ->where('production_plans.plant_id', $plantId)
// ->where('production_plans.line_id', $lineId)
// ->whereMonth('production_plans.created_at', $month)
// ->whereYear('production_plans.created_at', $year)
// ->select(
// 'production_plans.item_id',
// 'production_plans.plant_id',
// 'production_plans.line_id',
// 'production_plans.plan_quantity',
// 'production_plans.working_days',
// 'production_plans.leave_dates',
// 'items.code as item_code',
// 'items.description as item_description',
// 'lines.name as line_name',
// 'lines.line_capacity as line_capacity',
// 'plants.name as plant_name'
// )
// ->get();
// $leaveDates = [];
// if ($plans->isNotEmpty() && $plans[0]->leave_dates) {
// $leaveDates = array_map('trim', explode(',', $plans[0]->leave_dates));
// }
// $this->leaveDates = $leaveDates;
// $producedData = ProductionQuantity::selectRaw("
// plant_id,
// line_id,
// item_id,
// DATE(created_at) as prod_date,
// COUNT(*) as total_qty
// ")
// ->where('plant_id', $plantId)
// ->where('line_id', $lineId)
// ->whereMonth('created_at', $month)
// ->whereYear('created_at', $year)
// ->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
// ->get()
// ->groupBy(fn($row) =>
// $row->plant_id . '_' . $row->line_id . '_' . $row->item_id
// )
// ->map(fn($group) => $group->keyBy('prod_date'));
// $records = [];
// foreach ($plans as $plan) {
// $row = $plan->toArray();
// $remainingQty = (float) $row['plan_quantity'];
// $remainingDays = (int) ($row['working_days'] ?? 0);
// $lineCapacity = (float) ($row['line_capacity'] ?? 0);
// $dailyLineCapacity = (float) ($row['line_capacity'] ?? 0);
// $row['daily_line_capacity'] = [];
// $row['daily_target_dynamic'] = [];
// $row['produced_quantity'] = [];
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
// foreach ($dates as $date) {
// // Skip leave dates fast
// if (isset($leaveDates) && in_array($date, $leaveDates)) {
// $row['daily_line_capacity'][$date] = '-';
// $row['daily_target_dynamic'][$date] = '-';
// $row['produced_quantity'][$date] = '-';
// continue;
// }
// $todayTarget = $remainingDays > 0
// ? round($remainingQty / $remainingDays, 2)
// : 0;
// $producedQty = $producedData[$key][$date]->total_qty ?? 0;
// $row['daily_target_dynamic'][$date] = $todayTarget;
// $row['produced_quantity'][$date] = $producedQty;
// $row['daily_line_capacity'][$date] = $dailyLineCapacity;
// // Carry forward remaining qty
// $remainingQty = max(0, $remainingQty - $producedQty);
// if ($remainingDays > 0) {
// $remainingDays--;
// }
// }
// $records[] = $row;
// }
// $this->records = $records;
// }
public function exportProductionData()
{
return Excel::download(

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class CustomerPoMaster extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'item_id',
'customer_po',
'customer_name',
'quantity',
'created_at',
'updated_at',
'created_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
}

View File

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

View File

@@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE customer_po_masters (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
customer_po TEXT DEFAULT NULL,
customer_name TEXT DEFAULT NULL,
quantity TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_by TEXT DEFAULT NULL,
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP,
FOREIGN KEY (plant_id) REFERENCES plants(id),
FOREIGN KEY (item_id) REFERENCES items(id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('customer_po_masters');
}
};

View File

@@ -64,57 +64,57 @@ document.addEventListener('DOMContentLoaded', function () {
});
// function updateWorkingDays(date) {
// let totalDays = new Date(
// date.getFullYear(),
// date.getMonth()+1,
// 0
// ).getDate();
// let workingDays = totalDays - selectedDates.length;
// // document.querySelector('input[name="working_days"]').value = workingDays;
// const input = document.querySelector('#working_days');
// input.value = workingDays;
// input.dispatchEvent(new Event('input'));
// const monthInput = document.querySelector('#month');
// monthInput.value = date.getMonth() + 1; // 112 month number
// monthInput.dispatchEvent(new Event('input'));
// const yearInput = document.querySelector('#year');
// yearInput.value = date.getFullYear();
// yearInput.dispatchEvent(new Event('input'));
// const selectedDatesInput = document.querySelector('#selected_dates');
// selectedDatesInput.value = selectedDates.join(',');
// selectedDatesInput.dispatchEvent(new Event('input'));
// }
function updateWorkingDays(date) {
function updateWorkingDays(date) {
let totalDays = new Date(
date.getFullYear(),
date.getMonth() + 1,
date.getMonth()+1,
0
).getDate();
let workingDays = totalDays - selectedDates.length;
// document.querySelector('input[name="working_days"]').value = workingDays;
// Set values only
document.querySelector('#working_days').value = workingDays;
document.querySelector('#month').value = date.getMonth() + 1;
document.querySelector('#year').value = date.getFullYear();
document.querySelector('#selected_dates').value = selectedDates.join(',');
const input = document.querySelector('#working_days');
input.value = workingDays;
input.dispatchEvent(new Event('input'));
const monthInput = document.querySelector('#month');
monthInput.value = date.getMonth() + 1; // 112 month number
monthInput.dispatchEvent(new Event('input'));
const yearInput = document.querySelector('#year');
yearInput.value = date.getFullYear();
yearInput.dispatchEvent(new Event('input'));
const selectedDatesInput = document.querySelector('#selected_dates');
selectedDatesInput.value = selectedDates.join(',');
selectedDatesInput.dispatchEvent(new Event('input'));
// Trigger only ONE update (important)
document
.querySelector('#selected_dates')
.dispatchEvent(new Event('input'));
}
// function updateWorkingDays(date) {
// let totalDays = new Date(
// date.getFullYear(),
// date.getMonth() + 1,
// 0
// ).getDate();
// let workingDays = totalDays - selectedDates.length;
// // Set values only
// document.querySelector('#working_days').value = workingDays;
// document.querySelector('#month').value = date.getMonth() + 1;
// document.querySelector('#year').value = date.getFullYear();
// document.querySelector('#selected_dates').value = selectedDates.join(',');
// // Trigger only ONE update (important)
// document
// .querySelector('#selected_dates')
// .dispatchEvent(new Event('input'));
// }
calendar.render();
});

View File

@@ -6,10 +6,11 @@
<table class="w-full divide-y divide-gray-200 text-sm text-center">
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
<tr>
<th class="border px-4 py-2" rowspan="3">No</th>
<th class="border px-4 py-2" rowspan="4">No</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Plant</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Line</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Item Code</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Category</th>
<th class="border px-4 py-2 whitespace-nowrap" colspan="{{ count($dates) * 3 }}" class="text-center">
Production Plan Dates
@@ -45,6 +46,7 @@
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['plant_name'] }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['line_name'] }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['item_code'] }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['category'] }}</td>
{{-- @foreach($dates as $date)
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['target_plan'][$date] ?? '-' }}</td>