<s> import csv <EOL> import io <EOL> import json <EOL> import uuid <EOL> from couchdbkit import ResourceNotFound <EOL> from django . contrib import messages <EOL> from django . core . cache import cache <EOL> from corehq import privileges , toggles <EOL> from corehq . apps . accounting . decorators import requires_privilege_with_fallback <EOL> from corehq . apps . app_manager . util import all_case_properties_by_domain <EOL> from corehq . apps . casegroups . dbaccessors import get_case_groups_in_domain , get_number_of_case_groups_in_domain <EOL> from corehq . apps . casegroups . models import CommCareCaseGroup <EOL> from corehq . apps . hqwebapp . forms import BulkUploadForm <EOL> from corehq . apps . hqwebapp . templatetags . hq_shared_tags import static <EOL> from corehq . apps . hqwebapp . utils import get_bulk_upload_form <EOL> from corehq . util . spreadsheets . excel import JSONReaderError , WorkbookJSONReader <EOL> from corehq . util . timezones . conversions import ServerTime <EOL> from corehq . util . timezones . utils import get_timezone_for_user <EOL> from django . utils . decorators import method_decorator <EOL> from openpyxl . utils . exceptions import InvalidFileException <EOL> from corehq . apps . data_interfaces . tasks import ( <EOL> bulk_upload_cases_to_group , bulk_archive_forms , bulk_form_management_async ) <EOL> from corehq . apps . data_interfaces . forms import ( <EOL> AddCaseGroupForm , UpdateCaseGroupForm , AddCaseToGroupForm , <EOL> AddAutomaticCaseUpdateRuleForm ) <EOL> from corehq . apps . data_interfaces . models import ( AutomaticUpdateRule , <EOL> AutomaticUpdateRuleCriteria , AutomaticUpdateAction ) <EOL> from corehq . apps . domain . decorators import login_and_domain_required <EOL> from corehq . apps . domain . views import BaseDomainView <EOL> from corehq . apps . hqcase . utils import get_case_by_identifier <EOL> from corehq . apps . hqwebapp . views import CRUDPaginatedViewMixin , PaginatedItemException <EOL> from corehq . apps . data_interfaces . dispatcher import ( DataInterfaceDispatcher , EditDataInterfaceDispatcher , <EOL> require_can_edit_data ) <EOL> from corehq . apps . style . decorators import use_bootstrap3 , use_typeahead , use_angular_js <EOL> from corehq . const import SERVER_DATETIME_FORMAT <EOL> from . dispatcher import require_form_management_privilege <EOL> from . interfaces import FormManagementMode , BulkFormManagementInterface , CaseReassignmentInterface <EOL> from django . db import transaction <EOL> from django . core . urlresolvers import reverse <EOL> from django . http import HttpResponseRedirect , Http404 , HttpResponseServerError <EOL> from django . shortcuts import render <EOL> from djangular . views . mixins import JSONResponseMixin , allow_remote_invocation <EOL> from dimagi . utils . decorators . memoized import memoized <EOL> from django . utils . translation import ugettext as _ , ugettext_noop , ugettext_lazy <EOL> from soil . exceptions import TaskFailedError <EOL> from soil . util import expose_cached_download , get_download_context <EOL> from zipfile import BadZipfile <EOL> @ login_and_domain_required <EOL> def default ( request , domain ) : <EOL> if not request . project or request . project . is_snapshot : <EOL> raise Http404 ( ) <EOL> return HttpResponseRedirect ( default_data_view_url ( request , domain ) ) <EOL> def default_data_view_url ( request , domain ) : <EOL> if request . couch_user . can_view_reports ( ) : <EOL> from corehq . apps . export . views import FormExportListView <EOL> return reverse ( FormExportListView . urlname , args = [ domain ] ) <EOL> from corehq . apps . export . views import DeIdFormExportListView , user_can_view_deid_exports <EOL> if user_can_view_deid_exports ( domain , request . couch_user ) : <EOL> return reverse ( DeIdFormExportListView . urlname , args = [ domain ] ) <EOL> raise Http404 ( ) <EOL> class BulkUploadCasesException ( Exception ) : <EOL> pass <EOL> class DataInterfaceSection ( BaseDomainView ) : <EOL> section_name = ugettext_noop ( "<STR_LIT>" ) <EOL> @ method_decorator ( require_can_edit_data ) <EOL> def dispatch ( self , request , * args , ** kwargs ) : <EOL> return super ( DataInterfaceSection , self ) . dispatch ( request , * args , ** kwargs ) <EOL> @ property <EOL> def section_url ( self ) : <EOL> return reverse ( "<STR_LIT>" , args = [ self . domain ] ) <EOL> class CaseGroupListView ( DataInterfaceSection , CRUDPaginatedViewMixin ) : <EOL> template_name = "<STR_LIT>" <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_lazy ( "<STR_LIT>" ) <EOL> limit_text = ugettext_lazy ( "<STR_LIT>" ) <EOL> empty_notification = ugettext_lazy ( "<STR_LIT>" ) <EOL> loading_message = ugettext_lazy ( "<STR_LIT>" ) <EOL> deleted_items_header = ugettext_lazy ( "<STR_LIT>" ) <EOL> new_items_header = ugettext_lazy ( "<STR_LIT>" ) <EOL> @ property <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = [ self . domain ] ) <EOL> @ property <EOL> def parameters ( self ) : <EOL> return self . request . POST if self . request . method == '<STR_LIT:POST>' else self . request . GET <EOL> @ property <EOL> @ memoized <EOL> def total ( self ) : <EOL> return get_number_of_case_groups_in_domain ( self . domain ) <EOL> @ property <EOL> def column_names ( self ) : <EOL> return [ <EOL> _ ( "<STR_LIT>" ) , <EOL> _ ( "<STR_LIT>" ) , <EOL> _ ( "<STR_LIT>" ) , <EOL> ] <EOL> @ property <EOL> def page_context ( self ) : <EOL> return self . pagination_context <EOL> @ property <EOL> def paginated_list ( self ) : <EOL> for group in get_case_groups_in_domain ( <EOL> self . domain , <EOL> limit = self . limit , <EOL> skip = self . skip <EOL> ) : <EOL> item_data = self . _get_item_data ( group ) <EOL> item_data [ '<STR_LIT>' ] = self . get_update_form_response ( <EOL> self . get_update_form ( initial_data = { <EOL> '<STR_LIT>' : group . _id , <EOL> '<STR_LIT:name>' : group . name , <EOL> } ) <EOL> ) <EOL> yield { <EOL> '<STR_LIT>' : item_data , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def _get_item_data ( self , case_group ) : <EOL> return { <EOL> '<STR_LIT:id>' : case_group . _id , <EOL> '<STR_LIT:name>' : case_group . name , <EOL> '<STR_LIT>' : len ( case_group . cases ) , <EOL> '<STR_LIT>' : reverse ( CaseGroupCaseManagementView . urlname , args = [ self . domain , case_group . _id ] ) <EOL> } <EOL> def post ( self , * args , ** kwargs ) : <EOL> return self . paginate_crud_response <EOL> def get_create_form ( self , is_blank = False ) : <EOL> if self . request . method == '<STR_LIT:POST>' and not is_blank : <EOL> return AddCaseGroupForm ( self . request . POST ) <EOL> return AddCaseGroupForm ( ) <EOL> def get_update_form ( self , initial_data = None ) : <EOL> if self . request . method == '<STR_LIT:POST>' and self . action == '<STR_LIT>' : <EOL> return UpdateCaseGroupForm ( self . request . POST ) <EOL> return UpdateCaseGroupForm ( initial = initial_data ) <EOL> def get_create_item_data ( self , create_form ) : <EOL> case_group = create_form . create_group ( self . domain ) <EOL> return { <EOL> '<STR_LIT>' : self . _get_item_data ( case_group ) , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def get_deleted_item_data ( self , item_id ) : <EOL> case_group = CommCareCaseGroup . get ( item_id ) <EOL> item_data = self . _get_item_data ( case_group ) <EOL> case_group . soft_delete ( ) <EOL> return { <EOL> '<STR_LIT>' : item_data , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> @ use_bootstrap3 <EOL> def dispatch ( self , request , * args , ** kwargs ) : <EOL> return super ( CaseGroupListView , self ) . dispatch ( request , * args , ** kwargs ) <EOL> class ArchiveFormView ( DataInterfaceSection ) : <EOL> template_name = '<STR_LIT>' <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_noop ( "<STR_LIT>" ) <EOL> ONE_MB = <NUM_LIT> <EOL> MAX_SIZE = <NUM_LIT:3> * ONE_MB <EOL> @ method_decorator ( requires_privilege_with_fallback ( privileges . BULK_CASE_MANAGEMENT ) ) <EOL> def dispatch ( self , request , * args , ** kwargs ) : <EOL> if not toggles . BULK_ARCHIVE_FORMS . enabled ( request . user . username ) : <EOL> raise Http404 ( ) <EOL> return super ( ArchiveFormView , self ) . dispatch ( request , * args , ** kwargs ) <EOL> @ property <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = [ self . domain ] ) <EOL> @ property <EOL> def page_context ( self ) : <EOL> context = { } <EOL> context . update ( { <EOL> '<STR_LIT>' : { <EOL> "<STR_LIT>" : static ( <EOL> '<STR_LIT>' ) , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> } ) <EOL> context . update ( { <EOL> '<STR_LIT>' : get_bulk_upload_form ( context ) , <EOL> } ) <EOL> return context <EOL> @ property <EOL> @ memoized <EOL> def uploaded_file ( self ) : <EOL> try : <EOL> bulk_file = self . request . FILES [ '<STR_LIT>' ] <EOL> if bulk_file . size > self . MAX_SIZE : <EOL> raise BulkUploadCasesException ( _ ( u"<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) . format ( size = self . MAX_SIZE / self . ONE_MB ) ) <EOL> except KeyError : <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" ) ) <EOL> try : <EOL> return WorkbookJSONReader ( bulk_file ) <EOL> except ( InvalidFileException , BadZipfile ) : <EOL> try : <EOL> csv . DictReader ( io . StringIO ( bulk_file . read ( ) . decode ( '<STR_LIT:utf-8>' ) , <EOL> newline = None ) ) <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> except UnicodeDecodeError : <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" ) ) <EOL> except JSONReaderError as e : <EOL> raise BulkUploadCasesException ( _ ( '<STR_LIT>' ) % e . message ) <EOL> def process ( self ) : <EOL> try : <EOL> bulk_archive_forms . delay ( <EOL> self . domain , <EOL> self . request . couch_user , <EOL> list ( self . uploaded_file . get_worksheet ( ) ) <EOL> ) <EOL> messages . success ( self . request , _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> except BulkUploadCasesException as e : <EOL> messages . error ( self . request , e . message ) <EOL> return None <EOL> def post ( self , request , * args , ** kwargs ) : <EOL> self . process ( ) <EOL> return HttpResponseRedirect ( self . page_url ) <EOL> class CaseGroupCaseManagementView ( DataInterfaceSection , CRUDPaginatedViewMixin ) : <EOL> template_name = '<STR_LIT>' <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_noop ( "<STR_LIT>" ) <EOL> limit_text = ugettext_noop ( "<STR_LIT>" ) <EOL> empty_notification = ugettext_noop ( "<STR_LIT>" ) <EOL> loading_message = ugettext_noop ( "<STR_LIT>" ) <EOL> deleted_items_header = ugettext_noop ( "<STR_LIT>" ) <EOL> new_items_header = ugettext_noop ( "<STR_LIT>" ) <EOL> @ property <EOL> def group_id ( self ) : <EOL> return self . kwargs . get ( '<STR_LIT>' ) <EOL> @ property <EOL> @ memoized <EOL> def case_group ( self ) : <EOL> try : <EOL> return CommCareCaseGroup . get ( self . group_id ) <EOL> except ResourceNotFound : <EOL> raise Http404 ( ) <EOL> @ property <EOL> def parent_pages ( self ) : <EOL> return [ { <EOL> '<STR_LIT:title>' : CaseGroupListView . page_title , <EOL> '<STR_LIT:url>' : reverse ( CaseGroupListView . urlname , args = [ self . domain ] ) <EOL> } ] <EOL> @ property <EOL> def page_name ( self ) : <EOL> return _ ( "<STR_LIT>" % self . case_group . name ) <EOL> @ property <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = [ self . domain , self . group_id ] ) <EOL> @ property <EOL> def page_context ( self ) : <EOL> context = self . pagination_context <EOL> context . update ( { <EOL> '<STR_LIT>' : { <EOL> "<STR_LIT>" : static ( <EOL> '<STR_LIT>' ) , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> '<STR_LIT>' : self . bulk_upload_id , <EOL> '<STR_LIT>' : self . update_case_group_form , <EOL> '<STR_LIT>' : self . case_group . name , <EOL> } ) <EOL> context . update ( { <EOL> '<STR_LIT>' : get_bulk_upload_form ( context ) , <EOL> } ) <EOL> return context <EOL> @ property <EOL> @ memoized <EOL> def update_case_group_form ( self ) : <EOL> initial = { <EOL> '<STR_LIT:name>' : self . case_group . name , <EOL> '<STR_LIT>' : self . case_group . _id , <EOL> } <EOL> if self . is_case_group_update : <EOL> return UpdateCaseGroupForm ( self . request . POST , initial = initial ) <EOL> return UpdateCaseGroupForm ( initial = initial ) <EOL> @ property <EOL> def parameters ( self ) : <EOL> return self . request . POST if self . request . method == '<STR_LIT:POST>' else self . request . GET <EOL> @ property <EOL> @ memoized <EOL> def total ( self ) : <EOL> return self . case_group . get_total_cases ( ) <EOL> @ property <EOL> def column_names ( self ) : <EOL> return [ <EOL> _ ( "<STR_LIT>" ) , <EOL> _ ( "<STR_LIT>" ) , <EOL> _ ( "<STR_LIT>" ) , <EOL> _ ( "<STR_LIT>" ) , <EOL> ] <EOL> @ property <EOL> def paginated_list ( self ) : <EOL> for case in self . case_group . get_cases ( limit = self . limit , skip = self . skip ) : <EOL> yield { <EOL> '<STR_LIT>' : self . _get_item_data ( case ) , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> @ property <EOL> def allowed_actions ( self ) : <EOL> actions = super ( CaseGroupCaseManagementView , self ) . allowed_actions <EOL> actions . append ( '<STR_LIT>' ) <EOL> return actions <EOL> @ property <EOL> def bulk_response ( self ) : <EOL> return cache . get ( self . request . POST [ '<STR_LIT>' ] ) <EOL> @ property <EOL> def is_bulk_upload ( self ) : <EOL> return self . request . method == '<STR_LIT:POST>' and self . request . POST . get ( '<STR_LIT:action>' ) == '<STR_LIT>' <EOL> @ property <EOL> def is_case_group_update ( self ) : <EOL> return self . request . method == '<STR_LIT:POST>' and self . request . POST . get ( '<STR_LIT:action>' ) == '<STR_LIT>' <EOL> @ property <EOL> def bulk_upload_id ( self ) : <EOL> if not self . is_bulk_upload : <EOL> return None <EOL> try : <EOL> if self . uploaded_file : <EOL> upload_id = uuid . uuid4 ( ) . hex <EOL> bulk_upload_cases_to_group . delay ( <EOL> upload_id , <EOL> self . domain , <EOL> self . group_id , <EOL> list ( self . uploaded_file . get_worksheet ( ) ) <EOL> ) <EOL> messages . success ( self . request , _ ( "<STR_LIT>" ) ) <EOL> return upload_id <EOL> except BulkUploadCasesException as e : <EOL> messages . error ( self . request , e . message ) <EOL> return None <EOL> @ property <EOL> @ memoized <EOL> def uploaded_file ( self ) : <EOL> try : <EOL> bulk_file = self . request . FILES [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" ) ) <EOL> try : <EOL> return WorkbookJSONReader ( bulk_file ) <EOL> except ( InvalidFileException , BadZipfile ) : <EOL> try : <EOL> csv . DictReader ( io . StringIO ( bulk_file . read ( ) . decode ( '<STR_LIT:ascii>' ) , <EOL> newline = None ) ) <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> except UnicodeDecodeError : <EOL> raise BulkUploadCasesException ( _ ( "<STR_LIT>" ) ) <EOL> except JSONReaderError as e : <EOL> raise BulkUploadCasesException ( _ ( '<STR_LIT>' ) % e . message ) <EOL> def _get_item_data ( self , case ) : <EOL> return { <EOL> '<STR_LIT:id>' : case . _id , <EOL> '<STR_LIT>' : reverse ( '<STR_LIT>' , args = [ self . domain , case . _id ] ) , <EOL> '<STR_LIT:name>' : case . name , <EOL> '<STR_LIT>' : case . external_id if case . external_id else '<STR_LIT>' , <EOL> '<STR_LIT>' : getattr ( case , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> } <EOL> def get_create_form ( self , is_blank = False ) : <EOL> if self . request . method == '<STR_LIT:POST>' and not is_blank : <EOL> return AddCaseToGroupForm ( self . request . POST ) <EOL> return AddCaseToGroupForm ( ) <EOL> def get_create_item_data ( self , create_form ) : <EOL> case_identifier = create_form . cleaned_data [ '<STR_LIT>' ] <EOL> case = get_case_by_identifier ( self . domain , case_identifier ) <EOL> if case is None : <EOL> return { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT:id>' : case_identifier . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) , <EOL> '<STR_LIT>' : case_identifier , <EOL> '<STR_LIT:message>' : _ ( '<STR_LIT>' <EOL> '<STR_LIT>' ) , <EOL> } , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> item_data = self . _get_item_data ( case ) <EOL> if case . case_id in self . case_group . cases : <EOL> message = '<STR_LIT>' % _ ( "<STR_LIT>" ) <EOL> elif case . doc_type != '<STR_LIT>' : <EOL> message = '<STR_LIT>' % _ ( "<STR_LIT>" ) <EOL> else : <EOL> message = '<STR_LIT>' % _ ( "<STR_LIT>" ) <EOL> self . case_group . cases . append ( case . case_id ) <EOL> self . case_group . save ( ) <EOL> item_data [ '<STR_LIT:message>' ] = message <EOL> return { <EOL> '<STR_LIT>' : item_data , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def get_deleted_item_data ( self , item_id ) : <EOL> if not item_id : <EOL> raise PaginatedItemException ( "<STR_LIT>" ) <EOL> current_cases = set ( self . case_group . cases ) <EOL> self . case_group . cases = list ( current_cases . difference ( [ item_id ] ) ) <EOL> self . case_group . save ( ) <EOL> return { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def post ( self , request , * args , ** kwargs ) : <EOL> if self . is_bulk_upload or self . is_case_group_update : <EOL> if self . is_case_group_update and self . update_case_group_form . is_valid ( ) : <EOL> self . update_case_group_form . update_group ( ) <EOL> return HttpResponseRedirect ( self . page_url ) <EOL> return self . get ( request , * args , ** kwargs ) <EOL> return self . paginate_crud_response <EOL> @ use_bootstrap3 <EOL> def dispatch ( self , request , * args , ** kwargs ) : <EOL> return super ( CaseGroupCaseManagementView , self ) . dispatch ( request , * args , ** kwargs ) <EOL> class XFormManagementView ( DataInterfaceSection ) : <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_noop ( '<STR_LIT>' ) <EOL> def get_form_ids_or_query_string ( self , request ) : <EOL> if '<STR_LIT>' in self . request . POST : <EOL> import urllib <EOL> form_query_string = urllib . unquote ( self . request . POST . get ( '<STR_LIT>' ) ) <EOL> return form_query_string <EOL> else : <EOL> return self . request . POST . getlist ( '<STR_LIT>' ) <EOL> def post ( self , request , * args , ** kwargs ) : <EOL> form_ids_or_query_string = self . get_form_ids_or_query_string ( request ) <EOL> mode = self . request . POST . get ( '<STR_LIT>' ) <EOL> task_ref = expose_cached_download ( payload = None , expiry = <NUM_LIT:1> * <NUM_LIT> * <NUM_LIT> , file_extension = None ) <EOL> task = bulk_form_management_async . delay ( <EOL> mode , <EOL> self . domain , <EOL> self . request . couch_user , <EOL> form_ids_or_query_string <EOL> ) <EOL> task_ref . set_task ( task ) <EOL> return HttpResponseRedirect ( <EOL> reverse ( <EOL> XFormManagementStatusView . urlname , <EOL> args = [ self . domain , mode , task_ref . download_id ] <EOL> ) <EOL> ) <EOL> @ method_decorator ( require_form_management_privilege ) <EOL> def dispatch ( self , request , * args , ** kwargs ) : <EOL> return super ( XFormManagementView , self ) . dispatch ( request , * args , ** kwargs ) <EOL> class XFormManagementStatusView ( DataInterfaceSection ) : <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_noop ( '<STR_LIT>' ) <EOL> def get ( self , request , * args , ** kwargs ) : <EOL> context = super ( XFormManagementStatusView , self ) . main_context <EOL> mode = FormManagementMode ( kwargs [ '<STR_LIT>' ] ) <EOL> context . update ( { <EOL> '<STR_LIT>' : self . domain , <EOL> '<STR_LIT>' : kwargs [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : "<STR_LIT>" . format ( <EOL> url = reverse ( '<STR_LIT>' , args = [ self . domain , kwargs [ '<STR_LIT>' ] ] ) , <EOL> mode = mode . mode_name ) , <EOL> '<STR_LIT:title>' : mode . status_page_title , <EOL> '<STR_LIT>' : mode . error_text , <EOL> } ) <EOL> return render ( request , '<STR_LIT>' , context ) <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = self . args , kwargs = self . kwargs ) <EOL> @ require_can_edit_data <EOL> @ require_form_management_privilege <EOL> def xform_management_job_poll ( request , domain , download_id , <EOL> template = "<STR_LIT>" ) : <EOL> mode = FormManagementMode ( request . GET . get ( '<STR_LIT>' ) , validate = True ) <EOL> try : <EOL> context = get_download_context ( download_id , check_state = True ) <EOL> except TaskFailedError : <EOL> return HttpResponseServerError ( ) <EOL> context . update ( { <EOL> '<STR_LIT>' : mode . complete_short , <EOL> '<STR_LIT>' : mode , <EOL> '<STR_LIT>' : reverse ( EditDataInterfaceDispatcher . name ( ) , <EOL> args = [ domain , BulkFormManagementInterface . slug ] ) <EOL> } ) <EOL> return render ( request , template , context ) <EOL> class AutomaticUpdateRuleListView ( JSONResponseMixin , DataInterfaceSection ) : <EOL> template_name = '<STR_LIT>' <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_lazy ( "<STR_LIT>" ) <EOL> ACTION_ACTIVATE = '<STR_LIT>' <EOL> ACTION_DEACTIVATE = '<STR_LIT>' <EOL> ACTION_DELETE = '<STR_LIT>' <EOL> @ property <EOL> @ memoized <EOL> def project_timezone ( self ) : <EOL> return get_timezone_for_user ( None , self . domain ) <EOL> @ use_bootstrap3 <EOL> @ use_angular_js <EOL> @ method_decorator ( requires_privilege_with_fallback ( privileges . DATA_CLEANUP ) ) <EOL> def dispatch ( self , * args , ** kwargs ) : <EOL> return super ( AutomaticUpdateRuleListView , self ) . dispatch ( * args , ** kwargs ) <EOL> @ property <EOL> def page_context ( self ) : <EOL> return { <EOL> '<STR_LIT>' : ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> % self . domain ) , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def _format_rule ( self , rule ) : <EOL> return { <EOL> '<STR_LIT:id>' : rule . pk , <EOL> '<STR_LIT:name>' : rule . name , <EOL> '<STR_LIT>' : rule . case_type , <EOL> '<STR_LIT>' : rule . active , <EOL> '<STR_LIT>' : ( ServerTime ( rule . last_run ) <EOL> . user_time ( self . project_timezone ) <EOL> . done ( ) <EOL> . strftime ( SERVER_DATETIME_FORMAT ) ) if rule . last_run else '<STR_LIT:->' , <EOL> '<STR_LIT>' : reverse ( EditAutomaticUpdateRuleView . urlname , args = [ self . domain , rule . pk ] ) , <EOL> } <EOL> @ allow_remote_invocation <EOL> def get_pagination_data ( self , in_data ) : <EOL> try : <EOL> limit = int ( in_data [ '<STR_LIT>' ] ) <EOL> page = int ( in_data [ '<STR_LIT>' ] ) <EOL> except ( TypeError , KeyError , ValueError ) : <EOL> return { <EOL> '<STR_LIT:success>' : False , <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> start = ( page - <NUM_LIT:1> ) * limit <EOL> stop = limit * page <EOL> rules = AutomaticUpdateRule . objects . filter ( <EOL> domain = self . domain , <EOL> deleted = False <EOL> ) . order_by ( '<STR_LIT:name>' ) [ start : stop ] <EOL> total = AutomaticUpdateRule . objects . filter ( <EOL> domain = self . domain , <EOL> deleted = False <EOL> ) . count ( ) <EOL> return { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : map ( self . _format_rule , rules ) , <EOL> '<STR_LIT>' : total , <EOL> '<STR_LIT>' : page , <EOL> } , <EOL> '<STR_LIT:success>' : True , <EOL> } <EOL> @ allow_remote_invocation <EOL> def update_rule ( self , in_data ) : <EOL> try : <EOL> rule_id = in_data [ '<STR_LIT:id>' ] <EOL> except KeyError : <EOL> return { <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> try : <EOL> action = in_data [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> return { <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> if action not in ( <EOL> self . ACTION_ACTIVATE , <EOL> self . ACTION_DEACTIVATE , <EOL> self . ACTION_DELETE , <EOL> ) : <EOL> return { <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> try : <EOL> rule = AutomaticUpdateRule . objects . get ( pk = rule_id ) <EOL> except AutomaticUpdateRule . DoesNotExist : <EOL> return { <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> if rule . domain != self . domain : <EOL> return { <EOL> '<STR_LIT:error>' : _ ( "<STR_LIT>" ) , <EOL> } <EOL> if action == self . ACTION_ACTIVATE : <EOL> rule . activate ( ) <EOL> elif action == self . ACTION_DEACTIVATE : <EOL> rule . activate ( False ) <EOL> elif action == self . ACTION_DELETE : <EOL> rule . soft_delete ( ) <EOL> return { <EOL> '<STR_LIT:success>' : True , <EOL> } <EOL> class AddAutomaticUpdateRuleView ( JSONResponseMixin , DataInterfaceSection ) : <EOL> template_name = '<STR_LIT>' <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_lazy ( "<STR_LIT>" ) <EOL> @ property <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = [ self . domain ] ) <EOL> @ property <EOL> def initial_rule_form ( self ) : <EOL> return AddAutomaticCaseUpdateRuleForm ( <EOL> domain = self . domain , <EOL> initial = { <EOL> '<STR_LIT:action>' : AddAutomaticCaseUpdateRuleForm . ACTION_CLOSE , <EOL> } <EOL> ) <EOL> @ property <EOL> @ memoized <EOL> def rule_form ( self ) : <EOL> if self . request . method == '<STR_LIT:POST>' : <EOL> return AddAutomaticCaseUpdateRuleForm ( self . request . POST , domain = self . domain ) <EOL> else : <EOL> return self . initial_rule_form <EOL> @ property <EOL> def page_context ( self ) : <EOL> return { <EOL> '<STR_LIT>' : self . rule_form , <EOL> } <EOL> @ allow_remote_invocation <EOL> def get_case_property_map ( self ) : <EOL> data = all_case_properties_by_domain ( self . domain , <EOL> include_parent_properties = False ) <EOL> return { <EOL> '<STR_LIT:data>' : data , <EOL> '<STR_LIT:success>' : True , <EOL> } <EOL> @ use_bootstrap3 <EOL> @ use_angular_js <EOL> @ use_typeahead <EOL> @ method_decorator ( requires_privilege_with_fallback ( privileges . DATA_CLEANUP ) ) <EOL> def dispatch ( self , * args , ** kwargs ) : <EOL> return super ( AddAutomaticUpdateRuleView , self ) . dispatch ( * args , ** kwargs ) <EOL> def create_criteria ( self , rule ) : <EOL> for condition in self . rule_form . cleaned_data [ '<STR_LIT>' ] : <EOL> AutomaticUpdateRuleCriteria . objects . create ( <EOL> rule = rule , <EOL> property_name = condition [ '<STR_LIT>' ] , <EOL> property_value = condition [ '<STR_LIT>' ] , <EOL> match_type = condition [ '<STR_LIT>' ] , <EOL> ) <EOL> def create_actions ( self , rule ) : <EOL> if self . rule_form . _closes_case ( ) : <EOL> AutomaticUpdateAction . objects . create ( <EOL> rule = rule , <EOL> action = AutomaticUpdateAction . ACTION_CLOSE , <EOL> ) <EOL> if self . rule_form . _updates_case ( ) : <EOL> AutomaticUpdateAction . objects . create ( <EOL> rule = rule , <EOL> action = AutomaticUpdateAction . ACTION_UPDATE , <EOL> property_name = self . rule_form . cleaned_data [ '<STR_LIT>' ] , <EOL> property_value = self . rule_form . cleaned_data [ '<STR_LIT>' ] , <EOL> ) <EOL> def create_rule ( self ) : <EOL> with transaction . atomic ( ) : <EOL> rule = AutomaticUpdateRule . objects . create ( <EOL> domain = self . domain , <EOL> name = self . rule_form . cleaned_data [ '<STR_LIT:name>' ] , <EOL> case_type = self . rule_form . cleaned_data [ '<STR_LIT>' ] , <EOL> active = True , <EOL> server_modified_boundary = self . rule_form . cleaned_data [ '<STR_LIT>' ] , <EOL> ) <EOL> self . create_criteria ( rule ) <EOL> self . create_actions ( rule ) <EOL> def post ( self , request , * args , ** kwargs ) : <EOL> if self . rule_form . is_valid ( ) : <EOL> self . create_rule ( ) <EOL> return HttpResponseRedirect ( reverse ( AutomaticUpdateRuleListView . urlname , args = [ self . domain ] ) ) <EOL> return super ( JSONResponseMixin , self ) . get ( request , * args , ** kwargs ) <EOL> class EditAutomaticUpdateRuleView ( AddAutomaticUpdateRuleView ) : <EOL> urlname = '<STR_LIT>' <EOL> page_title = ugettext_lazy ( "<STR_LIT>" ) <EOL> @ property <EOL> @ memoized <EOL> def rule_id ( self ) : <EOL> return self . kwargs . get ( '<STR_LIT>' ) <EOL> @ property <EOL> def page_url ( self ) : <EOL> return reverse ( self . urlname , args = [ self . domain , self . rule_id ] ) <EOL> @ property <EOL> @ memoized <EOL> def rule ( self ) : <EOL> try : <EOL> rule = AutomaticUpdateRule . objects . get ( pk = self . rule_id ) <EOL> except AutomaticUpdateRule . DoesNotExist : <EOL> raise Http404 ( ) <EOL> if rule . domain != self . domain or rule . deleted : <EOL> raise Http404 ( ) <EOL> return rule <EOL> @ property <EOL> def initial_rule_form ( self ) : <EOL> conditions = [ ] <EOL> for criterion in self . rule . automaticupdaterulecriteria_set . order_by ( '<STR_LIT>' ) : <EOL> conditions . append ( { <EOL> '<STR_LIT>' : criterion . property_name , <EOL> '<STR_LIT>' : criterion . match_type , <EOL> '<STR_LIT>' : criterion . property_value , <EOL> } ) <EOL> update_case = False <EOL> update_property_name = None <EOL> update_property_value = None <EOL> for action in self . rule . automaticupdateaction_set . all ( ) : <EOL> if action . action == AutomaticUpdateAction . ACTION_UPDATE : <EOL> update_case = True <EOL> update_property_name = action . property_name <EOL> update_property_value = action . property_value <EOL> break <EOL> initial = { <EOL> '<STR_LIT:name>' : self . rule . name , <EOL> '<STR_LIT>' : self . rule . case_type , <EOL> '<STR_LIT>' : self . rule . server_modified_boundary , <EOL> '<STR_LIT>' : json . dumps ( conditions ) , <EOL> '<STR_LIT:action>' : ( <EOL> AddAutomaticCaseUpdateRuleForm . ACTION_UPDATE_AND_CLOSE <EOL> if update_case <EOL> else AddAutomaticCaseUpdateRuleForm . ACTION_CLOSE <EOL> ) , <EOL> '<STR_LIT>' : update_property_name , <EOL> '<STR_LIT>' : update_property_value , <EOL> } <EOL> return AddAutomaticCaseUpdateRuleForm ( domain = self . domain , initial = initial ) <EOL> @ property <EOL> @ memoized <EOL> def rule_form ( self ) : <EOL> if self . request . method == '<STR_LIT:POST>' : <EOL> return AddAutomaticCaseUpdateRuleForm ( <EOL> self . request . POST , <EOL> domain = self . domain , <EOL> initial = { '<STR_LIT>' : self . rule . case_type } <EOL> ) <EOL> else : <EOL> return self . initial_rule_form <EOL> def update_rule ( self , rule ) : <EOL> with transaction . atomic ( ) : <EOL> rule . name = self . rule_form . cleaned_data [ '<STR_LIT:name>' ] <EOL> rule . case_type = self . rule_form . cleaned_data [ '<STR_LIT>' ] <EOL> rule . server_modified_boundary = self . rule_form . cleaned_data [ '<STR_LIT>' ] <EOL> rule . last_run = None <EOL> rule . save ( ) <EOL> rule . automaticupdaterulecriteria_set . all ( ) . delete ( ) <EOL> rule . automaticupdateaction_set . all ( ) . delete ( ) <EOL> self . create_criteria ( rule ) <EOL> self . create_actions ( rule ) <EOL> def post ( self , request , * args , ** kwargs ) : <EOL> if self . rule_form . is_valid ( ) : <EOL> self . update_rule ( self . rule ) <EOL> return HttpResponseRedirect ( reverse ( AutomaticUpdateRuleListView . urlname , args = [ self . domain ] ) ) <EOL> return super ( JSONResponseMixin , self ) . get ( request , * args , ** kwargs ) </s>
