def test_transition_next(self):
        _get = Mock()
        _get.side_effect = [
            ContractStage(stage=self.stage1),
            ContractStage(stage=self.stage2)
        ]
        ContractStage.get_one = _get
        _fix = Mock(return_value=[])
        ContractStage._fix_start_time = _fix

        self.active_contract.current_stage_id = self.stage1.id
        self.active_contract.current_stage = self.stage1

        action = self.active_contract.transition(self.user)
        self.assertEquals(len(action), 2)
        self.assertTrue(_get.called)
        self.assertTrue(_fix.called_once)
        self.assertEquals(action[0].action_type, 'exited')
        self.assertEquals(action[0].action_detail['stage_name'],
                          self.stage1.name)
        self.assertEquals(action[1].action_type, 'entered')
        self.assertEquals(action[1].action_detail['stage_name'],
                          self.stage2.name)
        self.assertEquals(self.active_contract.current_stage_id,
                          self.stage2.id)
Exemplo n.º 2
0
    def _transition_to_next(self, user):
        stages = self.flow.stage_order
        current_stage_idx = stages.index(self.current_stage.id)

        current_stage = ContractStage.get_one(self.id, self.flow.id, self.current_stage.id)

        next_stage = ContractStage.get_one(
            self.id, self.flow.id, self.flow.stage_order[current_stage_idx + 1]
        )

        self.current_stage_id = next_stage.stage.id
        return [current_stage.log_exit(user), next_stage.log_enter(user)]
    def test_transition_backward(self):
        _get = Mock(return_value=[ContractStage(stage=self.stage1), ContractStage(stage=self.stage2)])
        ContractStage.get_multiple = _get

        self.active_contract.current_stage_id = self.stage2.id
        self.active_contract.current_stage = self.stage2

        action = self.active_contract.transition(self.user, destination=self.stage1.id)
        self.assertEquals(_get.call_count, 1)
        self.assertEquals(len(action), 1)
        self.assertEquals(action[0].action_type, 'reversion')
        self.assertTrue(_get.called_once)
        self.assertEquals(self.active_contract.current_stage_id, self.stage1.id)
Exemplo n.º 4
0
    def _transition_to_first(self, user):
        contract_stage = ContractStage.get_one(
            self.id, self.flow.id, self.flow.stage_order[0]
        )

        self.current_stage_id = self.flow.stage_order[0]
        return [contract_stage.log_enter(user)]
    def current_contract_stage(self):
        """The contract's current stage

        Because the :py:class:`~purchasing.data.contract_stages.ContractStage` model
        has a three-part compound primary key, we pass the contract's ID, the
        contract's :py:class:`~purchasing.data.flows.Flow` id and its
        :py:class:`~purchasing.data.stages.Stage` id
        """
        return ContractStage.get_one(self.id, self.flow.id, self.current_stage.id)
    def test_transition_start(self):
        _get = Mock(return_value=ContractStage(stage=self.stage1))
        ContractStage.get_one = _get

        self.assertTrue(self.active_contract.current_stage_id is None)
        action = self.active_contract.transition(self.user)
        self.assertEquals(_get.call_count, 1)
        self.assertEquals(len(action), 1)
        self.assertEquals(action[0].action_type, 'entered')
        self.assertEquals(self.active_contract.current_stage_id, self.stage1.id)
    def current_contract_stage(self):
        '''The contract's current stage

        Because the :py:class:`~purchasing.data.contract_stages.ContractStage` model
        has a three-part compound primary key, we pass the contract's ID, the
        contract's :py:class:`~purchasing.data.flows.Flow` id and its
        :py:class:`~purchasing.data.stages.Stage` id
        '''
        return ContractStage.get_one(self.id, self.flow.id,
                                     self.current_stage.id)
    def test_transition_last(self, complete):
        _get = Mock(return_value=ContractStage(stage=self.stage1))
        ContractStage.get_one = _get

        self.active_contract.parent = ContractBaseFactory.build(description='test')
        self.active_contract.current_stage_id = self.stage3.id
        self.active_contract.current_stage = self.stage3

        action = self.active_contract.transition(self.user)
        self.assertEquals(_get.call_count, 1)
        self.assertEquals(len(action), 1)
        self.assertEquals(action[0].action_type, 'exited')
        self.assertTrue(complete.called_once)
    def _transition_to_next(self, user, complete_time):
        stages = self.flow.stage_order
        current_stage_idx = stages.index(self.current_stage.id)

        current_stage = self.current_contract_stage
        next_stage = ContractStage.get_one(
            self.id, self.flow.id,
            self.flow.stage_order[current_stage_idx + 1])

        self.current_stage_id = next_stage.stage.id
        return [
            current_stage.log_exit(user, complete_time),
            next_stage.log_enter(user, complete_time)
        ]
    def create_contract_stages(self, contract):
        '''Creates new rows in contract_stage table.

        Extracts the rows out of the given flow, and creates new rows
        in the contract_stage table for each of them.

        If the stages already exist, that means that the contract
        is switching back into a flow that it had already been in.
        To handle this, the "revert" flag is set to true, which
        should signal to a downstream process to roll the stages
        back to the first one in the current flow.

        Arguments:
            contract: A :py:class:`~purchasing.data.contracts.ContractBase` object

        Returns:
            A three-tuple of (the flow's stage order, a list of the flow's
            :py:class:`~purchasing.data.contract_stages.ContractStage` objects,
            whether the we are "reverting")

        '''
        revert = False
        contract_stages = []
        for stage_id in self.stage_order:
            try:
                contract_stages.append(ContractStage.create(
                    contract_id=contract.id,
                    flow_id=self.id,
                    stage_id=stage_id,
                ))
            except (IntegrityError, FlushError):
                revert = True
                db.session.rollback()
                stage = ContractStage.query.filter(
                    ContractStage.contract_id == contract.id,
                    ContractStage.flow_id == self.id,
                    ContractStage.stage_id == stage_id
                ).first()
                if stage:
                    contract_stages.append(stage)
                else:
                    raise IntegrityError

            except Exception:
                raise

        contract.flow_id = self.id
        db.session.commit()

        return self.stage_order, contract_stages, revert
