تا قبل از نسخه (15.61) در هر مرحله و در هر وضعیت کار، اگر می خواستیم از عملیات خاص استفاده کنیم، فهرست کل عملیات خاصی که کاربر به آنها دسترسی داشت به نمایش در می آمد. این قضیه شاید به این دلیل بود که طبق تعریف اولیه، فرض می کردیم که عملیات خاص مستقل از وضعیت هستند و لذا باید در تمام وضعیتها امکان دسترسی و اجرا داشته باشند. اما آیا واقعا عملیات خاص مستقل از وضعیتها هستند؟
بررسی ارتباط عملیات خاص با وضعیت کارها
در واقع لزوما اینطور نیست و در عمل به مثالهایی می رسیم که عملیات خاص واقعا به وضعیت و داده های کار وابسته هستند. در واقع تعریف درست تر این است که عملیات خاص مستقل از وضعیت نیستند و بلکه ویژگی اصلی آنها این است که بطور معمول وضعیت را عوض نمی کنند.
توجه کنید که انجام عملیات خاص گاهی به داده های فیلدها و گاهی به وضعیت کار بستگی پیدا می کند البته این به معنی عدم انعطاف عملیات خاص نیست بلکه به معنی نسبی بودن استقلال از وضعیت است لذا همچنان این عملیات را می توانیم در وضعیتهای متعدد اجرا و یا تکرار کنیم. برای روشن تر شدن موضوع، در این زمینه به چند مثال توجه کنید:
مثال 1: فرض کنید در گردش کار فروش کالا، یک عملیات خاص برای تغییر قیمت کالا وجود دارد. حال آیا مدیر فروش در هر وضعیتی می تواند قیمت را تغییر دهد؟ واضح است که اینطور نیست و در واقع از وضعیت تایید قیمت پیش فاکتور توسط خریدار تا قبل از صدور فاکتور می تواند قیمت را به هر دلیل ویرایش کند. بنابراین پیش از تایید پیش فاکتور و پس از صدور فاکتور، این عملیات خاص کاربردی ندارد.
مثال 2: در یک گردش کار تامین کالاها، یک عملیات خاص برای استعلام قیمت کالاها طراحی شده است. واضح است که استعلام قیمت باید پس از درخواست کالا و تایید مدیر انجام شود و قبل از آن بی معنی است و کاربردی ندارد.
مثال 3: در یک گردش کار مدیریت وامها، یک عملیات خاص برای کسب تکلیف از مدیر پیش بینی شده است. حال فرض کنید اگر مبلغ درخواستی کمتر از مثلا 5 ملیون تومان بود دیگر لازم به کسب تکلیف نیست و لذا در اینجا این عملیات خاص کاربردی ندارد.
مثال 4: در گردش کار تامین نیروی انسانی، فرض کنید یک عملیات خاص از نوع اطلاع از وضعیت کار تعریف شده است. حال فرض کنید مدیر می خواهد از وضعیت متقاضیان استخدام مطلع شود، بدیهی است که قبل از بررسیها و مصاحبه های اولیه وضعیت متقاضیان کاربردی برای مدیر ندارد و از وضعیت بعد از مصاحبه و تایید کارشناسان است که مدیر نیاز و انگیزه به دیدن وضعیت کار دارد.
تا اینجا مثالهایی که زده شد به نوعی استاتیک هستند یعنی مدل و الگوی نمایش عملیات خاص تا حدود زیادی مشخص است اما مثالهای پویا و دینامیک نیز وجود دارد و این زمانی است که کاربر قرار است چند عملیات خاص را در یک وضعیت انجام دهد و قرار است هر کدام را که انجام داد از فهرست عملیات خاص خارج شود.
مثال 5: در گردش کار تامین نیروی انسانی، فرض کنید که یک زیرگردش برای عملیات «مصاحبه و گزینش متقاضیان» وجود دارد که مراحل زیر برای متقاضیان انجام می شود:
- مصاحبه عمومی
- مصاحبه فنی
- مصاحبه های تکمیلی
- اعلام قبول شدگان نهایی
حال فرض کنید که مدیر منابع انسانی سازمان در یک وضعیت خاص از گردش کار «تامین نیروی انسانی» چند عملیات خاص برای اطلاع از وضعیت کار داشته باشد. برای مثال به عملیات خاص زیر توجه کنید:

