How to modify/update task property at sharepoint ?

How to modify task list property at sharepoint directly using code ? Pertanyaan ini pasti akan banyak ditanyakan oleh para pemula yang baru saja “nyemplung” ke dalam sharepoint development khususnya workflow. Seperti yang kita ketahui, bahwa kita dapat saja menambahkan field properties pada task list. Tapi kemudian yang menjadi masalahnya adalah bagaimana cara assign valuenya ke dalam field / property yang baru saja kita tambahkan tersebut saat workflow berjalan.

Ok, sebelum kita masuk kedalam, perlu kita samakan persepsi mengenai 2 hal, yaitu :

  1. WorlflowProperties, yaitu properties yang dimiliki oleh workflow terkait list / dokumen yang membuat workflow tersebut berjalan ( trigger to activate workflow ).
  2. TaskProperties, yaitu properties yang dimiliki oleh workflow, dimana workflow di attach. Perubahan nilai / value pada taskproperties akan memicu workflow berjalan ( onTaskChanged -> dst ).

Ok, sekarang mari kita mulai. Biasanya saat kita develop sebuah workflow, workflow tersebut akan di attach pada sebuah dokumen di sharepoint. Jika sebuah dokumen di create, akan memicu workflow untuk create sebuah “task”. Nah, pada task yang dicreate oleh workflow ini, kita dapat menambahkan informasi sesuai dengan keinginan kita.

So, bagaimana caranya menambahkan informasi pada properties di task ? Ok, cara yang paling konvensional adalah dengan menggunakan extendedproperties.

   1: taskproperties.ExtendedProperties["myfield"]="mynewvalue";

Tapi apakah cara ini dapat berjalan ? Untuk properties yang ada pada taskform, assign properties seperti ini adalah benar. Tapi jika yang kita update adalah field dari task list, maka cara ini tidak akan berjalan. Buktikan deh… 😀

So, bagaimana cara seharusnya ? Hmm…. sebenarnya cara yang dipergunakan adalah sedikit tricky. Jika kita ketikkan taskproperties. , maka akan muncul beberapa properties yang bisa secara langsung di assign, seperti Assignee, Description, dll. Tapi tidak dengan field yang ditambahkan secara langsung pada sharepoint. Ah, kelamaan nih, caranya gimana ?????????. Sabar donk mas…. pelan – pelan….

Ok, karena kita tidak dapat update field pada task list secara langsung, maka kita gunakan trick. Caranya, gunakan properties “Description” sebagai wadah untuk transfer. Caranya, perhatikan kode berikut :

   1: taskProperties.Description = string.Format("{0};{1};{2}",
   2:                 workflowProperties.ListId, workflowProperties.Item.UniqueId,"Test Value");

Kode diatas biasanya terdapat pada prosedur OnTaskCreated, kita gunakan untuk assign value ke properties Description pada task. Kemudian buatlah sebuah handler yang akan kita attach pada list. Perhatikan kode berikut :

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using System.Web;
   5: using Microsoft.SharePoint;
   6:  
   7: namespace Workflow.TaskHandler
   8: {
   9:     public class TaskEventHandler : SPItemEventReceiver
  10:     {
  11:         public override void ItemAdded(SPItemEventProperties properties)
  12:         {
  13:             base.ItemAdded(properties);
  14:  
  15:             if (properties.ListItem["Description"] != null &&
  16:                 !string.IsNullOrEmpty(properties.ListItem["Description"].ToString()))
  17:             {
  18:                 string[] descriptionItem = properties.ListItem["Description"].ToString().Split(new char[] {';'});
  19:                 if (descriptionItem.Length > 2)
  20:                 {
  21:                     using (SPWeb web = properties.OpenWeb())
  22:                     {
  23:                         bool webAllowUnsafeUpdates = web.AllowUnsafeUpdates;
  24:                         web.AllowUnsafeUpdates = true;
  25:  
  26:                         if (!descriptionItem[2].Equals(string.Empty))
  27:                         {
  28:                             properties.ListItem["Custom Field"] = descriptionItem[2];
  29:                             properties.ListItem.SystemUpdate();
  30:                         }
  31:                         web.AllowUnsafeUpdates = webAllowUnsafeUpdates;
  32:                     }
  33:                 }
  34:             }
  35:         }
  36:     }
  37: }

Kode diatas adalah sebuah handler yang kita modifikasi dari handler asli dari sharepoint. Kegunaannya adalah untuk mengambil value dari field “Description”, dan assign ke field “Custom Field” yang sudah kita buat pada task. Apakah sudah selesai ? Hm… pada dasarnya sudah. Hanya butuh beberapa langkah kecil, yaitu assign handler yang sudah kita buat ke task, agar pada saat task di create/ add di list, handler ini secara otomatis akan berjalan. Tapi benarkah sudah selesai ??.

