BPMS یا SHAREPOINT ?

اگر شما هم جزو کسانی هستید که به دنبال راهکار برای مکانیزاسیون فرایندهای سازمان هستند به احتمال قوی این سوال برایتان پیش آمده که sharepoint و BPMS چه تفاوتی با هم دارند؟ در واقع منشا اصلی این سوال در اینجاست که سیستم های گردش کار وسیستم مدیریت فرایند کسب و کار چه تفاوتی با هم دارند؟

بنابر این مسئله ابتدا به تعریف جریان کار و تفاوت آن با راهکارهای BPM می پردازیم.

جریان کار: به یکسری فعالیت‌ها و وظایفی که طی یکسری مراحل از پیش تعیین شده گویند. که شامل گروه محدودی از افراد و یا نرم‌افزارهای مربوطه می باشد.
ولی

راهکار BPM: یک راهکار ساختار یافته‌­ای از روش­ها، سیاست­ها، معیارها و ابزارهای نرم­ افزاری جهت مدیریت و بهینه ­سازی مستمر فعالیت­ها و فرآیندهای یک سازمان می­باشد.
حال که کمی بیشتر با مفهوم جریان کار و راهکار BPM آشنا شدیم راحتتر میتوایم تفاوت Sharepoint و BPMS را درک کنیم. به طور خلاصه Sharepoint یک راهکار ساده برای مکانیزه کردن  فرایندهای ساده از جمله منابع انسانیست و نمی تواند به خوبی ارتباط بین فرایندهای دپارتمان‌های مختلف را برقرار کند اینجاست که یکی از تمایزهای آن با BPMS مشخص میشود چراکه BPMS می تواند به راحتی بین فرایند‌های سازمان در دپارتمان‌های مختلف ارتباط برقرار کند و یک یکپارچگی کامل را برای سازمان به ارمغان آورد.

آیا SHAREPOINT و BPMمی­توانند باهم کار کنند؟
بله. اگر شما تا آلان از SharePoint استفاده میکردید یک نکته‌ی خیلی خوب است و این کار خود به بلوغ سازمان شما برای حرکت به سمت BPM کمک میکند. شما می‌توانید در کنار BPM از SharePoint هم استفاده کنید و کم کم فرایندها و فعالیت‌های خود را از SharePoint به سمت BPM هدایت کنید تا بعد از مدت کوتاهی تمام فرایند‌های کسب و کار سازمان شما روی یک راهکار BPMS واقعی اجرا شود. از فواید این کار می‌توان به یکپارچگی بیشتر سازمان و مدیریت راحتتر و دقیقتر کارهای در یک بستر نرم افزاری اشاره کرد.

معرفی مدیران سیستم

جامعه مجازی مدیران سیستم با هدف تسهیل در ارتباطات و مدیریت چرخه های پیچیده طراحی و پیاده سازی شده است.این جامعه مجازی امکانات زیر را برای افرادی که عضو آن میشوند بصورت کاملا رایگان فراهم می آورد :

مکانیزم ساماندهی مکاتبات

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

 مدیریت ساختارها

 با کمی تغییر در ماهیت چارت سازمانی توانستم آن را طوری طراحی نمایم که کاربر بتواند خود را در ساختاری خود ساخته یا ساختاری که توسط دیگری ساخته شده قراردهد ) 

 همکاری

در این سامانه در صورت نیاز شما می توانید از یک سامانه کامل ثبت نام و گزارش گیری کامل بهره بگیرد – اگر جویای همکاران جدیدی هستید راه کاری کامل در سامانه طراحی شده است 

اسناد صادره و اسناد وارد

( در صورتی که سند ء بسته یا نامه ای به بیرون از سامانه صادر می کنید یا از بیرون وارد سامانه می کنید ء راه کاری کامل با فایل ساز و تمپلیت ساز برای کاربران در نظر گرفته شده است )

دبیرخانه ها

هر کاربر می تواند عضو یک تا چند دبیرخانه باشد ء منظور از دبیرخانه مرکزیست که کار کنترل بر اسناد را انجام میدهد

