def pi_update_signatories(context): """fire automatic transitions on submission of document""" #first commit all pending db transactions for signatory in context.signatories.values(): wfc = IWorkflowController(signatory, None) if wfc is not None: wfc.fireAutomatic()
def handleSchedule(object, event): """ move scheduled items from to be scheduled state to schedule when draft agenda is finalised and vice versa """ session = Session() s = removeSecurityProxy(object) sitting = session.query(domain.GroupSitting).options( eagerload("group_sitting_type"), eagerload("item_schedule")).get(s.group_sitting_id) schedulings = map(removeSecurityProxy, sitting.item_schedule) if sitting.status == "draft_agenda": for sch in schedulings: if sch.item.type != "heading": wfc = IWorkflowController(sch.item) wf = wfc.workflow next_state = get_states(sch.item.type, tagged=["tobescheduled"]) for transition_id in wfc.getSystemTransitionIds(): t = wf.get_transition(transition_id) if t.destination in next_state: #TODO find out why firetransition fails for reschedule even #when the user has requisite permissions wfc.fireTransition(transition_id, check_security=False) break elif sitting.status == "published_agenda": for sch in schedulings: if sch.item.type != "heading": wfc = IWorkflowController(sch.item) wf = wfc.workflow next_state = get_states(sch.item.type, tagged=["scheduled"]) for transition_id in wfc.getSystemTransitionIds(): t = wf.get_transition(transition_id) if t.destination in next_state: wfc.fireTransition(transition_id, check_security=False) break
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form.""" if (not interfaces.IWorkspaceOrAdminSectionLayer.providedBy(request) or interfaces.IFormEditLayer.providedBy(request) or IVersion.providedBy(context) ): return () #!+wfc.workflow wf = IWorkflow(context, None) if wf is None: return () #state = IWorkflowController(context).state_controller.get_status() wfc = IWorkflowController(context) wf = wfc.workflow # !+wfc.workflow tids = wfc.getManualTransitionIds() parliament_id = getCurrentParliamentId() _url = url.absoluteURL(context, request) site_url2 = url.absoluteURL(getSite(), request) results = [] for tid in tids: state_transition = wf.get_transition(tid) #Compares the current url to homepage to determine whether #we are on workspace or not. #Fix for bug 319 #Someone should probably review this. if _url == site_url2: transition_url = site_url2 + \ "/archive/browse/parliaments/obj-" + \ str(parliament_id) + \ "/change_workflow_state?" + \ "transition=%s&next_url=..." % tid else: transition_url = _url + \ "/change_workflow_state?"\ "transition=%s&next_url=..." % tid extra = {"id": "workflow-transition-%s" % tid, "separator": None, "class": ""} state_title = translate(str(state_transition.title), domain="bungeni", context=request) results.append( dict(title=state_title, description="", action=transition_url, selected=False, transition_id=tid, icon=None, extra=extra, submenu=None)) return results
def retract_item(item): schedule_feature = feature.get_feature(item, "schedule") if schedule_feature is None: return # take back to schedule pending wfc = IWorkflowController(item) for state in schedule_feature.get_param("schedulable_states"): transitions = wfc.getFireableTransitionIdsToward(state) if transitions: wfc.fireTransition(transitions[0]) break
def retract_item(item): schedule_feature = feature.get_feature(item, "schedule") if schedule_feature is None: return # take back to schedule pending wfc = IWorkflowController(item) for state in schedule_feature.get_param("schedulable_states"): transitions = wfc.getFireableTransitionIdsToward(state) if transitions: wfc.fireTransition(transitions[0]) break
def retract_item(item): manager = interfaces.ISchedulingManager(item, None) if manager is None: return wfc = IWorkflowController(item, None) if wfc is None: return #take back to schedule pending for state in manager.schedulable_states: transitions = wfc.getFireableTransitionIdsToward(state) if transitions: wfc.fireTransition(transitions[0]) break
def __call__(self): wfc = IWorkflowController(self.context) wf = wfc.workflow tids = wfc.getManualTransitionIds() transitions = {} context_url = url.absoluteURL(self.context, self.request) for tid in tids: item_url = "%s/change_workflow_state?transition_id=%s" % (context_url, tid) title = translate(wf.get_transition(tid).title, domain="bungeni", context=self.request) transitions[tid] = {"url":item_url, "title":title} misc.set_json_headers(self.request) return simplejson.dumps(transitions)
def handleSchedule(object, event): """ move scheduled items from to be scheduled state to schedule when draft agenda is finalised and vice versa """ session = Session() s = removeSecurityProxy(object) sitting = session.query(domain.GroupSitting ).options(eagerload("group_sitting_type"), eagerload("item_schedule") ).get(s.group_sitting_id) schedulings = map(removeSecurityProxy, sitting.item_schedule) if sitting.status == "draft_agenda": for sch in schedulings: if sch.item.type != "heading": wfc = IWorkflowController(sch.item) wf = wfc.workflow next_state = get_states(sch.item.type, tagged=["tobescheduled"]) for transition_id in wfc.getSystemTransitionIds(): t = wf.get_transition(transition_id) if t.destination in next_state: #TODO find out why firetransition fails for reschedule even #when the user has requisite permissions wfc.fireTransition(transition_id, check_security=False) break elif sitting.status == "published_agenda": for sch in schedulings: if sch.item.type != "heading": wfc = IWorkflowController(sch.item) wf = wfc.workflow next_state = get_states(sch.item.type, tagged=["scheduled"]) for transition_id in wfc.getSystemTransitionIds(): t = wf.get_transition(transition_id) if t.destination in next_state: wfc.fireTransition(transition_id, check_security=False) break
def add_wf_meta(enum): index, item = enum node = nodes[index] wfc = IWorkflowController(node.item, None) if wfc is None: return #!+SCHEDULING_FILTERS(mb, mar-2012) Find a more elegant way to do this # perhaps as a workflow feature if not len(wfc.workflow.get_state_ids(keys=["draft"], restrict=False)): return item["wf_state"] = translate_i18n(wfc.state_controller.get_state().title) item["wf_actions"] = [ dict(value=transition, text=translate_i18n(wfc.workflow.get_transition(transition).title)) for transition in wfc.getFireableTransitionIds() ]
def fireTransitionScheduled(item, check_security=False): try: IWorkflowController(item).fireTransitionToward("scheduled", check_security=False) raise RuntimeWarning( """It has WORKED !!! fireTransitionToward("scheduled")""") except (NoTransitionAvailableError, RuntimeWarning): debug.log_exc_info(sys.exc_info(), log.error)
def queue_object_serialization(obj): """Send a message to the serialization queue for non-draft documents """ connection = bungeni.core.notifications.get_mq_connection() if not connection: log.error("Could not get rabbitmq connection. Will not send " "AMQP message for this change." ) log.error("Serialization failure for item %r", obj) ## If there is no connection MQ dont publish at all !!! !+MQ(ah, 2014-09-19) """ log.warn("Publishing XML directly - this will slow things down") try: publish_to_xml(obj) except Exception, e: notify_serialization_failure(SERIALIZE_FAILURE_TEMPLATE, obj=obj, message="", error=e) notify_serialization_failure(None, body="Failed to find running RabbitMQ", subject="Notice - RabbitMQ") notify_serialization_failure(None, body="Failed to find running RabbitMQ", subject="Notice - RabbitMQ") return """ wf_state = None try: wfc = IWorkflowController(obj) wf_state = wfc.state_controller.get_state() except InvalidStateError: # this is probably a draft document - skip queueing log.warn("Could not get workflow state for object %s. " "State: %s ; this could be a document in draft state", obj, wf_state) return unproxied = zope.security.proxy.removeSecurityProxy(obj) mapper = object_mapper(unproxied) primary_key = mapper.primary_key_from_instance(unproxied) # !+CAPI(mb, Aug-2012) capi lookup in as at r9707 fails for some keys # e.g. get_type_info(instance).workflow_key resolves while # get_type_info(same_workflow_key) raises KeyError message = { "obj_key": primary_key, "obj_type": unproxied.__class__.__name__ } kwargs = dict( exchange=SERIALIZE_EXCHANGE, routing_key=SERIALIZE_ROUTING_KEY, body=simplejson.dumps(message), properties=pika.BasicProperties( content_type="text/plain", delivery_mode=2 ) ) txn = transaction.get() log.error("AACH key: %s , type : %s", primary_key, unproxied.__class__) txn.addAfterCommitHook(bungeni.core.notifications.post_commit_publish, (), kwargs)
def _traverse(self, request, name): self.context = removeSecurityProxy(self.context) session = Session() context = session.merge(self.context) debate = session.query(domain.DebateRecord) \ .filter(domain.DebateRecord.sitting_id == context.sitting_id) \ .first() if not debate: debate = domain.DebateRecord() debate.sitting_id = context.sitting_id session.add(debate) wfc = IWorkflowController(debate) wfc.fireAutomatic() session.flush() debate.__name__ = self.traversalName debate.__parent__ = self.context interface.alsoProvides(debate, ILocation) return debate
def dissolveChildGroups(groups, context): for group in groups: # !+group_dissolve(mr, may-2012) assumes that workflow of EVERY group # type has a state "active" AND a state "dissolved" AND a transition # from first to second AND that the semantic meaning of state # "dissolved" is indeed dissolution of the group... should probably # be replaced by a GroupType.dissolve() method that knows how to # dissolve itself. IWorkflowController(group).fireTransition("active-dissolved", check_security=False)
def _traverse(self, request, name): self.context = removeSecurityProxy(self.context) session = Session() context = session.merge(self.context) debate = session.query(domain.DebateRecord) \ .filter(domain.DebateRecord.sitting_id == context.sitting_id) \ .first() if not debate: debate = domain.DebateRecord() debate.sitting_id = context.sitting_id session.add(debate) wfc = IWorkflowController(debate) wfc.fireAutomatic() session.flush() debate.__name__ = self.traversalName debate.__parent__ = self.context interface.alsoProvides(debate, ILocation) return debate
def add_wf_meta(enum): index, item = enum node = nodes[index] item["item_id"] = node.item_id if model_interfaces.IScheduleText.providedBy(node.item): return if not include_wf: return wfc = IWorkflowController(node.item, None) if wfc is None: return item["wf_state"] = translate_i18n( wfc.state_controller.get_state().title) item["wf_actions"] = [ dict(value=transition, text=translate_i18n( wfc.workflow.get_transition(transition).title)) for transition in wfc.getFireableTransitionIds() ]
def schedule_sitting_items(context): # !+fireTransitionToward(mr, dec-2010) sequence of fireTransitionToward # calls was introduced in r5818, 28-jan-2010 -- here the code is reworked # to be somewhat more sane, and added logging of both SUCCESS and of # FAILURE of each call to fireTransitionToward(). # # The check/logging should be removed once it is understood whether # NoTransitionAvailableError is *always* raised (i.e. fireTransitionToward is # broken) or it is indeed raised correctly when it should be. def fireTransitionScheduled(item, wfc, toward): try: wfc.fireTransitionToward(toward, check_security=True) raise RuntimeWarning("It has WORKED !!! fireTransitionToward(%r)" % (toward)) except (NoTransitionAvailableError, RuntimeWarning): debug.log_exc_info(sys.exc_info(), log.error) for schedule in context.items.values(): wfc = IWorkflowController(schedule.item, None) if wfc is None: continue wf = wfc.workflow manager = interfaces.ISchedulingManager(schedule.item, None) if not manager: continue try: for target_state in manager.scheduled_states: if wf.get_state(target_state): fireTransitionScheduled(schedule.item, wfc, target_state) except InvalidStateError: # try to fire to next logical scheduled state if (wfc.state_controller.get_status() in manager.schedulable_states): transition_ids = wfc.getFireableTransitionIds() for transition_id in transition_ids: transition = wf.get_transition(transition_id) if (transition.destination in manager.scheduled_states): fireTransitionScheduled(schedule.item, wfc, toward=transition.destination) break
def add_wf_meta(enum): index, item = enum node = nodes[index] wfc = IWorkflowController(node.item, None) if wfc is None: return #!+SCHEDULING_FILTERS(mb, mar-2012) Find a more elegant way to do this # perhaps as a workflow feature if not len( wfc.workflow.get_state_ids(keys=["draft"], restrict=False)): return item["wf_state"] = translate_i18n( wfc.state_controller.get_state().title) item["wf_actions"] = [ dict(value=transition, text=translate_i18n( wfc.workflow.get_transition(transition).title)) for transition in wfc.getFireableTransitionIds() ]
def __call__(self): transition_id = self.request.get("transition_id", None) if transition_id: wfc = IWorkflowController(self.context) wf = wfc.workflow try: wf.get_transition(transition_id) except InvalidTransitionError: self.request.response.setStatus(400) return "Invalid Transition" try: wfc.fireTransition(transition_id) except WorkflowRuntimeError: self.request.response.setStatus(400) return "Runtime error occured while executing transition" self.request.response.setStatus(200) return "Success" else: self.request.response.setStatus(400) return "No transition id supplied"
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form. !+TAL-friendly(mr, sep-2011) means what? """ if (not interfaces.IWorkspaceOrAdminSectionLayer.providedBy(request) or interfaces.IFormEditLayer.providedBy(request) or IVersion.providedBy(context)): return () #!+wfc.workflow wf = IWorkflow(context, None) if wf is None: return () #state = IWorkflowController(context).state_controller.get_status() wfc = IWorkflowController(context) wf = wfc.workflow tids = wfc.getManualTransitionIds() _url = url.absoluteURL(context, request) results = [] for tid in tids: transit_url = \ "%s/change_workflow_state?transition_id=%s&next_url=..." % ( _url, tid) extra = { "id": "workflow-transition-%s" % tid, "separator": None, "class": "" } state_title = translate(str(wf.get_transition(tid).title), domain="bungeni", context=request) results.append( dict(title=state_title, description="", action=transit_url, selected=False, transition_id=tid, icon=None, extra=extra, submenu=None)) return results
def schedule_sitting_items(context): # !+fireTransitionToward(mr, dec-2010) sequence of fireTransitionToward # calls was introduced in r5818, 28-jan-2010 -- here the code is reworked # to be somewhat more sane, and added logging of both SUCCESS and of # FAILURE of each call to fireTransitionToward(). # # The check/logging should be removed once it is understood whether # NoTransitionAvailableError is *always* raised (i.e. fireTransitionToward is # broken) or it is indeed raised correctly when it should be. def fireTransitionScheduled(item, wfc, toward=SCHEDULED): try: wfc.fireTransitionToward(toward, check_security=True) raise RuntimeWarning( "It has WORKED !!! fireTransitionToward(%r)" % (toward)) except (NoTransitionAvailableError, RuntimeWarning): debug.log_exc_info(sys.exc_info(), log.error) for schedule in context.items.values(): wfc = IWorkflowController(schedule.item, None) if wfc is None: continue wf = wfc.workflow try: if wf.get_state(SCHEDULED): fireTransitionScheduled(schedule.item, wfc) except InvalidStateError: # try to fire to next logical scheduled state if (wfc.state_controller.get_status() in wfc.workflow.get_state_ids(tagged=[PENDING], restrict=False) ): transition_ids = wfc.getFireableTransitionIds() for transition_id in transition_ids: transition = wf.get_transition(transition_id) if (transition.destination in wfc.workflow.get_state_ids(tagged=[SCHEDULED], restrict=False) ): fireTransitionScheduled(schedule.item, wfc, toward=transition.destination) break
def check_finalized(schedule): wfc = IWorkflowController(schedule.item, None) if wfc is None: return True #!+TYPES(mb, march-2012) There might be a more elegant approach here # to filter out 'text records' from the schedule if interfaces.IBungeniParliamentaryContent.providedBy(schedule.item): manager = interfaces.ISchedulingManager(schedule.item) return (wfc.state_controller.get_status() not in manager.scheduled_states) else: return True
def check_finalized(schedule): wfc = IWorkflowController(schedule.item, None) if wfc is None: return True #!+TYPES(mb, march-2012) There might be a more elegant approach here # to filter out 'text records' from the schedule if interfaces.IBungeniParliamentaryContent.providedBy(schedule.item): return (wfc.state_controller.get_status() in wfc.workflow.get_state_ids(not_tagged=unfinalized_tags, restrict=False)) else: return True
def check_finalized(schedule): wfc = IWorkflowController(schedule.item, None) if wfc is None: return True #!+TYPES(mb, march-2012) There might be a more elegant approach here # to filter out 'text records' from the schedule if interfaces.ILegislativeContent.providedBy(schedule.item): schedule_feature = wfc.workflow.get_feature("schedule") return (wfc.state_controller.get_status() not in schedule_feature.get_param("scheduled_states")) else: return True
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form. !+TAL-friendly(mr, sep-2011) means what? """ if (not interfaces.IWorkspaceOrAdminSectionLayer.providedBy(request) or interfaces.IFormEditLayer.providedBy(request) or IVersion.providedBy(context) ): return () #!+wfc.workflow wf = IWorkflow(context, None) if wf is None: return () #state = IWorkflowController(context).state_controller.get_status() wfc = IWorkflowController(context) wf = wfc.workflow tids = wfc.getManualTransitionIds() _url = url.absoluteURL(context, request) results = [] for tid in tids: transit_url = ("%s/change_workflow_state?transition_id=%s&" "next_url=./workflow-redirect" % (_url, tid) ) extra = {"id": "workflow-transition-%s" % tid, "separator": None, "class": ""} state_title = translate(wf.get_transition(tid).title, domain="bungeni", context=request) results.append( dict(title=state_title, description="", action=transit_url, selected=False, transition_id=tid, icon=None, extra=extra, submenu=None)) return results
def sign_document(self, context): """Sign context for current user if they have not already signed. Called from ui.forms.common.SignOpenDocumentForm.handle_sign_document(). """ user = get_login_user() signatory = get_signatory(context, user) if not signatory: signatory = new_signatory(user.user_id, context.doc_id) else: if not signatory.status == SIGNATORY_CONSENTED_STATE: wfc = IWorkflowController(signatory) wfc.state_controller.set_status(SIGNATORY_CONSENTED_STATE) return signatory
def schedule_sitting_items(context): # !+fireTransitionToward(mr, dec-2010) sequence of fireTransitionToward # calls was introduced in r5818, 28-jan-2010 -- here the code is reworked # to be somewhat more sane, and added logging of both SUCCESS and of # FAILURE of each call to fireTransitionToward(). # # The check/logging should be removed once it is understood whether # NoTransitionAvailableError is *always* raised (i.e. fireTransitionToward is # broken) or it is indeed raised correctly when it should be. def fireTransitionScheduled(item, wfc, toward): try: wfc.fireTransitionToward(toward, check_security=True) raise RuntimeWarning("It has WORKED !!! fireTransitionToward(%r)" % (toward)) except (NoTransitionAvailableError, RuntimeWarning): probing.log_exc_info(sys.exc_info(), log.error) for schedule in context.items.values(): if not IFeatureSchedule.providedBy(schedule.item): continue wfc = IWorkflowController(schedule.item) wf = wfc.workflow schedule_feature = wf.get_feature("schedule") scheduled_states = schedule_feature.get_param("scheduled_states") schedulable_states = schedule_feature.get_param("schedulable_states") try: for target_state in scheduled_states: if wf.get_state(target_state): fireTransitionScheduled(schedule.item, wfc, target_state) except InvalidStateError: # try to fire to next logical scheduled state if schedule.item.status in schedulable_states: # !+is_schedulable transition_ids = wfc.getFireableTransitionIds() for transition_id in transition_ids: transition = wf.get_transition(transition_id) if transition.destination in scheduled_states: fireTransitionScheduled(schedule.item, wfc, toward=transition.destination) break
def add_wf_meta(enum): index, item = enum node = nodes[index] item["item_id"] = node.item_id if model_interfaces.IScheduleText.providedBy(node.item): return if not include_wf: return wfc = IWorkflowController(node.item, None) if wfc is None: return item["wf_state"] = translate_i18n( wfc.state_controller.get_state().title ) item["wf_actions"] = [ dict( value=transition, text=translate_i18n( wfc.workflow.get_transition(transition).title ) ) for transition in wfc.getFireableTransitionIds() ]
def on_signatory_doc_workflow_transition(self, context): """Perform any workflow related actions on signatories and/or parent. """ # make (head)context owner a default signatory when doc is submitted to # signatories for consent if self.document_submitted(context): if not self.is_signatory(context, user=context.owner): new_signatory(context.owner_id, context.doc_id) # setup roles for signatory in context.sa_signatories: login = signatory.user.login if self.document_submitted(context): utils.set_role("bungeni.Signatory", login, context) utils.set_role("bungeni.Owner", login, signatory) elif self.auto_unsign(context): utils.unset_role("bungeni.Signatory", login, context) elif self.elapse_signatures(context): if signatory.status not in SIGNATORY_CONSENTED_STATES: utils.unset_role("bungeni.Signatory", login, context) # update signatories for signatory in context.sa_signatories: wfc = IWorkflowController(signatory) wfc.fireAutomatic()
def extra(self): wfc = IWorkflowController(self.context, None) if wfc is None: return {"id": self.id} status = wfc.state_controller.get_status() stateTitle = translate(str(wfc.workflow.get_state(status).title), domain="bungeni", context=self.request) return { "id": self.id, "class": "state-%s" % status, "state": status, "stateTitle": stateTitle }
def on_signatory_doc_workflow_transition(self, context): """Perform any workflow related actions on signatories and/or parent. """ # make (head)context owner a default signatory when doc is submitted to # signatories for consent if self.document_submitted(context): if not self.is_signatory(context, user=context.owner): new_signatory(context.owner_id, context.doc_id) # setup roles for signatory in context.sa_signatories: login = signatory.user.login if self.document_submitted(context): utils.set_role("bungeni.Signatory", login, context) utils.set_role("bungeni.Owner", login, signatory) elif self.auto_unsign(context): utils.unset_role("bungeni.Signatory", login, context) elif self.elapse_signatures(context): if signatory.status not in SIGNATORY_CONSENTED_STATES: utils.unset_role("bungeni.Signatory", login, context) # update signatories for signatory in context.sa_signatories: wfc = IWorkflowController(signatory) wfc.fireAutomatic()
def setup_roles(self): if self.document_submitted(): make_owner_signatory(self.context) for signatory in self.signatories: login_id = signatory.owner.login IPrincipalRoleMap(self.context).assignRoleToPrincipal( SIGNATORY_ROLE, login_id) IPrincipalRoleMap(signatory).assignRoleToPrincipal( OWNER_ROLE, login_id) elif self.document_is_draft(): for signatory in self.signatories: IPrincipalRoleMap(self.context).unsetRoleForPrincipal( SIGNATORY_ROLE, signatory.owner.login) elif self.expire_signatures(): for signatory in self.signatories: wfc = IWorkflowController(signatory) if (wfc.state_controller.get_status() in SIGNATORIES_REJECT_STATES): IPrincipalRoleMap(self.context).unsetRoleForPrincipal( SIGNATORY_ROLE, signatory.owner.login)
def pi_unset_signatory_roles(context, all=False): """Unset signatory roles for members who have rejected document """ if all: for signatory in context.signatories.values(): owner_login = get_owner_login_pi(signatory) assign_signatory_role(context, owner_login, unset=True) else: for signatory in context.signatories.values(): wfc = IWorkflowController(signatory, None) if wfc is not None: if (wfc.state_controller.get_status() in SIGNATORIES_REJECT_STATES): owner_login = get_owner_login_pi(signatory) log.debug( "Removing signatory role for [%s] on " "document: [%s]", owner_login, signatory.item) assign_signatory_role(context, owner_login, unset=True) else: log.debug("Unable to get workflow controller for : %s", signatory)
def sign_document(context, user_id): """Sign context for this user if they have not already signed """ signatories = removeSecurityProxy(context.signatories) signatory = None for sgn in signatories.values(): if sgn.user_id == user_id: signatory = removeSecurityProxy(sgn) break if not signatory: session = Session() signatory = domain.Signatory() signatory.user_id = user_id signatory.head_id = context.doc_id session.add(signatory) session.flush() zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(signatory)) else: wfc = IWorkflowController(signatory) if not wfc.state_controller.get_status() == SIGNATORY_CONSENTED_STATE: wfc.state_controller.set_status(SIGNATORY_CONSENTED_STATE) return signatory
def dissolve(group): """Perform any actions required to dissolve a group - typically set as an action on group workflow state "dissolved". When a group is dissolved: - all members of this group get the end date of the group (if they do not have one yet) and there active_p status gets set to False. - any child group is ended and dissolved. """ from bungeni.core.workflows import dbutils dbutils.deactivate_group_members(group) for ended_child_group in dbutils.end_child_groups(group): # !+GROUP_DISSOLVE assumes that workflow of EVERY child group type has: # - a state "active" AND a state "dissolved" AND # - a transition from first to second AND # - that the semantic meaning of the state "dissolved" is indeed # dissolution of the group... # should probably replace with a GroupType.dissolve() method that # knows how to dissolve itself and/or as dissolve feature parameters IWorkflowController(ended_child_group).fireTransition( "active-dissolved", check_security=False) utils.unset_group_local_role(group)
def dissolveChildGroups(groups, context): for group in groups: IWorkflowController(group).fireTransition("active-dissolved", check_security=False)
def handle_insert(self, action, data): session = Session() data["rec_end_date"] = data["end_date"] self.template_data = [] initial_sitting = None length = data["event_length"] venue_id = unicode(data["venue"]) if data['venue'] else None if data.get("rec_type") not in [None, "none"]: data["end_date"] = data["start_date"] + timedelta(seconds=length) self.request.form["end_date"] = data["end_date"].strftime( DT_FORMAT) data["headless"] = "true" self.request.form["venue_id"] = data["venue_id"] = venue_id self.request.form["headless"] = "true" add_form = AddForm(self.sittings_container, self.request) add_form.update() if not add_form.errors: initial_sitting = removeSecurityProxy(add_form.created_object) else: return self.insert_sitting_failure_handler(action, data, add_form.errors) if ("rec_type" in data.keys()) and (data["rec_type"] not in [None, "none"]): # create recurring sittings #base_sitting_length = sitting_length + timedelta(hours=1) sitting_length = timedelta(seconds=length) base_sitting_length = timedelta(seconds=length) + timedelta( hours=1) dates = self.generate_dates(data) initial_sitting.recurring_type = data.get("rec_type") initial_sitting.recurring_id = 0 initial_sitting.sitting_length = length for count, date in enumerate(dates): if not count: #we've already added the initial sitting initial_sitting.recurring_end_date = ( dates[len(dates) - 1] + base_sitting_length) session.merge(initial_sitting) continue sitting_data = copy(data) sitting_data["start_date"] = date.strftime(DT_FORMAT) sitting_data["end_date"] = (date + sitting_length).strftime(DT_FORMAT) request_copy = copy(self.request) request_copy.form = sitting_data add_form = AddForm(self.sittings_container, request_copy) add_form.update() if not add_form.errors: # use finishConstruction API here obj = add_form.created_object obj.sitting_length = int(time.mktime(date.timetuple())) obj.recurring_id = initial_sitting.sitting_id session.merge(obj) else: initial_sitting.recurring_type = data.get("rec_type") initial_sitting.recurring_id = data.get("event_pid", 0) if data.get("event_length"): initial_sitting.sitting_length = data.get("event_length") session.merge(initial_sitting) wfc = IWorkflowController(initial_sitting) wfc.fireAutomatic() sitting_action = "inserted" if data["rec_type"] == "none": sitting_action = "deleted" session.merge(initial_sitting) self.template_data.append({ "sitting_id": initial_sitting.sitting_id, "action": sitting_action, "ids": data["ids"], }) self.request.response.setHeader("Content-type", "text/xml") return self.xml_template()
def update_signatories(self): for signatory in self.signatories: wfc = IWorkflowController(signatory) wfc.fireAutomatic()
def __init__(self, context): self.context = context self.object_type = context.type self.wf_status = IWorkflowController( context).state_controller.get_status()
def handle_insert(self, action, data): session = Session() data["rec_end_date"] = data["end_date"] self.template_data = [] initial_sitting = None length = data["event_length"] venue_id = unicode(data["venue"]) if data['venue'] else None if data.get("rec_type") not in [None, "none"]: data["end_date"] = data["start_date"] + timedelta(seconds=length) self.request.form["end_date"] = data["end_date"].strftime(DT_FORMAT) data["headless"] = "true" self.request.form["venue_id"] = data["venue_id"] = venue_id self.request.form["headless"] = "true" add_form = AddForm(self.sittings_container, self.request) add_form.update() if not add_form.errors: initial_sitting = removeSecurityProxy(add_form.created_object) else: return self.insert_sitting_failure_handler(action, data, add_form.errors ) if ("rec_type" in data.keys()) and (data["rec_type"] not in [None, "none"]): # create recurring sittings #base_sitting_length = sitting_length + timedelta(hours=1) sitting_length = timedelta(seconds=length) base_sitting_length = timedelta(seconds=length) + timedelta(hours=1) dates = self.generate_dates(data) initial_sitting.recurring_type = data.get("rec_type") initial_sitting.recurring_id = 0 initial_sitting.sitting_length = length for count, date in enumerate(dates): if not count: #we've already added the initial sitting initial_sitting.recurring_end_date = ( dates[len(dates)-1] + base_sitting_length) session.merge(initial_sitting) continue sitting_data = copy(data) sitting_data["start_date"] = date.strftime(DT_FORMAT) sitting_data["end_date"] = (date + sitting_length).strftime(DT_FORMAT) request_copy = copy(self.request) request_copy.form = sitting_data add_form = AddForm(self.sittings_container, request_copy) add_form.update() if not add_form.errors: # use finishConstruction API here obj = add_form.created_object obj.sitting_length = int(time.mktime(date.timetuple())) obj.recurring_id = initial_sitting.sitting_id session.merge(obj) else: initial_sitting.recurring_type = data.get("rec_type") initial_sitting.recurring_id = data.get("event_pid", 0) if data.get("event_length"): initial_sitting.sitting_length = data.get("event_length") session.merge(initial_sitting) wfc = IWorkflowController(initial_sitting) wfc.fireAutomatic() sitting_action = "inserted" if data["rec_type"] == "none": sitting_action = "deleted" session.merge(initial_sitting) self.template_data.append({ "sitting_id": initial_sitting.sitting_id, "action": sitting_action, "ids": data["ids"], }) self.request.response.setHeader("Content-type", "text/xml") return self.xml_template()
def update_signatories(self): for signatory in self.signatories: wfc = IWorkflowController(signatory) wfc.fireAutomatic()
def saveSchedule(self): session = Session() sitting_id = self.sitting.sitting_id record_keys = [] planned_index = 1 def add_planned_index(obj, index): """add planned order key for non text record types """ if not (model_interfaces.IScheduleText.providedBy(obj.item)): obj.planned_order = planned_index index = index + 1 return index for (index, data_item) in enumerate(self.data): real_index = index + 1 data_schedule_id = data_item.get("schedule_id") data_item_id = data_item.get("item_id") data_item_type = data_item.get("item_type") schedule_item_type = data_item_type data_item_text = data_item.get("item_text") data_item_wf_status = data_item.get("wf_status") if not data_item_id: # create text record before inserting into schedule text_record = domain.AgendaTextRecord( text=data_item_text, record_type = data_item_type, language=get_default_language() ) session.add(text_record) session.flush() notify(ObjectCreatedEvent(text_record)) data_item_id = domain.get_mapped_object_id(text_record) schedule_item_type = domain.AgendaTextRecord.type schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=schedule_item_type, real_order=real_index, sitting_id=sitting_id ) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) else: if data_schedule_id: current_record = removeSecurityProxy( self.context.get(getItemKey(data_schedule_id)) ) current_record.real_order = real_index planned_index = add_planned_index(current_record, planned_index) session.add(current_record) session.flush() notify(ObjectModifiedEvent(current_record)) #workflow operations wfc = IWorkflowController(current_record.item, None) if wfc: if wfc and data_item_wf_status: try: wfc.workflow.get_transition(data_item_wf_status) wfc.fireTransition(data_item_wf_status) except InvalidTransitionError: log.error( "Invalid transition [%s] for object: [%s] ", data_item_wf_status, current_record ) wfc.fireAutomatic() #update text for text records text_record = removeSecurityProxy(current_record.item) if model_interfaces.IScheduleText.providedBy(text_record): schedule_item_type = domain.AgendaTextRecord.type if text_record.text != data_item_text: text_record.text = data_item_text session.add(text_record) session.flush() notify(ObjectModifiedEvent(text_record)) else: schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=data_item_type, real_order=real_index, sitting_id=sitting_id ) planned_index = add_planned_index(schedule_record, planned_index) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) record_keys.append(self.RECORD_KEY % (schedule_item_type, data_item_id)) records_to_delete = filter( lambda item:(self.RECORD_KEY % (item.item_type, item.item_id) not in record_keys ), [removeSecurityProxy(rec) for rec in self.context.values()] ) map(session.delete, records_to_delete) map(lambda deleted:notify(ObjectRemovedEvent(deleted)), records_to_delete)
def redirect_to(self): wfc = IWorkflowController(self.context) if (wfc.state_controller.get_status() in wfc.workflow.get_state_ids(tagged=["draft"])): return "./schedule" return WorkflowRedirect.redirect_to
def doc_workflow(ob, event): wfc = IWorkflowController(ob, None) if wfc: manager = interfaces.ISignatoryManager(ob) manager.fire_workflow_actions()