Tunggu dulu. hehehe. Ada hal yang harus dipahami, yaitu apabila kita mengupdate properties dari sebuah task di task list yang didalamnya attach sebuah workflow, secara otomatis workflow akan execute OnTaskChanged. Hal ini tidak bisa dibiarkan, karena pada dasarnya kita hanya ingin update properties dari task, tanpa ingin workflow jalan ( kecuali memang diinginkan demikian. Tapi dalam kasus yang saya hadapi, tidak ). So, bagaimana solusinya ??  Ternyata cukup mudah. SPItemEventReceiver ternyata memiliki 2 fungsi yang bisa dipergunakan secara langsung, yaitu : DisabledEventFiring() dan EnableEventFiring(). So, setelah kita tambahkan, kode diatas seharusnya berubah menjadi berikut ini :

   1: base.DisableEventFiring();
   2: properties.ListItem["Default Approver"] = string.Empty;
   3: properties.ListItem.SystemUpdate();
   4: base.EnableEventFiring();

Dengan tambahan 2 baris perintah diatas, dijamin, perubahan pada task properties, selama masih dalam scope yang diinginkan oleh code kita, tidak akan membuat workflow berjalan.

Semoga berguna.

All About Infopath Form Development

Hm, development form menggunakan infopath memang gampang-gampang susah. Gampang, karena semuanya tinggal drag and drop, tanpa perlu coding ( jika perlu ). Susah, karena beberapa dokumentasi, baik yang terkait dengan data binding maupun yang lainnya cukup susah untuk di temukan referensinya.

Mengingat hal tersebut, maka saya tuliskan beberapa pengalaman yang pernah didapatkan saat development aplikasi ( workflow ) di sharepoint yang menggunakan infopath form sebagai UInya.

  1. Binding kedatabase, terutama untuk value decimal, selalu gunakan nilai decimal pada initialisasi awalnya. Percaya atau tidak, hal ini sudah saya buktikan. Jika pada awal koneksi ke database kita set nilainya adalah nilai bulat ( bukan decimal ) maka nanti pada saat bind ke data decimal, nilai yang akan disimpan pada file xmlnya adalah nilai bulat ( pembulatan dari nilai decimal yang di assign ke field ) dan bukan nilai asli seperti yang kita inginkan.
  2. Jika sebuah field pada infopath form di bind pada sebuah field didatabase, selalu gunakan nama field atau alias dari field, yang value-nya langsung diambil dari field pada table. Kasus ini sempat membuat saya bingung, kenapa field yang saya query dari database error waktu di execute di infopath. Usut punya usut, ternyata saat initialisasi awal, nilai yang saya assign adalah nilai absolut ( select "test" as myfield from tbl1 ). So, saat query kita modify menjadi ( select myfield from tbl1 ) akan raise error yang sangat tidak informatif alias susah untuk diketahui sebabnya pada infopath.

Demikian dulu yang bisa saya sampaikan. Semoga berguna buat rekan-rekan yang sedang dalam development menggunakan infopath form. Happy programming.

Bagaimana deploy sharepoint workflow pada load balancing server

Hemm… masalah ini ditemui waktu deploy workflow yang sudah dibuat ke server production client. Gampang-gampang susah ternyata. Topologi servernya seperti berikut ini :

myState Ada 4 server yang berjalan, 3 server sebagai sharepoint server dan 1 lagi sebagai database server, berikut detailnya :

-> 1 Server , running form load balancer services, dan indexing services

-> 2 Server, running web server

So, awalnya sempat bingung, kemana workflow harus diupload ? Usut punya usut, ternyata 3 server web, punya 1 alamat yang sama di client, eg : http://myspserver. So, batch file yang di create cukup point ke nama server tersebut untuk activate workflow. tapi ternyata ada masalah lain, yaitu karena bisa saja request dari client dilayani oleh server yang lain ( yg running web server ), so dll file dari code harus di upload dan diregister ke masing-masing web server. Hmm.. cukup ribet ternyata.

Apakah sudah sukses ? Ternyata belum, masih ada yang belum jalan. Content type form yang di diupload ternyata statusnya masih uploading, dan tidak berubah meski udah ditungguin selama 1 malam. Hikhik. Setelah diusut, ternyata service yang execute untuk upload dan activate content type form belum dijalankan. Mungkin ini masalahnya. Sebab jika kita menggunakan 1 server all in one, service untuk update akan langsung di excute. Uh…. setelah ngejalanin servicesnya, semuanya siap untuk di coba. Alhamdulillah, selesai juga. Sekarang tinggal menunggu feedback dari user. Semoga semua lancar. Amin…