قابلیت ها

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

Djangular

یکی از دغدغه های من آوردن AngularJS به Django بوده و این موضوع کاملا با Djangular پوشش داده میشه :)))

مراحل کار :

pip install django-angular
INSTALLED_APPS = (
    ...
    'djangular',
    ...
)

STATIC_ROOT and STATIC_URL فراموش نشود و سپس جرای دستور :

python manage.py collectstatic

دستور بالا مسیر استاتیک را با فایل های مورد نیاز دیجنگولار بروز رسانی میکند یعنی باید مسیر مورد نظر مجوز ویرایش را داشته باشد هاا

البته دیجانگولار هیچ مدل داده ای ندارد و بدون تغییرات بانک اطلاعاتی می تواند عملیات خود را ادامه دهد

 Integrate AngularJS with Django

XMLHttpRequest

معمولا در وب سایت ها درخواست های آژادکسی هدر خود را بصورت زیر ارسال میکنند :

X-Requested-With: XMLHttpRequest

این هدر است که به دیجانگو امکان میدهد تا بفهمد :

request.is_ajax()

حالا برای اینکه این امکان رو فراهم کنیم کافیگ زیر را برای appمون منویسیم

var my_app = angular.module('MyApp').config(function($httpProvider) {
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

 Template tags

برای اینکه تگ های آنگولار با تگ های دیجاگو گیژ نزنن کد زیر رو میزنیم :

var my_app = angular.module('MyApp').config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
});

راستی این رو هم اضافه کنید :

<script src="{% static 'djangular/js/django-angular.min.js' %}" type="text/javascript"></script>

و سپس :

var my_app = angular.module('myApp', [/* other dependencies */, 'ng.django.forms']);

حالا تو لینک زیر یه مثال خوب هست که بهش توجه کنیم :

https://github.com/jrief/django-angular/tree/master/examples

Integrate a Django form with an AngularJS model

هر گاه می خواهیم forms.Form رو ببریم بسمت AngularJS Env برای ما لازم است که به یک صفحه ی رندر شده ی AngularJSی دسترسی پیدا کنیم

ng-model="model_name"

where model_name corresponds to the named field from the declared form class. :)))

کد نمونه :

در نظر بگیریم که یک کلاس فرم ساده دیجانگو داریم که از یک فرم ورود متن ساده تشکیل شده است و ما می خواهیم دهنش رو با آوردن به djangularjs کلاس NgModelFormMixin سرویس کنیم

from django import forms
from django.utils import six
from djangular.forms import NgDeclarativeFieldsMetaclass, NgModelFormMixin

class ContactForm(six.with_metaclass(NgDeclarativeFieldsMetaclass, NgModelFormMixin, forms.Form)):
    subject = forms.CharField()
    # more fields ...

در مثال بالا همونطور که معلومه فرم ما از دیجانگو فرم برگفته شده است و در عوض میشه اینطوری هم نوشتش :

from djangular.forms import NgModelFormMixin, NgForm

class MyValidatedForm(NgModelFormMixin, NgForm):
    # members as above

و همینطور اینگونه :

from djangular.forms import NgModelFormMixin, NgModelForm

class MyValidatedForm(NgModelFormMixin, NgModelForm):
    class Meta:
         model = Article

    # fields as usual

حالا آبجکت های اینطوری رندر میشن :

<input id="id_subject" type="text" name="subject" ng-model="subject" />

حالا یه مثال کامل :

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

from django.views.generic import TemplateView

class ContactFormView(TemplateView):
    template = 'contact.html'

    def get_context_data(self, **kwargs):
        context = super(ContactFormView, self).get_context_data(**kwargs)
        context.update(contact_form=ContactForm())
        return context

و حالا تمپلیت contact.html

<form ng-controller="MyFormCtrl" name="contact_form">
    {{contact_form}}
    <button ng-click="submit()">Submit</button>
</form>

یه کمی هم جاوا اسکریپت قاطیش می کنیم :

