Compare commits
47 Commits
99a95dc150
...
jothi-patc
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a7b42dea5 | |||
| 0ce59ebe22 | |||
|
|
053c07bcfb | ||
| c032cdc58d | |||
|
|
b09ed3481a | ||
| 4074374614 | |||
|
|
c2d840d772 | ||
| 15712c44b6 | |||
|
|
119262405c | ||
| 99f7450e5e | |||
|
|
84748c5e3d | ||
| f6f6f0924e | |||
|
|
4ec781b942 | ||
| 3bab0310a1 | |||
|
|
f0f7bffe74 | ||
| 6924990ace | |||
|
|
40889f8802 | ||
| ba0b2c2709 | |||
|
|
62272df783 | ||
| 51416cdf37 | |||
|
|
53d55555d8 | ||
| a8ff5b5120 | |||
|
|
8c0a404665 | ||
| 4ca965ccb1 | |||
|
|
def447e12b | ||
| 22cbb6c4d3 | |||
|
|
f0b80554d2 | ||
| 6db07e1825 | |||
|
|
469e0e1bbe | ||
| 1bc0a4b01d | |||
|
|
d03b803bae | ||
| dc77a51c3c | |||
|
|
5be689a9c1 | ||
| b07a9596e5 | |||
|
|
59b94b2b26 | ||
| b96a54aae5 | |||
|
|
09b756b35b | ||
| fe0e1e139e | |||
|
|
ed26b4c705 | ||
| a95766fd45 | |||
|
|
9789f2828f | ||
| d5d5a6d193 | |||
|
|
f27ba80475 | ||
| 25125cfead | |||
|
|
1f657a626a | ||
| d6c6cf0c69 | |||
|
|
ca9261d75a |
23
.github/workflows/gemini-pr-review.yaml
vendored
23
.github/workflows/gemini-pr-review.yaml
vendored
@@ -5,15 +5,20 @@ name: Gemini PR Review
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
review:
|
||||
gemini-pr-review:
|
||||
runs-on: ubuntu-latest
|
||||
name: Gemini PR Review
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0 # This fetches the full history
|
||||
|
||||
@@ -22,7 +27,6 @@ jobs:
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache-dir
|
||||
run: |
|
||||
@@ -36,8 +40,14 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-global-
|
||||
|
||||
# - name: Install Gemini CLI globally
|
||||
# run: npm install -g --loglevel=http @google/gemini-cli
|
||||
- name: Install Gemini CLI globally (if not already installed)
|
||||
run: |
|
||||
if ! command -v gemini &> /dev/null; then
|
||||
echo "Gemini CLI not found, installing..."
|
||||
npm install -g --loglevel=http @google/gemini-cli
|
||||
else
|
||||
echo "Gemini CLI already installed."
|
||||
fi
|
||||
|
||||
- name: Generate git diff and review with Gemini
|
||||
id: review
|
||||
@@ -52,7 +62,6 @@ jobs:
|
||||
|
||||
cat /tmp/gemini-client-error*.json || true
|
||||
|
||||
|
||||
- name: Post output to PR comment
|
||||
id: post_comment
|
||||
run: |
|
||||
|
||||
@@ -220,7 +220,6 @@ class Scheduler extends Command
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to call Artisan commands with parameters.
|
||||
*/
|
||||
|
||||
@@ -67,13 +67,21 @@ class SendInvoiceTransitReport extends Command
|
||||
'im.id as invoice_master_id',
|
||||
'im.transport_name',
|
||||
DB::raw('CAST(im.transit_days AS INTEGER) as transit_days'),
|
||||
DB::raw('(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE)) as delayed_days')
|
||||
// DB::raw('(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE)) as delayed_days')
|
||||
DB::raw('
|
||||
GREATEST(
|
||||
0,
|
||||
(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE) - 1)
|
||||
- CAST(im.transit_days AS INTEGER)
|
||||
) AS delayed_days
|
||||
')
|
||||
)
|
||||
->when($plantId != 0, fn($q) => $q->where('it.plant_id', $plantId))
|
||||
->whereNotNull('it.lr_bl_aw_date')
|
||||
->whereRaw(
|
||||
'(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE)) >= CAST(im.transit_days AS INTEGER)'
|
||||
)
|
||||
->whereRaw('
|
||||
(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE))
|
||||
- CAST(im.transit_days AS INTEGER) > 0
|
||||
')
|
||||
->get();
|
||||
|
||||
|
||||
@@ -87,6 +95,13 @@ class SendInvoiceTransitReport extends Command
|
||||
foreach ($mailRules as $rule) {
|
||||
|
||||
$ruleInvoices = $results->where('invoice_master_id', $rule->invoice_master_id);
|
||||
//$ruleInvoices = $results->filter(fn($item) => $item->invoice_master_id == (int)$rule->invoice_master_id);
|
||||
|
||||
|
||||
if ($ruleInvoices->isEmpty()) {
|
||||
$this->info("Skipping rule {$rule->id} — no invoice transit data.");
|
||||
continue; // ❌ DO NOT SEND MAIL
|
||||
}
|
||||
|
||||
$invoiceMaster = InvoiceMaster::find($rule->invoice_master_id);
|
||||
|
||||
|
||||
73
app/Filament/Exports/AlertMailRuleExporter.php
Normal file
73
app/Filament/Exports/AlertMailRuleExporter.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\AlertMailRule;
|
||||
use App\Models\Plant;
|
||||
use Filament\Actions\Exports\ExportColumn;
|
||||
use Filament\Actions\Exports\Exporter;
|
||||
use Filament\Actions\Exports\Models\Export;
|
||||
|
||||
class AlertMailRuleExporter extends Exporter
|
||||
{
|
||||
protected static ?string $model = AlertMailRule::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('module')
|
||||
->label('MODULE'),
|
||||
ExportColumn::make('rule_name')
|
||||
->label('RULE NAME'),
|
||||
ExportColumn::make('email')
|
||||
->label('EMAIL'),
|
||||
ExportColumn::make('schedule_type')
|
||||
->label('SCHEDULE TYPE'),
|
||||
ExportColumn::make('plant')
|
||||
->label('PLANT CODE')
|
||||
->formatStateUsing(function ($state) {
|
||||
// $state is the plant ID from the database
|
||||
if ($state == 0) {
|
||||
return 'All Plants';
|
||||
}
|
||||
|
||||
$plant = Plant::find($state);
|
||||
return $plant ? $plant->code : 'Unknown';
|
||||
}),
|
||||
ExportColumn::make('cc_emails')
|
||||
->label('CC EMAILS'),
|
||||
ExportColumn::make('invoiceMaster.receiving_plant_name')
|
||||
->label('RECEIVING PLANT NAME'),
|
||||
ExportColumn::make('invoiceMaster.transport_name')
|
||||
->label('TRANSPORT NAME'),
|
||||
ExportColumn::make('created_at')
|
||||
->label('CREATED AT'),
|
||||
ExportColumn::make('created_by')
|
||||
->label('CREATED BY'),
|
||||
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 alert mail rule 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;
|
||||
}
|
||||
}
|
||||
141
app/Filament/Imports/AlertMailRuleImporter.php
Normal file
141
app/Filament/Imports/AlertMailRuleImporter.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Imports;
|
||||
|
||||
use App\Models\AlertMailRule;
|
||||
use App\Models\Plant;
|
||||
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 AlertMailRuleImporter extends Importer
|
||||
{
|
||||
protected static ?string $model = AlertMailRule::class;
|
||||
|
||||
public static function getColumns(): array
|
||||
{
|
||||
return [
|
||||
ImportColumn::make('module')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Module')
|
||||
->example('ProductionQuantities/InvoiceValidation/QualityValidation/InvoiceDataReport/InvoiceTransit')
|
||||
->label('Module')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('rule_name')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Rule Name')
|
||||
->example('ProductionMail/InvoiceMail/QualityMail/InvoiceDataMail/InvoiceTransitMail')
|
||||
->label('Rule Name')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('email')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Email')
|
||||
->example('admin@cripumps.com,ranjith.bala@cripumps.com')
|
||||
->label('Email')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('schedule_type')
|
||||
->exampleHeader('Schedule Type')
|
||||
->example('Daily/Live/Hourly')
|
||||
->label('Schedule Type'),
|
||||
ImportColumn::make('plant')
|
||||
->requiredMapping()
|
||||
->exampleHeader('Plant Code')
|
||||
->example('1000 or All Plants')
|
||||
->label('Plant Code')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('cc_emails')
|
||||
->exampleHeader('CC Email')
|
||||
->example('admin@cripumps.com,ranjith.bala@cripumps.com')
|
||||
->label('CC Email')
|
||||
->rules(['nullable', 'string']),
|
||||
//->rules(['cc_emails']),
|
||||
// ImportColumn::make('invoiceMaster')
|
||||
// ->relationship(),
|
||||
ImportColumn::make('receiving_plant_name')
|
||||
->exampleHeader('Receiving Plant Name')
|
||||
->example('BANGALORE')
|
||||
->label('Receiving Plant Name')
|
||||
->requiredMapping(),
|
||||
ImportColumn::make('transporter_name')
|
||||
->exampleHeader('Transporter Name')
|
||||
->example('SAFEXPRESS PRIVATE LIMITED')
|
||||
->label('Transporter Name')
|
||||
->requiredMapping(),
|
||||
];
|
||||
}
|
||||
|
||||
public function resolveRecord(): ?AlertMailRule
|
||||
{
|
||||
$warnMsg = [];
|
||||
|
||||
$user = Filament::auth()->user();
|
||||
|
||||
$operatorName = $user->name;
|
||||
|
||||
if (strtolower($this->data['plant']) == 'all plants') {
|
||||
$this->data['plant'] = 0;
|
||||
} else {
|
||||
$plant = Plant::where('code', $this->data['plant'])->first();
|
||||
if (!$plant) {
|
||||
$warnMsg[] = "Plant code '{$this->data['plant']}' not found.";
|
||||
$this->data['plant'] = null;
|
||||
} else {
|
||||
$this->data['plant'] = $plant->id;
|
||||
}
|
||||
}
|
||||
|
||||
$receivingPlantName = $this->data['receiving_plant_name'] ?? null;
|
||||
$transporterName = $this->data['transporter_name'] ?? null;
|
||||
|
||||
if (!$receivingPlantName || !$transporterName)
|
||||
{
|
||||
$warnMsg [] = 'Both Receiving Plant Name and Transporter Name are required.';
|
||||
}
|
||||
|
||||
$invoiceMaster = \App\Models\InvoiceMaster::where('receiving_plant_name', $receivingPlantName)
|
||||
->where('transport_name', $transporterName)
|
||||
->first();
|
||||
|
||||
if (!$invoiceMaster) {
|
||||
$warnMsg [] = "Invoice Master not found for Receiving Plant '{$receivingPlantName}' and Transporter '{$transporterName}'.";
|
||||
}
|
||||
|
||||
$this->data['invoice_master_id'] = $invoiceMaster->id;
|
||||
|
||||
unset($this->data['receiving_plant_name'], $this->data['transporter_name']);
|
||||
|
||||
if(! empty($warnMsg)){
|
||||
throw new RowImportFailedException(implode(', ', $warnMsg));
|
||||
}
|
||||
|
||||
return AlertMailRule::Create([
|
||||
'module' => $this->data['module'],
|
||||
'rule_name' => $this->data['rule_name'],
|
||||
'email' => $this->data['email'],
|
||||
'schedule_type' => $this->data['schedule_type'],
|
||||
'plant' => $this->data['plant'],
|
||||
'cc_emails' => $this->data['cc_emails'] ?? null,
|
||||
'invoice_master_id' => $invoiceMaster->id,
|
||||
'created_by' => $operatorName,
|
||||
'updated_by' => $operatorName,
|
||||
]);
|
||||
|
||||
//return new AlertMailRule();
|
||||
}
|
||||
|
||||
public static function getCompletedNotificationBody(Import $import): string
|
||||
{
|
||||
$body = 'Your alert mail rule 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;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use Filament\Actions\Imports\Exceptions\RowImportFailedException;
|
||||
use Filament\Actions\Imports\ImportColumn;
|
||||
use Filament\Actions\Imports\Importer;
|
||||
use Filament\Actions\Imports\Models\Import;
|
||||
use Filament\Facades\Filament;
|
||||
use Str;
|
||||
|
||||
class ProcessOrderImporter extends Importer
|
||||
@@ -38,41 +39,57 @@ class ProcessOrderImporter extends Importer
|
||||
->example('202500123456')
|
||||
->label('PROCESS ORDER')
|
||||
->rules(['required']),
|
||||
ImportColumn::make('created_by')
|
||||
->exampleHeader('CREATED BY')
|
||||
->example('RAW01234')
|
||||
->label('CREATED BY')
|
||||
ImportColumn::make('order_quantity')
|
||||
->exampleHeader('ORDER QUANTITY')
|
||||
->example('100')
|
||||
->label('ORDER QUANTITY')
|
||||
->rules(['required']),
|
||||
// ImportColumn::make('created_by')
|
||||
// ->exampleHeader('CREATED BY')
|
||||
// ->example('RAW01234')
|
||||
// ->label('CREATED BY')
|
||||
// ->rules(['required']),
|
||||
];
|
||||
}
|
||||
|
||||
public function resolveRecord(): ?ProcessOrder
|
||||
{
|
||||
$warnMsg = [];
|
||||
$plant = Plant::where('code', $this->data['plant'])->first();
|
||||
$itemCode = Item::where('code', $this->data['item'])->first();
|
||||
$plantCod = $this->data['plant'];
|
||||
$plant = null;
|
||||
$iCode = trim($this->data['item']);
|
||||
$processOrder = trim($this->data['process_order'] ?? '');
|
||||
$user = Filament::auth()->user();
|
||||
$operatorName = $user->name;
|
||||
|
||||
if (! $plant) {
|
||||
$warnMsg[] = 'Plant not found';
|
||||
} elseif (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
|
||||
$warnMsg[] = 'Invalid item code found';
|
||||
} elseif (! $itemCode) {
|
||||
$warnMsg[] = 'Item Code not found';
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
$processOrder = trim($this->data['process_order'] ?? '');
|
||||
if (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
|
||||
$warnMsg[] = 'Invalid item code found';
|
||||
} else {
|
||||
$itemCode = Item::where('code', $iCode)->first();
|
||||
if (! $itemCode) {
|
||||
$warnMsg[] = 'Item Code not found';
|
||||
}
|
||||
}
|
||||
|
||||
if ($processOrder == '') {
|
||||
$warnMsg[] = 'Process Order cannot be empty';
|
||||
}
|
||||
|
||||
$user = User::where('name', $this->data['created_by'])->first();
|
||||
if (! $user) {
|
||||
$warnMsg[] = 'User not found';
|
||||
}
|
||||
// $user = User::where('name', $this->data['created_by'])->first();
|
||||
// if (! $user) {
|
||||
// $warnMsg[] = 'User not found';
|
||||
// }
|
||||
|
||||
if ($plant && $processOrder != '') {
|
||||
if ($plant && $itemCode && $processOrder != '') {
|
||||
|
||||
$existingOrder = ProcessOrder::where('plant_id', $plant->id)
|
||||
->where('process_order', $processOrder)
|
||||
@@ -94,7 +111,7 @@ class ProcessOrderImporter extends Importer
|
||||
'coil_number' => '0',
|
||||
'order_quantity' => 0,
|
||||
'received_quantity' => 0,
|
||||
'created_by' => $user->name,
|
||||
'created_by' => $operatorName,
|
||||
]);
|
||||
|
||||
// return new ProcessOrder();
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Exports\AlertMailRuleExporter;
|
||||
use App\Filament\Imports\AlertMailRuleImporter;
|
||||
use App\Filament\Resources\AlertMailRuleResource\Pages;
|
||||
use App\Filament\Resources\AlertMailRuleResource\RelationManagers;
|
||||
use App\Models\AlertMailRule;
|
||||
@@ -23,6 +25,8 @@ use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\ValidationException as ValidationValidationException;
|
||||
use Filament\Tables\Actions\ImportAction;
|
||||
use Filament\Tables\Actions\ExportAction;
|
||||
|
||||
class AlertMailRuleResource extends Resource
|
||||
{
|
||||
@@ -250,6 +254,22 @@ class AlertMailRuleResource extends Resource
|
||||
Tables\Actions\ForceDeleteBulkAction::make(),
|
||||
Tables\Actions\RestoreBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->headerActions([
|
||||
ImportAction::make()
|
||||
->label('Import Alert Mail Rule')
|
||||
->color('warning')
|
||||
->importer(AlertMailRuleImporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view import alert mail rule');
|
||||
}),
|
||||
ExportAction::make()
|
||||
->label('Export Alert Mail Rule')
|
||||
->color('warning')
|
||||
->exporter(AlertMailRuleExporter::class)
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view export alert mail rule');
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ class InvoiceInTransitResource extends Resource
|
||||
->directory('uploads/temp'),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
InvoiceInTransit::truncate();
|
||||
$uploadedFile = $data['invoice_in_transit_file'];
|
||||
|
||||
$disk = Storage::disk('local');
|
||||
@@ -453,6 +454,22 @@ class InvoiceInTransitResource extends Resource
|
||||
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;
|
||||
}
|
||||
|
||||
foreach ($rows as $index => $row)
|
||||
{
|
||||
if ($index == 0) {
|
||||
|
||||
@@ -30,6 +30,8 @@ use Filament\Forms\Components\Select;
|
||||
use App\Models\Line;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use App\Models\Item;
|
||||
use App\Models\User;
|
||||
|
||||
// use App\Models\PalletValidation;
|
||||
// use Dom\Text;
|
||||
|
||||
@@ -286,10 +288,16 @@ class ProcessOrderResource extends Resource
|
||||
->disk('local')
|
||||
->directory('uploads/temp')
|
||||
->preserveFilenames()
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view process order packing slip');
|
||||
})
|
||||
->reactive(),
|
||||
Forms\Components\Actions::make([
|
||||
Action::make('uploadNow')
|
||||
->label('Upload PDF Now')
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view process order packing slip');
|
||||
})
|
||||
->action(function ($get, callable $set) {
|
||||
$uploadedFiles = $get('attachment');
|
||||
|
||||
@@ -377,6 +385,9 @@ class ProcessOrderResource extends Resource
|
||||
|
||||
Action::make('downloadAttachment')
|
||||
->label('Download PDF')
|
||||
->visible(function() {
|
||||
return Filament::auth()->user()->can('view process order packing slip');
|
||||
})
|
||||
->action(function ($get) {
|
||||
$equipmentNumber = $get('process_order');
|
||||
|
||||
|
||||
252
app/Filament/Resources/TestingTempResource.php
Normal file
252
app/Filament/Resources/TestingTempResource.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\TestingTempResource\Pages;
|
||||
use App\Filament\Resources\TestingTempResource\RelationManagers;
|
||||
use App\Models\TestingTemp;
|
||||
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\Actions\Action;
|
||||
use Filament\Notifications\Notification;
|
||||
use Storage;
|
||||
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
|
||||
|
||||
class TestingTempResource extends Resource
|
||||
{
|
||||
protected static ?string $model = TestingTemp::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')
|
||||
->label('File Name'),
|
||||
Forms\Components\Select::make('selected_file')
|
||||
->label('Select Uploaded File')
|
||||
->options(function () {
|
||||
return collect(Storage::disk('local')->files('uploads'))
|
||||
->mapWithKeys(function ($file) {
|
||||
return [
|
||||
$file => basename($file), // value => label
|
||||
];
|
||||
})
|
||||
->toArray();
|
||||
})
|
||||
->searchable()
|
||||
->reactive(),
|
||||
Forms\Components\FileUpload::make('attachment')
|
||||
->label('Upload')
|
||||
// ->acceptedFileTypes(['application/pdf'])
|
||||
->storeFiles(false)
|
||||
->disk('local')
|
||||
->directory('uploads/temp')
|
||||
->preserveFilenames()
|
||||
->reactive(),
|
||||
Forms\Components\Actions::make([
|
||||
Action::make('uploadNow')
|
||||
->label('File Upload')
|
||||
->color('success')
|
||||
->action(function ($get) {
|
||||
|
||||
$uploadedFiles = $get('attachment');
|
||||
|
||||
if (is_array($uploadedFiles) && count($uploadedFiles) > 0) {
|
||||
|
||||
$uploaded = reset($uploadedFiles);
|
||||
|
||||
if ($uploaded instanceof TemporaryUploadedFile) {
|
||||
|
||||
$baseName = $get('name');
|
||||
$extension = $uploaded->getClientOriginalExtension();
|
||||
|
||||
$finalFileName = $baseName . '.' . $extension;
|
||||
|
||||
$uploaded->storeAs(
|
||||
'uploads',
|
||||
$finalFileName,
|
||||
'local'
|
||||
);
|
||||
|
||||
Notification::make()
|
||||
->title("File uploaded successfully: {$finalFileName}")
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
|
||||
} else {
|
||||
Notification::make()
|
||||
->title('No file selected to upload')
|
||||
->warning()
|
||||
->send();
|
||||
}
|
||||
}),
|
||||
|
||||
// Action::make('downloadAttachment')
|
||||
// ->label('Download File')
|
||||
// ->action(function ($get) {
|
||||
|
||||
// $fileName = basename($get('selected_file'));
|
||||
|
||||
// //dd($fileName);
|
||||
|
||||
// // if (!$fileName) {
|
||||
// // Notification::make()
|
||||
// // ->title('Enter file name to download')
|
||||
// // ->danger()
|
||||
// // ->send();
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
// $files = Storage::disk('local')->files('uploads');
|
||||
|
||||
// foreach ($files as $file) {
|
||||
|
||||
// if (pathinfo($file, PATHINFO_FILENAME) === $fileName) {
|
||||
// dd($fileName);
|
||||
// Notification::make()
|
||||
// ->title("File downloaded successfully")
|
||||
// ->success()
|
||||
// ->send();
|
||||
|
||||
// return response()->download(
|
||||
// Storage::disk('local')->path($file)
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Notification::make()
|
||||
// // ->title('File not found')
|
||||
// // ->danger()
|
||||
// // ->send();
|
||||
// }),
|
||||
Action::make('downloadAttachment')
|
||||
->label('Download File')
|
||||
->action(function ($get) {
|
||||
|
||||
$filePath = $get('selected_file'); // uploads/filename.pdf
|
||||
|
||||
if (!$filePath || !Storage::disk('local')->exists($filePath)) {
|
||||
Notification::make()
|
||||
->title('File not found')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title('File downloaded successfully')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
return response()->download(
|
||||
Storage::disk('local')->path($filePath)
|
||||
);
|
||||
}),
|
||||
|
||||
Action::make('deleteAttachment')
|
||||
->label('Delete File')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->action(function ($get) {
|
||||
|
||||
$filePath = $get('selected_file'); // uploads/filename.pdf
|
||||
|
||||
if (!$filePath || !Storage::disk('local')->exists($filePath)) {
|
||||
Notification::make()
|
||||
->title('File not found')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Storage::disk('local')->delete($filePath);
|
||||
|
||||
Notification::make()
|
||||
->title('File deleted successfully')
|
||||
->success()
|
||||
->send();
|
||||
}),
|
||||
|
||||
]),
|
||||
Forms\Components\Hidden::make('created_by')
|
||||
->label('Created By')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
Forms\Components\Hidden::make('updated_by')
|
||||
->label('Updated By')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('ID')
|
||||
->numeric()
|
||||
->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(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListTestingTemps::route('/'),
|
||||
'create' => Pages\CreateTestingTemp::route('/create'),
|
||||
'view' => Pages\ViewTestingTemp::route('/{record}'),
|
||||
'edit' => Pages\EditTestingTemp::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TestingTempResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TestingTempResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateTestingTemp extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TestingTempResource::class;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TestingTempResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TestingTempResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditTestingTemp extends EditRecord
|
||||
{
|
||||
protected static string $resource = TestingTempResource::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\TestingTempResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TestingTempResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListTestingTemps extends ListRecords
|
||||
{
|
||||
protected static string $resource = TestingTempResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TestingTempResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TestingTempResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
class ViewTestingTemp extends ViewRecord
|
||||
{
|
||||
protected static string $resource = TestingTempResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
20
app/Models/TestingTemp.php
Normal file
20
app/Models/TestingTemp.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class TestingTemp extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
}
|
||||
106
app/Policies/TestingTempPolicy.php
Normal file
106
app/Policies/TestingTempPolicy.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use App\Models\TestingTemp;
|
||||
use App\Models\User;
|
||||
|
||||
class TestingTempPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('view-any TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('view TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('create TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('update TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('delete TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete any models.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('delete-any TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('restore TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore any models.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('restore-any TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate the model.
|
||||
*/
|
||||
public function replicate(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('replicate TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder the models.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('reorder TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, TestingTemp $testingtemp): bool
|
||||
{
|
||||
return $user->checkPermissionTo('force-delete TestingTemp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete any models.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->checkPermissionTo('force-delete-any TestingTemp');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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 testing_temps (
|
||||
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
|
||||
name 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
|
||||
);
|
||||
SQL;
|
||||
DB::statement($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('testing_temps');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user