def transition(contract_id, stage_id): contract = ContractBase.query.get(contract_id) stage = ContractStage.query.filter(ContractStage.id == stage_id).first() complete_form = CompleteForm(started=stage.entered) if (request.method == 'POST' and complete_form.validate_on_submit()) or (request.method == 'GET'): if request.method == 'POST': completed_time = current_app.config['DISPLAY_TIMEZONE'].localize( complete_form.complete.data ).astimezone(pytz.UTC).replace(tzinfo=None) else: completed_time = datetime.datetime.utcnow() if not contract: abort(404) clicked = int(request.args.get('destination')) if \ request.args.get('destination') else None try: actions = contract.transition(current_user, destination=clicked, complete_time=completed_time) for action in actions: db.session.add(action) db.session.commit() except IntegrityError: db.session.rollback() pass except Exception: db.session.rollback() raise current_app.logger.info( 'CONDUCTOR TRANSITION - Contract for {} (ID: {}) transition to {}'.format( contract.description, contract.id, contract.current_stage.name ) ) if contract.completed_last_stage(): url = url_for('conductor.edit', contract_id=contract.id) else: url = url_for('conductor.detail', contract_id=contract.id) return redirect(url) session['invalid_date-{}'.format(contract_id)] = complete_form.errors['complete'][0] return redirect(url_for('conductor.detail', contract_id=contract.id))
def detail(contract_id, stage_id=-1): '''View to control an individual stage update process ''' contract = ContractBase.query.get(contract_id) if not contract: abort(404) if contract.completed_last_stage(): return redirect(url_for('conductor.edit', contract_id=contract.id)) if stage_id == -1: # redirect to the current stage page contract_stage = contract.get_current_stage() if contract_stage: return redirect(url_for( 'conductor.detail', contract_id=contract_id, stage_id=contract_stage.id )) current_app.logger.warning('Could not find stages for this contract, aborting!') abort(500) stages = get_contract_stages(contract) try: active_stage = [i for i in stages if i.id == stage_id][0] current_stage = [i for i in stages if i.entered and not i.exited][0] if active_stage.entered is None: abort(404) except IndexError: abort(404) note_form = NoteForm() update_form = SendUpdateForm(obj=UpdateFormObj(current_stage)) opportunity_form = PostOpportunityForm( obj=contract.opportunity if contract.opportunity else ConductorObj(contract) ) metadata_form = ContractMetadataForm(obj=ContractMetadataObj(contract)) complete_form = CompleteForm() if session.get('invalid_date-{}'.format(contract_id), False): complete_form.errors['complete'] = session.pop('invalid_date-{}'.format(contract_id)) forms = { 'activity': note_form, 'update': update_form, 'post': opportunity_form, 'update-metadata': metadata_form } active_tab = '#activity' submitted_form = request.args.get('form', None) if submitted_form: if handle_form( forms[submitted_form], submitted_form, stage_id, current_user, contract, active_stage ): return redirect(url_for( 'conductor.detail', contract_id=contract_id, stage_id=stage_id )) else: active_tab = '#' + submitted_form actions = contract.filter_action_log() # actions = contract.build_complete_action_log() subscribers, total_subscribers = build_subscribers(contract) flows = Flow.query.filter(Flow.id != contract.flow_id).all() current_app.logger.info( 'CONDUCTOR DETAIL VIEW - Detail view for contract {} (ID: {}), stage {}'.format( contract.description, contract.id, current_stage.name ) ) opportunity_form.display_cleanup() if len(stages) > 0: return render_template( 'conductor/detail.html', stages=stages, actions=actions, active_tab=active_tab, note_form=note_form, update_form=update_form, opportunity_form=opportunity_form, metadata_form=metadata_form, complete_form=complete_form, contract=contract, current_user=current_user, active_stage=active_stage, current_stage=current_stage, flows=flows, subscribers=subscribers, total_subscribers=total_subscribers, current_stage_enter=pytz.UTC.localize( current_stage.entered ).astimezone(current_app.config['DISPLAY_TIMEZONE']), categories=opportunity_form.get_categories(), subcategories=opportunity_form.get_subcategories() ) abort(404)
def detail(contract_id, stage_id=-1): '''View to control an individual stage update process This is the primary view for conductor. All actions that users can take with a :py:class:`~purchasing.data.contracts.ContractBase` flow through here. .. seealso:: There are a number of forms that are used on this page to allow the users to do actions directly from the management step: * :py:class:`~purchasing.conductor.forms.NoteForm` to allow users to take notes * :py:class:`~purchasing.conductor.forms.SendUpdateForm` to allow users to send email updates * :py:class:`~purchasing.conductor.forms.PostOpportunityForm` to allow users to post opportunities directly to :doc:`/beacon` * :py:class:`~purchasing.conductor.forms.ContractMetadataForm` to allow users to update a contract's metadata * :py:class:`~purchasing.conductor.forms.CompleteForm` to allow users to transition to the next :py:class:`~purchasing.data.stages.Stage` in the contract's :py:class:`~purchasing.data.flows.Flow` :param contract_id: Primary key ID for a :py:class:`~purchasing.data.contracts.ContractBase` :param stage_id: Primary key ID for a :py:class:`~purchasing.data.contract_stages.ContractStage` :status 200: Render the detail :status 302: Post a specific form. This form will either transition to the next contract stage if it is a :py:class:`~purchasing.conductor.forms.CompleteForm`, or perform whatever action is in that form's ``post_validate_action`` method :status 404: Contract not found ''' contract = ContractBase.query.get(contract_id) if not contract: abort(404) if contract.completed_last_stage(): return redirect(url_for('conductor.edit', contract_id=contract.id)) if stage_id == -1: # redirect to the current stage page contract_stage = contract.get_current_stage() if contract_stage: return redirect( url_for('conductor.detail', contract_id=contract_id, stage_id=contract_stage.id)) current_app.logger.warning( 'Could not find stages for this contract, aborting!') abort(500) stages = contract.get_contract_stages() try: active_stage = [i for i in stages if i.id == stage_id][0] current_stage = [i for i in stages if i.entered and not i.exited][0] if active_stage.entered is None: abort(404) except IndexError: abort(404) note_form = NoteForm() update_form = SendUpdateForm(obj=UpdateFormObj(current_stage)) opportunity_form = PostOpportunityForm( obj=contract.opportunity if contract. opportunity else ConductorToBeaconObj(contract)) metadata_form = ContractMetadataForm(obj=ContractMetadataObj(contract)) complete_form = CompleteForm() if session.get('invalid_date-{}'.format(contract_id), False): complete_form.errors['complete'] = session.pop( 'invalid_date-{}'.format(contract_id)) forms = { 'activity': note_form, 'update': update_form, 'post': opportunity_form, 'update-metadata': metadata_form } active_tab = '#activity' submitted_form_name = request.args.get('form', None) if submitted_form_name: submitted_form = forms[submitted_form_name] if submitted_form.validate_on_submit(): action = ContractStageActionItem( contract_stage_id=stage_id, action_type=submitted_form_name, taken_by=current_user.id, taken_at=datetime.datetime.utcnow()) action = submitted_form.post_validate_action( action, contract, current_stage) db.session.add(action) db.session.commit() return redirect( url_for('conductor.detail', contract_id=contract_id, stage_id=stage_id)) else: active_tab = '#' + submitted_form_name actions = contract.filter_action_log() # actions = contract.build_complete_action_log() subscribers, total_subscribers = contract.build_subscribers() flows = Flow.query.filter(Flow.id != contract.flow_id).all() current_app.logger.info( 'CONDUCTOR DETAIL VIEW - Detail view for contract {} (ID: {}), stage {}' .format(contract.description, contract.id, current_stage.name)) opportunity_form.display_cleanup() if len(stages) > 0: return render_template( 'conductor/detail.html', stages=stages, actions=actions, active_tab=active_tab, note_form=note_form, update_form=update_form, opportunity_form=opportunity_form, metadata_form=metadata_form, complete_form=complete_form, contract=contract, current_user=current_user, active_stage=active_stage, current_stage=current_stage, flows=flows, subscribers=subscribers, total_subscribers=total_subscribers, current_stage_enter=localize_datetime(current_stage.entered), categories=opportunity_form.get_categories(), subcategories=opportunity_form.get_subcategories()) abort(404)
def transition(contract_id, stage_id): '''Transition a contract from one date to the next date :param contract_id: Primary key ID for a :py:class:`~purchasing.data.contracts.ContractBase` :param stage_id: Primary key ID for a :py:class:`~purchasing.data.contract_stages.ContractStage` .. seealso:: For the transition, see the :py:meth:`~purchasing.data.contracts.ContractBase.transition` method directly :status 302: Perform the transition, and redirect back to the detail view with either the new stage or the appropriate error message :status 404: Contract not found ''' contract = ContractBase.query.get(contract_id) stage = ContractStage.query.filter(ContractStage.id == stage_id).first() complete_form = CompleteForm(started=stage.entered) if (request.method == 'POST' and complete_form.validate_on_submit()) or (request.method == 'GET'): if request.method == 'POST': completed_time = current_app.config['DISPLAY_TIMEZONE'].localize( complete_form.complete.data).astimezone( pytz.UTC).replace(tzinfo=None) else: completed_time = datetime.datetime.utcnow() if not contract: abort(404) clicked = int(request.args.get('destination')) if \ request.args.get('destination') else None try: actions = contract.transition(current_user, destination=clicked, complete_time=completed_time) for action in actions: db.session.add(action) db.session.commit() except IntegrityError: db.session.rollback() pass except Exception: db.session.rollback() raise current_app.logger.info( 'CONDUCTOR TRANSITION - Contract for {} (ID: {}) transition to {}'. format(contract.description, contract.id, contract.current_stage.name)) if contract.completed_last_stage(): url = url_for('conductor.edit', contract_id=contract.id) else: url = url_for('conductor.detail', contract_id=contract.id) return redirect(url) session['invalid_date-{}'.format( contract_id)] = complete_form.errors['complete'][0] return redirect(url_for('conductor.detail', contract_id=contract.id))
def detail(contract_id, stage_id=-1): '''View to control an individual stage update process This is the primary view for conductor. All actions that users can take with a :py:class:`~purchasing.data.contracts.ContractBase` flow through here. .. seealso:: There are a number of forms that are used on this page to allow the users to do actions directly from the management step: * :py:class:`~purchasing.conductor.forms.NoteForm` to allow users to take notes * :py:class:`~purchasing.conductor.forms.SendUpdateForm` to allow users to send email updates * :py:class:`~purchasing.conductor.forms.PostOpportunityForm` to allow users to post opportunities directly to :doc:`/beacon` * :py:class:`~purchasing.conductor.forms.ContractMetadataForm` to allow users to update a contract's metadata * :py:class:`~purchasing.conductor.forms.CompleteForm` to allow users to transition to the next :py:class:`~purchasing.data.stages.Stage` in the contract's :py:class:`~purchasing.data.flows.Flow` :param contract_id: Primary key ID for a :py:class:`~purchasing.data.contracts.ContractBase` :param stage_id: Primary key ID for a :py:class:`~purchasing.data.contract_stages.ContractStage` :status 200: Render the detail :status 302: Post a specific form. This form will either transition to the next contract stage if it is a :py:class:`~purchasing.conductor.forms.CompleteForm`, or perform whatever action is in that form's ``post_validate_action`` method :status 404: Contract not found ''' contract = ContractBase.query.get(contract_id) if not contract: abort(404) if contract.completed_last_stage(): return redirect(url_for('conductor.edit', contract_id=contract.id)) if stage_id == -1: # redirect to the current stage page contract_stage = contract.get_current_stage() if contract_stage: return redirect(url_for( 'conductor.detail', contract_id=contract_id, stage_id=contract_stage.id )) current_app.logger.warning('Could not find stages for this contract, aborting!') abort(500) stages = contract.get_contract_stages() try: active_stage = [i for i in stages if i.id == stage_id][0] current_stage = [i for i in stages if i.entered and not i.exited][0] if active_stage.entered is None: abort(404) except IndexError: abort(404) note_form = NoteForm() update_form = SendUpdateForm(obj=UpdateFormObj(current_stage)) opportunity_form = PostOpportunityForm( obj=contract.opportunity if contract.opportunity else ConductorToBeaconObj(contract) ) metadata_form = ContractMetadataForm(obj=ContractMetadataObj(contract)) complete_form = CompleteForm() if session.get('invalid_date-{}'.format(contract_id), False): complete_form.errors['complete'] = session.pop('invalid_date-{}'.format(contract_id)) forms = { 'activity': note_form, 'update': update_form, 'post': opportunity_form, 'update-metadata': metadata_form } active_tab = '#activity' submitted_form_name = request.args.get('form', None) if submitted_form_name: submitted_form = forms[submitted_form_name] if submitted_form.validate_on_submit(): action = ContractStageActionItem( contract_stage_id=stage_id, action_type=submitted_form_name, taken_by=current_user.id, taken_at=datetime.datetime.utcnow() ) action = submitted_form.post_validate_action(action, contract, current_stage) db.session.add(action) db.session.commit() return redirect(url_for( 'conductor.detail', contract_id=contract_id, stage_id=stage_id )) else: active_tab = '#' + submitted_form_name actions = contract.filter_action_log() # actions = contract.build_complete_action_log() subscribers, total_subscribers = contract.build_subscribers() flows = Flow.query.filter(Flow.id != contract.flow_id).all() current_app.logger.info( 'CONDUCTOR DETAIL VIEW - Detail view for contract {} (ID: {}), stage {}'.format( contract.description, contract.id, current_stage.name ) ) opportunity_form.display_cleanup() if len(stages) > 0: return render_template( 'conductor/detail.html', stages=stages, actions=actions, active_tab=active_tab, note_form=note_form, update_form=update_form, opportunity_form=opportunity_form, metadata_form=metadata_form, complete_form=complete_form, contract=contract, current_user=current_user, active_stage=active_stage, current_stage=current_stage, flows=flows, subscribers=subscribers, total_subscribers=total_subscribers, current_stage_enter=localize_datetime(current_stage.entered), categories=opportunity_form.get_categories(), subcategories=opportunity_form.get_subcategories() ) abort(404)
def transition(contract_id, stage_id): '''Transition a contract from one date to the next date :param contract_id: Primary key ID for a :py:class:`~purchasing.data.contracts.ContractBase` :param stage_id: Primary key ID for a :py:class:`~purchasing.data.contract_stages.ContractStage` .. seealso:: For the transition, see the :py:meth:`~purchasing.data.contracts.ContractBase.transition` method directly :status 302: Perform the transition, and redirect back to the detail view with either the new stage or the appropriate error message :status 404: Contract not found ''' contract = ContractBase.query.get(contract_id) stage = ContractStage.query.filter(ContractStage.id == stage_id).first() complete_form = CompleteForm(started=stage.entered) if (request.method == 'POST' and complete_form.validate_on_submit()) or (request.method == 'GET'): if request.method == 'POST': completed_time = current_app.config['DISPLAY_TIMEZONE'].localize( complete_form.complete.data ).astimezone(pytz.UTC).replace(tzinfo=None) else: completed_time = datetime.datetime.utcnow() if not contract: abort(404) clicked = int(request.args.get('destination')) if \ request.args.get('destination') else None try: actions = contract.transition( current_user, destination=clicked, complete_time=completed_time ) for action in actions: db.session.add(action) db.session.commit() except IntegrityError: db.session.rollback() pass except Exception: db.session.rollback() raise current_app.logger.info( 'CONDUCTOR TRANSITION - Contract for {} (ID: {}) transition to {}'.format( contract.description, contract.id, contract.current_stage.name ) ) if contract.completed_last_stage(): url = url_for('conductor.edit', contract_id=contract.id) else: url = url_for('conductor.detail', contract_id=contract.id) return redirect(url) session['invalid_date-{}'.format(contract_id)] = complete_form.errors['complete'][0] return redirect(url_for('conductor.detail', contract_id=contract.id))