ria/app/Controllers/StockController.php
2025-03-18 12:18:22 +05:30

3633 lines
137 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;
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
public function loadView_incomingSilicaSandDetails()
{
//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('M-Y', $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', $month);
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
$data['remark'] = $remark;
return $this->loadViews("stock/incomingSilicaSandDetails", $this->global, $data, NULL);
}
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) {
$id = !empty($data['id']) ? $data['id'] : null;
$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
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
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);
}
public function addOrEditdrierMachineDetails()
{
// Retrieve form data from the POST request
$data = $this->request->getPost();
// Map the received data into a structured format using the helper function `mapDrierEntry`
$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.
*/
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
public function loadView_coatingMachineDetails()
{
if ($this->request->getMethod() === 'POST') {
// Get the month from the request
$month = $this->request->getPost('month');
// Convert month format from "M-Y" to "Y-m"
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
// Store selected month in session
$session = session();
$session->set('stock_month', $month);
} else {
$session = session();
$month = $session->get('stock_month');
// Default to the current month if no month is stored in session
if (empty($month)) {
$month = date('Y-m');
}
}
$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
->select('t_coatingmachinedetails.*,
JSON_ARRAYAGG(
JSON_OBJECT(
"client_given_name", t_batchcard_files.client_file_name,
"filename", t_batchcard_files.filename,
"batchCardId" , t_batchcard_files.id,
"coating_id", t_batchcard_files.coating_id
)
) as batchcard_files')
->join('t_batchcard_files', 't_batchcard_files.coating_id = t_coatingmachinedetails.id', 'left')
->where('t_coatingmachinedetails.date >=', $startDate)
->where('t_coatingmachinedetails.date <=', $endDate)
->groupBy('t_coatingmachinedetails.id')
->orderBy('t_coatingmachinedetails.date', 'asc')
->findAll();
// Convert month format from "Y-m" to "M-Y" for display
$date = DateTime::createFromFormat('Y-m', $month);
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
// Load the view with the required data
return $this->loadViews("stock/CoatingMachineDetail", $this->global, $data, NULL);
}
public function addNewCoatingMachineDetails()
{
$message1 = '';
$message2 = '';
$message3 = '';
$postData = $this->request->getPost();
$date = $postData['date'];
$shift = $postData['shift'];
// Check if the same shift already exists on the same date
$sameShiftOnDateExists = $this->coatingMachineDetails_model
->where('date', $date)
->where('shift', $shift)
->where('is_active', 1)
->first();
if (!empty($sameShiftOnDateExists)) {
return redirect()->back()->with('error', 'Already same shift exists on the same date ..!!');
}
// Start transaction
$this->db->transBegin();
try {
// Insert data into coating machine details table
$insertedId = $this->coatingMachineDetails_model->insert($postData);
if ($insertedId !== false && $insertedId > 0) {
$message1 = 'Coating Machine details updated successfully';
// Update gas stock consumption
$dateToBeInserted = $postData['date'];
$consumption = $postData['totalGasConsumption'];
$updatedResult = $this->updateGasStockConsumption($dateToBeInserted, $consumption);
if ($updatedResult === false || $updatedResult <= 0) {
throw new \Exception('Failed to update gas stock consumption.');
}
$message2 = 'And updated gas stock consumption.';
$message3 = " Warning..!! Kindly Update the next subsequent month Gas Stock If older month Gas Stock Updated..!!";
} else {
throw new \Exception('Failed to insert Coating machine details.');
}
// Handle batch card file uploads
if ($insertedId !== false && $insertedId > 0) {
$batchCardFiles = $this->request->getFileMultiple('batchCard');
if (!empty($batchCardFiles) && !($batchCardFiles[0]->getError() === UPLOAD_ERR_NO_FILE)) {
foreach ($batchCardFiles as $file) {
if ($file->isValid() && !$file->hasMoved()) {
$clientGivenName = $file->getClientName(); // Original filename
$newName = $file->getRandomName();
$path = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
if ($file->move($path, $newName)) {
// Insert file details into the database
$db = \Config\Database::connect();
$builder = $db->table('t_batchcard_files');
$data = [
'client_file_name' => $clientGivenName,
'filename' => $newName,
'coating_id' => $insertedId
];
$builder->insert($data);
}
}
}
}
}
if ($this->db->transStatus() === false) {
throw new \Exception('Transaction failed due to database errors.');
}
$this->db->transCommit();
// Redirect with success message
return redirect()->to("/coatingMachineDetails")
->with('success', $message1 . " " . $message2 . " " . $message3);
} catch (\Exception $error) {
$this->db->transRollback();
return redirect()->back()->with('error', ' ' . $error->getMessage());
}
}
public function updateCoatingMachineDetails()
{
$message1 = '';
$message2 = '';
$message3 = '';
$putData = $this->request->getPost();
$id = $putData['editCoatingMachineDetailId'];
// Start transaction
$this->db->transBegin();
try {
$updated = $this->coatingMachineDetails_model->update($id, $putData);
if ($updated !== false && $updated > 0) { // Assuming $id is the record ID being updated
$batchCardFiles = $this->request->getFileMultiple('batchCard');
if (is_array($batchCardFiles) && !empty($batchCardFiles)) {
// Step 4: Upload new files and insert into DB
foreach ($batchCardFiles as $index => $file) {
if ( !empty($batchCardFiles[$index]) && !($batchCardFiles[$index]->getError() === UPLOAD_ERR_NO_FILE)) {
$db = \Config\Database::connect();
$builder = $db->table('t_batchcard_files');
if ($file->isValid() && !$file->hasMoved()) {
$clientGivenName = $file->getClientName(); // User-given filename
$newName = $file->getRandomName(); // Randomized unique filename
$path = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
if ($file->move($path, $newName)) {
// Insert new file record into the database
$data = [
'client_file_name' => $clientGivenName,
'filename' => $newName,
'coating_id' => $id
];
$builder->insert($data);
}
}
}
}
}
}
if ($updated !== false && $updated > 0) {
$message1 = "successfully updated Coating machineDetail .";
//update Gas stock consumption if update is successfull..!!
$dateToBeUpdated = $putData['date'];
$existingCoatingGasConsumption = $putData['existingTotalGasConsumption'];
$updatedCoatingGasConsumption = $putData['totalGasConsumption'];
if ($existingCoatingGasConsumption != $updatedCoatingGasConsumption) {
$changeInConsumption = $updatedCoatingGasConsumption - $existingCoatingGasConsumption;
$updatedResult = $this->updateGasStockConsumption($dateToBeUpdated, $changeInConsumption);
if ($updatedResult === false || $updatedResult <= 0) {
// Explicit failure handling for gas stock update
throw new \Exception('Failed to update gas stock consumption.');
}
$message2 = 'And updated gas stock consumption.';
$message3 = "Warning..!! Kindly Update the next subsequent month Gas Stock If older month Gas Stock Updated..!!";
}
// Commit the transaction if all queries succeed
if ($this->db->transStatus() === false) {
throw new \Exception('Transaction failed due to database errors.');
}
$this->db->transCommit();
// Set flashdata for success message
return redirect()->to("/coatingMachineDetails")
->with('success', $message1 . " " . $message2 . " " . $message3);
} else {
throw new \Exception('Failed to update Coating machine details.');
}
} catch (\Exception $error) {
$this->db->transRollback();
return redirect()->back()->with('error', ' ' . $error->getMessage());
}
}
public function deleteBatchCardFile()
{
$data = $this->request->getPost();
if (!empty($data)) {
$batchId = $data['id'];
$db = \Config\Database::connect();
$builder = $db->table('t_batchcard_files');
// Step 1: Fetch the filename from DB before deleting
$fileRecord = $builder->select('filename')->where('id', $batchId)->get()->getRow();
if ($fileRecord) {
$path = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'batchcard';
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
$filePath = $path . DIRECTORY_SEPARATOR . $fileRecord->filename;
// Step 2: Delete the file from storage
if (file_exists($filePath)) {
unlink($filePath);
}
// Step 3: Delete the record from the database
$sql = "DELETE FROM t_batchcard_files WHERE id = ?";
$deleted = $db->query($sql, [$batchId]);
if ($deleted) {
return $this->response->setJSON([
'status' => '200',
'message' => "Deleted Batch Card File Successfully..!!"
]);
} else {
return $this->response->setJSON([
'status' => '400',
'message' => "Failed to Delete..!! Try Again Later"
]);
}
} else {
return $this->response->setJSON([
'status' => '404',
'message' => "File Not Found..!!"
]);
}
}
return $this->response->setJSON([
'status' => '400',
'message' => "Invalid Request..!!"
]);
}
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.');
}
// Example function to get batchcard files from DB
private function getBatchCardFiles($coatingId)
{
$batchCardFiles = $this->db->table('t_batchcard_files')
->where('coating_id', $coatingId)
->get()
->getResultArray();
return $batchCardFiles;
}
//Gas Stock Details
public function loadView_gasStockDetails()
{
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = "Gas Stock Details";
$previousMonth = DateTime::createFromFormat('Y-m', $month)->modify('-1 month')->format('Y-m');
$previousMonthStartDate = "$previousMonth-01";
$previousMonthEndDate = date("Y-m-t", strtotime($previousMonthStartDate));
$data['previousMonthGasStockDetails'] = $this->gasStockDetails_model
->select('date,balanceStock')
->where('date =', $previousMonthEndDate)
->orderBy('date', 'desc')
->findAll();
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$data['gasStockDetails'] = $this->gasStockDetails_model
->select(
't_gasstockdetails.*,
drier_summary.drierMachineGasconsumption AS drierMachineGasConsumption,
drier_summary.driedSand AS sandDried,
coating_summary.coatingMachineGasconsumption,
coating_summary.coatedSand'
)
// Subquery with early date filtering
->join(
'(SELECT date,
SUM(totalGasconsumption) AS coatingMachineGasconsumption,
SUM(totalCoatingSandInKg) / 1000 AS coatedSand
FROM t_coatingmachinedetails
WHERE is_active = 1
AND date >= ' . $this->db->escape($startDate) . '
AND date <= ' . $this->db->escape($endDate) . '
GROUP BY date
) AS coating_summary',
'coating_summary.date = t_gasstockdetails.date',
'left'
)
->join(
'(SELECT date,
SUM(total_gas_consumption) AS drierMachineGasconsumption,
SUM(sand_dried_qty) AS driedSand
FROM t_driermachinedetails
WHERE date >= ' . $this->db->escape($startDate) . '
AND date <= ' . $this->db->escape($endDate) . '
GROUP BY date
) AS drier_summary',
'drier_summary.date = t_gasstockdetails.date',
'left'
)
->where('t_gasstockdetails.date >=', $startDate)
->where('t_gasstockdetails.date <=', $endDate)
->groupBy('t_gasstockdetails.date')
->findAll();
$data['month'] = DateTime::createFromFormat('Y-m', $month)->format('M-Y');
return $this->loadViews("stock/gasStockDetails", $this->global, $data, NULL);
}
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..!!";
}
private function updateGasStockConsumption($date, $consumption)
{
// Check if an entry exists for the given date
$resultExists = $this->gasStockDetails_model
->where('date', $date)
->first();
if ($resultExists) {
// Ensure the date is in the correct format
if ($date instanceof DateTime) {
$date = $date->format('Y-m-d');
} elseif (!strtotime($date)) {
throw new \Exception("Invalid date format provided.");
} else {
$date = date('Y-m-d', strtotime($date));
}
// Get the last date of the month for the given date
$endDate = date('Y-m-t', strtotime($date));
// Fetch all stock entries from the given date till the end of the month
$resultExists = $this->gasStockDetails_model
->where('date >=', $date)
->where('date <=', $endDate)
->orderBy('date', 'asc')
->findAll();
$updatedOpeningStock = 0;
$updates = [];
// Update stock values for each day in the month
foreach ($resultExists as $index => $result) {
if ($index == 0) {
// Update the first entry with new consumption
$result['consumption'] = (float)($result['consumption']) + (float)($consumption);
$result['total'] = (float)$result['opening'] + (float)$result['purchaseBharath'] + (float)$result['purchaseIndian'];
$result['balanceStock'] = $result['total'] - $result['consumption'];
$updatedOpeningStock = (int)$result['balanceStock'];
} else {
// Update subsequent entries based on previous balance
$result['opening'] = (float)$updatedOpeningStock;
$result['total'] = (float)$result['opening'] + (float)$result['purchaseBharath'] + (float)$result['purchaseIndian'];
$result['balanceStock'] = (float)$result['total'] - (float)$result['consumption'];
$updatedOpeningStock = (int)$result['balanceStock'];
}
$updates[] = $result;
}
// Perform batch update if there are changes
if (!empty($updates)) {
$result = $this->gasStockDetails_model->updateBatch($updates, 'id');
return ($result !== false && $result > 0) ? $result : 0;
} else {
return 0;
}
} else {
// Get the last date of the previous month
$previousMonthDate = new DateTime($date);
$previousMonthDate = $previousMonthDate->modify('first day of this month')
->modify('-1 day')
->format('Y-m-d');
// Check if the previous month's last day entry exists
$previousMonthResultExists = $this->gasStockDetails_model
->where('date', $previousMonthDate)
->first();
$opening = 0;
// Set opening stock based on previous month's balance stock
if (!empty($previousMonthResultExists) && isset($previousMonthResultExists['balanceStock'])) {
$opening = $previousMonthResultExists['balanceStock'];
}
// Generate a list of all dates in the current month
$startDate = DateTime::createFromFormat('Y-m-d', $date)->modify('first day of this month')->format('Y-m-d');
$endDate = DateTime::createFromFormat('Y-m-d', $date)->modify('last day of this month')->format('Y-m-d');
$datesInMonth = [];
$inserts = [];
$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');
}
// Insert stock records for each day in the month
foreach ($datesInMonth as $dateInMonth) {
$balanceStock = $opening;
$consumptionForDate = 0;
if ($dateInMonth == $date) {
// Assign the given consumption for the provided date
$consumptionForDate = $consumption;
$balanceStock = $opening - $consumption;
}
$inserts[] = [
'date' => $dateInMonth,
'opening' => $opening,
'purchaseBharath' => null,
'purchaseIndian' => null,
'total' => null,
'consumption' => $consumptionForDate,
'balanceStock' => $balanceStock
];
// Update opening for the next day
$opening = $balanceStock;
}
// Perform batch insert if data is available
if (!empty($inserts)) {
$result = $this->gasStockDetails_model->insertBatch($inserts);
return ($result !== false && $result > 0) ? $result : 0;
} else {
return 0;
}
}
}
//diesel stock details
public function dieselMachineStockDetails(){
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$data = [];
$data['month'] = $month;
$this->global['pageTitle'] = 'Diesel Machine 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','diesel')
->findAll();
$filterUpdateNeeded = true ;
if( empty($customisedMachineCodes) && !empty($existingCustomMachineCodes)){
$customisedMachineCodes = array_column($existingCustomMachineCodes, 'materialCode') ;
$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','diesel')
->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' => "diesel",
'machine_id' => $customisedMachineCode
];
//checking filtered material code present in table , if not create dummy one for whole month
$findMachineCode = $this->factoryVehicleDieselDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('machine_id',$customisedMachineCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMachineCode)){
//create dummy entry for this
$this->createDummyEntryForDieselMachine($customisedMachineCode,$startDate,$endDate);
}
}
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','diesel')
->get()
->getResultArray();
}
}
//possible if no filter applied at all...!!!
if(empty($existingCustomMachineCodes)){
//no filter applied at all just present all active material codes
$existingCustomMachineCodes = $this->factoryMachine_model
->getAllActiveDieselMachines();
}else{
//if filter present,get that material codes
$existingCustomMachineCodes = $this->factoryMachine_model
->getSelectedDieselMachines(array_column($existingCustomMachineCodes, 'machine_id'));
}
//this existingCustomMachineCodes gets its machine 'id' after visiting factory machine master table in above step,
$machineCodeList = array_column($existingCustomMachineCodes, 'id');
$dieselMachines = $existingCustomMachineCodes;
$data['activeDieselMachines'] = $this->factoryMachine_model->getAllActiveDieselMachines();
// Get the previous month's last date diesel stock details for next month updation
$previousMonth = DateTime::createFromFormat('Y-m', $month)->modify('-1 month')->format('Y-m');
$previousMonthStartDate = "$previousMonth-01";
$previousMonthEndDate = date("Y-m-t", strtotime($previousMonthStartDate));
$data['previousMonthDieselMachineStockDetails'] = $this->factoryVehicleDieselDetails_model
->select(['machine_id', 'date', 'closing_reading'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['machine_id', 'date'])
->orderBy('date', 'desc')
->orderBy('machine_id', 'asc')
->findAll();
$data['previousMonthTotalDieselMachineStockDetails'] = $this->factoryVehicleDieselStockSummary_model
->select(['id', 'date', 'balance_stock'])
->distinct()
->where('date =', $previousMonthEndDate)
->groupBy(['id', 'date'])
->orderBy('date', 'desc')
->findAll();
// checking in database if the data is available for the month
$startDate = "$month-01";
$endDate = date("Y-m-t", strtotime($startDate));
$data['dieselMachineStockDetails'] = $this->factoryVehicleDieselDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->whereIn('machine_id',$machineCodeList)
->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();
// Initialize an empty array to hold the grouped data
$data['groupedDieselMachineStockDetails'] = [];
// Temporary array to store grouped data by date
$groupedByDate = [];
// Group by 'date'
foreach ($data['dieselMachineStockDetails'] 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['groupedDieselMachineStockDetails'] = array_values($groupedByDate);
// Sort each date's machines based on the custom order to set table header th
if (!empty($customisedMachineCodes)) {
usort($dieselMachines, 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;
});
}
$dieselMachinesCount = count($dieselMachines);
$data['dieselMachinesCount'] = $dieselMachinesCount;
$data['dieselMachines'] = $dieselMachines;
$date = DateTime::createFromFormat('Y-m', $month);
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate ;
// return $this->response->setJSON(['status' =>'success' ,'message' => $data['dieselMachines']]);
return $this->loadViews("stock/dieselStockDetails", $this->global, $data, NULL);
}
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(){
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month); //in M-Y format
$formattedDate = $date->format('Y-m'); //in Y-m format
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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, 'materialCode') ;
$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
];
//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',$customisedMachineCode)
->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($customisedMachineCode,$startDate,$endDate);
}
}
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 all active material codes
$existingCustomMachineCodes = $this->factoryMachine_model
->getAllActiveElectricMachines();
}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');
$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', $month)->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', $month);
$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);
}
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()
{
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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', $month);
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/dustAndRoughStockDetails", $this->global, $data, NULL);
}
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()
{
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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
];
//checking filtered material code present in table , if not create dummy one for whole month
$findMaterialCode = $this->resinStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('materialCode',$customisedMaterialCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMaterialCode)){
//create dummy entry for that
$this->createDummyEntryForResin($customisedMaterialCode,$startDate,$endDate);
}
}
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 all active material codes
$existingCustomMaterialCodes = $this->rawmaterialdetails_model->getAllResinMaterialCode();
}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');
$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', $month)->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', $month);
$formattedDate = $date->format('M-Y');
$data['month'] = $formattedDate;
return $this->loadViews("stock/resinStockDetails", $this->global, $data, NULL);
}
public function updateResinStockDetails()
{
$postData = $this->request->getPost();
$updateResinStockDetailsData = json_decode($postData['updateResinStockDetails'], true);
$updates = [];
$inserts = [];
foreach ($updateResinStockDetailsData as $data) {
$date = $data['date'];
$materialCode = $data['materialCode'];
$dbData = [
'date' => $data['date'],
'materialCode' => $data['materialCode'],
'customer' => $data['customer'],
'opening' => $data['opening'],
'receipt' => $data['receipt'],
'used' => $data['used'],
'balanceStock' => $data['balanceStock'],
];
$resultExists = $this->resinStockDetails_model
->where('date', $date)
->where('materialCode', $materialCode)
->first();
if (empty($resultExists)) {
$inserts[] = $dbData;
} else {
$dbData['id'] = $resultExists['id'];
$updates[] = $dbData;
}
}
if (!empty($inserts)) {
$this->resinStockDetails_model->insertBatch($inserts);
}
if (!empty($updates)) {
$updateResult = $this->resinStockDetails_model->updateBatch($updates, 'id');
if ($updateResult === FALSE) {
echo "Error during update";
} else {
echo "Data Updated Successfully";
return;
}
}
echo "Data Saved Successfully";
}
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);
}
}
}
// Bag Stock details starts
public function loadView_bagStockDetails()
{
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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
];
//checking filtered material code present in table , if not create dummy one for whole month
$findMaterialCode = $this->bagStockDetails_model
->where('date >=', $startDate)
->where('date <=', $endDate)
->where('materialCode',$customisedMaterialCode)
->findAll();
//check any material code is not present in stock table but applied in filter
if(empty($findMaterialCode)){
//create dummy entry for that
$this->createDummyEntryForBag($customisedMaterialCode,$startDate,$endDate);
}
}
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 all active material codes
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getAllBagMaterialCode();
}else{
//if filter present,get that material codes
$existingCustomMaterialCodes = $this->rawmaterialdetails_model
->getSelectedBagMaterialCode(array_column($existingCustomMaterialCodes, 'materialCode'));
}
$materialCodeList = array_column($existingCustomMaterialCodes, 'MaterialCode');
$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', $month)->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
foreach ($bagMaterials as $key => $bagMaterial) {
$materialCode = $bagMaterial['MaterialCode'];
$bagMaterials[$key]['customers'] = $this->bagStockDetails_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($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;
});
}
$bagMaterialcount = count($bagMaterials);
$data['bagMaterialcount'] = $bagMaterialcount;
$data['bagMaterials'] = $bagMaterials;
$date = DateTime::createFromFormat('Y-m', $month);
$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);
$inserts = [];
$updates = [];
foreach ($updateBagStockDetailsData as $data) {
$date = $data['date'];
$materialCode = $data['materialCode'];
$dbData = [
'date' => $data['date'],
'materialCode' => $data['materialCode'],
'customer' => $data['customer'],
'opening' => $data['opening'],
'receipt' => $data['receipt'],
'used' => $data['used'],
'balanceStock' => $data['balanceStock'],
];
$resultExists = $this->bagStockDetails_model
->where('date', $date)
->where('materialCode', $materialCode)
->first();
if (empty($resultExists)) {
$inserts[] = $dbData;
} else {
$dbData['id'] = $resultExists['id'];
$updates[] = $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(){
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
} else {
$session = session();
$month = $session->get('stock_month');
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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', $month);
$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
if ($this->request->getMethod() === 'POST') {
$month = $this->request->getPost('month');
$date = DateTime::createFromFormat('M-Y', $month);
$formattedDate = $date->format('Y-m');
$month = $formattedDate;
$session = session ();
$session->set('stock_month',$month);
} else {
$session = session();
//getting month from session if present
$month = $session->get('stock_month');
//else current month
if (empty($month)) {
$month = date('Y-m'); // Default to the current month
}
}
$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 ;
// dd( $data['trpAbstract']['Incoming Raw Sand Details'] );
// dd((int)$trpAbstract["Incoming Raw Sand Details"]['opening_stock']);
$date = DateTime::createFromFormat('Y-m', $month);
$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'],
'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 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;
}
/**
* Updates gas stock consumption if the value changes.
*/
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 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' => " ",
'trpPlusDrierGasConsumption' => " ",
'trpPhysicalGasPerTon' => " ",
'panelGasConsumption' => " ",
'panelGasPerTon' => " ",
'edRunningHours' => " ",
'edProduction' => " ",
'edUsage' => " ",
'trpProduction' => " ",
'trpProductionPerHour' => " ",
'waterReceipt' => " ",
'waterConsumption' => " ",
'ebReading' =>" ",
'ebReadingPerUnitTon' =>" ",
'msSeperation' => " ",
'edWaste' => " ",
'coolerBags' =>" ",
'edPlus20Waste' => " ",
'cycloneWaste' => " "
];
}
return $inserts;
}
}