diff --git a/ProcessMaker/Models/CaseNumber.php b/ProcessMaker/Models/CaseNumber.php new file mode 100644 index 0000000000..7b06ee69e5 --- /dev/null +++ b/ProcessMaker/Models/CaseNumber.php @@ -0,0 +1,36 @@ +id); + */ +class CaseNumber extends Model +{ + use HasFactory; + + protected $fillable = ['process_request_id']; + + /** + * Generate a unique sequence for a given name. + * + * @param int|string $id of the request + * @return int The next value in the sequence. + */ + public static function generate($requestId): int + { + // Create a new sequence with the given name + $sequence = self::create(['process_request_id' => $requestId]); + + // Return the id of the sequence as the next value in the sequence + return $sequence->id; + } +} diff --git a/ProcessMaker/Models/ProcessRequest.php b/ProcessMaker/Models/ProcessRequest.php index bca964b68e..e9edb23641 100644 --- a/ProcessMaker/Models/ProcessRequest.php +++ b/ProcessMaker/Models/ProcessRequest.php @@ -40,6 +40,7 @@ * @property string $participant_id * @property string $name * @property string $case_title + * @property int $case_number * @property string $status * @property array $data * @property string $collaboration_uuid @@ -61,6 +62,7 @@ * @OA\Property(property="status", type="string", enum={"ACTIVE", "COMPLETED", "ERROR", "CANCELED"}), * @OA\Property(property="name", type="string"), * @OA\Property(property="case_title", type="string"), + * @OA\Property(property="case_number", type="integer"), * @OA\Property(property="process_id", type="integer"), * @OA\Property(property="process", type="object"), * ), @@ -934,4 +936,15 @@ public function evaluateCaseTitle(array $data): string $mustache = new MustacheExpressionEvaluator(); return $mustache->render($mustacheTitle, $data); } + + public function isSystem() + { + $systemCategories = ProcessCategory::where('is_system', true)->pluck('id'); + return DB::table('category_assignments') + ->where('assignable_type', Process::class) + ->where('assignable_id', $this->process_id) + ->where('category_type', ProcessCategory::class) + ->whereIn('category_id', $systemCategories) + ->exists(); + } } diff --git a/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php b/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php index 4e706c03de..4356ea6677 100644 --- a/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php +++ b/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php @@ -611,6 +611,7 @@ private function serializeState(ProcessRequest $instance) return [ 'id' => $request->uuid, + 'request_id' => $request->getKey(), 'process_version_id' => $request->process_version_id, 'callable_id' => $request->callable_id, 'collaboration_uuid' => $request->collaboration_uuid, diff --git a/ProcessMaker/Nayra/Repositories/Deserializer.php b/ProcessMaker/Nayra/Repositories/Deserializer.php index 2560ccc80a..cc4729d9cc 100644 --- a/ProcessMaker/Nayra/Repositories/Deserializer.php +++ b/ProcessMaker/Nayra/Repositories/Deserializer.php @@ -194,6 +194,9 @@ public function unserializeInstance(array $serialized): ExecutionInstanceInterfa // Set process request properties $properties = array_merge($instance->getProperties(), $properties); $instance->setProperties($properties); + if (isset($properties['parent_request_id'])) { + $instance->parent_request_id = $properties['parent_request_id']; + } // Set request data if (!empty($serialized['data']) && is_array($serialized['data'])) { diff --git a/ProcessMaker/Observers/ProcessRequestObserver.php b/ProcessMaker/Observers/ProcessRequestObserver.php index b060e1a15e..7f8fc72910 100644 --- a/ProcessMaker/Observers/ProcessRequestObserver.php +++ b/ProcessMaker/Observers/ProcessRequestObserver.php @@ -4,6 +4,7 @@ use ProcessMaker\Events\RequestAction; use ProcessMaker\Events\RequestError; +use ProcessMaker\Models\CaseNumber; use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessRequestToken; use ProcessMaker\Models\ScheduledTask; @@ -64,7 +65,43 @@ public function saving(ProcessRequest $request) // When data is updated we update the case_title if ($request->isDirty('data')) { $data = $request->data; - $request->case_title = $request->evaluateCaseTitle($data); + // If request is a parent process, inherit the case title to the child requests + if (!$request->parent_request_id) { + $request->case_title = $request->evaluateCaseTitle($data); + // Copy the case title to the child requests + if (!empty($request->id)) { + ProcessRequest::where('parent_request_id', $request->id) + ->update(['case_title' => $request->case_title]); + } + } else { + // If request is a subprocess, inherit the case title from the parent + $request->case_title = ProcessRequest::whereId($request->parent_request_id) + ->select('case_title') + ->first() + ->case_title; + } + } + } + + public function created(ProcessRequest $request) + { + // If request is System, don't generate a case number + if ($request->isSystem()) { + return; + } + // If request is a subprocess, inherit the case number from the parent + if ($request->parent_request_id) { + $request->case_number = ProcessRequest::whereId($request->parent_request_id) + ->select('case_number') + ->first() + ->case_number; + + $request->save(); + + return; } + // If request is not a subprocess and not a system process, generate a case number + $request->case_number = CaseNumber::generate($request->id); + $request->save(); } } diff --git a/ProcessMaker/Repositories/ExecutionInstanceRepository.php b/ProcessMaker/Repositories/ExecutionInstanceRepository.php index dfe9da6d59..ec810be5f8 100644 --- a/ProcessMaker/Repositories/ExecutionInstanceRepository.php +++ b/ProcessMaker/Repositories/ExecutionInstanceRepository.php @@ -151,6 +151,12 @@ public function persistInstanceCreated(ExecutionInstanceInterface $instance) return; } + // Check if + $parent = $data['_parent'] ?? null; + if (!empty($parent) && is_numeric($parent['request_id'])) { + $instance->parent_request_id = $parent['request_id']; + } + // Save process request $instance->callable_id = $process->getId(); $instance->collaboration_uuid = $instance->getProperty('collaboration_uuid', null); diff --git a/database/migrations/2023_12_04_100557_create_case_numbers_table.php b/database/migrations/2023_12_04_100557_create_case_numbers_table.php new file mode 100644 index 0000000000..db4703ebb6 --- /dev/null +++ b/database/migrations/2023_12_04_100557_create_case_numbers_table.php @@ -0,0 +1,27 @@ +id(); + $table->unsignedInteger('process_request_id')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('case_numbers'); + } +}; diff --git a/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php b/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php new file mode 100644 index 0000000000..917566e453 --- /dev/null +++ b/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php @@ -0,0 +1,28 @@ +unsignedInteger('case_number')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('process_requests', function (Blueprint $table) { + $table->dropColumn('case_number'); + }); + } +}; diff --git a/resources/js/requests/components/RequestsListing.vue b/resources/js/requests/components/RequestsListing.vue index 70756a6fb0..4c29b302b3 100644 --- a/resources/js/requests/components/RequestsListing.vue +++ b/resources/js/requests/components/RequestsListing.vue @@ -34,6 +34,17 @@ #{{ props.rowData.id }} +