my_app.controller('MyFormCtrl', function($scope, $http) {
    $scope.submit = function() {
        var in_data = { subject: $scope.subject };
        $http.post('/url/of/your/contact_form_view', in_data)
            .success(function(out_data) {
                // do something
            });
    }
});

و اما اینکه <form> نیازی به method or action نداره و از طریق success کنترلر ارسال میشه و تمام ابعاد قضیه رو شامل ارسال و پاسخ رو در نظر میگیره مثل ارسال ارورهای اعتبارسنجی شده و …

به طور معمول form view میبایست داده های پست شده رو از طریق POST دریافت کنه در حالی که AngularJS دیتا رو از طریق multipart/form-data or application/x-www-form-urlencoded نمی تونه ارسال کنه البته به خاطر یه سری مسایل دیکودینگ هااا

برای جواب داده به فرم هم بهتره از کد زیر استفاده بشه :

import json
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseBadRequest

class ContactFormView(TemplateView):
    # use ‘get_context_data()’ from above

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(ContactFormView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        if not request.is_ajax():
            return HttpResponseBadRequest('Expected an XMLHttpRequest')
        in_data = json.loads(request.body)
        bound_contact_form = CheckoutForm(data={'subject': in_data.get('subject')})
        # now validate ‘bound_contact_form’ and use it as in normal Django

در مثال بالا csrf_exempt رو زدیم ها ولی بکار نبریدش کلا یعنی همیشه از امنیتش استفاده کنید

Prefixing the form fields

The problem with this implementation, is that one must remember to access each form field three times. Once in the declaration of the form, once in the Ajax handler of the AngularJS controller, and once in the post handler of the view. This make maintenance hard and is a violation of the DRY principle. Therefore it makes sense to add a prefix to the model names. One possibility would be to add the argument scope_prefix on each form’s instantiation, ie.:

متن بالا رو نمی تونم ترجمه کنم خدتون بخونید بهتره

حالا برای اینکه مشکل متن بالا پیش نیاد بهتره از prefixاستفاده کنیم

class ContactForm(NgModelFormMixin, forms.Form):
    # declare form fields

    def __init__(self, *args, **kwargs):
        kwargs.update(scope_prefix='my_prefix')
        super(ContactForm, self).__init__(*args, **kwargs)

حالا خروجی تو آنگولار به شکل زیر میشه میشه :

<input id="id_subject" type="text" name="subject" ng-model="my_prefix.subject" />

این بالاییه حالا میتونه ارسال آزاکسی رو راحتتر کنه برای اینکه هر ارسال بروی یک آبجکت جاوا اسکریپتی انجام میشه :)) و میشه اون رو بصورت  scope.my_prefix ارسال نمود

$http.post('/url/of/contact_form_view', $scope.my_prefix)

Validate Django forms using AngularJS

NgFormValidationMixin

from django import forms
from django.utils import six
from djangular.forms import NgDeclarativeFieldsMetaclass, NgFormValidationMixin

class MyValidatedForm(six.with_metaclass(NgDeclarativeFieldsMetaclass, NgFormValidationMixin, forms.Form)):
    form_name = 'my_valid_form'
    surname = forms.CharField(label='Surname', min_length=3, max_length=20)
    age = forms.DecimalField(min_value=18, max_value=99)

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

from djangular.forms import NgFormValidationMixin, NgForm

class MyValidatedForm(NgFormValidationMixin, NgForm):
    # members as above
from djangular.forms import NgFormValidationMixin, NgModelForm

class MyValidatedForm(NgFormValidationMixin, NgModelForm):
    class Meta:
         model = Article

    # fields as usual

هر صفحه ای انگولارجی اس نیاز به یک نام منحصربفرد داره در غیر اینصورت اعتبار سنجی ها شاسکول میشن. در نتیجه باید هر فرم از NgFormValidationMixin گرفته بشه

اگر در یک صفحه فقط یک فرم داشته باشیم، نام فرم میتواند در به class declaration مثل مثال پایین اضافه بشه :

تک فرمی :

def get_context_data(self, **kwargs):
    context = super(MyRenderingView, self).get_context_data(**kwargs)
    context.update(form=MyValidatedForm())
    return context

