Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the .php extension to the file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry the branch is not the correct.. I'm updating

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an error at the moment to run the upgrade

Uncaught Error: Class "PopulateCasesStartedAndParticipatedStartedStageAndProgress" not found

Rename the file upgrade to 2025_09_02_134901_populate_cases_started_and_participated_stage_and_progress.php to match with the class name

Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

use Illuminate\Support\Facades\DB;
use ProcessMaker\Upgrades\UpgradeMigration as Upgrade;

class PopulateCasesStartedAndParticipatedStageAndProgress extends Upgrade
{
/**
* Batch size for processing large tables
*/
private const BATCH_SIZE = 10000;

/**
* Run the upgrade migration.
*
* @return void
*/
public function up()
{
echo PHP_EOL . ' Populating cases_participated with stage and progress data...' . PHP_EOL;
$startTime = microtime(true);

// Update last_stage_name and progress based on case_status using optimized batch processing
$this->updateStageAndProgressDataOptimized();
$this->logTimeElapsed('Updated stage and progress data', $startTime);

echo PHP_EOL;
}

/**
* Log the time elapsed since the start of the process.
*
* @param string $message Message to log
* @param float $startTime Time when the processing started (in microseconds)
* @return void
*/
private function logTimeElapsed(string $message, float $startTime): void
{
$currentTime = microtime(true);
$timeElapsed = $currentTime - $startTime;

// Format the elapsed time to 4 decimal places for higher precision
echo " {$message} - Time elapsed: " . number_format($timeElapsed, 4) . ' seconds' . PHP_EOL;
}

/**
* Reverse the upgrade migration.
*
* @return void
*/
public function down()
{
DB::table('cases_started')->update([
'last_stage_id' => null,
'last_stage_name' => null,
'progress' => 0,
]);
DB::table('cases_participated')->update([
'last_stage_id' => null,
'last_stage_name' => null,
'progress' => 0,
]);
}

/**
* Update the last_stage_name and progress fields using optimized batch processing
*
* @return void
*/
private function updateStageAndProgressDataOptimized()
{
// Define status mappings with their corresponding stage names and progress values
$statusMappings = [
'COMPLETED' => ['stage' => 'COMPLETED', 'progress' => 100],
'IN_PROGRESS' => ['stage' => 'IN_PROGRESS', 'progress' => 50],
'ACTIVE' => ['stage' => 'IN_PROGRESS', 'progress' => 50],
'DRAFT' => ['stage' => 'DRAFT', 'progress' => 0],
'ERROR' => ['stage' => 'ERROR', 'progress' => 0],
'CANCELED' => ['stage' => 'CANCELED', 'progress' => 0],
'PAUSED' => ['stage' => 'PAUSED', 'progress' => 0],
];

// Process each status for cases_participated table
foreach ($statusMappings as $status => $mapping) {
$this->processBatchByStatus(
'cases_participated',
$status,
$mapping['stage'],
$mapping['progress'],
"{$status} cases with progress {$mapping['progress']}%"
);
}

// Process each status for cases_started table
foreach ($statusMappings as $status => $mapping) {
$this->processBatchByStatus(
'cases_started',
$status,
$mapping['stage'],
$mapping['progress'],
"{$status} cases with progress {$mapping['progress']}%"
);
}
}

/**
* Process cases by status in batches for better performance
*
* @param string $tableName
* @param string $status
* @param string $stageName
* @param int $progress
* @param string $description
* @return void
*/
private function processBatchByStatus(string $tableName, string $status, string $stageName, int $progress, string $description)
{
$offset = 0;
$totalProcessed = 0;

do {
// Get batch of IDs to process - now we update ALL records with this status
// regardless of their current last_stage_name or progress values
$batchIds = DB::table($tableName)
->where('case_status', $status)
->whereNull('last_stage_name')
->select('id')
->offset($offset)
->limit(self::BATCH_SIZE)
->pluck('id')
->toArray();

if (empty($batchIds)) {
break;
}

// Update batch using raw SQL for better performance
$updated = DB::table($tableName)
->whereIn('id', $batchIds)
->update([
'last_stage_name' => $stageName,
'progress' => $progress,
]);

$totalProcessed += $updated;
$offset += self::BATCH_SIZE;

// Progress indicator for large tables
if ($totalProcessed % 50000 === 0) {
echo " Processed {$tableName} table {$totalProcessed} {$status} cases..." . PHP_EOL;
}
} while (count($batchIds) === self::BATCH_SIZE);

if ($totalProcessed > 0) {
echo " Updated {$tableName} table {$totalProcessed} {$description}" . PHP_EOL;
}
}
}