17. Son Tarih (Due Date) Desteği

Kullanıcı Görevlerine son tarih (due date) atanabilir — görevin tamamlanması gereken son tarihi belirten bir özellik. Workingflow bu bilgiyi BPMN tanımından okur ve süresi geçmiş görevleri otomatik olarak vurgular.

Nasıl Çalışır

Özellik Detay
Ayarlandığı yer Camunda Modeler → Kullanıcı Görevi Özellikleri → "Due Date" alanı
BPMN özniteliği flowable:dueDate
Kabul eder Sabit tarih, ISO 8601 süre, veya süreç değişkeni ifadesi
Gecikme gösterimi Görev satırı Görevlerim ve Tüm Görevler listelerinde kırmızı olur

[!IMPORTANT] Son tarihler asla zorunlu tutulmaz — yalnızca bilgilendirme amaçlıdır. Süresi geçmiş bir görev normal şekilde tamamlanabilir. Kırmızı vurgu, acil aksiyon gerektiren görevlere dikkat çekmek içindir.


Senaryo 1: Görev Oluşturulmasından İtibaren Sabit Süre

En yaygın kullanım. Görev, oluşturulduğu andan itibaren belirli bir süre sonra sona erer.

Kullanıcı Görevinin Due Date alanına yazın:

P3D

Bu "görev atandıktan 3 gün sonra" anlamına gelir. Görev oluşturulduğunda Flowable son tarihi otomatik hesaplar.

Yaygın süre formatları (ISO 8601):

Süre Anlamı
PT1H 1 saat
PT24H 24 saat
P1D 1 gün
P3D 3 gün
P1W 1 hafta
P2W 2 hafta
P1M 1 ay
PT2H30M 2 saat 30 dakika

BPMN XML:

<userTask id="approveRequest" name="Talebi Onayla"
          flowable:assignee="${manager}"
          flowable:dueDate="P3D">
</userTask>

Senaryo 2: Sabit Tarih (Statik)

Belirli ve bilinen bir son tarih için. Tarih ISO 8601 formatında olmalıdır.

Due Date alanına yazın:

2026-06-15T17:00:00

Kabul edilen tarih formatları:

Format Örnek
Tam tarih-saat 2026-06-15T17:00:00
Sadece tarih 2026-06-15

BPMN XML:

<userTask id="submitReport" name="Yıllık Raporu Gönder"
          flowable:assignee="${accountant}"
          flowable:dueDate="2026-06-15T17:00:00">
</userTask>

Senaryo 3: Form Değişkeninden Tarih

Bir önceki form kullanıcıdan bir son tarih toplar ve sonraki görev bu tarihi son tarih olarak kullanır.

Adım 1: Başlangıç Formu veya Kullanıcı Görevinde son tarihi toplayın:

<userTask id="submitRequest" name="Talep Gönder" flowable:assignee="${initiator}">
    <extensionElements>
        <activiti:formProperty id="description" name="Açıklama" type="string" required="true"/>
        <activiti:formProperty id="requestedDeadline" name="Son Tarih" type="date" required="true"/>
    </extensionElements>
</userTask>

Adım 2: Sonraki görevin Due Date alanında değişkeni referans verin:

<userTask id="approveRequest" name="Talebi Onayla"
          flowable:assignee="${manager}"
          flowable:dueDate="${requestedDeadline}">
</userTask>

${requestedDeadline} ifadesi, bir önceki formda ayarlanan tarih değişkenini okur. Flowable bunu görev oluşturulurken çözümler.


Senaryo 4: Tarih Değişkeni + Süre Ofseti (Script Görevi)

"Formdaki bir tarih + birkaç gün fazla" gibi bir hesaplama gerektiğinde, bunu bir Script Görevi ile hesaplamanız gerekir çünkü Due Date alanı aritmetik ifadeleri desteklemez.

Örnek: Kullanıcı tercih ettiği son tarihi girer, ancak onay görevine 2 gün eklenir.