بدیهی است که در هر مرحله از زیر گردش کار «مصاحبه و گزینش متقاضیان» یکی از فهرست های بالا معنی دار است و مدیر منابع انسانی باید فهرست متناسب با آن مرحله را ملاحظه کند. برای مثال اگر مصاحبه ها آغاز نشده باشد تنها عملیات خاص شماره 1 (ملاحظه فهرست متقاضیان) معنی دار است و اگر تعدادی از متقاضیان برای مرحله مصاحبه فنی انتخاب شده اند، تنها عملیات خاص شماره 2 (ملاحظه فهرست متقاضیان در حال مصاحبه فنی) مناسب است و به همین ترتیب تا آخرین مرحله گزینش که قبول شدگان نهایی اعلام می شود تنها عملیات خاص شماره 5 (ملاحظه فهرست قبول شدگان نهایی) کاربرد پیدا می کند.
بنابراین به نظر می رسد باید راه حلی پیدا کنیم تا در تمام وضعیتها، تمام عملیات خاص نمایش داده نشود چرا که باعث سردرگمی و گاهی اشتباه سهوی کاربر می گردد. بلکه باید عملیات خاصی را که در این وضعیت و با این داده ها مناسب است نمایش دهیم.
پالایش فهرست عملیات خاص
راه حلی که در سیستم مدیریت فرایندهای نوسا پیاده سازی شده است این است که در چنین مواردی در هر وضعیت گردش کار، عملیات خاص منتخب و مورد نیاز آن وضعیت نمایش داده شود و بقیه عملیات خاص به نوعی مخفی (Hide) شود.
تابع نمایش عملیات خاص
برای این کار از تابع GetVisibleActionList با مشخصات زیر استفاده می کنیم.
function GetVisibleActionList: String
این تابع از نوع توابع ثابت است و هر زمان که کلاینت درخواست فهرست عملیات خاص را به سرور می فرستد، این تابع صدا زده (Call) می شود. اگر این تابع تعریف نشده باشد، مانند حالت کلاسیک تمام عملیات خاصی که کاربر به آنها دسترسی دارد نمایش داده می شود. اما اگر بخواهید در وضعیتهای خاص یا محتوای معینی از فیلدها، بعضی از عملیات خاص را نمایش دهید آنگاه باید یک رشته حرفی از کدهای عملیات خاص مورد نظر با جداکننده کاما در خروجی این تابع قرار دهید. به مثال زیر توجه کنید:
function GetVisibleActionList( ) {
return "1, 3"
}
در این مثال، دو عملیات خاص با کدهای 1 و 3 قابل نمایش است و موارد دیگر نمایش داده نمی شود. البته این مثال فقط برای توضیح فرمت این تابع است و واضح است که در عالم واقع چنین مثالی معنی ندارد. بلکه در واقعیت، فهرست عملیات خاص، بر اساس مقادیر فیلدها و وضعیت کارها تعیین و انتخاب می شود.
تعیین شرط برای نمایش عملیات خاص
تا پیش از این، نمایش عملیات خاص تنها بر اساس کاربر و مجاز بودن دسترسی او محدود می شد. اما از این به بعد، می توانیم از طریق تعیین شرط هم می توانیم نمایش عملیات خاص را مدیریت کنیم. تعیین شرط هم می تواند براساس مقدار یک فیلد خاص باشد و هم بر مبنای قرار گرفتن کار در یک وضعیت (status) خاص. به عبارت بهتر، ویژگیهای موجود WorkState در هر کار، می تواند تعیین کننده انتخاب عملیات خاص مناسب برای نمایش باشد. به دو مثال در این زمینه توجه کنید:
مثال 1: براساس محتوای فیلدها
فرض کنید در گردش کار «تامین کالاها» ، سه عملیات خاص به ترتیب زیر وجود دارد:
- ملاحظه موجودی کالا در انبار
- ثبت برگه خروج کالا از انبار
- درخواست خرید کالا
در این گردش کار، ابتدا یک کاربر کالایی را درخواست می کند و این درخواست به دست مسئول انبار می رسد. حال مسئول انبار باید ابتدا موجودی کالا را در انبار چک کند، بنابراین در این مرحله فقط عملیات خاص 1 معنی دار است و باید نمایش داده شود. حال با توجه به محتوای فیلد موجودی کالا، اگر کالا موجود باشد آنگاه عملیات خاص 2 را اجرا می کند و برگه خروج از انبار را صادر می کند و کالا را به درخواست کننده تحویل می دهد. در غیر این صورت اگر موجود صفر باشد آنگاه عملیات خاص 3 را اجرا می کند و درخواست خرید کالا را به تدارکات ارسال می کند.
حال اگر نام فیلد موجودی کالا در انبار stock باشد آنگاه تابع محدود کردن نمایش عملیات خاص به شکل زیر خواهد بود:
function GetVisibleActionList() {
var selectedOpCode="1";
if (WorkState.stock==0) {
selectedOpCode="3";
} else if (WorkState.stock>0) {
selectedOpCode="2";
}
return selectedOpCode;
}
مثال 2: بر اساس یک وضعیت خاص
فرض کنید در گردش کار «مدیریت همایشها» کاربران شرکت کننده در همایش می توانند دو عملیات خاص زیر را انجام دهند:
- ملاحظه وضعیت کار
- چاپ گواهی شرکت در همایش به فرمت WORD
در این گردش کار، هر شرکت کننده در همایش تا قبل از برگزاری همایش باید بتواند وضعیت درخواست خود را ملاحظه کند. مثلا این که آیا ثبت نام او انجام شده است یا این که کارت شرکت در همایش برای او صادر شده است یا نه و .... و در انتها یک وضعیت به نام «همایش برگزار شده» وجود دارد که در این وضعیت، باید بتواند با استفاده از عملیات خاص 2، گواهی شرکت در همایش را چاپ کند، بدیهی است که تا قبل از این وضعیت (اتمام همایش) استفاده از عملیات خاص 2، بدون کاربرد و بی معنی است. بنابراین در این مثال، تابع محدود کردن نمایش عملیات خاص می تواند به شکل زیر باشد:
function GetVisibleActionList() {
var selectedOpCode="1";
var wfKey=WorkState.WorkflowKey;
var stKey=WorkUtils.GetWorkStatusKeyByCode(wfKey, 12);
if (WorkState.CurStatusKey==stKey) {
selectedOpCode="1, 2";
}
return selectedOpCode;
}
در این مثال فرض شده است که کد وضعیت «همایش برگزار شده» برابر با 12 است. مطابق شرطی که در این تابع تعیین شده است، تا قبل از اتمام همایش، کاربران شرکت کننده فقط عملیات خاص 1 (ملاحظه وضعیت کار) را مشاهده خواهند کرد و به محضی که کار در وضعیت «همایش برگزار شده» قرار گرفت، آنگاه می توانند عملیات خاص 2 (چاپ گواهی شرکت در همایش) را نیز مشاهده و استفاده کنند.
ضمیمه: گروه بندی عملیات خاص
احتمالا در گردش کارهایی که با تعداد زیادی از عملیات خاص روبرو شده اید نیاز به نوعی دسته بندی برای این عملیات را حس کرده اید. بخصوص در مواردی که نوعی تشابه ماهیتی میان تعدادی از عملیات خاص وجود داشته باشد این نیاز بیشتر حس می شود. به عنوان مثال به فهرست عملیات خاص گردش کار «تامین کالاها» توجه کنید:

