def get_previous_milestone(self, milestone): current_milestone_type_index = MILESTONE_TYPES.index(milestone.type_) if current_milestone_type_index > 0: previous_milestone = search_list_with_dicts( milestone.__parent__.milestones, 'type_', MILESTONE_TYPES[current_milestone_type_index - 1]) return previous_milestone
def get_next_milestone(self, milestone): current_milestone_type_index = MILESTONE_TYPES.index(milestone.type_) if current_milestone_type_index + 1 < len(MILESTONE_TYPES): next_milestone = search_list_with_dicts( milestone.__parent__.milestones, 'type_', MILESTONE_TYPES[current_milestone_type_index + 1]) return next_milestone
def validate_document_upload_milestone_not_terminal_status(request, **kwargs): contract = request.context document_of = request.validated['document'].documentOf if not document_of == 'milestone': return milestone_id = request.validated['document'].relatedItem # document could be uploaded to the contract, not a milestone contract_has_milestones = contract.milestones is not None if not contract_has_milestones: return milestone = search_list_with_dicts(contract.milestones, 'id', milestone_id) terminal_status = milestone.status in MILESTONE_TERMINAL_STATUSES if terminal_status: request.errors.add( 'body', 'status', "Can\'t attach document to milestone in current ({0}) status".format(milestone.status) ) request.errors.status = 403 raise error_handler(request)
def validate_dueDate(self, request, dueDate): approval_milestone = search_list_with_dicts( request.context.__parent__.milestones, 'type_', 'approval') if approval_milestone.dueDate >= dueDate: request.errors.add( 'body', 'dueDate', 'dueDate must be greater than dueDate of approval milestone') request.errors.status = 422 raise error_handler(request)
def set_dueDate(self, milestone, contract): """Sets dueDate of the Milestone Also takes into account milestone's type, so this method can be used on any milestone of Ceasefire contracting. :param milestone: milestone to work with :param contract: contract, related to milestone :type milestone: openprocurement.contracting.ceasefire.models.Milestone :type start_date: openprocurement.contracting.ceasefire.models.Contract :return: dueDate of milestone :rtype: datetime.datetime """ if milestone.type_ == 'financing': milestone.dueDate = calculate_business_date( contract.dateSigned, MILESTONE_FINANCING_DUEDATE_OFFSET, context=contract, working_days=False, specific_hour=18, result_is_working_day=True) elif milestone.type_ == 'approval': financing_milestone = search_list_with_dicts( contract.milestones, 'type_', 'financing') milestone.dueDate = calculate_business_date( financing_milestone.dateMet, MILESTONE_APPROVAL_DUEDATE_OFFSET, context=contract, working_days=False, specific_hour=18, result_is_working_day=True) elif milestone.type_ == 'reporting' and milestone.dueDate is None: approval_milestone = search_list_with_dicts( contract.milestones, 'type_', 'approval') milestone.dueDate = datetime.combine( date( approval_milestone.dateMet.year + MILESTONE_REPORTING_DUEDATE_OFFSET_YEARS, approval_milestone.dateMet.month, approval_milestone.dateMet.day), approval_milestone.dateMet.time())
def prepare_milestones_all_met(test_case, contract_data=None): contract, milestones = prepare_milestones_reporting( test_case, contract_data) reporting_milestone = search_list_with_dicts(milestones, 'type_', 'reporting') dateMet_to_set = reporting_milestone.dueDate - timedelta(days=5) assert reporting_milestone.type_ == 'reporting' response = patch_milestone( test_case, contract, reporting_milestone.id, {'data': { 'dateMet': dateMet_to_set.isoformat() }}) test_case.assertEqual(response.status, '200 OK') resp = get_contract(test_case, contract.data.id) contract.data.update(resp) return (contract, contract.data.milestones)
def test_unsuccessful_search(self): result = search_list_with_dicts(self.container, 'login', 'user3') assert result is None
def test_successful_search(self): result = search_list_with_dicts(self.container, 'login', 'user2') assert result['other'] == 'I am User'