<!-- Adım 1: Kullanıcı son tarih girer -->
<userTask id="submitRequest" name="Talep Gönder" flowable:assignee="${initiator}">
    <extensionElements>
        <activiti:formProperty id="preferredDeadline" name="Tercih Edilen Son Tarih" type="date" required="true"/>
    </extensionElements>
</userTask>

<sequenceFlow sourceRef="submitRequest" targetRef="calcDeadline"/>

<!-- Adım 2: Ofsetli son tarihi hesapla -->
<scriptTask id="calcDeadline" name="Son Tarih Hesapla" scriptFormat="super-js">
  <script>
    var preferred = execution.getVariable('preferredDeadline');
    var approvalDeadline = wf.addDays(preferred, 2);
    execution.setVariable('approvalDueDate', approvalDeadline);
  </script>
</scriptTask>

<sequenceFlow sourceRef="calcDeadline" targetRef="approveRequest"/>

<!-- Adım 3: Hesaplanan tarihi kullan -->
<userTask id="approveRequest" name="Talebi Onayla"
          flowable:assignee="${manager}"
          flowable:dueDate="${approvalDueDate}">
</userTask>

İpucu: Hafta sonlarını atlamak istiyorsanız wf.addDays() yerine wf.addBusinessDays() kullanın.


Senaryo 5: Süreç Başlangıç Tarihi + Süre (Script Görevi)

Son tarih, görevin oluşturulma zamanına değil sürecin başlatılma zamanına göre belirlenmesi gerektiğinde.

<!-- Son tarihi hesapla: süreç başlangıcı + 5 iş günü -->
<scriptTask id="calcDeadline" name="Son Tarih Hesapla" scriptFormat="super-js">
  <script>
    var startDate = wf.getProcessStartDate(execution);
    var deadline = wf.addBusinessDays(startDate, 5);
    execution.setVariable('processDeadline', deadline);
  </script>
</scriptTask>

<sequenceFlow sourceRef="calcDeadline" targetRef="reviewTask"/>

<userTask id="reviewTask" name="Belgeyi İncele"
          flowable:assignee="${reviewer}"
          flowable:dueDate="${processDeadline}">
</userTask>

Senaryo 6: Formdan Gelen Dinamik Süre (Script Görevi)

Gün sayısının kendisi kullanıcı girdisinden geldiğinde (örn. "Onay kaç gün içinde tamamlanmalı?").

<!-- Kullanıcı SLA'yı belirler -->
<userTask id="configure" name="SLA Yapılandır" flowable:assignee="${initiator}">
    <extensionElements>
        <activiti:formProperty id="slaDays" name="Onay SLA (gün)" type="long" required="true"/>
    </extensionElements>
</userTask>

<sequenceFlow sourceRef="configure" targetRef="calcSla"/>

<!-- Dinamik girdiden son tarih hesapla -->
<scriptTask id="calcSla" name="SLA Son Tarihini Hesapla" scriptFormat="super-js">
  <script>
    var days = execution.getVariable('slaDays');
    var deadline = wf.addDays(wf.now(), days);
    execution.setVariable('slaDueDate', deadline);
  </script>
</scriptTask>

<sequenceFlow sourceRef="calcSla" targetRef="approveTask"/>

<userTask id="approveTask" name="Onayla"
          flowable:assignee="${manager}"
          flowable:dueDate="${slaDueDate}">
</userTask>

Gecikme Gösterimi

Son tarihi geçmiş görevler, Görevlerim ve Tüm Görevler listelerinde otomatik olarak kırmızı satır ile vurgulanır. Yapılandırma gerekmez — görevin bir son tarihi varsa ve bu tarih geçmişte kalmışsa satır kırmızıya döner.

Durum Gösterim
Son tarih ayarlanmamış Normal satır
Son tarih gelecekte Normal satır
Son tarih geçmiş Kırmızı satır (table-danger)

Gecikme E-posta Bildirimleri

Son tarihler tek başına pasiftir — kırmızı satır yalnızca kullanıcı görev listesini açtığında görünür. Son tarih geldiğinde kullanıcıları proaktif olarak bilgilendirmek için, son tarihi bir kesintisiz sınır zamanlayıcı olayı (non-interrupting boundary timer) ve ${sendReminder} delegesi ile birleştirin.

