در جریان عادی گردش کار، ممکن است کار در بعضی از وضعیتها بطور موقت در حالت توقف یا انتظار قرار بگیرد، این مورد در وضعیتهای عادی و وضعیتهای تصمیم گیر دارای تاخیر به وجود می آید. در این وضعیتها بعضی از وظایف، توسط سیستم و بطور خودکار انجام می شود و بعضی از وظایف، توسط یک عامل انسانی انجام می شود. در حالت معمول و در وضعیتهای تصمیم گیر باید منتظر اتمام زمان تاخیر باشیم تا در انتها وظیفه مورد نظر بر حسب شرایط تعیین شده اجرا شود، در وضعیتهای عادی نیز انجام وظیفه وابسته به تصمیم کاربر است و تا زمانی که کاربر تصمیم به انجام وظیفه نگرفته است، کار متوقف می ماند. به همین خاطر از زمانی که کار در یک وضعیت قرار می گیرد تا زمان انجام وظیفه بعدی، یک فاصله (Gap) زمانی به وجود می آید، حال ممکن است در شرایط خاصی و به دلایل متعدد مدیریتی، بخواهیم این گپ زمانی را از بین ببریم و از این طریق کنترل گردش کار را به دست بگیریم و وظیفه مورد نظر خود را اجرا کنیم یا این که جریان عادی گردش کار را تغییر بدهیم. برخی از این دلایل به شرح زیر است:
- جلوگیری از رسوب کار در گلوگاههای گردش کار
- تصمیمهای لحظه ای مدیریت برای تغییر روند گردش کار
برای کنترل جریان گردش کار، روشهای مختلفی وجود دارد که در ادامه به آن می پردازیم
انواع کنترل جریان گردش کار
دو نوع کنترل در جریان گردش کار قابل تصور است. اگر الگوی کنترل از قبل معلوم باشد کنترل سیستماتیک است و اگر لحظه ای، متغیر و غیرقابل پیش بینی باشد، از نوع کنترل نامنظم می باشد. در ادامه این مفاهیم را بیشتر توضیح می دهیم.
کنترل سیستماتیک
این نوع از کنترل ها دارای الگو و طرح معین و قابل پیش بینی هستند. این نوع از کنترل به روشهای زیر انجام می شود:
- بیدار کردن دستی کارها: در نوار ابزار محاوره فهرست کارها، آیکونی وجود دارد که کاربر می تواند به شکل دستی آن را کلیک کند و کار مورد نظر خود را از حالت تاخیر یا انتظار بیرون آورد.
- وضعیتهای دیده بان (Watch Dog) : در این وضعیتها کاملا رفتار سیستم و گردش کار تعیین شده و مشخص است. اگر کاربر تا زمان خاصی وظیفه مورد نظر را انجام ندهد، گردش کار به شکل خودکار و در مسیری که تعیین شده است، به جریان می افتد.
- ارسال پیام (message) و رخداد (event): در این روش، یک گردش کار مدیریتی، پیامی حاوی پارامترهای مورد نیاز را به گردش کار مقصد ارسال می کند و براساس الگوی موجود در تابع WorkProcessMessage مقادیر فیلدها را ویرایش می کند یا اینکه باعث تغییر مسیر (وضعیت) سیستم می گردد.
کنترل نامنظم :دستور ادامه کار (ContinueWork)
این نوع از کنترل، فاقد الگو و پیش بینی نشده است. در این حالت نیز، کنترل توسط یک گردش مدیریتی انجام می شود. نحوه این کنترل به این شکل است که در وضعیتی که کار در کارتابل یک کاربر است، منتظر تصمیم کاربر نمی ماند واز طریق تابعContinueWork دستور ادامه کار را به گردش کار صادر می کند. از طریق این دستور، مشخص می شود که اولا کدام وظیفه خروجی از وضعیت فعلی باید انجام شود و ثانیا مقادیر فیلدها در اثر انجام این وظیفه چقدر تغییر خواهد کرد.
در وضعیتهای تصمیم گیر دارای تاخیر نیز با استفاده از این تابع می توانیم کار را بیدار کنیم و وظیفه مورد نظر خود را اجرا کنیم. نکته مهم در اینجا این است که در این وضعیتها، مدیر می تواند اولویت و شرایط تعیین شده برای انجام عادی وظایف را کنار بگذارد و وظیفه مورد نظر خود را اجرا نماید.
ویژگیهای انواع کنترل در گردش کار
کنترل سیستماتیک
- روشهای دیده بان و ارسال پیام، روش مبتنی بر check pending است و بنابراین اجرای آن به صورت دقیق در دست ما نیست. به عبارت دیگر در گردش کارهای کنترلی مبتنی بر محاسبه دقیق زمان، استفاده از این روش مناسب نیست.
- روش ارسال پیام مستقل از وضعیت فعلی کار است. به این معنی که کافی است یک کاربر اختیار اجرای تابع WorkSendMessage را داشته باشد. حال با این تابع می تواند، هر داده ای را ارسال و هر فیلدی را ویرایش کند. ضمنا با این روش امکان تغییر مسیر به هر وضعیت دلخواه (مستقل از وضعیت فعلی کار) وجود دارد. بدیهی است که امنیت داده ها در این روش پایین است و امکان تغییرات ناخواسته وجود دارد.
- در این روش در وضعیتهای با چند خروجی باید برای هر وضعیت مقصد یک وضعیت دریافت پیام جداگانه ایجاد کنیم برای نمونه به دیاگرام زیر توجه کنید:
در یک گردش کار درخواست وام ضروری، و در وضعیت "در انتظار بررسی امور مالی" که با رنگ سبز مشخص است، سه وظیفه خروجی وجود دارد که با رنگ قرمز نمایش داده شده است. حال اگر بخواهیم از روش ارسال پیام برای انتخاب یکی از خروجی ها استفاده کنیم آنگاه باید سه وضعیت دریافت پیام که با رنگ زرد مشخص شده است داشته باشیم. ملاحظه می کنید که این روش دیاگرام را شلوغ و پیچیده می کند.
- در این روش، هر گونه تغییر در سیاستهای کنترلی باید در گردش کار مقصد، اعمال شود. یعنی این که باید در دیاگرام و برنامه این گردش کار (مثلا در تابع WorkProcessMessage) ویرایش های مورد نظر انجام شود. به این ترتیب، بدیهی است که تغییرات مکرر در طراحی گردش کار، آن را از یکدستی خارج ساخته و احتمال بروز خطاهای ناخواسته را بالا می برد. ضمن این که ممکن است به دلیل وجود کارهای باز، بعضی از این تغییرات امکان نداشته یا اینکه در کارهای باز تولید اشکال نماید.
اصل 1: هر گاه منطق کنترل در مقصد طراحی شود از روش کنترل منظم استفاده می کنیم. به عبارت دیگر وقتی می خواهیم تاثیر کنترلها به شکل کاملا برنامه ریزی شده و در مقصد پیش بینی شده باشد از این روش استفاده می کنیم. در این حالت، شخص کنترل کننده (مثلا مدیر)، امکان تغییر منطق تجاری را ندارد و تنها می تواند پیامی را منطبق با منطق تجاری ارسال نماید. ضمنا در این روش امکان اعمال سلیقه های متعدد توسط کنترل کننده های متعدد وجود ندارد چون قواعد تجاری در مقصد طراحی شده است.
کنترل نامنظم (ContinueWork)
- این روش وظیفه را به شکل آنی انجام می دهد و وابسته به check pending نیست بنابراین در مواردی که نیاز داریم وظیفه مورد نظر بدون تاخیر و فوری انجام شود باید از این روش استفاده کنیم.
- این روش کاملا وابسته به وضعیت فعلی کار است. یعنی فقط در حالتی که کار در یک وضعیت خاص باشد کار می کند و فقط فیلدهایی قابل ویرایش در فرم خاص وظیفه امکان مقدار دهی دارند و لذا امنیت داده ها در این روش بالاتر است.
- در این روش، انتخاب و انجام وظیفه مورد نظر در وضعیتهای با خروجی های متعدد نیز براحتی انجام می شود و نیازی به ویرایش دیاگرام و برنامه گردش کار وجود ندارد.
- در این روش، تغییر سیاستهای کنترلی و مدیریتی هیچ تاثیری در طراحی گردش کار مقصد ندارد. به عبارت دیگر گردش کار مقصد مستقل از گردش کار کنترلی است و هرگونه تغییرات لازم در سیاستها و تصمیمهای مدیریتی در گردش کار کنترلی اعمال می شود.
اصل 2: هرگاه بخواهیم منطق کنترل را در گردش کار مبدا اعمال کنیم آنگاه از روش کنترل نامنظم استفاده می کنیم. در این روش گردش کار مقصد دست نمی خورد و تمام قواعد تجاری در گردش کار مبدا اعمال می شود. در این روش کاربر کنترل کننده، امکان هرگونه تغییر در منطق تجاری را دارد و کاربران متعدد می توانند برحسب شرایط، کنترلهای متنوعی را در گردش کار مقصد اعمال نمایند.
سوال برای تفکر بیشتر: به نظر شما کدامیک از روشهای کنترل جریان گردش کار مزیت بیشتری دارد؟ در چه شرایطی بهتر است از روش کنترل سیستماتیک و در چه شرایطی بهتر است از روش کنترل نامنظم استفاده کنیم؟
حال که با ویژگیها و کارکردهای "ادامه کار" آشنا شدیم بهتر است با جزئیات تابع ادامه کار (ContiueWork) را به شکل دقیق تری آشنا شویم.
دستور ادامه کار از طریق تابع ContinueWork
برای شرح کارکرد این تابع ابتدا نگاهی به الگوی این تابع بیندازیم:
function ContinueWork(dbName, data)
این تابع، یک وظیفه معین را در یک کار در پایگاه dbName با مشخصاتی که توسط پارامتر data بیان میشود انجام میدهد. بدیهی است این وظیفه باید یکی از وظیفههای مجاز در وضعیت فعلی کار باشد. data یک XML با ساختار زیر است:
ملاحظه می کنید که در این xml مشخص می شود که کدام وظیفه (با کد یا کلید وظیفه) در کدام کار (با کلید کار تعیین شده) باید انجام شود. و ضمنا مقادیر فیلدهای موجود در فرم خاص این وظیفه نیز تعیین شده است.
نکته 1: مقدار خالی برای dbName عملیات را در پایگاه جاری انجام میدهد.
نکته 2: برای اجرای موفق این تابع لازم است UserName و Password مناسب قبلا تعیین شده باشند.
نکته 3: اگر وظیفه تعیین نشده باشد و وضعیت فعلی کار تنها یک وظیفه خروجی داشته باشد همان وظیفه انجام خواهد شد.
مثال: تعیین تکلیف درخواستهای وام ضروری
فرض کنید در گردش کار درخواست وام ضروری، چندین کار باز در وضعیت در انتظار بررسی امور مالی وجود دارد:
حال فرض کنید مدیر عامل به دلایل مختلف مثلا غیبت مدیر امور مالی، نیاز به تسویه حساب فوری و .... تصمیم می گیرد تکلیف تمام درخواستهای باز را مشخص کند. به این شکل که :
- درخواستهای کارمندان با کمتر از 3 سال سابقه کار و مبلغ بیشتر از 10 ملیون تومان لغو شود.
- برای کارمندان دیگر، درخواستهای کمتر از 5 ملیون تایید و درخواستهای بیش از این مبلغ به 5 ملیون تومان کاهش یابد.
برای این کار مدیر می تواند در یک گردش کار کنترلی ، از تابع اجرایی زیر استفاده کند:
حال طبق روال گذشته، بخشهای اصلی این تابع را توضیح می دهیم
در ابتدا کارهای باز گردش کار "درخواست وام ضروری" را جستجو می کنیم. کد این گردش کار 5111 است و چون برای مشخصه Status مقداری تعیین نکرده ایم، لذا فقط کارهای فعال بازیابی می شود. در اینجا متغیر res شامل کلیدکارهای باز می باشد.
از آنجایی که ادامه کارها براساس مقدار فیلدهای کارها انتخاب می شود لذا ما باید حالت کارها (WorkState) را در وضعیت فعلی داشته باشیم. برای اقدام روی تمام کارها، از یک حلقه for استفاده شده است که به تعداد کلید کارهای متغیر res تکرار می شود.
چون در تابع ContinueWork نیاز به کلید گردش کار داریم در این سطر، کلید گردش کار را در متغیر wfKey قرار می دهیم.
چون قصد داریم در وضعیت "در انتظار بررسی امور مالی" ادامه کار را اجرا کنیم لذا به کلید این وضعیت نیاز داریم که در اینجا در متغیر stKey ذخیره می کنیم.
در اینجا متغیر xml لازم برای سه وظیفه خروجی از وضعیت "در انتظار بررسی امور مالی" تعریف شده است. برای یادآوری این وظایف به شکل زیر توجه کنید:
با توجه به محتوای متفاوت task3 با task1 و task2 در اینجا وظایف را به تفکیک بررسی می کنیم:
ملاحظه می کنید که برای وظایف "لغو درخواست (کد 4)" و "تایید و دستور پرداخت (کد 5) " این پارامتر به شکل ساده و بدون مقداردهی فیلدها تعریف شده است:
اما برای وظیفه "تغییر مبلغ وام (کد 6) " مقدار فیلد مبلغ تایید شده وام تغییر می کند و مبلغ ثابت 5 ملیون تومان در این فیلد وارد می شود.
در این مرحله، ابتدا چک می شود که وضعیت فعلی کار (ws.CurStatsKey) همان وضعیت "در انتظار بررسی امور مالی " باشد. سپس شرط سابقه کار (ws.workYears) بیشتر از 3 سال و مبلغ درخواستی (ws.reqAmount)کمتر از 10 ملیون تومان اعمال می شود و در غیر این صورت task1 (لغو درخواست) اجرا می شود. در صورت معتبر بودن درخواست، برای مبالغ درخواستی مساوی یا کمتر از 5 ملیون تومان وظیفه task2(تایید و دستور پرداخت) اجرا می شود و برای مبالغ بیش از این، با اجرای task3(تغییر مبلغ وام)، مبلغ وام تایید شده به 5 ملیون تومان کاهش می یابد.
با اجرای این تابع، فهرست کارهای درخواست وام ضروری به شکل زیر تغییر می کند:
ملاحظه می کنید که از میان 9 درخواست، 5 درخواست به دلیل نداشتن شرایط لازم لغو شده است. 3 درخواست تایید شده است و تنها 1 درخواست تغییر یافته است.