ria/app/Controllers/StockController.php
2025-05-07 10:14:28 +05:30

3395 lines
126 KiB
PHP

<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use App\Models\Supplier_model;
use App\Models\PowerConsumptionDetails;
use App\Models\CoatingMachineDetailsModel;
use App\Models\DrierMachineDetailsModel;
use App\Models\FactoryMachineModel;
use App\Models\FactoryVehicleDieselDetailsModel;
use App\Models\FactoryVehicleDieselStockSummaryModel;
use App\Models\IncomingSilicaSandDetailsModel;
use App\Models\Inwardgateregister_model;
use App\Models\Rawmaterialdetails_model;
use App\Models\BagStockDetailsModel;
use App\Models\DustAndRoughModel;
use App\Models\ResinStockModel;
use App\Models\GasStockModel;
use App\Models\TrpSandUseStockModel;
use App\Models\TrpProductionModel;
use App\Models\TrpProductionMaintenanceModel;
use App\Models\TrpProductionWasteModel;
use App\Models\Employeedetails_model;
use App\Models\PowerConsumptionSummaryModel;
use App\Models\MonthWiseMaterialInStockModel;
use App\Models\MonthWiseMachinesInStockModel;
use App\Models\TrpAbstractModel;
helper('stock');
use CodeIgniter\HTTP\ResponseInterface;
use DateTime;
use DatePeriod;
use DateInterval;
use Directory;
class StockController extends BaseController
{
protected $supplier_model;
protected $powerConsumptionDetails_model;
protected $powerConsumptionSummary_model;
protected $coatingMachineDetails_model;
protected $drierMachineDetails_model;
protected $factoryMachine_model;
protected $factoryVehicleDieselDetails_model;
protected $factoryVehicleDieselStockSummary_model;
protected $session;
protected $incomingSilicaSandDetails_model;
protected $inwardGateRegister_model;
protected $rawmaterialdetails_model;
protected $bagStockDetails_model;
protected $Rawmaterialdetails_model;
protected $dustAndRoughStockDetails_model;
protected $resinStockDetails_model;
protected $gasStockDetails_model;
protected $TrpSandUseStock_model;
protected $TrpProduction_model;
protected $TrpProductionMaintenance_model;
protected $TrpProductionWaste_model;
protected $db;
protected $employeedetails_model;
protected $monthWiseMaterialInStockModel ;
protected $monthWiseMachineInStockModel ;
protected $trpAbstract_model ;
/**
* This is default constructor of the class
*/
public function __construct()
{
$this->db = \Config\Database::connect();
parent::__construct();
$this->supplier_model = new Supplier_model();
$this->powerConsumptionDetails_model = new PowerConsumptionDetails();
$this->coatingMachineDetails_model = new CoatingMachineDetailsModel();
$this->drierMachineDetails_model = new DrierMachineDetailsModel();
$this->factoryMachine_model = new FactoryMachineModel();
$this->factoryVehicleDieselDetails_model = new FactoryVehicleDieselDetailsModel();
$this->factoryVehicleDieselStockSummary_model = new FactoryVehicleDieselStockSummaryModel();
$this->rawmaterialdetails_model = new Rawmaterialdetails_model();
$this->incomingSilicaSandDetails_model = new IncomingSilicaSandDetailsModel();
$this->inwardGateRegister_model = new Inwardgateregister_model();
$this->bagStockDetails_model = new BagStockDetailsModel();
$this->dustAndRoughStockDetails_model = new DustAndRoughModel();
$this->resinStockDetails_model = new ResinStockModel();
$this->gasStockDetails_model = new GasStockModel();
$this->TrpSandUseStock_model = new TrpSandUseStockModel();
$this->TrpProduction_model = new TrpProductionModel();
$this->TrpProductionMaintenance_model = new TrpProductionMaintenanceModel();
$this->TrpProductionWaste_model = new TrpProductionWasteModel();
$this->employeedetails_model = new Employeedetails_model();
$this->powerConsumptionSummary_model = new PowerConsumptionSummaryModel();
$this->monthWiseMaterialInStockModel = new MonthWiseMaterialInStockModel();
$this->monthWiseMachineInStockModel = new MonthWiseMachinesInStockModel();
$this->trpAbstract_model = new TrpAbstractModel();
$this->session = session();
helper('form');
$this->isLoggedIn();
}
public function index()
{
//
}
//incoming Silica Sand Details starts
// refactored
public function loadView_incomingSilicaSandDetails()
{
//here - one remark is for comments and another remark here is alais status of the sand report , due to client request naming is given wrong ,
//hope you bear it..!!
//we did ..!!
//getting month in post
if ($this->request->getMethod() === 'POST') {
//getting remark value which is used to specify the issd entry is accepted/rejected/conditionally accepted..
$remark = $this->request->getPost('remark');
$month = $this->request->getPost('month');
//formatting the date format of Jan-2025 to 2025-01
$date = DateTime::createFromFormat('d-M-Y', '01-'.$month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
//setting session for any month change
$session = session();
$session->set('stock_month',$month);
} else {
//if request is in get method getting remark in query params in new_header.php file(navbar)
$remark = $this->request->getVar('remark');
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
//if no monthis set in session setting Default to the current month
$month = date('Y-m');
}
}
$data['month'] = $month;
//set page title
$this->global['pageTitle'] = 'Incoming Silica Sand Details';
$materialCodes = [];
//getting all silica sand raw materials material code
$silicaSandMaterialCodes = $this->rawmaterialdetails_model->getAllSilicaRawMaterialCode();
$materialCodes [] = $silicaSandMaterialCodes;
//getting all waste Core Sand Material Codes
$wasteCoreSandMaterialCodes = $this->rawmaterialdetails_model->getAllWasteCoreSandMaterialCode();
$materialCodes [] = $wasteCoreSandMaterialCodes;
$materialCodes = call_user_func_array('array_merge', $materialCodes);
if (!empty($materialCodes)) {
//remark filter may apply or not
$data['igrDetails'] = $this->inwardGateRegister_model->findIgrDetailsForIncomingSilicaSand($materialCodes, $month, $remark);
} else {
$data['igrDetails'] = [];
}
$data['testedBy'] = [];
//['lab assistant', 'factory manager', 'lab head']
$data['testedBy'] = $this->employeedetails_model->incomingSilicaSandTestedBy();
//['factory manager', 'lab head']
$data['approvedBy'] = $this->employeedetails_model->incomingSilicaSandApprovedBy();
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
$data['remark'] = $remark;
return $this->loadViews("stock/incomingSilicaSandDetails", $this->global, $data, NULL);
}
//insert or update incoming silica sand details
//refactored
public function updateIncomingSilicaSandDetails()
{
$postData = $this->request->getPost();
$incomingSilicaSandDetailsData = json_decode($postData['incomingSilicaSandDetailsData'], true);
if (empty($incomingSilicaSandDetailsData)) {
echo "No data provided";
return;
}
$existingRecords = $this->incomingSilicaSandDetails_model
->whereIn('id', array_column($incomingSilicaSandDetailsData, 'id'))
->findAll();
$existingIds = array_column($existingRecords, 'id');
$inserts = [];
$updates = [];
foreach ($incomingSilicaSandDetailsData as $data) {
//check for id and assign null if not present
$id = empty($data['id']) ? null : $data['id'] ;
$dbData = [
'igrNo_fk' => $data['igrNo'],
'gradeCondition' => $data['gradeCondition'],
'_10' => $data['_10'],
'_20' => $data['_20'],
'_30' => $data['_30'],
'_40' => $data['_40'],
'_50' => $data['_50'],
'_70' => $data['_70'],
'_100' => $data['_100'],
'_140' => $data['_140'],
'_200' => $data['_200'],
'_300' => $data['_300'],
'pan' => $data['pan'],
'total' => $data['total'],
'afsSpec' => $data['afsSpec'],
'afsActual' => $data['afsActual'],
'plus20loss' => $data['plus20loss'],
'plus30Loss' => $data['plus30Loss'],
'moistureSpec' => $data['moistureSpec'],
'moistureActual' => $data['moistureActual'],
'moistureLoss' => $data['moistureLoss'],
'moistureLossQty' => $data['moistureLossQty'],
'sieveLossQty' => $data['sieveLossQty'],
'salableQty' => $data['salableQty'],
'remark' => $data['remark'],
'materialCode' => $data['materialCode'],
'clayOrLossOfIgnition' => $data['clayOrLossOfIgnition'],
'testedBy' => $data['testedBy'],
'approvedBy' => $data['approvedBy'],
'reportComments' => $data['reportComments'],
'gradeRange' => $data['gradeRange'],
'reportTime' => $data['reportTime'],
];
if ($id && in_array($id, $existingIds)) {
$dbData['id'] = $id;
$updates[] = $dbData;
} else {
$inserts[] = $dbData;
}
}
if (!empty($updates)) {
$this->incomingSilicaSandDetails_model->updateBatch($updates, 'id');
}
if (!empty($inserts)) {
$this->incomingSilicaSandDetails_model->insertBatch($inserts);
}
echo "Data Saved Successfully";
}
//This is particulary updated by the lab technichians
//refactored
public function updateLabReport()
{
$postData = $this->request->getPost();
$id = $postData['id'];
$dbData = [
'igrNo_fk' => $postData['igrNo'],
'materialCode' => $postData['materialCode'],
'_10' => $postData['_10Mm'],
'_20' => $postData['_20Mm'],
'_30' => $postData['_30Mm'],
'_40' => $postData['_40Mm'],
'_50' => $postData['_50Mm'],
'_70' => $postData['_70Mm'],
'_100' => $postData['_100Mm'],
'_140' => $postData['_140Mm'],
'_200' => $postData['_200Mm'],
'_300' => $postData['_300Mm'],
'pan' => $postData['pan'],
'total' => $postData['total'],
'plus20Loss' => $postData['plus20Loss'],
'plus30Loss' => $postData['plus30Loss'],
'moistureSpec' => $postData['moistureSpec'],
'moistureActual' => $postData['moistureActual'],
'moistureLoss' => $postData['moistureLoss'],
'moistureLossQty' => $postData['moistureLossQty'],
'sieveLossQty' => $postData['sieveLossQty'],
'salableQty' => $postData['salableQty'],
'testedBy' => $postData['testedBy'],
'approvedBy' => $postData['approvedBy'],
'clayOrLossOfIgnition' => $postData['clayOrLossOfIgnition'],
'reportComments' => $postData['reportComments'],
'gradeRange' => $postData['gradeRange'],
'reportTime' => $postData['reportTime'],
'remark' => $postData['remark']
];
$resultExists = $this->incomingSilicaSandDetails_model
->where('id', $id)
->first();
if ($resultExists) {
$updated = $this->incomingSilicaSandDetails_model
->update($id, $dbData);
} else {
$updated = $this->incomingSilicaSandDetails_model
->insert($dbData);
}
if ($updated) {
return $this->response->setJSON(['status' => 'success', 'message' => 'Data Updated Successfully']);
} else {
return $this->response->setJSON(['status' => 'error', 'message' => 'Failed to update data']);
}
}
//Drier machine details
//refactored
public function drierMachineDetails()
{
// Drier machine details follow a different method of processing stock month and date format than other stock records.
// The stock month and date format must be handled carefully while generating and updating data.
if ($this->request->getMethod() === 'POST') {
// Retrieve the month value from the POST request (expected in "M-Y" format, e.g., "Jan-2025")
$currentMonth = $this->request->getPost('month');
// Convert the month format from "M-Y" (Jan-2025) to "Y-m" (2025-01) for database processing
$date = DateTime::createFromFormat('M-Y', $currentMonth);
$formattedDate = $date->format('Y-m');
$session = session();
$session->set('stock_month', $formattedDate);
} else {
$session = session();
$currentMonth = $session->get('stock_month');
// If no month is set in the session, default to the current month in "M-Y" format
if (empty($currentMonth)) {
$currentMonth = date('M-Y');
} else {
// Convert the stored "Y-m" format (e.g., 2025-01) back to "M-Y" (e.g., Jan-2025) for display
$currentMonth = DateTime::createFromFormat('Y-m', $currentMonth);
$currentMonth = $currentMonth->format('M-Y');
}
}
// Retrieve the list of dates for the selected month in database-compatible format
$monthData = $this->getMonthDatesFromInput($currentMonth);
// Set the active filter for suppliers (1 means active suppliers will be fetched)
$isActiveFilter = 1;
$data['startDate'] = $monthData[0]['database']; // First day of the selected month
$data['endDate'] = $monthData[count($monthData) - 1]['database']; // Last day of the selected month
// Generate available time slots for drier machine processing
$data['timeDropdown'] = $this->generateTimeOptions();
$data['supplierData'] = $this->supplier_model->supplierlisting($isActiveFilter);
// Retrieve drier machine details for the selected date range
$data['drierDetails'] = $this->drierMachineDetails_model
->where('date >=', $data['startDate'])
->where('date <=', $data['endDate'])
->orderBy('date', 'asc')
->findAll();
$data['datefordropdown'] = $currentMonth;
// Set the page title for display
$this->global['pageTitle'] = 'Drier Details';
$this->loadViews("stock/drierMachineDetails", $this->global, $data, NULL);
}
//add or edit drier machine Details
//refactored
public function addOrEditdrierMachineDetails()
{
$data = $this->request->getPost();
$drierData[] = $this->mapDrierEntry($data);
// Begin a database transaction to ensure atomicity
$this->db->transBegin();
try {
// Arrays to store data for batch insert and batch update operations
$inserts = [];
$updates = [];
foreach ($drierData as $row) {
// Retrieve the ID of the existing entry (if present)
$existingRow = $row['id'];
$data = $row;
if ($existingRow) {
$existingRow = $this->drierMachineDetails_model->where('id', $row['id'] ?? '')->first();
// Handle gas stock updates for the existing record
$this->handleGasStockUpdate($existingRow, $row);
$updates[] = $data ;
} else {
// If it's a new record, update gas stock consumption before inserting
$this->updateGasStockConsumption($data['date'], $data['total_gas_consumption']);
$inserts[] = $data ;
}
}
if (!empty($inserts)) {
$this->drierMachineDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
$this->drierMachineDetails_model->updateBatch($updates, 'id');
}
// Check if the transaction encountered any database errors
if ($this->db->transStatus() === false) {
throw new \Exception('Transaction failed due to database error.');
}
$this->db->transCommit();
return redirect()->to("/drierMachineDetails")->with('success', "Data Saved Successfully");
} catch (\Exception $error) {
// Rollback the transaction in case of an error
$this->db->transRollback();
return redirect()->back()->with('error', ' ' . $error->getMessage());
}
}
/**
* Maps input row to expected format.
*/
// refactored
private function mapDrierEntry(array $data): array
{
return [
'id' => $data['id'] ?? null,
'date' => $this->convertToDateWithFlexibleFormats($data['date'], ["d-m-Y", "Y-m-d", "m/d/Y", "m-d-Y"], "Y-m-d"),
'drier_on_time' => $data['drier_on_time'],
'drier_off_time' => $data['drier_off_time'],
'drier_running_hours' => $data['drier_running_hours'],
'supplier_name' => $data['supplier_name'],
'input_sand_moisture' => $data['input_sand_moisture'],
'total_gas_consumption' => $data['total_gas_consumption'],
'gas_per_ton' => $data['gas_per_ton'],
'input_sand_qty' => $data['input_sand_qty'],
'moisture_loss_qty' => $data['moisture_loss_qty'],
'sand_dried_qty' => $data['sand_dried_qty'],
'qty_per_hours' => $data['qty_per_hours'],
'dust_qty' => $data['dust_qty'],
'customer_name' => $data['customer_name']
];
}
//Coating Machine Details starts
//refactored
public function loadView_coatingMachineDetails()
{
$month = getStockMonth($this->request);
$data['month'] = $month;
$this->global['pageTitle'] = 'Coating Machine Details';
// Define start and end date for the selected month
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
// Fetch coating machine details with batch card file details
$data['coatingMachineDetails'] = $this->coatingMachineDetails_model->coatingMachineDetails($startDate,$endDate);
// Convert month format from "Y-m" to "M-Y" for display
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
// Load the view with the required data
return $this->loadViews("stock/CoatingMachineDetail", $this->global, $data, NULL);
}
//add new coating machine details
// refactored
public function addNewCoatingMachineDetails()
{
$postData = $this->request->getPost();
$date = $postData['date'];
$shift = $postData['shift'];
$multipleShift = $this->coatingMachineDetails_model->isShiftExists($date, $shift);
if (!empty($multipleShift)) {
return redirect()->back()->with('error', 'Already same shift exists on the same date ..!!');
}
$this->db->transBegin();
try {
$insertedId = $this->coatingMachineDetails_model->insert($postData);
if (!$insertedId) {
throw new \Exception('Failed to insert Coating Machine Details.');
}
$this->updateGasConsumptionOrFail($postData['date'], $postData['totalGasConsumption']);
$this->handleBatchCardUploads($insertedId);
if ($this->db->transStatus() === false) {
throw new \Exception('Transaction failed due to database errors.');
}
$this->db->transCommit();
$successMessage = 'Coating Machine details updated successfully. ' . 'And updated gas stock consumption. '. 'Warning..!! Kindly Update the next subsequent month Gas Stock If older month Gas Stock Updated..!!';
return redirect()->to("/coatingMachineDetails")->with('success', $successMessage);
} catch (\Exception $error) {
$this->db->transRollback();
return redirect()->back()->with('error', $error->getMessage());
}
}
//update coating machine details
// refactored
public function updateCoatingMachineDetails()
{
$putData = $this->request->getPost();
$id = $putData['editCoatingMachineDetailId'];
$this->db->transBegin();
try {
$updated = $this->coatingMachineDetails_model->update($id, $putData);
if (!$updated) {
throw new \Exception('Failed to update Coating machine details.');
}
$this->handleBatchCardUploads($id);
$messages = ['successfully updated Coating machineDetail.'];
$this->handleGasConsumptionAdjustment($putData, $messages);
if ($this->db->transStatus() === false) {
throw new \Exception('Transaction failed due to database errors.');
}
$this->db->transCommit();
return redirect()->to("/coatingMachineDetails")
->with('success', implode(" ", $messages));
} catch (\Exception $error) {
$this->db->transRollback();
return redirect()->back()->with('error', $error->getMessage());
}
}
//deleteBatchCardFile
// refactored
public function deleteBatchCardFile()
{
$data = $this->request->getPost();
if (empty($data)) {
return $this->respondWithJson(400, "Invalid Request..!!");
}
$batchId = $data['id'];
$fileRecord = $this->getBatchCardFileRecord($batchId);
if (!$fileRecord) {
return $this->respondWithJson(404, "File Not Found..!!");
}
$fileDeleted = $this->deleteBatchCardFileFromStorage($fileRecord->filename);
$recordDeleted = $this->deleteBatchCardFileRecord($batchId);
if ($recordDeleted) {
return $this->respondWithJson(200, "Deleted Batch Card File Successfully..!!");
}
return $this->respondWithJson(400, "Failed to Delete..!! Try Again Later");
}
//downloadBatchCardZip
// refactored
public function downloadBatchcardZip()
{
$coatingId = $this->request->getGet('coating_id');
$date = $this->request->getGet('date');
$batchCardFiles = $this->getBatchCardFiles($coatingId); // Fetch files from DB
if (empty($batchCardFiles)) {
return redirect()->back()->with('error', 'No batchcard files found.');
}
$zipFileName = 'batchcard_files_' . $date . '.zip';
$zipPath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($zipPath))
{
mkdir($zipPath, 0777, true);
}
$zipFilePath = $zipPath . DIRECTORY_SEPARATOR . $zipFileName; // CI4 WRITEPATH safe directory
$zip = new \ZipArchive();
if ($zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) === true) {
foreach ($batchCardFiles as $file) {
$originalFilePath = $zipPath . DIRECTORY_SEPARATOR . $file['filename']; // Actual stored file
$clientFileName = $file['client_file_name'] ?? $file['filename']; // Use client name if available
if (file_exists($originalFilePath)) {
$zip->addFile($originalFilePath, $clientFileName); // Rename inside ZIP
}
}
$zip->close();
$response = $this->response->download($zipFilePath, null)->setFileName($zipFileName);
// Delete ZIP after response is sent
register_shutdown_function(function () use ($zipFilePath) {
if (file_exists($zipFilePath)) {
unlink($zipFilePath);
}
});
return $response;
}
return redirect()->back()->with('error', 'Failed to create ZIP file.');
}
//Gas Stock Details
// refactored
public function loadView_gasStockDetails()
{
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = "Gas Stock Details";
$previousMonthDates = $this->getPreviousMonthDateRange($month);
$data['previousMonthGasStockDetails'] = $this->gasStockDetails_model
->select('date, balanceStock')
->where('date', $previousMonthDates['end'])
->orderBy('date', 'desc')
->findAll();
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$data['gasStockDetails'] = $this->gasStockDetails_model->gasStockDetails($startDate, $endDate);
// Format month for view display (e.g., Apr-2025)
$formattedDate = DateTime::createFromFormat('Y-m-d', $startDate)->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/gasStockDetails", $this->global, $data, NULL);
}
// updateGasStockDetails
// refactored
public function updateGasStockDetails()
{
$postData = $this->request->getPost();
$updateGasStockDetailsData = json_decode($postData['updateGasStockDetails'], true);
$updates = [];
$inserts = [];
foreach ($updateGasStockDetailsData as $data) {
$date = $data['date'];
$dbData = [
'date' => $data['date'] ,
'opening' => $data['opening'] ,
'purchaseBharath' => $data['purchaseBharath'] ,
'purchaseIndian' => $data['purchaseIndian'] ,
'total' => $data['total'] ,
'consumption' => $data['consumption'] ,
'balanceStock' => $data['balanceStock'] ,
'trp_panel_gas_consumption' => $data['trpPanelGasConsumption'] ,
'trp_physical_gas_consumption' => $data['trpPhysicalGasConsumption'] ,
'trp_sand_production' => $data['trpSandProduction'] ,
'rotary_drier_consumption' => $data['rotaryDrierConsumption']
];
$resultExists = $this->gasStockDetails_model
->where('date', $date)
->first();
if (empty($resultExists)) {
$inserts[] = $dbData;
} else {
$dbData['id'] = $resultExists['id'];
$updates[] = $dbData;
}
}
if (!empty($inserts)) {
$this->gasStockDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
$updateResult = $this->gasStockDetails_model->updateBatch($updates, 'id');
if ($updateResult === FALSE) {
echo "Error during update";
} else {
echo "Data Updated Successfully";
return;
}
}
echo "Data Saved Successfully Warning..!! Kindly Update the next subsequent month Gas Stock If older month Gas Stock Updated..!!";
}
//updateGasStockConsumption
// refactored
private function updateGasStockConsumption($date, $consumption)
{
$date = $this->convertToDateWithFlexibleFormats($date,["d-m-Y", "Y-m-d", "m/d/Y", "m-d-Y"],"Y-m-d");
$resultExists = $this->gasStockDetails_model->where('date', $date)->first();
if ($resultExists) {
$endDate = date('Y-m-t', strtotime($date));
$records = $this->gasStockDetails_model->where('date >=', $date)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
$updatedOpeningStock = 0;
foreach ($records as $i => &$r) {
if ($i == 0) {
$r['consumption'] += (float)$consumption;
$r['total'] = (float)$r['opening'] + (float)$r['purchaseBharath'] + (float)$r['purchaseIndian'];
$r['balanceStock'] = $r['total'] - $r['consumption'];
$updatedOpeningStock = (int)$r['balanceStock'];
} else {
$r['opening'] = (float)$updatedOpeningStock;
$r['total'] = (float)$r['opening'] + (float)$r['purchaseBharath'] + (float)$r['purchaseIndian'];
$r['balanceStock'] = $r['total'] - $r['consumption'];
$updatedOpeningStock = (int)$r['balanceStock'];
}
}
//elvis operator
return $this->gasStockDetails_model->updateBatch($records, 'id') ?: 0;
}
$prevDate = (new DateTime($date))->modify('first day of this month')->modify('-1 day')->format('Y-m-d');
$prev = $this->gasStockDetails_model->where('date', $prevDate)->first();
$opening = (!empty($prev) && isset($prev['balanceStock'])) ? $prev['balanceStock'] : 0;
$start = (new DateTime($date))->modify('first day of this month');
$end = (new DateTime($date))->modify('last day of this month');
$period = new DatePeriod($start, new DateInterval('P1D'), $end->modify('+1 day'));
$inserts = [];
foreach ($period as $d) {
$dStr = $d->format('Y-m-d');
$cons = ($dStr == $date) ? $consumption : 0;
$balance = ($dStr == $date) ? $opening - $consumption : $opening;
$inserts[] = [
'date' => $dStr,
'opening' => $opening,
'purchaseBharath' => null,
'purchaseIndian' => null,
'total' => null,
'consumption' => $cons,
'balanceStock' => $balance
];
$opening = $balance;
}
//elvis operator
return $this->gasStockDetails_model->insertBatch($inserts) ?: 0;
}
//diesel stock details
//refactored
public function dieselMachineStockDetails()
{
$month = getStockMonth($this->request);
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$currentDate = new DateTime();
$data = [
'month' => $month,
'activeDieselMachines' => $this->factoryMachine_model->getAllActiveDieselMachines(),
];
$this->global['pageTitle'] = 'Diesel Machine Stock Details';
$customisedMachineCodes = $this->getOrUpdateCustomisedMachineCodes($month);
if ($this->isCurrentMonth($startDate, $endDate, $currentDate)) {
$this->ensureDieselDetailsForMonth($customisedMachineCodes, $startDate, $endDate);
}
$dieselMachines = $this->factoryMachine_model->getSelectedDieselMachines($customisedMachineCodes);
$dieselMachinesCount = count($dieselMachines);
[$prevDetails, $prevTotals] = $this->getPreviousMonthStockDetails($month);
$data['previousMonthDieselMachineStockDetails'] = $prevDetails;
$data['previousMonthTotalDieselMachineStockDetails'] = $prevTotals;
$data['dieselMachineStockDetails'] = $this->factoryVehicleDieselDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('machine_id', $customisedMachineCodes)
->groupBy(['machine_id', 'date'])
->orderBy('date', 'asc')
->orderBy('machine_id', 'asc')
->findAll();
$data['totalDiesel'] = $this->factoryVehicleDieselStockSummary_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
$data['groupedDieselMachineStockDetails'] = $this->groupAndSortStockDetails(
$data['dieselMachineStockDetails'],
$customisedMachineCodes
);
if (!empty($customisedMachineCodes)) {
$dieselMachines = $this->sortMachinesByCustomOrder($dieselMachines, $customisedMachineCodes);
}
$data['dieselMachinesCount'] = $dieselMachinesCount;
$data['dieselMachines'] = $dieselMachines;
$data['month'] = DateTime::createFromFormat('Y-m-d', "$month-01")->format('M-Y');
return $this->loadViews("stock/dieselStockDetails", $this->global, $data, NULL);
}
//updateDieselMachineDetails
public function updateDieselMachineDetails() {
$postData = $this->request->getPost();
$updateDmDetailsData = json_decode($postData['updateDieselMachineDetails'], true);
$updateTotalDmDetailsData = $updateDmDetailsData[0];
$updateDmDetailsData = $updateDmDetailsData[1];
$updatesDmR = [];
$insertsDmR = [];
$updatesTotalDmR = [];
$insertsTotalDmR = [];
// Fetch existing records in bulk for diesel machine details
$dates = array_column($updateDmDetailsData, 'date');
$machineIds = array_column($updateDmDetailsData, 'machine_id');
$existingDmRecords = $this->factoryVehicleDieselDetails_model
->whereIn('date', $dates)
->whereIn('machine_id', $machineIds)
->findAll();
$existingDmMap = [];
foreach ($existingDmRecords as $record) {
$existingDmMap [$record['date']] [$record['machine_id']] = $record;
}
foreach ($updateDmDetailsData as $data) {
$date = $data['date'];
$machineId = $data['machine_id'];
$dbData = [
'date' => $data['date'],
'machine_id' => $data['machine_id'],
'opening_reading' => $data['opening_reading'],
'closing_reading' => $data['closing_reading'],
'filling_diesel' => $data['filling_diesel'],
'consumption' => $data['consumption'],
'running_hours' => $data['running_hours'],
'mileage' => $data['mileage']
];
if (isset($existingDmMap[$date][$machineId])) {
$dbData['id'] = $existingDmMap[$date][$machineId]['id'];
$updatesDmR[] = $dbData;
} else {
$insertsDmR[] = $dbData;
}
}
// Fetch existing records in bulk for diesel stock summary
$dates = array_column($updateTotalDmDetailsData, 'date');
$existingTotalDmRecords = $this->factoryVehicleDieselStockSummary_model
->whereIn('date', $dates)
->findAll();
$existingTotalDmMap = [];
foreach ($existingTotalDmRecords as $record) {
$existingTotalDmMap[$record['date']] = $record;
}
foreach ($updateTotalDmDetailsData as $data) {
$date = $data['date'];
$dbData = [
'date' => $data['date'],
'opening_stock' => $data['opening_stock'],
'purchase_diesel' => $data['purchase_diesel'],
'total_filling_diesel' => $data['total_filling_diesel'],
'balance_stock' => $data['balance_stock']
];
if (isset($existingTotalDmMap[$date])) {
$dbData['id'] = $existingTotalDmMap[$date]['id'];
$updatesTotalDmR[] = $dbData;
} else {
$insertsTotalDmR[] = $dbData;
}
}
// Start the transaction
$this->db->transBegin();
try {
if (!empty($insertsDmR)) {
$this->factoryVehicleDieselDetails_model->insertBatch($insertsDmR);
}
if (!empty($updatesDmR)) {
$this->factoryVehicleDieselDetails_model->updateBatch($updatesDmR, 'id');
}
if (!empty($insertsTotalDmR)) {
$this->factoryVehicleDieselStockSummary_model->insertBatch($insertsTotalDmR);
}
if (!empty($updatesTotalDmR)) {
$this->factoryVehicleDieselStockSummary_model->updateBatch($updatesTotalDmR, 'id');
}
// Commit the transaction if all operations are successful
$this->db->transCommit();
echo "Data Saved Successfully";
} catch (\Exception $error) {
// Rollback the transaction in case of any errors
$this->db->transRollback();
echo "An error occurred: " . $error->getMessage();
}
}
//power stock details
public function powerConsumptionDetails(){
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Power Consumption Stock Details';
//filter part starts
//start date dynamic from front-end
$startDate = "$month-01";
//end date of given month
$endDate = date("Y-m-t", strtotime($startDate));
//filter applied currently
$customisedMachineCodes = $this->request->getPost('customisedMachineCodes') ?? [];
//already applied filter
$existingCustomMachineCodes = $this->monthWiseMachineInStockModel
->select('machine_id')
->where('date',"$month-01")
->where('machine_category','electric')
->findAll();
$filterUpdateNeeded = true ;
if( empty($customisedMachineCodes) && !empty($existingCustomMachineCodes)){
$customisedMachineCodes = array_column($existingCustomMachineCodes, 'machine_id') ;
$filterUpdateNeeded = false ;
}
//check user applies for filter currently
if(!empty($customisedMachineCodes) && $filterUpdateNeeded){
//user applied filter,
//check already filter existing , if exists remove that ,
if(!empty($existingCustomMachineCodes)){
//hard delete done..!!
$existingCustomMachineCodes = $this->monthWiseMachineInStockModel
->where('date',"$month-01")
->where('machine_category','electric')
->delete();
}
//if no filter already exists or removed current one , just add current filter for that month ....!!
$inserts = [];
foreach($customisedMachineCodes as $index => $customisedMachineCode){
$inserts [] = [
'date' => "$month-01",
'machine_category' => "electric",
'machine_id' => $customisedMachineCode
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMachineInStockModel->insertBatch($inserts);
//get the currently applied filter
$existingCustomMachineCodes = $this->monthWiseMachineInStockModel
->select('machine_id')
->where('date',"$month-01")
->where('machine_category','electric')
->get()
->getResultArray();
}
}
//possible if no filter applied at all...!!!
if(empty($existingCustomMachineCodes) ){
//no filter applied at all just present previous month material codes
$previousMonth = date('Y-m-01', strtotime('-1 month', strtotime("$month-01")));
$previousMonthCustomMachineCodes = $this->monthWiseMachineInStockModel
->select('machine_id')
->where('date',"$previousMonth")
->where('machine_category','electric')
->get()
->getResultArray();
if(!empty($previousMonthCustomMachineCodes)){
$existingCustomMachineCodes = $this->factoryMachine_model
->getSelectedElectricMachines(array_column($previousMonthCustomMachineCodes, 'machine_id'));
}else{
// inserting all active if no previous month present
$existingCustomMachineCodes = $this->factoryMachine_model
->getAllActiveElectricMachines();
//if no filter exists , just add current filter for that month ....!!
$inserts = [];
foreach($existingCustomMachineCodes as $index => $customisedMachineCode){
$inserts [] = [
'date' => "$month-01",
'machine_category' => "electric",
'machine_id' => $customisedMachineCode['id']
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMachineInStockModel->insertBatch($inserts);
}
}
}else{
//if filter present,get that material codes
$existingCustomMachineCodes = $this->factoryMachine_model
->getSelectedElectricMachines(array_column($existingCustomMachineCodes, 'machine_id'));
}
//this existingCustomMachineCodes gets its machine after visiting factory machine master table
$machineCodeList = array_column($existingCustomMachineCodes, 'id');
$currentDate = new DateTime();
if($startDate == $currentDate->format('Y-m-01') && $endDate == $currentDate->format('Y-m-t')){
foreach($machineCodeList as $index => $machineCode){
//checking filtered material code present in table , if not create dummy one for whole month
$findMachineCode = $this->powerConsumptionDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('machine_id',$machineCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMachineCode)){
//create dummy entry for this
$this->createDummyEntryForElectricMachine($machineCode,$startDate,$endDate);
}
}
}
$electricMachines = $existingCustomMachineCodes;
$data['activeElectricMachines'] = $this->factoryMachine_model->getAllActiveElectricMachines();
// Get the previous month's last date power consumption stock details for next month updation
$previousMonth = DateTime::createFromFormat('Y-m-d', $month.'-01')->modify('-1 month')->format('Y-m');
$previousMonthStartDate = "$previousMonth-01";
$previousMonthEndDate = date("Y-m-t", strtotime($previousMonthStartDate));
$data['previousMonthPowerConsumptionStockDetails'] = $this->powerConsumptionDetails_model
->select(['machine_id', 'date', 'closing_units'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['machine_id', 'date'])
->orderBy('date', 'desc')
->orderBy('machine_id', 'asc')
->findAll();
$data['previousMonthTotalPowerMachineStockDetails'] = $this->powerConsumptionSummary_model
->select(['id', 'date', 'final_reading'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['id', 'date'])
->orderBy('date', 'desc')
->findAll();
// checking in database if the data is available for the month
$data['powerConsumptionStockDetails'] = $this->powerConsumptionDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('machine_id',$machineCodeList)
->groupBy(['machine_id', 'date'])
->orderBy('date', 'asc')
->orderBy('machine_id', 'asc')
->findAll();
$data['totalPower'] = $this->powerConsumptionSummary_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
// Initialize an empty array to hold the grouped data
$data['groupedPowerConsumptionStockDetails'] = [];
// Temporary array to store grouped data by date
$groupedByDate = [];
// Group by 'date'
foreach ($data['powerConsumptionStockDetails'] as $detail) {
$date = $detail['date'];
// Initialize the outer array for this date if it doesn't exist
if (!isset($groupedByDate[$date])) {
$groupedByDate[$date] = [];
}
/*******************************************************************************************************************
creating an sub array (inner array) for date wise and append the detail into an array as sub-array
$groupedByDate[] outer array
$groupedByDate[$date]
will look like [[material1],[material2],[material3],[material4],[material5]] inner array
the above process is done for single row (date wise) and the same process is repeated for all the rows
*******************************************************************************************************************/
$groupedByDate[$date][] = $detail;
}
// Sort each date's machines based on the custom order to set table body td
if (!empty($customisedMachineCodes)) {
foreach ($groupedByDate as $date => &$machines) {
usort($machines, function ($a, $b) use ($customisedMachineCodes) {
$indexA = array_search($a['machine_id'], $customisedMachineCodes);
$indexB = array_search($b['machine_id'], $customisedMachineCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
unset($machines);
}
// Reset the structure to have indexed arrays without the date keys
$data['groupedPowerConsumptionStockDetails'] = array_values($groupedByDate);
// Sort each date's machines based on the custom order to set table header th
if (!empty($customisedMachineCodes)) {
usort($electricMachines, function ($a, $b) use ($customisedMachineCodes) {
$indexA = array_search($a['id'], $customisedMachineCodes);
$indexB = array_search($b['id'], $customisedMachineCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
$electricMachinesCount = count($electricMachines);
$data['electricMachinesCount'] = $electricMachinesCount;
$data['electricMachines'] = $electricMachines;
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
// return $this->response->setJSON(['status' =>'success' ,'message' => $data['electricMachines']]);
return $this->loadViews("stock/powerConsumptionDetails", $this->global, $data, NULL);
}
//updatePowerConsumptionDetails
public function updatePowerConsumptionDetails(){
//pm stands for power machine
$postData = $this->request->getPost();
$updatePowerConsumptionDetailsData = json_decode($postData['updatePowerConsumptionDetails'], true);
$updateTotalPmDetailsData = $updatePowerConsumptionDetailsData[0];
$updatePmDetailsData = $updatePowerConsumptionDetailsData[1];
//PmR stands for power machine readings
$updatesPmR = [];
$insertsPmR = [];
$updatesTotalPmR = [];
$insertsTotalPmR = [];
// Fetch existing records in bulk for power machine details
$dates = array_column($updatePmDetailsData, 'date');
$machineIds = array_column($updatePmDetailsData, 'machine_id');
$existingPmRecords = $this->powerConsumptionDetails_model
->whereIn('date', $dates)
->whereIn('machine_id', $machineIds)
->findAll();
$existingPmMap = [];
foreach ($existingPmRecords as $record) {
$existingPmMap[$record['date']][$record['machine_id']] = $record;
}
foreach ($updatePmDetailsData as $data) {
$date = $data['date'];
$machineId = $data['machine_id'];
$dbData = [
'date' => $data['date'],
'machine_id' => $data['machine_id'],
'opening_units' => $data['opening_units'],
'closing_units' => $data['closing_units'],
'total_units' => $data['total_units'],
];
if (isset($existingPmMap[$date][$machineId])) {
$dbData['id'] = $existingPmMap[$date][$machineId]['id'];
$updatesPmR[] = $dbData;
} else {
$insertsPmR[] = $dbData;
}
}
// Fetch existing records in bulk for power stock summary
$dates = array_column($updateTotalPmDetailsData, 'date');
$existingTotalPmRecords = $this->powerConsumptionSummary_model
->whereIn('date', $dates)
->findAll();
$existingTotalPmMap = [];
foreach ($existingTotalPmRecords as $record) {
$existingTotalPmMap[$record['date']] = $record;
}
foreach ($updateTotalPmDetailsData as $data) {
$date = $data['date'];
$dbData = [
'date' => $data['date'],
'opening_reading' => $data['opening_reading'],
'final_reading' => $data['final_reading'],
'total_reading' => $data['total_reading'],
'total_units' => $data['total_units'],
'average_pf' => $data['average_pf'],
'present_pf' => $data['present_pf'],
'md' => $data['md'],
'mf' => $data['mf']
];
if (isset($existingTotalPmMap[$date])) {
$dbData['id'] = $existingTotalPmMap[$date]['id'];
$updatesTotalPmR[] = $dbData;
} else {
$insertsTotalPmR[] = $dbData;
}
}
// Start the transaction
$this->db->transBegin();
try {
if (!empty($insertsPmR)) {
$this->powerConsumptionDetails_model->insertBatch($insertsPmR);
}
if (!empty($updatesPmR)) {
$this->powerConsumptionDetails_model->updateBatch($updatesPmR, 'id');
}
if (!empty($insertsTotalPmR)) {
$this->powerConsumptionSummary_model->insertBatch($insertsTotalPmR);
}
if (!empty($updatesTotalPmR)) {
$this->powerConsumptionSummary_model->updateBatch($updatesTotalPmR, 'id');
}
// Commit the transaction if all operations are successful
$this->db->transCommit();
echo "Data Saved Successfully";
} catch (\Exception $error) {
// Rollback the transaction in case of any errors
$this->db->transRollback();
echo "An error occurred: " . $error->getMessage();
}
}
//Dust And Rough Stock Details
public function loadView_dustAndRoughStockDetails()
{
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Dust And Rough Stock Details';
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$data['dustAndRoughStockDetails'] = $this->dustAndRoughStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/dustAndRoughStockDetails", $this->global, $data, NULL);
}
//updateDustAndRoughStockDetails
public function updateDustAndRoughStockDetails()
{
$postData = $this->request->getPost();
$updateDustAndRoughStockDetailsData = json_decode($postData['updateDustAndRoughStockDetails'], true);
$updates = [];
$inserts = [];
foreach ($updateDustAndRoughStockDetailsData as $data) {
$data['date'] = DateTime::createFromFormat('d-m-Y', $data['date'])->format('Y-m-d');
$date = $data['date'];
$dbData = [
'date' => $data['date'],
'finalRough' => $data['finalRough'],
'dust' => $data['dust'],
'total' => $data['total']
];
$resultExists = $this->dustAndRoughStockDetails_model
->where('date', $date)
->first();
if (empty($resultExists)) {
$inserts[] = $dbData;
} else {
$updates[] = $dbData;
}
}
if (!empty($inserts)) {
$this->dustAndRoughStockDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
$updateResult = $this->dustAndRoughStockDetails_model->updateBatch($updates, 'date');
if ($updateResult === FALSE) {
echo "Error during update";
} else {
echo "Data Updated Successfully";
return;
}
}
echo "Data Saved Successfully";
}
//Resin Stock Details
public function loadView_resinStockDetails()
{
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Resin Stock Details';
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$customisedMaterialCodes = $this->request->getPost('customisedMaterialCodes') ?? [];
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$month-01")
->where('stock_category','resin')
->findAll();
$filterUpdateNeeded = true ;
if( empty($customisedMaterialCodes) && !empty($existingCustomMaterialCodes)){
$customisedMaterialCodes = array_column($existingCustomMaterialCodes, 'materialCode') ;
$filterUpdateNeeded = false ;
}
//check user applies for filter currently
if(!empty($customisedMaterialCodes) && $filterUpdateNeeded){
//user applied new filter,
//check already filter existing , if exists remove that ,
if(!empty($existingCustomMaterialCodes)){
//hard delete done..!!
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->where('date',"$month-01")
->where('stock_category','resin')
->delete();
}
//if no filter already exists or removed current one , just add current filter for that month ....!!
$inserts = [];
foreach($customisedMaterialCodes as $index => $customisedMaterialCode){
$inserts [] = [
'date' => "$month-01",
'stock_category' => "resin",
'materialCode' => $customisedMaterialCode
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMaterialInStockModel->insertBatch($inserts);
//get the currently applied filter
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$month-01")
->where('stock_category','resin')
->get()->getResultArray();
}
}
//possible if no filter applied at all...!!!
if(empty($existingCustomMaterialCodes)){
//no filter applied at all just present previous month material codes
$previousMonth = date('Y-m-01', strtotime('-1 month', strtotime("$month-01")));
$previousMonthCustomMachineCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$previousMonth")
->where('stock_category','resin')
->get()
->getResultArray();
if(!empty($previousMonthCustomMachineCodes)){
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getSelectedResinMaterialCode(array_column($previousMonthCustomMachineCodes, 'materialCode'));
}else{
// inserting all active if no previous month present
$existingCustomMaterialCodes = $this->rawmaterialdetails_model->getAllResinMaterialCode();
$inserts = [];
foreach($existingCustomMaterialCodes as $index => $customisedMaterialCode){
$inserts [] = [
'date' => "$month-01",
'stock_category' => "resin",
'materialCode' => $customisedMaterialCode['MaterialCode']
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMaterialInStockModel->insertBatch($inserts) ;
}
}
}else{
//if filter present , Reuse the filter and get that material codes
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getSelectedResinMaterialCode(array_column($existingCustomMaterialCodes, 'materialCode'));
}
$materialCodeList = array_column($existingCustomMaterialCodes, 'MaterialCode');
$currentDate = new DateTime();
if($startDate == $currentDate->format('Y-m-01') && $endDate == $currentDate->format('Y-m-t')){
foreach($materialCodeList as $index => $materialCode){
//checking filtered material code present in table , if not create dummy one for whole month if it is current month
$findMachineCode = $this->resinStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('materialCode',$materialCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMachineCode)){
//create dummy entry for this
$this->createDummyEntryForResin($materialCode,$startDate,$endDate);
}
}
}
$resinMaterials = $existingCustomMaterialCodes ;
$data['activeResinMaterials'] = $this->rawmaterialdetails_model->getAllResinMaterialCode();
// Get the previous month's last date resin stock details for next month updation
$previousMonth = DateTime::createFromFormat('Y-m-d', $month.'-01')->modify('-1 month')->format('Y-m');
$previousMonthStartDate = "$previousMonth-01";
$previousMonthEndDate = date("Y-m-t", strtotime($previousMonthStartDate));
$data['previousMonthResinStockDetails'] = $this->resinStockDetails_model
->select(['materialCode', 'date', 'balanceStock'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['materialCode', 'date'])
->orderBy('date', 'desc')
->orderBy('materialCode', 'asc')
->findAll();
// checking in database if the data is available for the month
$data['resinStockDetails'] = $this->resinStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('materialCode',$materialCodeList)
->groupBy(['materialCode', 'date'])
->orderBy('date', 'asc')
->orderBy('materialCode', 'asc')
->findAll();
// Initialize an empty array to hold the grouped data
$data['groupedResinStockDetails'] = [];
// Temporary array to store grouped data by date
$groupedByDate = [];
// Group by 'date'
foreach ($data['resinStockDetails'] as $detail) {
$date = $detail['date'];
// Initialize the outer array for this date if it doesn't exist
if (!isset($groupedByDate[$date])) {
$groupedByDate[$date] = [];
}
/*******************************************************************************************************************
creating an sub array (inner array) for date wise and append the detail into an array as sub-array
$groupedByDate[] outer array
$groupedByDate[$date]
will look like [[material1],[material2],[material3],[material4],[material5]] inner array
the above process is done for single row (date wise) and the same process is repeated for all the rows
*******************************************************************************************************************/
$groupedByDate[$date][] = $detail;
}
// Sort each date's materials based on the custom order to set table body td
if (!empty($customisedMaterialCodes)) {
foreach ($groupedByDate as $date => &$materials) {
usort($materials, function ($a, $b) use ($customisedMaterialCodes) {
$indexA = array_search($a['materialCode'], $customisedMaterialCodes);
$indexB = array_search($b['materialCode'], $customisedMaterialCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
unset($materials);
}
// Reset the structure to have indexed arrays without the date keys
//this is for tbody table data td
$data['groupedResinStockDetails'] = array_values($groupedByDate);
// getting customer for creating table headers
// checking already existing stock if yes then get customer from the existing stock
// if not set customer in db , then set '' empty string
foreach ($resinMaterials as $key => $resinMaterial) {
$materialCode = $resinMaterial['MaterialCode'];
$resinMaterials[$key]['customers'] = $this->resinStockDetails_model
->select('customer')
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('materialCode', $materialCode)
->first()['customer'] ?? '';
}
// Sort each date's materials based on the custom order to set table header th
if (!empty($customisedMaterialCodes)) {
usort($resinMaterials, function ($a, $b) use ($customisedMaterialCodes) {
$indexA = array_search($a['MaterialCode'], $customisedMaterialCodes);
$indexB = array_search($b['MaterialCode'], $customisedMaterialCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
$resinMaterialCount = count($resinMaterials);
$data['resinMaterialCount'] = $resinMaterialCount;
$data['resinMaterials'] = $resinMaterials;
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/resinStockDetails", $this->global, $data, NULL);
}
// updateResinStockDetails
public function updateResinStockDetails()
{
$postData = $this->request->getPost('updateResinStockDetails');
$updateResinStockDetailsData = json_decode($postData, true);
if (empty($updateResinStockDetailsData)) {
echo "No data provided";
return;
}
$inserts = [];
$updates = [];
$dates = array_column($updateResinStockDetailsData, 'date');
$materialCodes = array_column($updateResinStockDetailsData, 'materialCode');
// Fetch existing records in bulk to reduce queries
$existingRecords = $this->resinStockDetails_model
->whereIn('date', $dates)
->whereIn('materialCode', $materialCodes)
->findAll();
$existingMap = [];
foreach ($existingRecords as $record) {
$existingMap[$record['date'] . '_' . $record['materialCode']] = $record['id'];
}
foreach ($updateResinStockDetailsData as $data) {
$key = $data['date'] . '_' . $data['materialCode'];
$dbData = [
'date' => $data['date'],
'materialCode' => $data['materialCode'],
'customer' => $data['customer'],
'opening' => $data['opening'],
'receipt' => $data['receipt'],
'used' => $data['used'],
'balanceStock' => $data['balanceStock'],
];
if (isset($existingMap[$key])) {
$dbData['id'] = $existingMap[$key];
$updates[] = $dbData;
} else {
$inserts[] = $dbData;
}
}
if (!empty($inserts)) {
$this->resinStockDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
if ($this->resinStockDetails_model->updateBatch($updates, 'id') === false) {
echo "Error during update";
return;
}
}
echo "Data Saved Successfully";
}
// Bag Stock details starts
public function loadView_bagStockDetails()
{
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Bag Stock Details';
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
///////////////////////////filter part starts//////////////////////////
$customisedMaterialCodes = $this->request->getPost('customisedMaterialCodes') ?? [];
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$month-01")
->where('stock_category','packing_material')
->findAll();
$filterUpdateNeeded = true ;
if( empty($customisedMaterialCodes) && !empty($existingCustomMaterialCodes)){
$customisedMaterialCodes = array_column($existingCustomMaterialCodes, 'materialCode') ;
$filterUpdateNeeded = false ;
}
//check user applies for filter currently
if(!empty($customisedMaterialCodes) && $filterUpdateNeeded){
//user applied filter,
//check already filter existing , if exists remove that ,
if(!empty($existingCustomMaterialCodes)){
//hard delete done..!!
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->where('date',"$month-01")
->where('stock_category','packing_material')
->delete();
}
//if no filter already exists or removed current one , just add current filter for that month ....!!
$inserts = [];
foreach($customisedMaterialCodes as $index => $customisedMaterialCode){
$inserts [] = [
'date' => "$month-01",
'stock_category' => "packing_material",
'materialCode' => $customisedMaterialCode
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMaterialInStockModel->insertBatch($inserts);
//get the currently applied filter
$existingCustomMaterialCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$month-01")
->where('stock_category','packing_material')
->get()->getResultArray();
}
}
//possible if no filter applied at all...!!!
if(empty($existingCustomMaterialCodes)){
//no filter applied at all just present previous month material codes
$previousMonth = date('Y-m-01', strtotime('-1 month', strtotime("$month-01")));
$previousMonthCustomMachineCodes = $this->monthWiseMaterialInStockModel
->select('materialCode')
->where('date',"$previousMonth")
->where('stock_category','packing_material')
->get()
->getResultArray();
if(!empty($previousMonthCustomMachineCodes)){
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getSelectedBagMaterialCode(array_column($previousMonthCustomMachineCodes, 'materialCode'));
}else{
// inserting all active if no previous month present
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getAllBagMaterialCode();
//if no filter already exists or removed current one , just add current filter for that month ....!!
$inserts = [];
foreach($existingCustomMaterialCodes as $index => $customisedMaterialCode){
$inserts [] = [
'date' => "$month-01",
'stock_category' => "packing_material",
'materialCode' => $customisedMaterialCode['MaterialCode']
];
}
if(!empty($inserts)){
//insert all the latest applied filter
$this->monthWiseMaterialInStockModel->insertBatch($inserts) ;
}
}
}else{
//if filter present,get that material codes
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getSelectedBagMaterialCode(array_column($existingCustomMaterialCodes, 'materialCode'));
}
$materialCodeList = array_column($existingCustomMaterialCodes, 'MaterialCode');
$currentDate = new DateTime();
if($startDate == $currentDate->format('Y-m-01') && $endDate == $currentDate->format('Y-m-t')){
foreach($materialCodeList as $index => $materialCode){
//checking filtered material code present in table , if not create dummy one for whole month for current month only
$findMachineCode = $this->bagStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('materialCode',$materialCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMachineCode)){
//create dummy entry for this
$this->createDummyEntryForBag($materialCode,$startDate,$endDate);
}
}
}
$bagMaterials = $existingCustomMaterialCodes ;
$data['activeBagMaterials'] = $this->rawmaterialdetails_model->getAllBagMaterialCode();
///////////////////////////filter part ends//////////////////////////
// Get the previous month's last date bag stock details for next month updation
$previousMonth = DateTime::createFromFormat('Y-m-d', $month.'-01')->modify('-1 month')->format('Y-m');
$previousMonthStartDate = "$previousMonth-01";
$previousMonthEndDate = date("Y-m-t", strtotime($previousMonthStartDate));
$data['previousMonthBagStockDetails'] = $this->bagStockDetails_model
->select(['materialCode', 'date', 'balanceStock'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['materialCode', 'date'])
->orderBy('date', 'desc')
->orderBy('materialCode', 'asc')
->findAll();
// checking in database if the data is available for the month
$data['bagStockDetails'] = $this->bagStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('materialCode',$materialCodeList)
->groupBy(['materialCode', 'date'])
->orderBy('date', 'asc')
->orderBy('materialCode', 'asc')
->findAll();
// Initialize an empty array to hold the grouped data
$data['groupedBagStockDetails'] = [];
// Temporary array to store grouped data by date
$groupedByDate = [];
// Group by 'date'
foreach ($data['bagStockDetails'] as $detail) {
$date = $detail['date'];
// Initialize the array for this date if it doesn't exist
if (!isset($groupedByDate[$date])) {
$groupedByDate[$date] = [];
}
/*******************************************************************************************************************
creating an sub array (inner array) for date wise and append the detail into an array as sub-array
$groupedByDate[] outer array
$groupedByDate[$date]
will look like [[bag1],[bag2],[bag3],[bag4],[bag5]] inner array
the above process is done for single row (date wise) and the same process is repeated for all the rows
*******************************************************************************************************************/
// Append the detail to the sub-array for this date
$groupedByDate[$date][] = $detail;
}
// Sort each date's materials based on the custom order to set table body td
if (!empty($customisedMaterialCodes)) {
foreach ($groupedByDate as $date => &$materials) {
usort($materials, function ($a, $b) use ($customisedMaterialCodes) {
$indexA = array_search($a['materialCode'], $customisedMaterialCodes);
$indexB = array_search($b['materialCode'], $customisedMaterialCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
unset($materials);
}
// Reset the structure to have indexed arrays without the date keys
$data['groupedBagStockDetails'] = array_values($groupedByDate);
// getting customer for creating table headers
// checking already existing stock if yes then get customer from the existing stock
// if not set customer as '' empty string
// Collect all material codes to query in one go
$materialCodes = array_column($bagMaterials, 'MaterialCode');
// Get current month customers in bulk
$currentCustomers = $this->bagStockDetails_model
->select('materialCode, customer')
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('materialCode', $materialCodes)
->findAll();
// Map them as materialCode => customer
$currentCustomerMap = [];
foreach ($currentCustomers as $row) {
$currentCustomerMap[$row['materialCode']] = $row['customer'];
}
// Get previous month customers in bulk
$previousStartDate = date('Y-m-01', strtotime('-1 month', strtotime($startDate)));
$previousEndDate = date('Y-m-t', strtotime('-1 month', strtotime($startDate)));
$previousCustomers = $this->bagStockDetails_model
->select('materialCode, customer')
->where('date >=', $previousStartDate)
->where('date <=', $previousEndDate)
->whereIn('materialCode', $materialCodes)
->findAll();
// Map them as materialCode => customer
$previousCustomerMap = [];
foreach ($previousCustomers as $row) {
$previousCustomerMap[$row['materialCode']] = $row['customer'];
}
// Now merge this data efficiently
foreach ($bagMaterials as $key => $bagMaterial) {
$materialCode = $bagMaterial['MaterialCode'];
// First, check in current month
$customer = $currentCustomerMap[$materialCode] ?? '';
// If not found or empty/blank, check in previous month
if (trim($customer) === '') {
$customer = $previousCustomerMap[$materialCode] ?? '';
}
// Set final customer value
$bagMaterials[$key]['customers'] = $customer;
}
// Sort each date's materials based on the custom order to set table header th
if (!empty($customisedMaterialCodes)) {
usort($bagMaterials, function ($a, $b) use ($customisedMaterialCodes) {
$indexA = array_search($a['MaterialCode'], $customisedMaterialCodes);
$indexB = array_search($b['MaterialCode'], $customisedMaterialCodes);
if ($indexA === false && $indexB === false) {
return 0;
}
if ($indexA === false) {
return 1;
}
if ($indexB === false) {
return -1;
}
return $indexA - $indexB;
});
}
// dd($bagMaterials);
$bagMaterialcount = count($bagMaterials);
$data['bagMaterialcount'] = $bagMaterialcount;
$data['bagMaterials'] = $bagMaterials;
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/bagStockDetails", $this->global, $data, NULL);
}
public function updateBagStockDetails()
{
$postData = $this->request->getPost();
$updateBagStockDetailsData = json_decode($postData['updateBagStockDetails'], true);
if (empty($updateBagStockDetailsData)) {
echo "No data provided";
return;
}
$inserts = [];
$updates = [];
$dates = array_column($updateBagStockDetailsData, 'date');
$materialCodes = array_column($updateBagStockDetailsData, 'materialCode');
// Fetch existing records in bulk to reduce queries
$existingRecords = $this->bagStockDetails_model
->whereIn('date', $dates)
->whereIn('materialCode', $materialCodes)
->findAll();
$existingMap = [];
foreach ($existingRecords as $record) {
$existingMap[$record['date'] . '_' . $record['materialCode']] = $record['id'];
}
foreach ($updateBagStockDetailsData as $data) {
$key = $data['date'] . '_' . $data['materialCode'];
$dbData = [
'date' => $data['date'],
'materialCode' => $data['materialCode'],
'customer' => $data['customer'],
'opening' => $data['opening'],
'receipt' => $data['receipt'],
'used' => $data['used'],
'balanceStock' => $data['balanceStock'],
];
if (isset($existingMap[$key])) {
$dbData['id'] = $existingMap[$key];
$updates[] = $dbData;
} else {
$inserts[] = $dbData;
}
}
if (!empty($inserts)) {
$inserted = $this->bagStockDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
$updateResult = $this->bagStockDetails_model->updateBatch($updates, 'id');
if ($updateResult === FALSE) {
echo "Error during update";
} else {
echo "Data Updated Successfully";
return;
}
}
echo "Data Saved Successfully";
}
public function trpSandUseStockDetails(){
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Trp Sand Use Stock Details';
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$data['trpSandUseStockDetails'] = $this->TrpSandUseStock_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/trpSandUseStockDetails", $this->global, $data, NULL);
}
public function updateTrpSandUseStockDetails(){
$postData = $this->request->getPost();
$updateTrpSandUseStockDetailsData = json_decode($postData['updateTrpSandUseStockDetails'], true);
$updates = [];
$inserts = [];
foreach ($updateTrpSandUseStockDetailsData as $data) {
$data['date'] = DateTime::createFromFormat('d-m-Y', $data['date'])->format('Y-m-d');
$date = $data['date'];
$dbData = [
'date' => $data['date'],
'rough_kgs' => $data['rough_kgs'],
'fine_kgs' => $data['fine_kgs'],
'total_kgs' => $data['total_kgs'],
'customer_name' => $data['customer_name']
];
$resultExists = $this->TrpSandUseStock_model
->where('date', $date)
->first();
if (empty($resultExists)) {
$inserts[] = $dbData;
} else {
$dbData['id'] = $resultExists['id'];
$updates[] = $dbData;
}
}
if (!empty($inserts)) {
$this->TrpSandUseStock_model->insertBatch($inserts);
}
if (!empty($updates)) {
$updateResult = $this->TrpSandUseStock_model->updateBatch($updates, 'id');
if ($updateResult === FALSE) {
echo "Error during update";
} else {
echo "Data Updated Successfully";
return;
}
}
echo "Data Saved Successfully";
}
public function trpProductionDetails(){
//filtering month in post request
$month = getStockMonth($this->request);
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Trp production Details';
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$trpProductionMaintenanceData = $this->TrpProductionMaintenance_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->find();
/*
no data found for given month , create dummy data for that month
because trp production involves join with other tables which are entried by other users so it is better to be empty
and create dummy data for that month .else join wont work
*/
if(empty($trpProductionMaintenanceData)){
$inserts = [];
$inserts = $this->createDummyDataForTrp($startDate, $endDate);
$freshEntry = true ;
$this->updateTrpProductionDetails($inserts ,$freshEntry);
}
$result = $this->TrpProduction_model->trpProductionDetails($startDate,$endDate);
$data['trpProductionDetails'] = $result[0] ;
$data['crsClientList'] = $result[1] ;
$data['wcsSupplierList'] = $result[2] ;
$trpAbstract = $this->trpAbstract_model->where('date', $startDate)->findAll();
$groupedTrpAbstract = [] ;
foreach($trpAbstract as $abs){
if(!isset($groupedTrpAbstract[$abs['particulars']])){
$groupedTrpAbstract[$abs['particulars']] = $abs ;
}
}
$trpAbstract = $groupedTrpAbstract ;
$data['trpAbstract'] = $trpAbstract ;
$date = DateTime::createFromFormat('Y-m-d', $month.'-01');
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/trpProductionStockDetails", $this->global, $data, NULL);
}
public function updateTrpProductionDetails($inserts = null, $freshEntry = false)
{
//getting values from post request
$postData['updateTrpProductionDetails'] = json_decode($this->request->getPost('updateTrpProductionDetails'),true);
//checking if post data is empty data ?
if (empty($postData['updateTrpProductionDetails'])) {
//if empty data , we still check for inserts data is available or not
if (empty($inserts)) {
//if both fails return "no data found"
return $this->response->setJSON(['error' => 'No data found to update']);
} else {
//if inserts data is available , then assign to post data
$postData['updateTrpProductionDetails'] = $inserts;
}
}
$updateTrpProductionDetails = $postData['updateTrpProductionDetails'];
// Extract all dates from post data
$dates = array_column($updateTrpProductionDetails, 'Date');
//format from "d-m-Y" to db "Y-m-d" format
$formattedDates = array_map(fn($date) => $this->convertToDateWithFlexibleFormats($date, ["d-m-Y", "Y-m-d", "m/d/Y", "m-d-Y"], "Y-m-d"), $dates);
// Fetch all existing maintenance , production and waste records for the given formatted dates
$existingMaintenance = $this->TrpProductionMaintenance_model->whereIn('date', $formattedDates)->findAll();
$existingProduction = $this->TrpProduction_model->whereIn('date', $formattedDates)->findAll();
$existingWaste = $this->TrpProductionWaste_model->whereIn('date', $formattedDates)->findAll();
//getting list of existing dates of maintenance , production and waste records
$existingMaintenanceDateList = array_column($existingMaintenance, null, 'date');
$existingProductionDateList = array_column($existingProduction, null, 'date');
$existingWasteDateList = array_column($existingWaste, null, 'date');
$updateMaintenance = [];
$updateProduction = [];
$updateWaste = [];
$insertMaintenance = [];
$insertProduction = [];
$insertWaste = [];
foreach ($updateTrpProductionDetails as $data) {
$date = $this->convertToDateWithFlexibleFormats($data['Date'], ["d-m-Y", "Y-m-d", "m/d/Y", "m-d-Y"], "Y-m-d");
// Data arrays
$dbDataTrpMaintenance = [
'date' => $date,
'openingTime' => $data['openingTime'],
'closingTime' => $data['closingTime'],
'totalHours' => $data['totalHours'],
'coldStart' => $data['coldStart'],
'breakdownHours' => $data['breakdownHours'],
'burnerFiringHours' => $data['burnerFiringHours'],
'sandFeedingHours' => $data['sandFeedingHours'],
'workingPersonEngineers' => $data['workingPersonEngineers'],
'workingPersonSupervisiors' => $data['workingPersonSupervisiors'],
'workingPersonOperators' => $data['workingPersonOperators'],
'rollerDrivers' => $data['rollerDrivers'],
'natureOfMaintenance' => $data['natureOfMaintenance'],
'location' => $data['location'],
'description' => $data['description']
];
$dbDataTrpProduction = [
'date' => $date,
'gasReceiptBg' => $data['gasReceiptBg'],
'gasReceiptPg' => $data['gasReceiptPg'],
'physicalGasConsumption' => $data['physicalGasConsumption'],
'drierGasConsumption' => $data['drierGasConsumption'],
'trpPlusDrierGasConsumption' => $data['trpPlusDrierGasConsumption'],
'trpPhysicalGasPerTon' => $data['trpPhysicalGasPerTon'],
'panelGasConsumption' => $data['panelGasConsumption'],
'panelGasPerTon' => $data['panelGasPerTon'],
'edRunningHours' => $data['edRunningHours'],
'edProduction' => $data['edProduction'],
'edUsage' => $data['edUsage'],
'trpProduction' => $data['trpProduction'],
'trpProductionPerHour' => $data['trpProductionPerHour'],
'waterReceipt' => $data['waterReceipt'],
'waterConsumption' => $data['waterConsumption'],
'ebReading' => $data['ebReading'],
'ebReadingPerUnitTon' => $data['ebReadingPerUnitTon'],
];
$dbDataTrpWaste = [
'date' => $date,
'msSeperation' => $data['msSeperation'],
'edWaste' => $data['edWaste'],
'coolerBags' => $data['coolerBags'],
'edPlus20Waste' => $data['edPlus20Waste'],
'cycloneWaste' => $data['cycloneWaste'],
];
// Check if data already exists
if (isset($existingMaintenanceDateList[$date])) {
$dbDataTrpMaintenance['id'] = (int) $existingMaintenanceDateList[$date]['id'];
$updateMaintenance[] = $dbDataTrpMaintenance;
} else {
$insertMaintenance[] = $dbDataTrpMaintenance;
}
if (isset($existingProductionDateList[$date])) {
$dbDataTrpProduction['id'] = (int) $existingProductionDateList[$date]['id'];
$updateProduction[] = $dbDataTrpProduction;
} else {
$insertProduction[] = $dbDataTrpProduction;
}
if (isset($existingWasteDateList[$date])) {
$dbDataTrpWaste['id'] = (int) $existingWasteDateList[$date]['id'];
$updateWaste[] = $dbDataTrpWaste;
} else {
$insertWaste[] = $dbDataTrpWaste;
}
}
// Start transaction
$this->db->transBegin();
try {
// Insert new records in batch
if (!empty($insertMaintenance)) {
$this->TrpProductionMaintenance_model->insertBatch($insertMaintenance);
}
if (!empty($insertProduction)) {
$this->TrpProduction_model->insertBatch($insertProduction);
}
if (!empty($insertWaste)) {
$this->TrpProductionWaste_model->insertBatch($insertWaste);
}
// Update existing records in batch
if (!empty($updateMaintenance)) {
$this->TrpProductionMaintenance_model->updateBatch($updateMaintenance, 'id');
}
if (!empty($updateProduction)) {
$this->TrpProduction_model->updateBatch($updateProduction, 'id');
}
if (!empty($updateWaste)) {
$this->TrpProductionWaste_model->updateBatch($updateWaste, 'id');
}
// Commit transaction if successful
$this->db->transCommit();
if (!$freshEntry) {
echo "Data Saved Successfully";
}
} catch (\Exception $error) {
// Rollback transaction on error
$this->db->transRollback();
echo "An error occurred: " . $error->getMessage();
}
}
public function updateAbstractDetails() {
$updateAbstractDetails = json_decode($this->request->getPost('updateAbstractDetails'), true);
if (empty($updateAbstractDetails)) {
echo "No data received";
return;
}
$date = trim($updateAbstractDetails[0]['date']);
$monthPresent = $this->trpAbstract_model->where('date', $date)->findAll();
if ( count($monthPresent) > 1 ) { // Update existing records
foreach ($updateAbstractDetails as $updateAbstractDetail) {
$this->trpAbstract_model
->where('date', trim($updateAbstractDetail['date']))
->where('particulars', trim($updateAbstractDetail['particulars']))
->set($updateAbstractDetail)
->update(); // Correct update usage
}
$result = true; // Indicate success
} else { // Insert new records
$result = $this->trpAbstract_model->insertBatch($updateAbstractDetails);
}
if ($result) {
echo "Data Saved Successfully";
} else {
echo "Error in Submitting the abstract";
}
}
// -------------------------------------------- in-house class helpers ----------------------------------------------
public function getMonthDatesFromInput($monthYear)
{
$date = DateTime::createFromFormat('M-Y', $monthYear);
if (!$date) {
return "Invalid date format. Use 'M-yyyy' format.";
}
$year = $date->format('Y');
$month = $date->format('m');
$totalDays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$dates = [];
for ($day = 1; $day <= $totalDays; $day++) {
$currentDate = DateTime::createFromFormat('Y-m-d', "$year-$month-$day");
$dates[] = [
'readable' => $currentDate->format('d-m-Y'),
'database' => $currentDate->format('Y-m-d')
];
}
return $dates;
}
public function generateTimeOptions()
{
$times = [];
$start = strtotime('00:00'); // Start at midnight (12:00 AM)
$end = strtotime('23:45'); // End at 11:45 PM
while ($start <= $end) {
$timeValue = date('H:i', $start); // 24-hour format for value
$timeLabel = date('h:i A', $start); // 12-hour format with AM/PM for display
$times[$timeValue] = $timeLabel; // Store time in associative array
$start = strtotime('+15 minutes', $start); // Increment by 15 minutes
}
return $times;
}
private function handleGasStockUpdate($existingRow, $newRow)
{
$existingConsumption = $existingRow['total_gas_consumption']; //eg:400
$updatedConsumption = $newRow['total_gas_consumption']; //eg:500
if ($existingConsumption != $updatedConsumption) {
$changeInConsumption = $updatedConsumption - $existingConsumption; // 500-400 = 100
$this->updateGasStockConsumption($existingRow['date'], $changeInConsumption); // +100 will be the change
}
}
function convertToDateWithFlexibleFormats($dateInput, array $inputFormats, string $outputFormat): ?string
{
// If it's already a DateTime object, just format it
if ($dateInput instanceof DateTime) {
return $dateInput->format($outputFormat);
}
// If it's a string, attempt to parse it
if (is_string($dateInput)) {
foreach ($inputFormats as $format) {
$date = DateTime::createFromFormat($format, $dateInput);
if ($date) {
return $date->format($outputFormat);
}
}
}
return $dateInput;
}
public function createDummyEntryForBag($customisedMaterialCode, $startDate, $endDate)
{
if (!empty($customisedMaterialCode)) {
$inserts = [];
// Convert start and end date to timestamps
$startTimestamp = strtotime($startDate);
$endTimestamp = strtotime($endDate);
while ($startTimestamp <= $endTimestamp) {
$inserts[] = [
'date' => date('Y-m-d', $startTimestamp), // Convert timestamp to date format
'materialCode' => $customisedMaterialCode,
'customer' => ' ',
'opening' => ' ',
'receipt' => ' ',
'used' => ' ',
'balanceStock' => ' ',
];
$startTimestamp = strtotime('+1 day', $startTimestamp); // Move to the next day
}
if (!empty($inserts)) {
$this->bagStockDetails_model->insertBatch($inserts);
}
}
}
public function createDummyEntryForResin($customisedMaterialCode, $startDate, $endDate)
{
if (!empty($customisedMaterialCode)) {
$inserts = [];
// Convert start and end date to timestamps
$startTimestamp = strtotime($startDate);
$endTimestamp = strtotime($endDate);
while ($startTimestamp <= $endTimestamp) {
$inserts[] = [
'date' => date('Y-m-d', $startTimestamp), // Convert timestamp to date format
'materialCode' => $customisedMaterialCode,
'customer' => ' ',
'opening' => ' ',
'receipt' => ' ',
'used' => ' ',
'balanceStock' => ' ',
];
$startTimestamp = strtotime('+1 day', $startTimestamp); // Move to the next day
}
if (!empty($inserts)) {
$this->resinStockDetails_model->insertBatch($inserts);
}
}
}
public function createDummyEntryForDieselMachine($customisedMachineCode, $startDate, $endDate)
{
if (!empty($customisedMachineCode)) {
$inserts = [];
// Convert start and end date to timestamps
$startTimestamp = strtotime($startDate);
$endTimestamp = strtotime($endDate);
while ($startTimestamp <= $endTimestamp) {
$inserts[] = [
'date' => date('Y-m-d', $startTimestamp), // Convert timestamp to date format
'machine_id' => $customisedMachineCode,
'opening_units' => ' ',
'closing_units' => ' ',
'total_units' => ' ',
];
$startTimestamp = strtotime('+1 day', $startTimestamp); // Move to the next day
}
if (!empty($inserts)) {
$this->factoryVehicleDieselDetails_model->insertBatch($inserts);
}
}
}
public function createDummyEntryForElectricMachine($customisedMachineCode, $startDate, $endDate)
{
if (!empty($customisedMachineCode)) {
$inserts = [];
// Convert start and end date to timestamps
$startTimestamp = strtotime($startDate);
$endTimestamp = strtotime($endDate);
while ($startTimestamp <= $endTimestamp) {
$inserts[] = [
'date' => date('Y-m-d', $startTimestamp), // Convert timestamp to date format
'machine_id' => $customisedMachineCode,
'opening_units' => ' ',
'closing_units' => ' ',
'total_units' => ' ',
];
$startTimestamp = strtotime('+1 day', $startTimestamp); // Move to the next day
}
if (!empty($inserts)) {
$this->powerConsumptionDetails_model->insertBatch($inserts);
}
}
}
public function createDummyDataForTrp($startDate, $endDate)
{
$datesInMonth = [];
$inserts = [];
$trpAbstract = [] ;
$period = new DatePeriod(
new DateTime($startDate),
new DateInterval('P1D'),
(new DateTime($endDate))->modify('+1 day')
);
foreach ($period as $day) {
$datesInMonth[] = $day->format('Y-m-d');
}
foreach ($datesInMonth as $datesInMonthIndex => $dateInMonth) {
$inserts[] = [
'Date' => $dateInMonth,
'openingTime' => " ",
'closingTime' => " ",
'totalHours' => " ",
'coldStart' => " ",
'breakdownHours' => " ",
'burnerFiringHours' => " ",
'sandFeedingHours' => " ",
'workingPersonEngineers' => " ",
'workingPersonSupervisiors' => " ",
'workingPersonOperators' => " ",
'rollerDrivers' => " ",
'natureOfMaintenance' => '',
'location' => '',
'description' => '',
'gasReceiptBg' => " ",
'gasReceiptPg' => " ",
'physicalGasConsumption' => " ",
'drierGasConsumption' => " ",
'trpPlusDrierGasConsumption' => " ",
'trpPhysicalGasPerTon' => " ",
'panelGasConsumption' => " ",
'panelGasPerTon' => " ",
'edRunningHours' => " ",
'edProduction' => " ",
'edUsage' => " ",
'trpProduction' => " ",
'trpProductionPerHour' => " ",
'waterReceipt' => " ",
'waterConsumption' => " ",
'ebReading' =>" ",
'ebReadingPerUnitTon' =>" ",
'msSeperation' => " ",
'edWaste' => " ",
'coolerBags' =>" ",
'edPlus20Waste' => " ",
'cycloneWaste' => " "
];
}
return $inserts;
}
private function updateGasConsumptionOrFail($date, $consumption)
{
$result = $this->updateGasStockConsumption($date, $consumption);
if (!$result) {
throw new \Exception('Failed to update gas stock consumption.');
}
}
private function handleGasConsumptionAdjustment($data, &$messages)
{
$existingConsumption = $data['existingTotalGasConsumption'];
$newConsumption = $data['totalGasConsumption'];
if ($existingConsumption == $newConsumption) {
return;
}
$change = $newConsumption - $existingConsumption;
$result = $this->updateGasStockConsumption($data['date'], $change);
if (!$result) {
throw new \Exception('Failed to update gas stock consumption.');
}
$messages[] = 'And updated gas stock consumption.';
$messages[] = 'Warning..!! Kindly Update the next subsequent month Gas Stock If older month Gas Stock Updated..!!';
}
private function handleBatchCardUploads($coatingId)
{
$files = $this->request->getFileMultiple('batchCard');
if (empty($files) || $files[0]->getError() === UPLOAD_ERR_NO_FILE) {
return;
}
$uploadPath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($uploadPath)) {
mkdir($uploadPath, 0777, true);
}
$db = \Config\Database::connect();
$builder = $db->table('t_batchcard_files');
$inserts = [];
foreach ($files as $file) {
if (!$file->isValid() || $file->hasMoved()) {
continue;
}
$clientName = $file->getClientName();
$newName = $file->getRandomName();
if ($file->move($uploadPath, $newName)) {
$inserts [] = [
'client_file_name' => $clientName,
'filename' => $newName,
'coating_id' => $coatingId
];
}
}
if(!empty($inserts)){
$builder->insertBatch($inserts);
}
}
private function getBatchCardFileRecord($id)
{
$db = \Config\Database::connect();
return $db->table('t_batchcard_files')
->select('filename')
->where('id', $id)
->get()
->getRow();
}
private function deleteBatchCardFileFromStorage($filename)
{
$path = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
$filePath = $path . DIRECTORY_SEPARATOR . $filename;
if (file_exists($filePath)) {
unlink($filePath);
}
return 1;
}
private function deleteBatchCardFileRecord($id)
{
$db = \Config\Database::connect();
return $db->query("DELETE FROM t_batchcard_files WHERE id = ?", [$id]);
}
private function respondWithJson($status, $message)
{
return $this->response->setJSON([
'status' => (string)$status,
'message' => $message
]);
}
private function getBatchCardFiles($coatingId)
{
$batchCardFiles = $this->db->table('t_batchcard_files')
->where('coating_id', $coatingId)
->get()
->getResultArray();
return $batchCardFiles;
}
private function getPreviousMonthDateRange(string $currentMonth): array
{
$previousMonth = DateTime::createFromFormat('Y-m-d', $currentMonth . '-01')
->modify('-1 month')
->format('Y-m');
$startDate = "$previousMonth-01";
$endDate = date("Y-m-t", strtotime($startDate));
return [
'start' => $startDate,
'end' => $endDate
];
}
private function getOrUpdateCustomisedMachineCodes($month)
{
$filterCodes = $this->request->getPost('customisedMachineCodes') ?? [];
$existingCodes = $this->monthWiseMachineInStockModel
->select('machine_id')
->where('date', "$month-01")
->where('machine_category', 'diesel')
->findAll();
$filterUpdateNeeded = true;
if (empty($filterCodes) && !empty($existingCodes)) {
return array_column($existingCodes, 'machine_id');
}
if (!empty($filterCodes) && $filterUpdateNeeded) {
$this->monthWiseMachineInStockModel
->where('date', "$month-01")
->where('machine_category', 'diesel')
->delete();
$inserts = array_map(fn($code) => [
'date' => "$month-01",
'machine_category' => "diesel",
'machine_id' => $code
], $filterCodes);
if (!empty($inserts)) {
$this->monthWiseMachineInStockModel->insertBatch($inserts);
}
return $filterCodes;
}
// If no filter applied at all — fallback to previous month or all active
if (empty($existingCodes)) {
$previousMonth = date('Y-m-01', strtotime('-1 month', strtotime("$month-01")));
$prevCodes = $this->monthWiseMachineInStockModel
->select('machine_id')
->where('date', "$previousMonth")
->where('machine_category', 'diesel')
->get()
->getResultArray();
if (!empty($prevCodes)) {
return array_column($prevCodes, 'machine_id');
} else {
$activeMachines = $this->factoryMachine_model->getAllActiveDieselMachines();
$inserts = array_map(fn($m) => [
'date' => "$month-01",
'machine_category' => "diesel",
'machine_id' => $m['id']
], $activeMachines);
$this->monthWiseMachineInStockModel->insertBatch($inserts);
return array_column($activeMachines, 'id');
}
}
return array_column($existingCodes, 'machine_id');
}
private function isCurrentMonth($startDate, $endDate, $currentDate)
{
return $startDate == $currentDate->format('Y-m-01') && $endDate == $currentDate->format('Y-m-t');
}
private function ensureDieselDetailsForMonth($machineCodes, $startDate, $endDate)
{
foreach ($machineCodes as $code) {
$exists = $this->factoryVehicleDieselDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('machine_id', $code)
->findAll();
if (empty($exists)) {
$this->createDummyEntryForDieselMachine($code, $startDate, $endDate);
}
}
}
private function getPreviousMonthStockDetails($month)
{
$previousMonth = DateTime::createFromFormat('Y-m-d', "$month-01")
->modify('-1 month')->format('Y-m');
$prevStart = "$previousMonth-01";
$prevEnd = date("Y-m-t", strtotime($prevStart));
$details = $this->factoryVehicleDieselDetails_model
->select(['machine_id', 'date', 'closing_reading'])
->distinct()
->where('date =', $prevEnd)
->groupBy(['machine_id', 'date'])
->orderBy('date', 'desc')
->orderBy('machine_id', 'asc')
->findAll();
$totals = $this->factoryVehicleDieselStockSummary_model
->select(['id', 'date', 'balance_stock'])
->distinct()
->where('date =', $prevEnd)
->groupBy(['id', 'date'])
->orderBy('date', 'desc')
->findAll();
return [$details, $totals];
}
private function groupAndSortStockDetails($details, $customisedOrder)
{
$grouped = [];
foreach ($details as $detail) {
$grouped[$detail['date']][] = $detail;
}
if (!empty($customisedOrder)) {
foreach ($grouped as &$machines) {
usort($machines, fn($a, $b) => $this->compareByCustomOrder($a, $b, $customisedOrder));
}
}
return array_values($grouped);
}
private function sortMachinesByCustomOrder($machines, $customOrder)
{
usort($machines, fn($a, $b) => $this->compareByCustomOrder($a, $b, $customOrder, 'id'));
return $machines;
}
private function compareByCustomOrder($a, $b, $order, $key = 'machine_id')
{
$indexA = array_search($a[$key], $order);
$indexB = array_search($b[$key], $order);
if ($indexA === false && $indexB === false) return 0;
if ($indexA === false) return 1;
if ($indexB === false) return -1;
return $indexA - $indexB;
}
}