ملاحظه می کنید که اولا تعداد عملیات خاص زیاد است و ثانیا عملیاتهای خاص با ماهیت مشابه نیز وجود دارد. برای مثال تعدادی از عملیاتهای خاص به امور مربوط به قیمت گذاری و تخفیف و ... مرتبط است (که در شکل بالا با خط قرمز مشخص شده است) و تعدادی از عملیاتها در واقع نوعی ملاحظه وضعیت و گزارشگیری است. نکته دیگر این است که با توجه به اینکه ترتیب سطرها نیز براساس کد عملیات است لذا عملیاتهای خاص با ماهیت مشابه، در کنار هم قرار نگرفته است و به همین دلیل پیدا کردن عملیات خاص مورد نظر کاربر از این فهرست، در مواردی دشوار خواهد بود.
برای حل این مشکل و راحت تر شدن دستیابی به عملیاتهای خاص مورد نظر، امکان جدیدی به سیستم مدیریت فرایندها افزوده شده است که از طریق آن می توانیم عملیات خاص را با توجه به ماهیت آنها گروه بندی کنیم.

ملاحظه می کنید که ستون جدیدی به نام «گروه» به محاوره تعریف عملیات خاص اضافه شده است که می توانیم از این طریق به هر عملیات خاص، یک گروه مناسب را اختصاص دهیم. برای مثال در شکل بالا یک گروه به نام «مرتبط با قیمت کالا» را مشاهده می کنید که به عملیاتهای خاص با ماهیت قیمت اختصاص داده شده است. ضمنا برای عملیاتهای دیگر نیز گروه های مناسبی تعیین شده است. در هر صورت پس از گروه بندی، مشاهده عملیات خاص به شکل زیر خواهد بود:

نمایش این گروه بندی در کلاینت وب به شکل زیر است:

همانطور که می بینید، عملیاتهای خاص به شکل منظم و گروه بندی شده نمایش داده شده است. واضح است که این رابط کاربری، تجربه بسیار بهتری را برای کاربر به همراه خواهد داشت.