Exemplo n.º 11
0
    def create_contract_stages(self, contract):
        '''Creates new rows in contract_stage table.

        Extracts the rows out of the given flow, and creates new rows
        in the contract_stage table for each of them.

        If the stages already exist, that means that the contract
        is switching back into a flow that it had already been in.
        To handle this, the "revert" flag is set to true, which
        should signal to a downstream process to roll the stages
        back to the first one in the current flow.

        Arguments:
            contract: A :py:class:`~purchasing.data.contracts.ContractBase` object

        Returns:
            A three-tuple of (the flow's stage order, a list of the flow's
            :py:class:`~purchasing.data.contract_stages.ContractStage` objects,
            whether the we are "reverting")

        '''
        revert = False
        contract_stages = []
        for stage_id in self.stage_order:
            try:
                contract_stages.append(
                    ContractStage.create(
                        contract_id=contract.id,
                        flow_id=self.id,
                        stage_id=stage_id,
                    ))
            except (IntegrityError, FlushError):
                revert = True
                db.session.rollback()
                stage = ContractStage.query.filter(
                    ContractStage.contract_id == contract.id,
                    ContractStage.flow_id == self.id,
                    ContractStage.stage_id == stage_id).first()
                if stage:
                    contract_stages.append(stage)
                else:
                    raise IntegrityError

            except Exception:
                raise

        contract.flow_id = self.id
        db.session.commit()

        return self.stage_order, contract_stages, revert
Exemplo n.º 12
0
    def _transition_backwards_to_destination(self, user, destination):
        destination_idx = self.flow.stage_order.index(destination)
        current_stage_idx = self.flow.stage_order.index(self.current_stage_id)

        if destination_idx > current_stage_idx:
            raise Exception('Skipping stages is not currently supported')

        stages = self.flow.stage_order[destination_idx:current_stage_idx + 1]
        to_revert = ContractStage.get_multiple(self.id, self.flow_id, stages)

        actions = []
        for contract_stage_ix, contract_stage in enumerate(to_revert):
            if contract_stage_ix == 0:
                actions.append(contract_stage.log_reopen(user))
                contract_stage.entered = datetime.datetime.now()
                contract_stage.exited = None
                self.current_stage_id = contract_stage.stage.id
            else:
                contract_stage.full_revert()

        return actions
    def _transition_backwards_to_destination(self, user, destination,
                                             complete_time):
        destination_idx = self.flow.stage_order.index(destination)
        current_stage_idx = self.flow.stage_order.index(self.current_stage_id)

        if destination_idx > current_stage_idx:
            raise Exception('Skipping stages is not currently supported')

        stages = self.flow.stage_order[destination_idx:current_stage_idx + 1]
        to_revert = ContractStage.get_multiple(self.id, self.flow_id, stages)

        actions = []
        for contract_stage_ix, contract_stage in enumerate(to_revert):
            if contract_stage_ix == 0:
                actions.append(contract_stage.log_reopen(user, complete_time))
                contract_stage.entered = complete_time
                contract_stage.exited = None
                self.current_stage_id = contract_stage.stage.id
            else:
                contract_stage.full_revert()

        return actions
Exemplo n.º 14
0
def create_contract_stages(flow_id, contract_id, contract=None):
    '''Creates new rows in contract_stage table.

    Extracts the rows out of the given flow, and creates new rows
    in the contract_stage table for each of them.
    '''
    revert = False
    contract = contract if contract else ContractBase.query.get(contract_id)
    stages = Flow.query.get(flow_id).stage_order
    contract_stages = []
    for stage_id in stages:
        try:
            contract_stages.append(ContractStage.create(
                contract_id=contract_id,
                flow_id=flow_id,
                stage_id=stage_id,
            ))

        except (IntegrityError, FlushError):
            revert = True
            db.session.rollback()
            stage = ContractStage.query.filter(
                ContractStage.contract_id == contract_id,
                ContractStage.flow_id == flow_id,
                ContractStage.stage_id == stage_id
            ).first()
            if stage:
                contract_stages.append(stage)
            else:
                raise IntegrityError

        except Exception:
            raise

    contract.flow_id = flow_id
    db.session.commit()

    return stages, contract_stages, revert
 def current_contract_stage(self):
     return ContractStage.get_one(self.id, self.flow.id, self.current_stage.id)
    def _transition_to_first(self, user, complete_time):
        contract_stage = ContractStage.get_one(self.id, self.flow.id,
                                               self.flow.stage_order[0])

        self.current_stage_id = self.flow.stage_order[0]
        return [contract_stage.log_enter(user, complete_time)]
Exemplo n.º 17
0
 def _transition_to_last(self, user):
     current_stage = ContractStage.get_one(self.id, self.flow.id, self.current_stage.id)
     exit = current_stage.log_exit(user)
     self.parent.complete()
     return [exit]