Skip to content

Commit 018d359

Browse files
authored
Merge pull request #8506 from ProcessMaker/bugfix/FOUR-25910-b
FOUR-25910: Old processes do not update the progress bar status (Error and Canceled)
2 parents ec367da + 3c1e9ca commit 018d359

1 file changed

Lines changed: 158 additions & 0 deletions

File tree

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\DB;
4+
use ProcessMaker\Upgrades\UpgradeMigration as Upgrade;
5+
6+
class PopulateCasesStartedAndParticipatedWithStagesAndProgress extends Upgrade
7+
{
8+
/**
9+
* Batch size for processing large tables
10+
*/
11+
private const BATCH_SIZE = 10000;
12+
13+
/**
14+
* Run the upgrade migration.
15+
*
16+
* @return void
17+
*/
18+
public function up()
19+
{
20+
echo PHP_EOL . ' Populating cases_participated with stage and progress data...' . PHP_EOL;
21+
$startTime = microtime(true);
22+
23+
// Update last_stage_name and progress based on case_status using optimized batch processing
24+
$this->updateStageAndProgressDataOptimized();
25+
$this->logTimeElapsed('Updated stage and progress data', $startTime);
26+
27+
echo PHP_EOL;
28+
}
29+
30+
/**
31+
* Log the time elapsed since the start of the process.
32+
*
33+
* @param string $message Message to log
34+
* @param float $startTime Time when the processing started (in microseconds)
35+
* @return void
36+
*/
37+
private function logTimeElapsed(string $message, float $startTime): void
38+
{
39+
$currentTime = microtime(true);
40+
$timeElapsed = $currentTime - $startTime;
41+
42+
// Format the elapsed time to 4 decimal places for higher precision
43+
echo " {$message} - Time elapsed: " . number_format($timeElapsed, 4) . ' seconds' . PHP_EOL;
44+
}
45+
46+
/**
47+
* Reverse the upgrade migration.
48+
*
49+
* @return void
50+
*/
51+
public function down()
52+
{
53+
DB::table('cases_started')->update([
54+
'last_stage_id' => null,
55+
'last_stage_name' => null,
56+
'progress' => 0,
57+
]);
58+
DB::table('cases_participated')->update([
59+
'last_stage_id' => null,
60+
'last_stage_name' => null,
61+
'progress' => 0,
62+
]);
63+
}
64+
65+
/**
66+
* Update the last_stage_name and progress fields using optimized batch processing
67+
*
68+
* @return void
69+
*/
70+
private function updateStageAndProgressDataOptimized()
71+
{
72+
// Define status mappings with their corresponding stage names and progress values
73+
$statusMappings = [
74+
'COMPLETED' => ['stage' => 'COMPLETED', 'progress' => 100],
75+
'IN_PROGRESS' => ['stage' => 'IN_PROGRESS', 'progress' => 50],
76+
'ACTIVE' => ['stage' => 'IN_PROGRESS', 'progress' => 50],
77+
'DRAFT' => ['stage' => 'DRAFT', 'progress' => 0],
78+
'ERROR' => ['stage' => 'ERROR', 'progress' => 0],
79+
'CANCELED' => ['stage' => 'CANCELED', 'progress' => 0],
80+
'PAUSED' => ['stage' => 'PAUSED', 'progress' => 0],
81+
];
82+
83+
// Process each status for cases_participated table
84+
foreach ($statusMappings as $status => $mapping) {
85+
$this->processBatchByStatus(
86+
'cases_participated',
87+
$status,
88+
$mapping['stage'],
89+
$mapping['progress'],
90+
"{$status} cases with progress {$mapping['progress']}%"
91+
);
92+
}
93+
94+
// Process each status for cases_started table
95+
foreach ($statusMappings as $status => $mapping) {
96+
$this->processBatchByStatus(
97+
'cases_started',
98+
$status,
99+
$mapping['stage'],
100+
$mapping['progress'],
101+
"{$status} cases with progress {$mapping['progress']}%"
102+
);
103+
}
104+
}
105+
106+
/**
107+
* Process cases by status in batches for better performance
108+
*
109+
* @param string $tableName
110+
* @param string $status
111+
* @param string $stageName
112+
* @param int $progress
113+
* @param string $description
114+
* @return void
115+
*/
116+
private function processBatchByStatus(string $tableName, string $status, string $stageName, int $progress, string $description)
117+
{
118+
$offset = 0;
119+
$totalProcessed = 0;
120+
121+
do {
122+
// Get batch of IDs to process - now we update ALL records with this status
123+
// regardless of their current last_stage_name or progress values
124+
$batchIds = DB::table($tableName)
125+
->where('case_status', $status)
126+
->whereNull('last_stage_name')
127+
->select('id')
128+
->offset($offset)
129+
->limit(self::BATCH_SIZE)
130+
->pluck('id')
131+
->toArray();
132+
133+
if (empty($batchIds)) {
134+
break;
135+
}
136+
137+
// Update batch using raw SQL for better performance
138+
$updated = DB::table($tableName)
139+
->whereIn('id', $batchIds)
140+
->update([
141+
'last_stage_name' => $stageName,
142+
'progress' => $progress,
143+
]);
144+
145+
$totalProcessed += $updated;
146+
$offset += self::BATCH_SIZE;
147+
148+
// Progress indicator for large tables
149+
if ($totalProcessed % 50000 === 0) {
150+
echo " Processed {$tableName} table {$totalProcessed} {$status} cases..." . PHP_EOL;
151+
}
152+
} while (count($batchIds) === self::BATCH_SIZE);
153+
154+
if ($totalProcessed > 0) {
155+
echo " Updated {$tableName} table {$totalProcessed} {$description}" . PHP_EOL;
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)