Files
pds/app/Http/Controllers/InvoiceValidationController.php
2025-08-12 16:14:41 +05:30

825 lines
32 KiB
PHP

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