def assign(contract_id, flow_id, user_id):
    '''Assign a contract to an admin or a conductor
    '''
    contract = ContractBase.query.get(contract_id)
    try:
        stages = create_contract_stages(flow_id, contract_id, contract=contract)
        _, contract, _ = transition_stage(contract_id, contract=contract, stages=stages)
    except IntegrityError, e:
        # we already have the sequence for this, so just
        # rollback and pass
        db.session.rollback()
        pass
def detail(contract_id, stage_id=-1):
    '''View to control an individual stage update process
    '''
    if request.args.get('transition'):

        clicked = int(request.args.get('destination')) if \
            request.args.get('destination') else None

        stage, mod_contract, complete = transition_stage(
            contract_id, destination=clicked, user=current_user
        )
        if complete:
            return redirect(url_for('conductor.edit', contract_id=mod_contract.id))

        return redirect(url_for(
            'conductor.detail', contract_id=contract_id, stage_id=stage.id
        ))

    if stage_id == -1:
        # redirect to the current stage page
        contract_stage = ContractStage.query.join(
            ContractBase, ContractBase.id == ContractStage.contract_id
        ).filter(
            ContractStage.contract_id == contract_id,
            ContractStage.stage_id == ContractBase.current_stage_id
        ).first()

        return redirect(url_for(
            'conductor.detail', contract_id=contract_id, stage_id=contract_stage.id
        ))

    stages = db.session.query(
        ContractStage.contract_id, ContractStage.stage_id, ContractStage.id,
        ContractStage.entered, ContractStage.exited, Stage.name,
        Stage.send_notifs, Stage.post_opportunities, ContractBase.description
    ).join(Stage, Stage.id == ContractStage.stage_id).join(
        ContractBase, ContractBase.id == ContractStage.contract_id
    ).filter(
        ContractStage.contract_id == contract_id
    ).order_by(ContractStage.id).all()

    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()
    opportunity_form = PostOpportunityForm()

    forms = {
        'activity': note_form, 'update': update_form, 'post': opportunity_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):
            return redirect(url_for(
                'conductor.detail', contract_id=contract_id, stage_id=stage_id
            ))
        else:
            active_tab = '#' + submitted_form

    actions = ContractStageActionItem.query.filter(
        ContractStageActionItem.contract_stage_id == stage_id
    ).order_by(db.text('taken_at asc')).all()

    actions.extend([
        ContractStageActionItem(action_type='entered', action_detail=active_stage.entered, taken_at=active_stage.entered),
        ContractStageActionItem(action_type='exited', action_detail=active_stage.exited, taken_at=active_stage.exited)
    ])
    actions = sorted(actions, key=lambda stage: stage.get_sort_key())

    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, contract_id=contract_id,
            current_user=current_user, active_stage=active_stage,
            current_stage=current_stage
        )
    abort(404)