17. Yükseltme ve Hatırlatıcılar (Yaygın Kullanım Senaryoları)

Bu desenler, Kesintiye Uğratmayan Sınır Olayları (Non-Interrupting Boundary Events) (cancelActivity="false") kullanarak süresi geçmiş görevlerin nasıl yönetileceğini gösterir. Bu, sistem yükseltme (escalation) eylemini gerçekleştirirken görevin aktif kalmasını sağlar.

Senaryo 1: 2 gün içinde tamamlanmazsa yeniden ata

Görev 48 saat boyunca beklerse, otomatik olarak bir yöneticiye (manager) devret.

<userTask id="task" name="Employee Task" flowable:assignee="${employee}"/>

<!-- Non-interrupting timer: triggers after 2 days -->
<boundaryEvent id="timer2days" attachedToRef="task" cancelActivity="false">
    <timerEventDefinition>
        <timeDuration>P2D</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="timer2days" targetRef="escalateToManager"/>

<serviceTask id="escalateToManager" flowable:delegateExpression="${reassignTask}">
    <extensionElements>
        <flowable:field name="targetAssignee" stringValue="manager@workingflow.com"/>
        <flowable:field name="clearExisting" stringValue="true"/>
    </extensionElements>
</serviceTask>

Senaryo 2: Belirli bir Tarihe kadar tamamlanmazsa yeniden ata

Önceki bir formda belirlenen "Son Teslim Tarihi" (dueDate değişkeni) geçerse, görevi yeniden ata.

<userTask id="task" name="Time Sensitive Task" flowable:assignee="${employee}"/>

<!-- Non-interrupting timer: triggers at specific ISO date stored in variable -->
<boundaryEvent id="timerDate" attachedToRef="task" cancelActivity="false">
    <timerEventDefinition>
        <timeDate>${dueDate}</timeDate>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="timerDate" targetRef="reassignToBackup"/>

<serviceTask id="reassignToBackup" flowable:delegateExpression="${reassignTask}">
    <extensionElements>
        <flowable:field name="targetAssignee" stringValue="backup_user@workingflow.com"/>
        <flowable:field name="clearExisting" stringValue="true"/>
    </extensionElements>
</serviceTask>

Senaryo 3: 2 gün içinde tamamlanmazsa e-posta gönder

Görev 48 saattir beklemedeyse bir "Dürtme" (Nudge) e-postası gönder, ancak görevi kullanıcıya atanmış halde bırak.

<userTask id="task" name="Employee Task" flowable:assignee="${employee}"/>

<boundaryEvent id="nudgeTimer" attachedToRef="task" cancelActivity="false">
    <timerEventDefinition>
        <timeDuration>P2D</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="nudgeTimer" targetRef="sendNudge"/>

<serviceTask id="sendNudge" flowable:delegateExpression="${sendReminder}">
    <extensionElements>
        <flowable:field name="to" expression="${employee}"/>
        <flowable:field name="subject" stringValue="Task Overdue"/>
        <flowable:field name="body" stringValue="This task has been pending for 2 days."/>
    </extensionElements>
</serviceTask>

Senaryo 4: Belirli bir Tarihe kadar tamamlanmazsa e-posta gönder

Son teslim tarihi (dueDate değişkeni) geçerse bir uyarı e-postası gönder.

<userTask id="task" name="Deadline Task" flowable:assignee="${employee}"/>

<boundaryEvent id="deadlineTimer" attachedToRef="task" cancelActivity="false">
    <timerEventDefinition>
        <timeDate>${dueDate}</timeDate>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="deadlineTimer" targetRef="sendWarning"/>

<serviceTask id="sendWarning" flowable:delegateExpression="${sendReminder}">
    <extensionElements>
        <flowable:field name="to" expression="${employee}"/>
        <flowable:field name="subject" stringValue="Deadline Missed"/>
        <flowable:field name="body" stringValue="You have missed the deadline for this task."/>
    </extensionElements>
</serviceTask>

Senaryo 5: Görev tamamlanana kadar düzenli hatırlatıcılar gönder

Belirli bir programla (örneğin her saat başı veya her 24 saatte bir) görevin beklediğini bildiren e-postalar gönder.

<userTask id="pendingTask" name="Pending Approval" flowable:assignee="${assignee}"/>

<!-- Non-interrupting, repeating timer: sends reminder every hour -->
<boundaryEvent id="reminderTimer" attachedToRef="pendingTask" cancelActivity="false">
    <timerEventDefinition>
        <timeCycle>R/PT1H</timeCycle>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="reminderTimer" targetRef="sendReminder"/>

<serviceTask id="sendReminder" flowable:delegateExpression="${sendReminder}">
    <extensionElements>
        <flowable:field name="to" expression="${assignee}"/>
        <flowable:field name="subject" stringValue="Task Reminder"/>
        <flowable:field name="body" stringValue="You have a pending task awaiting your action."/>
    </extensionElements>
</serviceTask>

SendReminderDelegate Alanları

Alan Açıklama
to Alıcı e-postası (${assignee} gibi bir ifade (expression) kullanabilir)
toRole Bir roldeki (ör. ROLE_MANAGER) tüm kullanıcılara gönder. to alanı ile birleştirilebilir.
subject E-posta konu satırı
body E-posta gövde metni — iş akışı yazarının (author) yazdığı özel mesaj

Otomatik çözümlenen bağlam (context): Süreç adı ve mevcut görev adı her e-postaya otomatik olarak dahil edilir — BPMN yapılandırmasına gerek yoktur. Çalışma zamanında (runtime) Flowable motorundan çözümlenirler ve e-posta şablonunda mesaj gövdesinin üzerindeki yapılandırılmış alanlar olarak görünürler.

E-posta biçimi: E-postalar, bir Thymeleaf şablonu kullanılarak HTML olarak gönderilir. Şablon etiketlerinin dili (ör. "Süreç", "Görev", "Mesaj"), Yönetici → Sistem Ayarları (Admin → System Settings) menüsünden ayarlanan sistem geneli dile uyar. BPMN'de yazdığınız body metni, şablonun içine olduğu gibi (as-is) yerleştirilir.