15. Hizmet Görevleri (Otomasyon)
Hizmet görevleri (Service Tasks), sistem mantığını otomatik olarak yürütmenize olanak tanır. flowable:delegateExpression niteliğini kullanarak belirli bir işleme başvurursunuz.
📋 Mevcut Temsilciler (Delegates) Özeti
| Temsilci Adı | Bean Adı (${...}) |
Açıklama | Gerekli Alanlar (<flowable:field>) |
|---|---|---|---|
| Hatırlatıcı Gönder | sendReminder |
E-posta bildirimi gönderir. | to (e-posta), subject (konu), body (içerik) |
| Görevi Yeniden Ata | reassignTask |
Aktif görevlerin atamasını değiştirir (örneğin yükseltme/escalation için). | targetAssignee (veya targetCandidateGroups), clearExisting |
| Role Göre Ata | assignUsersByRole |
Belirli bir role sahip tüm kullanıcıları bulur ve bir e-posta listesi döndürür. | roleName, outputVariable (sonuç değişkeni adı) |
| PDF Oluştur | generatePdf |
Satır içi (inline) bir HTML şablonundan bir PDF belgesi oluşturur. | template (HTML), outputVariable (sonuç değişkeni adı) |
Mevcut İşlemler
1. Role Göre Kullanıcıları Getir (assignUsersByRole)
Belirli bir role sahip tüm kullanıcıları getirir ve e-postalarını bir liste değişkeninde saklar. Bu öncelikle Paralel Çoklu Örnek (Parallel Multi-Instance) görevleri (bir görevi roldeki herkese atamak) için kullanılır.
Girdiler (Alanlar):
roleName: Rol anahtarı (ör.ROLE_MANAGER).outputVariable: Listenin saklanacağı değişkenin adı (varsayılan:targetUsers).
Örnek: Anketi Tüm Yöneticilere Ata
<!-- Step 1: Fetch list of managers -->
<serviceTask id="fetchMgrs" flowable:delegateExpression="${assignUsersByRole}">
<extensionElements>
<flowable:field name="roleName" stringValue="ROLE_MANAGER"/>
<flowable:field name="outputVariable" stringValue="managerList"/>
</extensionElements>
</serviceTask>
<!-- Step 2: Create a task for EACH manager in the list -->
<userTask id="survey" name="Manager Survey" flowable:assignee="${assignee}">
<multiInstanceLoopCharacteristics isSequential="false"
flowable:collection="managerList"
flowable:elementVariable="assignee"/>
</userTask>
2. PDF Belgesi Oluştur (generatePdf)
İçerisinde ${variable} yer tutucuları bulunan satır içi (inline) bir HTML şablonundan PDF belgesi oluşturur. Şablon doğrudan BPMN Hizmet Görevinin içine bir <flowable:field> olarak yazılır — harici dosyalara veya şablon yönetimine gerek yoktur.
Girdiler (Alanlar):
| Alan | Gerekli | Açıklama |
|---|---|---|
template |
✅ Evet | ${variable} yer tutucuları içeren satır içi HTML içeriği. Bir <flowable:string><![CDATA[...]]></flowable:string> bloğunun içine yazılır. |
outputVariable |
✅ Evet | Oluşturulan dosya adını tutacak süreç değişkeninin adı. PDF'e sonraki görevlerde başvurmak için kullanılır. |
outputFileName |
❌ İsteğe Bağlı | PDF dosya adının okunabilir kısmı. Varsayılan olarak document'tır. Çakışmaları önlemek için her zaman başa bir UUID öneki eklenir (ör. a8f3b2c1_invoice.pdf). |
Nasıl Çalışır:
- İş akışı tasarımcısı
flowable:delegateExpression="${generatePdf}"içeren bir Hizmet Görevi yerleştirir ve HTML şablonunu satır içi (inline) yazar. - Çalışma zamanında (runtime) temsilci,
templatealanını okur ve süreç değişkenlerini kullanarak basit bir${var}regex (düzenli ifade) değişimi gerçekleştirir. - Flying Saucer, işlenmiş HTML+CSS'i bir PDF bayt akışına (byte stream) dönüştürür.
- PDF, mevcut
StorageServicearacılığıylauploads/{processInstanceId}/{uuid}_{outputFileName}.pdfyoluna kaydedilir. - Oluşturulan dosya adı,
outputVariabletarafından belirtilen isimle bir süreç değişkeni olarak saklanır. - Bir
ProcessAttachmentkaydı oluşturulur, böylece PDF sonraki tüm Kullanıcı Görevleri için otomatik olarak "Süreç Belgeleri" (Process Documents) kartında görünür — form alanına gerek yoktur.
Örnek: Fatura PDF'i Oluşturma
<!-- Step 1: Employee enters invoice data -->
<userTask id="fillData" name="Enter Invoice Details" flowable:assignee="${initiator}">
<extensionElements>
<activiti:formProperty id="itemName" name="Item Name" type="string" required="true"/>
<activiti:formProperty id="price" name="Price" type="double" required="true"/>
<activiti:formProperty id="buyDate" name="Purchase Date" type="date" required="true"/>
</extensionElements>
</userTask>
<!-- Step 2: Generate PDF (automatic, no human interaction) -->
<serviceTask id="genInvoice" flowable:delegateExpression="${generatePdf}">
<extensionElements>
<flowable:field name="outputVariable" stringValue="generatedInvoice"/>
<flowable:field name="outputFileName" stringValue="invoice"/>
<flowable:field name="template">
<flowable:string><![CDATA[
<html><body>
<h1>Invoice</h1>
<p>Item: ${itemName}</p>
<p>Price: ${price} USD</p>
<p>Date: ${buyDate}</p>
</body></html>
]]></flowable:string>
</flowable:field>
</extensionElements>
</serviceTask>
<!-- Step 3: Manager reviews — PDF is automatically visible in the "Process Documents" card -->
<userTask id="reviewInvoice" name="Review Invoice" flowable:candidateGroups="ROLE_MANAGER">
<extensionElements>
<activiti:formProperty id="decision" name="Decision" type="enum" required="true">
<activiti:value id="approve" name="Approve"/>
<activiti:value id="reject" name="Reject"/>
</activiti:formProperty>
</extensionElements>
</userTask>
Otomatik görünürlük: Oluşturulan PDF,
generatePdfHizmet Görevinden sonraki her Kullanıcı Görevinde "Süreç Belgeleri" kartında görünür — herhangi bir form alanına gerek yoktur. Bu, kullanıcı tarafından yüklenen dosyalar için kullanılan desenin aynısıdır.
Şablon formatı: Şablonlar HTML + CSS 2.1'i destekler (Flying Saucer sınırlaması). Görsel eklemek için (örneğin şirket logosu), base64 veri URI'si olarak gömün (
<img src="data:image/png;base64,..." />).
Doğrulama: Bir BPMN,
templatealanı olmadan${generatePdf}kullanırsa, bu bir Hata olarak kabul edilir ve dağıtımı (deployment) engeller.