Sınır zamanlayıcı, son tarih anında tam olarak tetiklenir ve bir e-posta gönderir; görev ise kullanıcının tamamlaması için açık kalır.

Örnek 1: Statik 3 günlük SLA ile gecikme bildirimi

<userTask id="approve" name="Talebi Onayla"
          flowable:assignee="${manager}"
          flowable:dueDate="P3D">
</userTask>

<!-- Kesintisiz sınır zamanlayıcı: son tarih geldiğinde tetiklenir -->
<boundaryEvent id="overdueAlert" attachedToRef="approve" cancelActivity="false">
    <timerEventDefinition>
        <timeDuration>P3D</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="overdueAlert" targetRef="sendOverdueEmail"/>

<serviceTask id="sendOverdueEmail" flowable:delegateExpression="${sendReminder}">
    <extensionElements>
        <flowable:field name="to" expression="${manager}"/>
        <flowable:field name="subject" stringValue="Görev Gecikti: Talebi Onayla"/>
        <flowable:field name="body" stringValue="Onay göreviniz son tarihini geçti. Lütfen aksiyon alın."/>
    </extensionElements>
</serviceTask>

Örnek 2: Form değişkeninden dinamik son tarih

Son tarih hesaplanmış bir değişkenden geldiğinde (örn. Script Görevi ile), aynı değişkeni <timeDate> ile kullanın:

<userTask id="review" name="Belgeyi İncele"
          flowable:assignee="${reviewer}"
          flowable:dueDate="${calculatedDeadline}">
</userTask>

<!-- Zamanlayıcı, hesaplanan son tarihte tetiklenir -->
<boundaryEvent id="reviewOverdue" attachedToRef="review" cancelActivity="false">
    <timerEventDefinition>
        <timeDate>${calculatedDeadline}</timeDate>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="reviewOverdue" targetRef="notifyReviewOverdue"/>

<serviceTask id="notifyReviewOverdue" flowable:delegateExpression="${sendReminder}">
    <extensionElements>
        <flowable:field name="to" expression="${reviewer}"/>
        <flowable:field name="subject" stringValue="İnceleme Son Tarihi Geçti"/>
        <flowable:field name="body" stringValue="İnceleme görevi son tarihini geçti."/>
    </extensionElements>
</serviceTask>

Örnek 3: Son tarihten sonra tekrarlayan hatırlatıcılar

Görev tamamlanana kadar son tarihten sonra her gün bir hatırlatıcı e-postası gönderin:

<boundaryEvent id="dailyNag" attachedToRef="approve" cancelActivity="false">
    <timerEventDefinition>
        <!-- Son tarihi bekle, sonra günlük tekrarla -->
        <timeCycle>R/P3D/P1D</timeCycle>
    </timerEventDefinition>
</boundaryEvent>

[!TIP] Sınır zamanlayıcı ve flowable:dueDate bağımsız özelliklerdir — sadece birlikte mükemmel çalışırlar. Son tarih, arayüzdeki kırmızı satırı kontrol eder. Sınır zamanlayıcı ise e-posta bildirimini kontrol eder. İkisini ayrı ayrı veya birlikte kullanabilirsiniz.


Hızlı Referans

Ne İstiyorsunuz Due Date Alanı Değeri Script Görevi Gerekli mi?
Görev oluşturulmasından 3 gün sonra P3D Hayır
Görev oluşturulmasından 24 saat sonra PT24H Hayır
Belirli sabit tarih 2026-06-15T17:00:00 Hayır
Form değişkeninden tarih ${myDateVariable} Hayır
Form tarihi + ekstra gün ${calculatedDate} Evet — wf.addDays() kullanın
Süreç başlangıcı + N gün ${calculatedDate} Evet — wf.getProcessStartDate() + wf.addDays()
Kullanıcı girdisinden dinamik gün ${calculatedDate} Evet — wf.addDays(wf.now(), days)