diff --git a/app/Filament/Resources/InvoiceDataValidationResource.php b/app/Filament/Resources/InvoiceDataValidationResource.php
index b4f76ac..8f0f71c 100644
--- a/app/Filament/Resources/InvoiceDataValidationResource.php
+++ b/app/Filament/Resources/InvoiceDataValidationResource.php
@@ -23,6 +23,7 @@ use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\StickerMaster;
use App\Models\User;
+use DB;
use Filament\Tables\Actions\ExportAction;
class InvoiceDataValidationResource extends Resource
@@ -213,16 +214,13 @@ class InvoiceDataValidationResource extends Resource
$invalidPlantType = [];
$seenPlantDoc = [];
- $duplicateEntries = [];
+ //$duplicateEntries = [];
$duplicateEntriesExcel = [];
- $duplicateGroupedByPlant = [];
- $duplicateGroupedByPlantExcel = [];
foreach ($rows as $index => $row)
{
if ($index == 0) continue; // Skip header
-
$DisChaDesc = trim($row[3]);
$plantCode = trim($row[4]);
$CustomerCode = trim($row[5]);
@@ -231,7 +229,7 @@ class InvoiceDataValidationResource extends Resource
$CusTradeName = trim($row[9]);
$CusLocation = trim($row[10]);
- // if (empty($plantCode)) $invalidPlantCode[] = "Row {$index}";
+ // if (empty($plantCode)) $invalidPlantCode[] = "Row {$index}";
if (empty($DisChaDesc)){
$invalidDisChaDesc[] = "Row {$index}";
}
@@ -250,7 +248,7 @@ class InvoiceDataValidationResource extends Resource
{
$invalidCusLocation[] = "Row {$index}";
}
- // if (empty($createdBy)) $invalidUser[] = "Row {$index}";
+ // if (empty($createdBy)) $invalidUser[] = "Row {$index}";
if (strlen($plantCode) < 4) {
$invalidPlantCode[] = $plantCode;
@@ -258,31 +256,30 @@ class InvoiceDataValidationResource extends Resource
if (!is_numeric($plantCode)) {
$invalidPlantType[] = $plantCode;
}
- else if(!Plant::where('code', $plantCode)->first())
+ else if (!Plant::where('code', $plantCode)->first())
{
$invalidPlaCoFound[] = $plantCode;
}
- // --- Find Plant by code ---
+ // --- Find Plant by code ---
$plant = Plant::where('code', $plantCode)->first();
- //Duplicate Check in DB ---
- $exists = InvoiceDataValidation::where('plant_id', $plant->id)
- ->where('document_number', $DocNo)
- ->first();
+ // //Duplicate Check in DB ---
+ // $exists = InvoiceDataValidation::where('plant_id', $plant->id)
+ // ->where('document_number', $DocNo)
+ // ->first();
- if ($exists)
- {
- $duplicateEntries[] = "Duplicate record: Document Number '{$DocNo}' already exists for Plant {$plant->name}";
- }
+ // if ($exists)
+ // {
+ // $duplicateEntries[] = "Duplicate record: Document Number '{$DocNo}' already exists for Plant '{$plant->name}'";
+ // }
//Also check duplicates within the same file ---
$uniqueKey = $plantCode . '_' . $DocNo;
if (in_array($uniqueKey, $seenPlantDoc)) {
- $duplicateEntriesExcel[] = "Duplicate in file at Row {$index}: Document Number '{$DocNo}' already exist for Plant {$plant->name}";
+ $duplicateEntriesExcel[] = "Duplicate in file at Row {$index}: Document Number '{$DocNo}' already exists for Plant '{$plant->name}'";
}
$seenPlantDoc[] = $uniqueKey;
-
}
if (!empty($invalidCustomerCode) || !empty($invalidDocNo) || !empty($invalidDocDate) || !empty($invalidCusTradeName) || !empty($invalidCusLocation))
@@ -307,96 +304,101 @@ class InvoiceDataValidationResource extends Resource
}
return;
}
-
-
- if (!empty($invalidPlantCode)) {
+ else if (!empty($invalidPlantCode))
+ {
$invalidPlantCode = array_unique($invalidPlantCode);
Notification::make()
- ->title('Invalid Plant Codes')
- ->body('The following plant codes should contain minimum 4 digits:
' . implode(', ', $invalidPlantCode))
- ->danger()
- ->send();
+ ->title('Invalid Plant Codes')
+ ->body('The following plant codes should contain minimum 4 digits:
' . implode(', ', $invalidPlantCode))
+ ->danger()
+ ->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
- else if(!empty($invalidPlantType))
+ else if (!empty($invalidPlantType))
{
$invalidPlantType = array_unique($invalidPlantType);
Notification::make()
- ->title('Invalid Plant Codes')
- ->body('The following plant codes should contain numeric values:
' . implode(', ', $invalidPlantType))
- ->danger()
- ->send();
- if ($disk->exists($path)) {
- $disk->delete($path);
- }
- return;
- }
- if (!empty($invalidPlaCoFound)) {
- $invalidPlaCoFound = array_unique($invalidPlaCoFound);
- Notification::make()
- ->title('Invalid Plant Codes')
- ->body('The following plant codes not found in plants:
' . implode(', ', $invalidPlaCoFound))
- ->danger()
- ->send();
- if ($disk->exists($path)) {
- $disk->delete($path);
- }
- return;
- }
-
- foreach ($duplicateEntries as $message)
- {
- if (preg_match("/Document Number '([^']+)' already exists for Plant (.+)/", $message, $matches)) {
- $docNo = $matches[1];
- $plantName = trim($matches[2]);
- $duplicateGroupedByPlant[$plantName][] = $docNo;
- }
- }
-
- foreach ($duplicateEntriesExcel as $message) {
- if (preg_match("/Document Number '([^']+)' already exist(?:s)?(?: for Plant (.+))?/", $message, $matches)) {
- $docNo = $matches[1];
- $plantName = $matches[2] ?? 'Unknown';
- $duplicateGroupedByPlantExcel[$plantName][] = $docNo;
- }
- }
-
- if (!empty($duplicateGroupedByPlant)) {
- $errorMsg = 'Duplicate Entries in Database:
';
-
- foreach ($duplicateGroupedByPlant as $plant => $docNumbers) {
- $count = count($docNumbers);
-
- if ($count > 10)
- {
- $errorMsg .= "Duplicate record(s) for Plant {$plant}: {$count} document numbers already exist in DB
";
- }
- else
- {
- $errorMsg .= "Duplicate record(s) for Plant {$plant}: "
- . implode(', ', $docNumbers)
- . " already exist
";
- }
- }
-
- Notification::make()
- //->title('Duplicate Entries in Database')
- ->body($errorMsg)
+ ->title('Invalid Plant Codes')
+ ->body('The following plant codes should contain numeric values:
' . implode(', ', $invalidPlantType))
->danger()
->send();
-
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
- if (!empty($duplicateGroupedByPlantExcel))
+ else if (!empty($invalidPlaCoFound))
{
+ $invalidPlaCoFound = array_unique($invalidPlaCoFound);
+ Notification::make()
+ ->title('Invalid Plant Codes')
+ ->body('The following plant codes not found in plants:
' . implode(', ', $invalidPlaCoFound))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ return;
+ }
- $errorMsg = 'Duplicate Entries found in Uploaded File:
';
+ // if (!empty($duplicateEntries))
+ // {
+ // $duplicateGroupedByPlant = [];
+
+ // foreach ($duplicateEntries as $message)
+ // {
+ // if (preg_match("/Document Number '([^']+)' already exists for Plant '([^']+)'/", $message, $matches)) {
+ // $docNo = $matches[1];
+ // $plantName = trim($matches[2]);
+ // $duplicateGroupedByPlant[$plantName][] = $docNo;
+ // }
+ // }
+
+ // $errorMsg = 'Duplicate Document Number found in Database :
';
+
+ // foreach ($duplicateGroupedByPlant as $plant => $docNumbers) {
+ // $count = count($docNumbers);
+
+ // if ($count > 10)
+ // {
+ // $errorMsg .= "Duplicate record(s) for Plant {$plant} : {$count} document numbers already exist in DB
";
+ // }
+ // else
+ // {
+ // $errorMsg .= "Duplicate record(s) for Plant {$plant} : "
+ // . implode(', ', $docNumbers)
+ // . " already exist
";
+ // }
+ // }
+
+ // Notification::make()
+ // //->title('Duplicate Entries in Database')
+ // ->body($errorMsg)
+ // ->danger()
+ // ->send();
+
+ // if ($disk->exists($path)) {
+ // $disk->delete($path);
+ // }
+ // return;
+ // }
+
+ if (!empty($duplicateEntriesExcel))
+ {
+ $duplicateGroupedByPlantExcel = [];
+
+ foreach ($duplicateEntriesExcel as $message) {//"/Document Number '([^']+)' already exist(?:s)?(?: for Plant (.+))?/"
+ if (preg_match("/Document Number '([^']+)' already exists for Plant '([^']+)'/", $message, $matches)) {
+ $docNo = $matches[1];
+ $plantName = $matches[2] ?? 'Unknown';
+ $duplicateGroupedByPlantExcel[$plantName][] = $docNo;
+ }
+ }
+
+ $errorMsg = 'Duplicate Document Number found in Uploaded File :
';
foreach ($duplicateGroupedByPlantExcel as $plant => $docNumbers)
{
@@ -405,16 +407,16 @@ class InvoiceDataValidationResource extends Resource
$count = count($uniqueDocNumbers);
if ($count > 10) {
- $errorMsg .= "Duplicate record(s) for Plant {$plant}: {$count} document numbers already exist in uploaded file
";
+ $errorMsg .= "Duplicate Document Numbers for Plant {$plant} : {$count} Document Numbers already exist in uploaded file
";
} else {
- $errorMsg .= "Duplicate record(s) for Plant {$plant}: "
+ $errorMsg .= "Duplicate Document Numbers for Plant {$plant} : '"
. implode(', ', $uniqueDocNumbers)
- . " already exist
";
+ . "' already exist in uploaded file
";
}
}
Notification::make()
- //->title('Duplicate Entries in Uploaded File')
+ //->title('Duplicate Document Number in Uploaded File')
->body($errorMsg)
->danger()
->send();
@@ -425,79 +427,138 @@ class InvoiceDataValidationResource extends Resource
return;
}
- // if(!empty($duplicateEntriesExcel))
+ // if (!empty($duplicateEntriesExcel))
// {
- // //$errorMsg = 'Duplicate Entries found in the uploaded file:
' . implode('
', $duplicateEntriesExcel);
- // $errorMsg = buildDuplicateMessage($duplicateEntriesExcel, 'Duplicate Entries found in Uploaded File');
+ // //$errorMsg = 'Duplicate Document Number found in the uploaded file:
' . implode('
', $duplicateEntriesExcel);
+ // $errorMsg = buildDuplicateMessage($duplicateEntriesExcel, 'Duplicate Document Number found in Uploaded File');
// Notification::make()
- // ->title('Duplicate Entries in Uploaded File')
+ // ->title('Duplicate Document Number in Uploaded File')
// ->body($errorMsg)
-
$successCount = 0;
- $failCount = 0;
+ $failedRecords = [];
- foreach ($rows as $index => $row) {
- if ($index == 0) continue;
+ DB::beginTransaction();
- $DisChaDesc = trim($row[3]);
- $plantCode = trim($row[4]);
- $CustomerCode = trim($row[5]);
- $DocNo = trim($row[6]);
- $DocDate = trim($row[7]);
- $CusTradeName = trim($row[9]);
- $CusLocation = trim($row[10]);
+ try
+ {
+ foreach ($rows as $index => $row) {
+ if ($index == 0) continue;
- try
- {
- $plant = Plant::where('code', $plantCode)->first();
+ $rowNumber = $index + 1;
- if (!empty($DocDate)) {
- if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $DocDate)) {
- [$day, $month, $year] = preg_split('/[-\/]/', $DocDate);
- $formattedDate = "{$year}-{$month}-{$day}";
- } elseif (is_numeric($DocDate)) {
- $formattedDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($DocDate)->format('Y-m-d');
- } else {
- $formattedDate = date('Y-m-d', strtotime($DocDate));
+ try {
+ $DisChaDesc = trim($row[3]);
+ $plantCode = trim($row[4]);
+ $CustomerCode = trim($row[5]);
+ $DocNo = trim($row[6]);
+ $DocDate = trim($row[7]);
+ $CusTradeName = trim($row[9]);
+ $CusLocation = trim($row[10]);
+
+ if (empty($DocNo)) {
+ throw new \Exception("Row '{$rowNumber}' Missing QR Code");
}
- } else {
- $formattedDate = null;
- }
- $inserted = InvoiceDataValidation::create([
- 'plant_id' => $plant->id,
- 'distribution_channel_desc' => $DisChaDesc,
- 'customer_code' => $CustomerCode,
- 'document_number' => $DocNo,
- 'document_date' => $formattedDate,
- 'customer_trade_name' => $CusTradeName,
- 'customer_location' => $CusLocation,
- 'created_by' => $operatorName,
- ]);
+ $plant = Plant::where('code', $plantCode)->first();
+ if (!$plant) {
+ throw new \Exception("Invalid plant code : '{$plantCode}'");
+ }
+
+ if (!empty($DocDate)) {
+ if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $DocDate)) {
+ [$day, $month, $year] = preg_split('/[-\/]/', $DocDate);
+ $formattedDate = "{$year}-{$month}-{$day}";
+ } elseif (is_numeric($DocDate)) {
+ $formattedDate = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($DocDate)->format('Y-m-d');
+ } else {
+ $formattedDate = date('Y-m-d', strtotime($DocDate));
+ }
+ } else {
+ $formattedDate = null;
+ }
+
+ $record = InvoiceDataValidation::where('plant_id', $plant->id)
+ ->where('document_number', $DocNo)
+ ->first();
+
+ $curStat = $record ? 'Updation' : 'Insertion';
+
+ if ($record) {
+ $record->update([
+ 'distribution_channel_desc' => $DisChaDesc,
+ 'customer_code' => $CustomerCode,
+ 'document_date' => $formattedDate,
+ 'customer_trade_name' => $CusTradeName,
+ 'customer_location' => $CusLocation,
+ 'updated_by' => $operatorName
+ ]);
+ $inserted = $record;
+ } else {
+ // Record does not exist, create with 'created_by'
+ $inserted = InvoiceDataValidation::create([
+ 'plant_id' => $plant->id,
+ 'document_number' => $DocNo,
+ 'distribution_channel_desc' => $DisChaDesc,
+ 'customer_code' => $CustomerCode,
+ 'document_date' => $formattedDate,
+ 'customer_trade_name' => $CusTradeName,
+ 'customer_location' => $CusLocation,
+ 'created_by' => $operatorName
+ ]);
+ }
+ // $inserted = InvoiceDataValidation::create([
+ // 'plant_id' => $plant->id,
+ // 'document_number' => $DocNo,
+ // 'distribution_channel_desc' => $DisChaDesc,
+ // 'customer_code' => $CustomerCode,
+ // 'document_date' => $formattedDate,
+ // 'customer_trade_name' => $CusTradeName,
+ // 'customer_location' => $CusLocation,
+ // 'created_by' => $operatorName
+ // ]);
+
+ if (!$inserted) {
+ throw new \Exception("{$curStat} failed for Document Number : {$DocNo}");
+ }
- if ($inserted) {
$successCount++;
- } else {
- $failCount++;
+ } catch (\Exception $e) {
+ $failedRecords[] = [
+ 'row' => $rowNumber,
+ 'document_number' => $DocNo ?? null,
+ 'error' => $e->getMessage()
+ ];
}
- } catch (\Exception $e) {
- $failCount++;
+ }
+
+ DB::commit();
+
+ if (count($failedRecords) > 0) {
+ $failedSummary = collect($failedRecords)
+ ->map(fn($f) => "Row {$f['row']} ({$f['document_number']}) : {$f['error']}")
+ ->take(5) // limit preview to first 5 errors
+ ->implode("\n");
+
+ Notification::make()
+ ->title('Partial Import Warning')
+ ->body("'{$successCount}' records inserted. " . count($failedRecords) . " failed.\n\n{$failedSummary}")
+ ->warning()
+ ->send();
+ } else {
+ Notification::make()
+ ->title('Import Success')
+ ->body("Successfully imported '{$successCount}' records.")
+ ->success()
+ ->send();
}
}
- if($successCount > 0)
+ catch (\Exception $e)
{
+ DB::rollBack();
Notification::make()
- ->title('Import Summary')
- ->body("Successfully inserted: {$successCount} records")
- ->success()
- ->send();
- }
- else
- {
- Notification::make()
- ->title('Import Summary')
- ->body("Failed to insert any records.")
+ ->title('Import Failed')
+ ->body("No records were inserted. Error : {$e->getMessage()}")
->danger()
->send();
}
@@ -506,10 +567,10 @@ class InvoiceDataValidationResource extends Resource
->visible(function() {
return Filament::auth()->user()->can('view import invoice data validation');
}),
- ExportAction::make()
- ->exporter(InvoiceDataValidationExporter::class)
- ->visible(function() {
- return Filament::auth()->user()->can('view export invoice data validation');
+ ExportAction::make()
+ ->exporter(InvoiceDataValidationExporter::class)
+ ->visible(function() {
+ return Filament::auth()->user()->can('view export invoice data validation');
}),
]);
}