چند فرمی :

def get_context_data(self, **kwargs):
    context = super(MyRenderingView, self).get_context_data(**kwargs)
    context.update(form1=MyValidatedForm(form_name='my_valid_form1'),
                   form2=MyValidatedForm(form_name='my_valid_form2'))
    return context

 Render this form in a template

<form name="{{ form.form_name }}" novalidate>
  {{ form }}
  <input type="submit" value="Submit" />
</form>

Use the directive novalidate to disable the browser’s native form validation

این هم برای دکمه ی سابمیت :

<input type="submit" class="btn" ng-disabled="{{ form.form_name }}.$invalid" value="Submit">

 More granular output

from django import forms
from djangular.forms import NgFormValidationMixin

class MyValidatedForm(NgFormValidationMixin, forms.Form):
    email = forms.EmailField(label='Email')
<ul class="djng-form-errors" ng-hide="subscribe_form.email.$pristine">
  <li ng-show="subscribe_form.email.$error.required" class="ng-hide">This field is required.</li>
  <li ng-show="subscribe_form.email.$error.email" class="">Enter a valid email address.</li>
</ul>

 Combine NgFormValidationMixin with NgModelFormMixin

from django import forms
from djangular.forms import NgFormValidationMixin, NgModelFormMixin

class MyValidatedForm(NgModelFormMixin, NgFormValidationMixin, forms.Form):
    # custom form fields

but don’t do this

class MyValidatedForm(NgFormValidationMixin, NgModelFormMixin, forms.Form):
    # custom form fields

and this :

form = MyValidatedForm(form_name='my_form', scope_prefix='my_model')

css class for errors :

ul.djng-form-errors {
        margin-left: 0;
        display: inline-block;
        list-style-type: none;
}
ul.djng-form-errors li.invalid {
        color: #e9322d;
}
ul.djng-form-errors li.invalid:before {
        content: "\2716\20";  /* adds a red cross before the error message */
}
ul.djng-form-errors li.valid:before {
        color: #00c900;
        content: "\2714";  /* adds a green tick */
}

If you desire an alternative CSS class or an alternative way of rendering the list of errors, then initialize the form instance with

class MyErrorList(list):
    # rendering methods go here

# during form instantiation
my_form = MyForm(error_class=MyErrorList)

توجه کنید و مثال های دیگر

from django import forms

class MyForm(forms.Form):
    # other fields
    date = forms.DateField(label='Date',
        widget=forms.widgets.DateInput(attrs={'validate-date': '^(\d{4})-(\d{1,2})-(\d{1,2})$'}))
<input name="date" ng-model="my_form_data.birth_date" type="text" validate-date="^(\d{4})-(\d{1,2})-(\d{1,2})$" />
angular.module('MyApp', ['ng.django.forms']);

Django REST framework

django REST framework logoDjango REST framework یک فریم ورک قدرتمند و انعطاف پذیر است که طراحی سرور ساید و تا قسمتی کلاینت ساید یک وب پرتال پیچیده را ساده می نماید.تعدادی از دلایلی که شما را مجاب می کند تا از این فریم ورک استفاده نمایید بشرح زیر است :* API های این فریم ورک توسط مرورگر شما قابل استفاده است و نیازی به کد زدن شما ندارد !!* سیستم های کنترل دسترسی شامل پکیج های OAuth1a and OAuth2* سریال سازی شامل ORM and non-ORM data sources* بهینه سازی تمام مسیرهای طراحان دیجانگو در جهت مختصر نویسی و استحکام* مستند سازی قدرتمند و کامل* استفاده توسط تعداد زیادی از شرکت های بزرگ مثل Mozzila and Eventbrite 

نحوه ی نصب :

Requirements

REST framework requires the following:

  • Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)
  • Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7+, 1.8)

The following packages are optional:

Installation

Install using pip, including any optional packages you want…

pip install djangorestframework
pip install markdown       # Markdown support for the browsable API.
pip install django-filter  # Filtering support

…or clone the project from github.

git clone git@github.com:tomchristie/django-rest-framework.git

Add 'rest_framework' to your INSTALLED_APPS setting.

INSTALLED_APPS = (
    ...
    'rest_framework',
)

If you’re intending to use the browsable API you’ll probably also want to add REST framework’s login and logout views. Add the following to your root urls.py file.

urlpatterns = [
    ...
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

خوب با نحوه ی نصب این فریم ورک آشنا شدیمهمانطور که مشاهده می کنید این فریم ورک جایگزین خوبی را برای صفحه مدیریت جانگو ایجاد میکنه. یعنی اگر قبلا از rahsoon.com:8000/admin استفاده میشد برای ایجاد کاربری جدید حالا این فریم ورک از همین آدرس و با استفاده از روش دیگری برای ساختن کاربری جدید جایگزین می نمایدمثالی مختصری از نحوه ی استفاده این فریم ورک را اشاره می کنمدر نظر داشته باشید می خواهیم 
TopTal

Django User Authentication

در رست فریم ورک دی جانگو Authentication معمولا قبل از هر request اجرا میشه و همچنین قبل از اجرا شدن هر کدیاین کنترل هویت در دو مدل در رست کنترل میشه :request.user property  : این خصیصه به یک instance از پکیج contrib.auth در کلاس User اختصاص داده میشهrequest.auth property : این خصیصه نیز برای فعالیت های اضافی در کنترل های صحت عمکلردها بکار بسته میشود بعنوان مثال این خصیصه می تواند نشان دهنده ی یک رشته فعالیت هایی باشد که طراح مشخص کرده آیا کاربرش انجام داده یا خیرخوب چگونه صحت سنجی کاربر کار می کندAuthentication Schema معمولا بصورت لیستی از کلاس ها قرار میگیرد. رست شروع می کند و به ترتیب صحت سنجی را با کلاس های لیست شده انجام می دهد و سپس request.auth and request.user  را برای اولین کلاسی که به درستی صحت سنجی شده باشد را بر میگرداند.اگر صحت سنجی کلاسی صورت نپذیرد بجای آن دو خصیصه یک کلاس بنام django.contrib.auth.models.AnonymousUser برای request.user برگشت داده شده و همچنین None به request.auth اختصاص داده میشود. ضمنا می توان این وضعیت را UNAUTHENTICATED_USER and UNAUTHENTICATED_TOKEN در settings.py مدیریت نمود.مواردی که باید تحقیق شود : فرق بین router and url در django rest framework : در اصل این روتر ها یکی از امکانات viewSet ها هستند که بر میگردد به مدلی که برنامه نویس برای توسعه ی نرم افزار خود در پیش گرفته است.زمانی که از viewset بجای view‌استفاده می نماییم می توانیم بصورت خودکار از ui درخواست ها را گرفته و با کمترین شلوغی در کد با یک روتر کلاس در ویو ست آنها را اجرا کرده و نتیجه را منعکس نماییم. در نتیجه با استفاده از این روتر کلاس ها می توانیم در restframework admin نیز این مسیر ها را مشاهده و دستکاری نماییمحالا برای اینکه از دیجانگو به درک بهتری برسم دارم این آدرس رو پیاده سازی و تست میکنم :‌خوب مثال یک لینک اشاره رو ردیف کردم :چیزی که تو این مثال اورده بود بیشتر شبیه به همون متدهای قبلی جانگو فرم بود و فقط بجای مثلا فرم یه سریالایزر از نوع مدل گذاشتمحالا میرم تو مثال دوم 

farsiTutorial 2: Requests and ResponsesFrom this point we’re going to really start covering the core of REST framework. Let’s introduce a couple of essential building blocks.Request objectsREST framework introduces a Request object that extends the regular HttpRequest, and provides more flexible request parsing. The core functionality of the Request object is the request.data attribute, which is similar to request.POST, but more useful for working with Web APIs.request.POST # Only handles form data. Only works for 'POST' method. request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods. 
farsiResponse objectsREST framework also introduces a Response object, which is a type of TemplateResponse that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.return Response(data) # Renders to content type as requested by the client.
farsitatus codesUsing numeric HTTP status codes in your views doesn’t always make for obvious reading, and it’s easy to not notice if you get an error code wrong. REST framework provides more explicit identifiers for each status code, such as HTTP_400_BAD_REQUEST in thestatus module. It’s a good idea to use these throughout rather than using numeric identifiers.
farsiWrapping API viewsREST framework provides two wrappers you can use to write API views.The @api_view decorator for working with function based views.The APIView class for working with class based views.These wrappers provide a few bits of functionality such as making sure you receive Request instances in your view, and adding context to Response objects so that content negotiation can be performed.The wrappers also provide behaviour such as returning 405 Method Not Allowed responses when appropriate, and handling anyParseError exception that occurs when accessing request.data with malformed input.
farsiPulling it all togetherOkay, let’s go ahead and start using these new components to write a few views.We don’t need our JSONResponse class in views.py anymore, so go ahead and delete that. Once that’s done we can start refactoring our views slightly.from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from snippets.models import Snippet from snippets.serializers import SnippetSerializer @api_view(['GET', 'POST']) def snippet_list(request): """ List all snippets, or create a new snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)Our instance view is an improvement over the previous example. It’s a little more concise, and the code now feels very similar to if we were working with the Forms API. We’re also using named status codes, which makes the response meanings more obvious.Here is the view for an individual snippet, in the views.py module.@api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)This should all feel very familiar – it is not a lot different from working with regular Django views.Notice that we’re no longer explicitly tying our requests or responses to a given content type. request.data can handle incomingjson requests, but it can also handle other formats. Similarly we’re returning response objects with data, but allowing REST framework to render the response into the correct content type for us.
farsiAdding optional format suffixes to our URLsTo take advantage of the fact that our responses are no longer hardwired to a single content type let’s add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as http://example.com/api/items/4/.json.Start by adding a format keyword argument to both of the views, like so.def snippet_list(request, format=None):anddef snippet_detail(request, pk, format=None):Now update the urls.py file slightly, to append a set of format_suffix_patterns in addition to the existing URLs.from django.conf.urls import patterns, url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views urlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail), ] urlpatterns = format_suffix_patterns(urlpatterns)We don’t necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format.How’s it looking?Go ahead and test the API from the command line, as we did in tutorial part 1. Everything is working pretty similarly, although we’ve got some nicer error handling if we send invalid requests.We can get a list of all of the snippets, as before.http http://127.0.0.1:8000/snippets/ HTTP/1.1 200 OK ... [ { "id": 1, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" } ]We can control the format of the response that we get back, either by using the Accept header:http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSON http http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTMLOr by appending a format suffix:http http://127.0.0.1:8000/snippets/.json # JSON suffix http http://127.0.0.1:8000/snippets/.api # Browsable API suffixSimilarly, we can control the format of the request that we send, using the Content-Type header.# POST using form data http --form POST http://127.0.0.1:8000/snippets/ code="print 123" { "id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly" } # POST using JSON http --json POST http://127.0.0.1:8000/snippets/ code="print 456" { "id": 4, "title": "", "code": "print 456", "linenos": false, "language": "python", "style": "friendly" }Now go and open the API in a web browser, by visiting http://127.0.0.1:8000/snippets/.BrowsabilityBecause the API chooses the content type of the response based on the client request, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a web browser. This allows for the API to return a fully web-browsable HTML representation.Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API.See the browsable api topic for more information about the browsable API feature and how to customize it.What’s next?In tutorial part 3, we’ll start using class based views, and see how generic views reduce the amount of code we need to write. 
farsiTutorial 3: Class Based ViewsWe can also write our API views using class based views, rather than function based views. As we’ll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code DRY.
farsiRewriting our API using class based viewsWe’ll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring of views.py.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from django.http import Http404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class SnippetList(APIView): """ List all snippets, or create a new snippet. """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)So far, so good. It looks pretty similar to the previous case, but we’ve got better separation between the different HTTP methods. We’ll also need to update the instance view in views.py.class SnippetDetail(APIView): """ Retrieve, update or delete a snippet instance. """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)That’s looking good. Again, it’s still pretty similar to the function based view right now.We’ll also need to refactor our urls.py slightly now we’re using class based views.from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views urlpatterns = [ url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns)Okay, we’re done. If you run the development server everything should be working just as before.
farsiUsing mixinsOne of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.The create/retrieve/update/delete operations that we’ve been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework’s mixin classes.Let’s take a look at how we can compose the views by using the mixin classes. Here’s our views.py module again.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from rest_framework import mixins from rest_framework import generics class SnippetList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)We’ll take a moment to examine exactly what’s happening here. We’re building our view using GenericAPIView, and adding inListModelMixin and CreateModelMixin.The base class provides the core functionality, and the mixin classes provide the .list() and .create() actions. We’re then explicitly binding the get and post methods to the appropriate actions. Simple enough stuff so far.class SnippetDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)Pretty similar. Again we’re using the GenericAPIView class to provide the core functionality, and adding in mixins to provide the.retrieve().update() and .destroy() actions.
farsiUsing generic class based viewsUsing the mixin classes we’ve rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our views.py module even more.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from rest_framework import generics class SnippetList(generics.ListCreateAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer class SnippetDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializerWow, that’s pretty concise. We’ve gotten a huge amount for free, and our code looks like good, clean, idiomatic Django.Next we’ll move onto part 4 of the tutorial, where we’ll take a look at how we can deal with authentication and permissions for our API.
farsiTutorial 4: Authentication & PermissionsCurrently our API doesn’t have any restrictions on who can edit or delete code snippets. We’d like to have some more advanced behavior in order to make sure that:Code snippets are always associated with a creator.Only authenticated users may create snippets.Only the creator of a snippet may update or delete it.Unauthenticated requests should have full read-only access.
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish

مدیریت فرایند کسب و کار (BPM) چیست؟

BPM را می توان برای سازمانها کوچک و بزرگ به طور مشابهی به کار گرفت.
هدف: بهبود انجام کار و افزایش سرعت آن با استفاده از یک یا تمام موارد زیر:

aka BPM: مجموعه ای جامع، کاملا درک شده و مستند از فرآیندهای همسان- که عمدتا در چارچوبی فرآیندی تعریف می شود تا موجب وضوح و کارآیی شود
aka BPI/ BPM : رویکردی به ارتقای فرآیند که شامل رویکردی بر سنجش و کنترل روزانه فرآیندهای کاری برای بهبود و کارایی مداوم می شود
aka BPMS/SOA/BI: استفاده از فن آوری اطلاعات یا نرم افزارهای اطلاعاتی از جمله مدلسازی فرآیند، شبیه سازی فرآیند، مراکز، روند کار، ادغام، گزارش دهی و سایر فن آوریها برای تسهیل موارد 1 و 2 و نیز خودکار کردن و به حداثر رساندن فرآیندها
در ادامه پیش از اینکه وارد بحث شویم به تعریف چند اصطلاح اصلی می پردازیم.

تعریف فرآیند کسب و کار
فرآیند کار می تواند هر چیزی باشد از پردازش سفارش یک مشتری تا باز کردن حسابی جدید، یا راه انداختن کارمندی جدید. این فرآیند، مجموعه ای از اقدامات روزمره ای است که برای رسیدن به هدفی مطلوب انجام می دهیم.

انواع فرآیندهای کسب و کار
فرآیندهای کار سطوح و انواع مختلفی دارند. فرآیندهایی که در اینجا “اَبَر فرآیندها” می نامیم، فرآیندهای کاری، عملیاتی و پشتیبانی را شامل می شوند.
فرآیندهای عملیاتی- که جریانهای ارزش اصلی یا فرآیندهای اصلی نیز محسوب می شوند- فرآینهایی هستند که در طراحی، تولید و تحویل محصولات و خدمات یک کمپانی حرف اول را می زنند. جدول بالا مثالهایی از این ابر فرآیندهای کار را شامل می شود. مفهومی کلیدی در BPM آن است که بر حداکثری نمودن “جریان ارزش” یا فرآیندی تمرکز نمود که در مجموع برای مشتری ارزش به همراه دارد.
ابر فرآیندها را معمولا می توان به فرآیندها یا گروهها سطح بالا تقسیم کرد. مثلا اگر با دقت بیشتری به ابر فرآیند مدیریت چرخه حضور کارکنان در سازمان توجه کنیم، می توانیم آن را به چندین فرآیند کاری مانند استخدام، راه انداختن کارمند، مدیریت منافع، مرور عملکرد و خروج کارکنان تقسیم کنیم.
همانطور که در روند کار مرور عملکرد در سمت راست نشان داده شده، این فرآیندهای کاری سطح بالا به نوبه خود می توانند به فرآیندهایی در سطح روند کار تقسیم شوند تا هر فرآیند را تکمیل نمایند. درک اینکه چطور فعالیتهای روزانه در نهایت موجب انجام فرآیندهای سطح بالا و ابر فرآیندها می شوند ایجاد نظم و توازن فعالیتهای کاری برای دستیابی به اهداف استراتژیک و اهداف کاری اساسی و ضروری است.
با مراجعه به APQC، درباره چارچوبهای فرآیند استاندارد صنعت که دارای مقوله ها و مشکلات فرآیندی تعریف شده ای است، بیشتر بیاموزید.

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

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

اتوماسیون اداری به سبک راهسون

سازمان خود را با راهسون مکانیزه کنید

سامانه مدیریت یکپارچه راهسون تمامی نیاز های شما را به نرم افزارهایی از جمله  CRM, ‌BPMS, اتوماسیون اداری و … برطرف می کند. در این سامانه تمامی ابزارهای مورد نیاز برای مکانیزه سازی سازمان وجود دارد همچنین راهسون سعی داشته تا بتواند این نرم افزارهای اداری را به ساده ترین شکل ممکن طراحی کند تا کاربر بتواند بدون هیچ مشکلی از آن استفاده کند.
این ابزار بسیار پیشرفته به شکلی قیمت گذاری شده تا حتی شرکت های کوچک (بین ۵ تا ۳۰ نفر) هم بتوانند به راحتی آنرا تهیه کنند و از آن برای مدیریت کسب و کار خود استفاده کنند.

اتوماسیون اداری به سبک راهسون چه سودی دارد؟

بهره مندی از سیستم مدیریت مشتریان CRM بسیار پیشرفته
خودکار شدن تمام گردش های کاری سازمان ازجمله مرخصی, درخواست کالا و تمام گردش های کاری تخصصی کسب و کار شما
پیگیری و پایش کارها با کامپیوتر, تبلت و یا تلفن همراه خود
افزایش سرعت انجام کارها تا 70%
کاهش استفاده از کاغذ برای فرم ها و نامه ها تا 80%
بهره مندی از سیستم نامه نگاری و مکاتبات الکترونیکی راهسون
گزارش گیری از کارها و فرایندهای سازمان
بررسی و ارزیابی کارکرد کارکنان
و …

اتوماسیون اداری و سامانه راهسون برای شرکت های ۵ تا ۳۰ نفر:

بدون نیاز به سرور برای شرکت
ارائه سرور مجازی اختصاصی به هر سازمان
استفاده از سامانه به صورت اینترنتی در بستر ابر
هزینه بسیار کم
بهره مندی از پیشرفته ترین ابزارهای مکانیزاسیون سازمان و اتوماسیون اداری با کمترین هزیته
کاملا تحت وب
و …
اتوماسیون اداری و سامانه راهسون برای سازمان های بزرگ ۵۰ تا ۱۰۰۰۰ نفر:

نصب سامانه روی سرورهای مشتری
راه اندازی روی شبکه محلی شرکت
بدون نیاز به نصب هیچ گونه نرم افزار روی کامپیوترهای کارکنان
تماما تحت وب
بهره مندی از سیستم مدیریت فرایند کسب و کار ‌BPMS
تمامی ابزار های مدیریت چارت سازمان و منابع انسانی
قیمت بسیار مناسب
امکان یکپارچگی با دیگر نرم افزارهای سازمان
و …