def validate_data(request, model, partial=False): data = validate_json_data(request) if data is None: return try: if partial and isinstance(request.context, model): new_patch = apply_data_patch(request.context.serialize(), data) m = model(request.context.serialize()) m.import_data(new_patch, strict=True) m.validate() if request.authenticated_role == 'Administrator': role = 'Administrator' elif request.authenticated_role == 'chronograph': role = 'chronograph' elif request.authenticated_role == 'auction': role = 'auction_{}'.format(request.method.lower()) elif isinstance(request.context, Tender): role = 'edit_{}'.format(request.context.status) else: role = 'edit' method = m.to_patch else: m = model(data) m.validate() method = m.serialize role = 'create' except (ModelValidationError, ModelConversionError), e: for i in e.message: request.errors.add('body', i, e.message[i]) request.errors.status = 422 data = None
def validate_data(request, model, partial=False): data = validate_json_data(request) if data is None: return if partial: data = filter_data(data) else: data = filter_data(data, blacklist=['status']) try: if partial and isinstance(request.context, model): new_patch = apply_data_patch(request.context.serialize(), data) m = model(request.context.serialize()) m.import_data(new_patch) m.validate() if request.authenticated_userid == 'chronograph': data = m.serialize('chronograph') elif request.authenticated_userid == 'auction': data = m.serialize('auction_{}'.format(request.method.lower())) elif model == Tender: data = m.serialize('edit') else: data = m.serialize() else: model(data).validate(partial=partial) except (ModelValidationError, ModelConversionError), e: for i in e.message: request.errors.add('body', i, e.message[i]) request.errors.status = 422 return
def validate_patch_tender_ua_data(request): data = validate_json_data(request) if request.context.status == 'draft': default_status = type(request.tender).fields['status'].default if data and data.get('status') != default_status: request.errors.add('body', 'data', 'Can\'t update tender in current (draft) status') request.errors.status = 403 return request.validated['data'] = {'status': default_status} request.context.status = default_status return if data: if 'items' in data: items = request.context.items cpv_group_lists = [i.classification.id[:3] for i in items] for item in data['items']: if 'classification' in item and 'id' in item['classification']: cpv_group_lists.append(item['classification']['id'][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add('body', 'item', 'Can\'t change classification') request.errors.status = 403 return None if 'enquiryPeriod' in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data['enquiryPeriod']): request.errors.add('body', 'item', 'Can\'t change enquiryPeriod') request.errors.status = 403 return None return validate_data(request, type(request.tender), True, data)
def apply_patch(request, data=None, save=True, src=None): data = request.validated['data'] if data is None else data patch = data and apply_data_patch(src or request.context.serialize(), data) if patch: request.context.import_data(patch) if save: return save_auction(request)
def apply_patch(request, data=None, save=True, src=None): data = request.validated["data"] if data is None else data patch = data and apply_data_patch(src or request.context.serialize(), data) if patch: request.context.import_data(patch) if save: return save_plan(request)
def validate_data(request, model, partial=False): data = validate_json_data(request) if data is None: return try: if partial and isinstance(request.context, model): new_patch = apply_data_patch(request.context.serialize(), data) m = model(request.context.serialize()) m.import_data(new_patch, strict=True) m.validate() if request.authenticated_role == 'Administrator': role = 'Administrator' elif request.authenticated_role == 'chronograph': role = 'chronograph' elif request.authenticated_role == 'auction': role = 'auction_{}'.format(request.method.lower()) elif isinstance(request.context, Tender): role = 'edit_{}'.format(request.context.status) else: role = 'edit' method = m.to_patch else: m = model(data) m.validate() method = m.serialize role = 'create' except (ModelValidationError, ModelConversionError), e: for i in e.message: request.errors.add('body', i, e.message[i]) request.errors.status = 422 data = None
def validate_patch_tender_ua_data(request): data = validate_json_data(request) if request.context.status == "draft": validate_patch_tender_data_draft(request) return if data: if "items" in data: items = request.context.items cpv_group_lists = [i.classification.id[:3] for i in items] for item in data["items"]: if "classification" in item and "id" in item["classification"]: cpv_group_lists.append(item["classification"]["id"][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add("body", "item", "Can't change classification") request.errors.status = 403 raise error_handler(request.errors) if "enquiryPeriod" in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data["enquiryPeriod"]): request.errors.add("body", "item", "Can't change enquiryPeriod") request.errors.status = 403 raise error_handler(request.errors) return validate_data(request, type(request.tender), True, data)
def patch(self): """Tender Edit (partial) For example here is how procuring entity can change number of items to be procured and total Value of a tender: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607 HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 }, "itemsToBeProcured": [ { "quantity": 6 } ] } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "id": "4879d3f8ee2443169b5fbbc9f89fa607", "tenderID": "UA-64e93250be76435397e8c992ed4214d1", "dateModified": "2014-10-27T08:12:34.956Z", "value": { "amount": 600 }, "itemsToBeProcured": [ { "quantity": 6 } ] } } """ tender = self.request.validated['tender'] if tender.status in ['complete', 'unsuccessful']: self.request.errors.add('body', 'data', 'Can\'t change tender in current status') self.request.errors.status = 403 return src = tender.serialize("plain") tender_data = filter_data(self.request.validated['data']) if tender_data: tender.import_data(apply_data_patch(src, tender_data)) save_tender(tender, src, self.request) return {'data': tender.serialize(tender.status)}
def apply_patch(request, obj_name, data=None, save=True, src=None, additional_obj_names=""): save_map = { "framework": save_framework, "submission": save_submission, "qualification": save_qualification, "agreement": save_agreement, } data = request.validated["data"] if data is None else data patch = data and apply_data_patch(src or request.context.serialize(), data) if patch: # Can't be replaced to "obj_name in save_map" because obj_name for child patch same as for parent if request.context.__class__.__name__.lower() in save_map: request.validated[obj_name].import_data(patch) else: request.context.import_data(patch) if save: save_func = save_map.get(obj_name) return save_func(request, additional_obj_names=additional_obj_names)
def save_submission_changes(self): if self.submission_document_patch: patch = apply_data_patch(self.submission_document, self.submission_document_patch) self.submission_document.update(patch) self.db.save(self.submission_document) self.submission_document = self.db.get(self.submission_id) self.submission_document_patch = {}
def validate_data(request, model, partial=False, data=None): if data is None: data = validate_json_data(request) try: if partial and isinstance(request.context, model): initial_data = request.context.serialize() m = model(initial_data) new_patch = apply_data_patch(initial_data, data) if new_patch: m.import_data(new_patch, partial=True, strict=True) m.__parent__ = request.context.__parent__ m.validate() role = request.context.get_role() method = m.to_patch else: m = model(data) m.__parent__ = request.context m.validate() method = m.serialize role = 'create' except (ModelValidationError, ModelConversionError), e: for i in e.message: request.errors.add('body', i, e.message[i]) request.errors.status = 422 raise error_handler(request.errors)
def save_changes(self): if self.framework_document_patch: patch = apply_data_patch(self.framework_document, self.framework_document_patch) self.framework_document.update(patch) self.db.save(self.framework_document) self.framework_document = self.db.get(self.framework_id) self.framework_document_patch = {}
def validate_patch_tender_stage2_data(request): data = validate_json_data(request) if request.context.status == 'draft': default_statuses = ['active.tendering', STAGE2_STATUS] if data.get('status') not in default_statuses: raise_operation_error(request, 'Can\'t update tender in current ({0}) status'.format(data['status'])) request.validated['data'] = {'status': data.get('status')} request.context.status = data.get('status') return if data: if 'items' in data: items = request.context.items cpv_group_lists = [i.classification.id[:3] for i in items] for item in data['items']: if 'classification' in item and 'id' in item['classification']: cpv_group_lists.append(item['classification']['id'][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add('body', 'item', 'Can\'t change classification') request.errors.status = 403 raise error_handler(request.errors) if 'enquiryPeriod' in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data['enquiryPeriod']): request.errors.add('body', 'item', 'Can\'t change enquiryPeriod') request.errors.status = 403 raise error_handler(request.errors) if request.context.status == STAGE2_STATUS and data.get('status') == 'active.tendering': data = validate_data(request, type(request.tender), True, data) if data: # if no error then add status to validate data request.context.status = 'active.tendering' data['status'] = 'active.tendering' else: data = validate_data(request, type(request.tender), True, data) return data
def validate_patch_tender_ua_data(request): data = validate_json_data(request) # TODO try to use original code openprocurement.tender.core.validation.validate_patch_tender_data if request.context.status == 'draft': default_status = type(request.tender).fields['status'].default if data and data.get('status') != default_status: raise_operation_error( request, 'Can\'t update tender in current (draft) status') request.validated['data'] = {'status': default_status} request.context.status = default_status return if data: if 'items' in data: items = request.context.items cpv_group_lists = [i.classification.id[:3] for i in items] for item in data['items']: if 'classification' in item and 'id' in item['classification']: cpv_group_lists.append(item['classification']['id'][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add('body', 'item', 'Can\'t change classification') request.errors.status = 403 raise error_handler(request.errors) if 'enquiryPeriod' in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data['enquiryPeriod']): request.errors.add('body', 'item', 'Can\'t change enquiryPeriod') request.errors.status = 403 raise error_handler(request.errors) return validate_data(request, type(request.tender), True, data)
def validate_data(request, model, partial=False, data=None): if data is None: data = validate_json_data(request) if data is None: return try: if partial and isinstance(request.context, model): initial_data = request.context.serialize() m = model(initial_data) new_patch = apply_data_patch(initial_data, data) if new_patch: m.import_data(new_patch, partial=True, strict=True) m.__parent__ = request.context.__parent__ m.validate() role = request.context.get_role() method = m.to_patch else: m = model(data) m.__parent__ = request.context m.validate() method = m.serialize role = 'create' except (ModelValidationError, ModelConversionError), e: for i in e.message: request.errors.add('body', i, e.message[i]) request.errors.status = 422 data = None
def save_agreement_changes(self): if self.agreement_document_patch: patch = apply_data_patch(self.agreement_document, self.agreement_document_patch) self.agreement_document.update(patch) self.db.save(self.agreement_document) self.agreement_document = self.db.get(self.agreement_id) self.agreement_document_patch = {}
def patch(self): """Tender Edit (partial) For example here is how procuring entity can change number of items to be procured and total Value of a tender: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607 HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 }, "itemsToBeProcured": [ { "quantity": 6 } ] } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "id": "4879d3f8ee2443169b5fbbc9f89fa607", "tenderID": "UA-64e93250be76435397e8c992ed4214d1", "dateModified": "2014-10-27T08:12:34.956Z", "value": { "amount": 600 }, "itemsToBeProcured": [ { "quantity": 6 } ] } } """ tender = self.request.validated['tender'] if tender.status in ['complete', 'unsuccessful']: self.request.errors.add('body', 'data', 'Can\'t change tender in current status') self.request.errors.status = 403 return src = tender.serialize("plain") tender_data = filter_data(self.request.validated['data']) if tender_data: tender.import_data(apply_data_patch(src, tender_data)) save_tender(tender, src, self.request) return {'data': tender.serialize(tender.status)}
def save_changes(self): if self.tender_document_patch: self.tender_document.update( apply_data_patch(self.tender_document, self.tender_document_patch)) self.db.save(self.tender_document) self.tender_document = self.db.get(self.tender_id) self.tender_document_patch = {}
def validate_agreement_patch(request, **kwargs): data = validate_json_data(request) if data: if "features" in data: if apply_data_patch([f.serialize() for f in request.context.features], data["features"]): request.errors.add("body", "features", "Can't change features") request.errors.status = 403 raise error_handler(request) return validate_data(request, type(request.agreement), True, data=data)
def apply_patch(request, data=None, save=True, src=None): data = request.validated["data"] if data is None else data patch = data and apply_data_patch(src or request.context.serialize(), data) if patch: request.context.import_data(patch) if save: return save_plan(request) if get_revision_changes(request.validated["plan"].serialize("plain"), request.validated["plan_src"]): return True # should return True if there're any actual changes (either save = True or False
def patch(self): """Post an Answer """ tender = self.request.validated['tender'] question = self.request.validated['question'] question_data = filter_data(self.request.validated['data']) if question_data: src = tender.serialize("plain") question.import_data(apply_data_patch(question.serialize(), question_data)) save_tender(tender, src, self.request) return {'data': question.serialize(self.request.validated['tender'].status)}
def patch(self): """Update of contract """ if self.request.validated['tender_status'] not in ['active.awarded', 'complete']: self.request.errors.add('body', 'data', 'Can\'t update contract in current tender status') self.request.errors.status = 403 return contract = self.request.validated['contract'] contract_data = self.request.validated['data'] if contract_data: contract.import_data(apply_data_patch(contract.serialize(), contract_data)) save_tender(self.request) return {'data': contract.serialize()}
def patch(self): """Post a complaint resolution """ tender = self.request.validated['tender'] if tender.status not in ['active.enquiries', 'active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: self.request.errors.add('body', 'data', 'Can\'t update complaint in current tender status') self.request.errors.status = 403 return complaint = self.request.validated['complaint'] if complaint.status != 'pending': self.request.errors.add('body', 'data', 'Can\'t update complaint in current status') self.request.errors.status = 403 return complaint_data = self.request.validated['data'] if complaint_data: if complaint_data.get('status', '') == 'cancelled': self.request.errors.add('body', 'data', 'Can\'t cancel complaint') self.request.errors.status = 403 return complaint.import_data(apply_data_patch(complaint.serialize(), complaint_data)) if complaint.status == 'resolved' and tender.status != 'active.enquiries': for i in tender.complaints: if i.status == 'pending': i.status = 'cancelled' tender.status = 'cancelled' elif complaint.status in ['declined', 'invalid'] and tender.status == 'active.awarded': pending_complaints = [ i for i in tender.complaints if i.status == 'pending' ] pending_awards_complaints = [ i for a in tender.awards for i in a.complaints if i.status == 'pending' ] stand_still_time_expired = tender.awardPeriod.endDate + STAND_STILL_TIME < get_now() if not pending_complaints and not pending_awards_complaints and stand_still_time_expired: active_awards = [ a for a in tender.awards if a.status == 'active' ] if active_awards: tender.status = 'complete' else: tender.status = 'unsuccessful' save_tender(self.request) return {'data': complaint.serialize("view")}
def patch(self): """Post an Answer """ tender = self.request.validated['tender'] question = self.request.validated['question'] question_data = filter_data(self.request.validated['data']) if question_data: src = tender.serialize("plain") question.import_data( apply_data_patch(question.serialize(), question_data)) save_tender(tender, src, self.request) return { 'data': question.serialize(self.request.validated['tender'].status) }
def patch(self): """Update of proposal Example request to change bid proposal: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 } } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "value": { "amount": 600, "currency": "UAH", "valueAddedTaxIncluded": true } } } """ tender = self.request.validated['tender'] if tender.status != 'active.tendering': self.request.errors.add( 'body', 'data', 'Can\'t change bid in current tender status') self.request.errors.status = 403 return bid = self.request.validated['bid'] bid_data = filter_data(self.request.validated['data']) if bid_data: src = tender.serialize("plain") bid.import_data(apply_data_patch(bid.serialize(), bid_data)) save_tender(tender, src, self.request) return {'data': bid.serialize("view")}
def patch(self): """Update of proposal Example request to change bid proposal: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 } } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "value": { "amount": 600, "currency": "UAH", "valueAddedTaxIncluded": true } } } """ tender = self.request.validated['tender'] if tender.status != 'active.tendering': self.request.errors.add('body', 'data', 'Can\'t change bid in current tender status') self.request.errors.status = 403 return bid = self.request.validated['bid'] bid_data = filter_data(self.request.validated['data']) if bid_data: src = tender.serialize("plain") bid.import_data(apply_data_patch(bid.serialize(), bid_data)) save_tender(tender, src, self.request) return {'data': bid.serialize("view")}
def patch(self): """Post a complaint resolution """ tender = self.request.validated['tender'] if tender.status not in ['active.enquiries', 'active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: self.request.errors.add('body', 'data', 'Can\'t update complaint in current tender status') self.request.errors.status = 403 return complaint = self.request.validated['complaint'] complaint_data = filter_data(self.request.validated['data']) if complaint_data: src = tender.serialize("plain") complaint.import_data(apply_data_patch(complaint.serialize(), complaint_data)) save_tender(tender, src, self.request) return {'data': complaint.serialize("view")}
def apply_patch(request, obj_name, data=None, save=True, src=None): save_map = { "framework": save_framework, "submission": save_submission, "qualification": save_qualification, } data = request.validated["data"] if data is None else data patch = data and apply_data_patch(src or request.context.serialize(), data) if patch: if isinstance(request.validated[obj_name], request.context.__class__): request.context.import_data(patch) if save: save_func = save_map.get(obj_name) return save_func(request)
def set_tendering_status(self): data = { "status": "active.tendering", "enquiryPeriod": { "startDate": (now - timedelta(days=10)).isoformat(), "endDate": (now).isoformat() }, "tenderPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=7)).isoformat() } } tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def set_tendering_status(self): data = { "status": "active.tendering", "enquiryPeriod": { "startDate": (now - timedelta(days=15)).isoformat(), "endDate": (now).isoformat() }, "tenderPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=30)).isoformat() } } tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def set_status(self, status, extra=None): if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender) authorization = self.app.authorization self.app.authorization = ('Basic', ('chronograph', '')) #response = self.app.patch_json('/tenders/{}'.format(self.tender_id), {'data': {'id': self.tender_id}}) response = self.app.get('/tenders/{}'.format(self.tender_id)) self.app.authorization = authorization self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') return response
def set_status(self, status, extra=None): data = {'status': status} if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender) # authorization = self.app.authorization #self.app.authorization = ('Basic', ('chronograph', '')) response = self.app.get('/tenders/{}'.format(self.tender_id)) #self.app.authorization = authorization self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') return response
def patch(self): """Post a complaint resolution for award """ tender = self.request.validated['tender'] if tender.status not in ['active.qualification', 'active.awarded']: self.request.errors.add( 'body', 'data', 'Can\'t update complaint in current tender status') self.request.errors.status = 403 return complaint = self.request.validated['complaint'] complaint_data = filter_data(self.request.validated['data']) if complaint_data: src = tender.serialize("plain") complaint.import_data( apply_data_patch(complaint.serialize(), complaint_data)) save_tender(tender, src, self.request) return {'data': complaint.serialize("view")}
def set_pre_qualification_status(self, extra=None): data = { "enquiryPeriod": { "startDate": (now - timedelta(days=45)).isoformat(), "endDate": (now - timedelta(days=30)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=30)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": { "startDate": (now).isoformat(), } } if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def set_pre_qualification_status(self, extra=None): data = { "enquiryPeriod": { "startDate": (now - timedelta(days=45)).isoformat(), "endDate": (now - timedelta(days=30)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=30)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": { "startDate": (now).isoformat(), } } if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def validate_patch_tender_ua_data(request): data = validate_json_data(request) items = request.context.items if data: if 'items' in data: cpv_group_lists = [i.classification.id[:3] for i in items] for item in data['items']: if 'classification' in item and 'id' in item['classification']: cpv_group_lists.append(item['classification']['id'][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add('body', 'item', 'Can\'t change classification') request.errors.status = 403 return None if 'enquiryPeriod' in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data['enquiryPeriod']): request.errors.add('body', 'item', 'Can\'t change enquiryPeriod') request.errors.status = 403 return None return validate_data(request, request.tender.__class__, True, data)
def validate_patch_tender_stage2_data(request): data = validate_json_data(request) if request.context.status == "draft": default_statuses = ["active.tendering", STAGE2_STATUS] if "status" in data and data.get("status") not in default_statuses: raise_operation_error( request, "Can't update tender in current ({0}) status".format( data["status"])) request.validated["data"] = {"status": data.get("status")} request.context.status = data.get("status") return if data: if "items" in data: items = request.context.items cpv_group_lists = [i.classification.id[:3] for i in items] for item in data["items"]: if "classification" in item and "id" in item["classification"]: cpv_group_lists.append(item["classification"]["id"][:3]) if len(set(cpv_group_lists)) != 1: request.errors.add("body", "item", "Can't change classification") request.errors.status = 403 raise error_handler(request.errors) if "enquiryPeriod" in data: if apply_data_patch(request.context.enquiryPeriod.serialize(), data["enquiryPeriod"]): request.errors.add("body", "item", "Can't change enquiryPeriod") request.errors.status = 403 raise error_handler(request.errors) if request.context.status == STAGE2_STATUS and data.get( "status") == "active.tendering": data = validate_data(request, type(request.tender), True, data) if data: # if no error then add status to validate data request.context.status = "active.tendering" data["status"] = "active.tendering" else: data = validate_data(request, type(request.tender), True, data) return data
def validate_object_data(request, model, partial=False, data=None, allow_bulk=False): with handle_data_exceptions(request): if partial and isinstance(request.context, model): initial_data = request.context.serialize() m = model(initial_data) new_patch = apply_data_patch(initial_data, data) if new_patch: m.import_data(new_patch, partial=True, strict=True) m.__parent__ = request.context.__parent__ m.validate() role = request.context.get_role() method = m.to_patch else: m = model(data) m.__parent__ = request.context m.validate() method = m.serialize role = "create" if hasattr(type(m), "_options") and role not in type(m)._options.roles: request.errors.add("url", "role", "Forbidden") request.errors.status = 403 raise error_handler(request) else: data = method(role) request.validated["data"] = data if not partial: m = model(data) m.__parent__ = request.context validated_name = get_model_namespace(model).lower() if allow_bulk: request.validated["{}_bulk".format(validated_name)] = [m] else: request.validated[validated_name] = m return data
def set_qualification_status(self): data = { "status": 'active.qualification', "enquiryPeriod": { "startDate": (now - timedelta(days=18)).isoformat(), "endDate": (now - timedelta(days=8)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat() } } tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def set_qualification_status(self): data = { "status": 'active.qualification', "enquiryPeriod": { "startDate": (now - timedelta(days=46)).isoformat(), "endDate": (now - timedelta(days=31)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=31)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat() } } tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def validate_data(request, model, partial=False, data=None): if data is None: data = validate_json_data(request) with handle_data_exceptions(request): if partial and isinstance(request.context, model): initial_data = request.context.serialize() m = model(initial_data) new_patch = apply_data_patch(initial_data, data) if new_patch: m.import_data(new_patch, partial=True, strict=True) m.__parent__ = request.context.__parent__ m.validate() role = request.context.get_role() method = m.to_patch else: m = model(data) m.__parent__ = request.context m.validate() method = m.serialize role = "create" if hasattr(type(m), "_options") and role not in type(m)._options.roles: request.errors.add("url", "role", "Forbidden") request.errors.status = 403 raise error_handler(request.errors) else: data = method(role) request.validated["data"] = data if not partial: m = model(data) m.__parent__ = request.context if model._options.namespace: request.validated[model._options.namespace.lower()] = m else: request.validated[model.__name__.lower()] = m return data
def time_shift(self, status, extra=None): now = get_now() tender = self.db.get(self.tender_id) data = {} if status == 'enquiryPeriod_ends': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=28)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=28)).isoformat(), "endDate": (now + timedelta(days=2)).isoformat() }, }) if status == 'active.pre-qualification': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now).isoformat(), } }) elif status == 'active.pre-qualification.stand-still': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": { "startDate": (now).isoformat(), }, }) if 'lots' in tender and tender['lots']: data['lots'] = [] for index, lot in enumerate(tender['lots']): lot_data = {'id': lot['id']} if lot['status'] is 'active': lot_data["auctionPeriod"] = { "startDate": (now + COMPLAINT_STAND_STILL).isoformat() } data['lots'].append(lot_data) else: data.update({ "auctionPeriod": { "startDate": (now + COMPLAINT_STAND_STILL).isoformat() } }) elif status == 'active.auction': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - TENDERING_DURATION + QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL).isoformat() }, "qualificationPeriod": { "startDate": (now - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now).isoformat() } }) if 'lots' in tender and tender['lots']: data['lots'] = [] for index, lot in enumerate(tender['lots']): lot_data = {'id': lot['id']} if lot['status'] == 'active': lot_data["auctionPeriod"] = { "startDate": (now).isoformat() } data['lots'].append(lot_data) else: data.update({"auctionPeriod": {"startDate": now.isoformat()}}) elif status == 'complete': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat() }, "awardPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat() } } for i in self.initial_lots] }) if extra: data.update(extra) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def patch(self): """Update of award Example request to change the award: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607/awards/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 } } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "id": "4879d3f8ee2443169b5fbbc9f89fa607", "date": "2014-10-28T11:44:17.947Z", "status": "active", "suppliers": [ { "id": { "name": "Державне управління справами", "scheme": "https://ns.openprocurement.org/ua/edrpou", "uid": "00037256", "uri": "http://www.dus.gov.ua/" }, "address": { "countryName": "Україна", "postalCode": "01220", "region": "м. Київ", "locality": "м. Київ", "streetAddress": "вул. Банкова, 11, корпус 1" } } ], "value": { "amount": 600, "currency": "UAH", "valueAddedTaxIncluded": true } } } """ tender = self.request.validated['tender'] if tender.status != 'active.qualification': self.request.errors.add('body', 'data', 'Can\'t change award in current tender status') self.request.errors.status = 403 return award = self.request.validated['award'] award_data = filter_data(self.request.validated['data']) if award_data: src = tender.serialize("plain") award.import_data(apply_data_patch(award.serialize(), award_data)) save_tender(tender, src, self.request) return {'data': award.serialize("view")}
def patch(self): """Update of award Example request to change the award: .. sourcecode:: http PATCH /tenders/4879d3f8ee2443169b5fbbc9f89fa607/awards/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 Host: example.com Accept: application/json { "data": { "value": { "amount": 600 } } } And here is the response to be expected: .. sourcecode:: http HTTP/1.0 200 OK Content-Type: application/json { "data": { "id": "4879d3f8ee2443169b5fbbc9f89fa607", "date": "2014-10-28T11:44:17.947Z", "status": "active", "suppliers": [ { "id": { "name": "Державне управління справами", "scheme": "https://ns.openprocurement.org/ua/edrpou", "uid": "00037256", "uri": "http://www.dus.gov.ua/" }, "address": { "countryName": "Україна", "postalCode": "01220", "region": "м. Київ", "locality": "м. Київ", "streetAddress": "вул. Банкова, 11, корпус 1" } } ], "value": { "amount": 600, "currency": "UAH", "valueAddedTaxIncluded": true } } } """ tender = self.request.validated['tender'] if tender.status != 'active.qualification': self.request.errors.add('body', 'data', 'Can\'t update award in current tender status') self.request.errors.status = 403 return award = self.request.validated['award'] if award.status != 'pending': self.request.errors.add('body', 'data', 'Can\'t update award in current status') self.request.errors.status = 403 return award_data = self.request.validated['data'] if award_data: award.import_data(apply_data_patch(award.serialize(), award_data)) if award.status == 'active': award.contracts.append(Contract({'awardID': award.id})) tender.awardPeriod.endDate = get_now() tender.status = 'active.awarded' elif award.status == 'unsuccessful': awards = self.request.validated['awards'] unsuccessful_awards = [i.bid_id for i in awards if i.status == 'unsuccessful'] bids = [i for i in sorted(tender.bids, key=lambda i: (i.value.amount, i.date)) if i.id not in unsuccessful_awards] if bids: bid = bids[0].serialize() award_data = { 'bid_id': bid['id'], 'status': 'pending', 'value': bid['value'], 'suppliers': bid['tenderers'], } award = Award(award_data) tender.awards.append(award) self.request.response.headers['Location'] = self.request.route_url('Tender Awards', tender_id=tender.id, award_id=award['id']) else: tender.awardPeriod.endDate = get_now() tender.status = 'active.awarded' save_tender(self.request) return {'data': award.serialize("view")}
def set_status(self, status, extra=None): data = {'status': status} if status == 'active.tendering': data.update({ "enquiryPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=7)).isoformat() }, "tenderPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=7)).isoformat() } }) elif status == 'active.auction': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=7)).isoformat(), "endDate": (now).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=7)).isoformat(), "endDate": (now).isoformat() }, "auctionPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'active.qualification': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'active.awarded': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'complete': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=18)).isoformat(), "endDate": (now - timedelta(days=11)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=18)).isoformat(), "endDate": (now - timedelta(days=11)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=11)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() }, "awardPeriod": { "startDate": (now - timedelta(days=10)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=11)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() } } for i in self.initial_lots] }) if extra: data.update(extra) auction = self.db.get(self.auction_id) auction.update(apply_data_patch(auction, data)) self.db.save(auction) authorization = self.app.authorization self.app.authorization = ('Basic', ('chronograph', '')) #response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) response = self.app.get('/auctions/{}'.format(self.auction_id)) self.app.authorization = authorization self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') return response
def set_status(self, status, extra=None): data = {"status": status} if status == "active.tendering": data.update( { "enquiryPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now + TENDERING_DURATION - QUESTIONS_STAND_STILL).isoformat(), }, "tenderPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now + TENDERING_DURATION).isoformat(), }, } ) elif status == "active.pre-qualification": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": {"startDate": (now).isoformat()}, } ) elif status == "active.pre-qualification.stand-still": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": {"startDate": (now).isoformat()}, "auctionPeriod": {"startDate": (now + COMPLAINT_STAND_STILL).isoformat()}, } ) elif status == "active.auction": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": ( now - COMPLAINT_STAND_STILL - TENDERING_DURATION + QUESTIONS_STAND_STILL ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL).isoformat(), }, "qualificationPeriod": { "startDate": (now - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now).isoformat(), }, "auctionPeriod": {"startDate": (now).isoformat()}, } ) if self.initial_lots: data.update({"lots": [{"auctionPeriod": {"startDate": (now).isoformat()}} for i in self.initial_lots]}) elif status == "active.qualification": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat(), "endDate": ( now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=1) ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), }, "auctionPeriod": {"startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat()}, "awardPeriod": {"startDate": (now).isoformat()}, } ) if self.initial_lots: data.update( { "lots": [ { "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat(), } } for i in self.initial_lots ] } ) elif status == "active.awarded": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": ( now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=2) ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat(), }, "auctionPeriod": { "startDate": (now - timedelta(days=2)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat(), }, "awardPeriod": {"startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat()}, } ) if self.initial_lots: data.update( { "lots": [ { "auctionPeriod": { "startDate": (now - timedelta(days=2)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat(), } } for i in self.initial_lots ] } ) elif status == "complete": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=4)).isoformat(), "endDate": ( now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=3) ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=4)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), }, "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat(), }, "awardPeriod": {"startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat()}, } ) if self.initial_lots: data.update( { "lots": [ { "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat(), } } for i in self.initial_lots ] } ) if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender) authorization = self.app.authorization self.app.authorization = ("Basic", ("chronograph", "")) # response = self.app.patch_json('/tenders/{}'.format(self.tender_id), {'data': {'id': self.tender_id}}) response = self.app.get("/tenders/{}".format(self.tender_id)) self.app.authorization = authorization self.assertEqual(response.status, "200 OK") self.assertEqual(response.content_type, "application/json") return response
def time_shift(self, status, extra=None): now = get_now() tender = self.db.get(self.tender_id) data = {} if status == "enquiryPeriod_ends": data.update( { "enquiryPeriod": { "startDate": (now - timedelta(days=28)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat(), }, "tenderPeriod": { "startDate": (now - timedelta(days=28)).isoformat(), "endDate": (now + timedelta(days=2)).isoformat(), }, } ) if status == "active.pre-qualification": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat(), }, "tenderPeriod": {"startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now).isoformat()}, } ) elif status == "active.pre-qualification.stand-still": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat(), }, "tenderPeriod": {"startDate": (now - TENDERING_DURATION).isoformat(), "endDate": (now).isoformat()}, "qualificationPeriod": {"startDate": (now).isoformat()}, } ) if "lots" in tender and tender["lots"]: data["lots"] = [] for index, lot in enumerate(tender["lots"]): lot_data = {"id": lot["id"]} if lot["status"] is "active": lot_data["auctionPeriod"] = {"startDate": (now + COMPLAINT_STAND_STILL).isoformat()} data["lots"].append(lot_data) else: data.update({"auctionPeriod": {"startDate": (now + COMPLAINT_STAND_STILL).isoformat()}}) elif status == "active.auction": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL).isoformat(), "endDate": ( now - COMPLAINT_STAND_STILL - TENDERING_DURATION + QUESTIONS_STAND_STILL ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL).isoformat(), }, "qualificationPeriod": { "startDate": (now - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now).isoformat(), }, } ) if "lots" in tender and tender["lots"]: data["lots"] = [] for index, lot in enumerate(tender["lots"]): lot_data = {"id": lot["id"]} if lot["status"] == "active": lot_data["auctionPeriod"] = {"startDate": (now).isoformat()} data["lots"].append(lot_data) else: data.update({"auctionPeriod": {"startDate": now.isoformat()}}) elif status == "complete": data.update( { "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": ( now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=3) ).isoformat(), }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), }, "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat(), }, "awardPeriod": {"startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat()}, } ) if self.initial_lots: data.update( { "lots": [ { "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat(), } } for i in self.initial_lots ] } ) if extra: data.update(extra) tender.update(apply_data_patch(tender, data)) self.db.save(tender)
def set_status(self, status, extra=None): data = {'status': status} if status == 'active.enquiries': data.update({ "enquiryPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=7)).isoformat() }, "tenderPeriod": { "startDate": (now + timedelta(days=7)).isoformat(), "endDate": (now + timedelta(days=14)).isoformat() } }) elif status == 'active.tendering': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=10)).isoformat(), "endDate": (now).isoformat() }, "tenderPeriod": { "startDate": (now).isoformat(), "endDate": (now + timedelta(days=7)).isoformat() } }) elif status == 'active.auction': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=14)).isoformat(), "endDate": (now - timedelta(days=7)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=7)).isoformat(), "endDate": (now).isoformat() }, "auctionPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [ { "auctionPeriod": { "startDate": (now).isoformat() } } for i in self.initial_lots ] }) elif status == 'active.qualification': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=15)).isoformat(), "endDate": (now - timedelta(days=8)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [ { "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } } for i in self.initial_lots ] }) elif status == 'active.awarded': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=15)).isoformat(), "endDate": (now - timedelta(days=8)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=8)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [ { "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } } for i in self.initial_lots ] }) elif status == 'complete': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=25)).isoformat(), "endDate": (now - timedelta(days=18)).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=18)).isoformat(), "endDate": (now - timedelta(days=11)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=11)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() }, "awardPeriod": { "startDate": (now - timedelta(days=10)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() } }) if self.initial_lots: data.update({ 'lots': [ { "auctionPeriod": { "startDate": (now - timedelta(days=11)).isoformat(), "endDate": (now - timedelta(days=10)).isoformat() } } for i in self.initial_lots ] }) if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender) authorization = self.app.authorization self.app.authorization = ('Basic', ('chronograph', '')) #response = self.app.patch_json('/tenders/{}'.format(self.tender_id), {'data': {'id': self.tender_id}}) response = self.app.get('/tenders/{}'.format(self.tender_id)) self.app.authorization = authorization self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') return response
def patch(self): """Post a complaint resolution for award """ tender = self.request.validated['tender'] if tender.status not in ['active.qualification', 'active.awarded']: self.request.errors.add('body', 'data', 'Can\'t update complaint in current tender status') self.request.errors.status = 403 return complaint = self.request.validated['complaint'] if complaint.status != 'pending': self.request.errors.add('body', 'data', 'Can\'t update complaint in current status') self.request.errors.status = 403 return complaint_data = self.request.validated['data'] if complaint_data: if complaint_data.get('status', '') == 'cancelled': self.request.errors.add('body', 'data', 'Can\'t cancel complaint') self.request.errors.status = 403 return complaint.import_data(apply_data_patch(complaint.serialize(), complaint_data)) if complaint.status == 'resolved': award = self.request.validated['award'] if tender.status == 'active.awarded': tender.status = 'active.qualification' tender.awardPeriod.endDate = None if award.status == 'unsuccessful': for i in tender.awards[tender.awards.index(award):]: i.status = 'cancelled' for j in i.complaints: if j.status == 'pending': j.status = 'cancelled' for i in award.contracts: i.status = 'cancelled' award.status = 'cancelled' unsuccessful_awards = [i.bid_id for i in tender.awards if i.status == 'unsuccessful'] bids = [i for i in sorted(tender.bids, key=lambda i: (i.value.amount, i.date)) if i.id not in unsuccessful_awards] if bids: bid = bids[0].serialize() award_data = { 'bid_id': bid['id'], 'status': 'pending', 'value': bid['value'], 'suppliers': bid['tenderers'], } award = Award(award_data) tender.awards.append(award) else: tender.awardPeriod.endDate = get_now() tender.status = 'active.awarded' elif complaint.status in ['declined', 'invalid'] and tender.status == 'active.awarded': pending_complaints = [ i for i in tender.complaints if i.status == 'pending' ] pending_awards_complaints = [ i for a in tender.awards for i in a.complaints if i.status == 'pending' ] stand_still_time_expired = tender.awardPeriod.endDate + STAND_STILL_TIME < get_now() if not pending_complaints and not pending_awards_complaints and stand_still_time_expired: active_awards = [ a for a in tender.awards if a.status == 'active' ] if active_awards: tender.status = 'complete' else: tender.status = 'unsuccessful' save_tender(self.request) return {'data': complaint.serialize("view")}
def set_status(self, status, extra=None): data = {'status': status} if status == 'active.tendering': data.update({ "enquiryPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now + TENDERING_DURATION - QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now + TENDERING_DURATION).isoformat() } }) elif status == 'active.pre-qualification': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": { "startDate": (now).isoformat(), } }) elif status == 'active.qualification': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() }, "awardPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'active.pre-qualification.stand-still': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - timedelta(days=1)).isoformat(), "endDate": (now).isoformat(), }, "qualificationPeriod": { "startDate": (now).isoformat(), }, "auctionPeriod": { "startDate": (now + COMPLAINT_STAND_STILL).isoformat() } }) elif status == 'active.stage2.pending': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - TENDERING_DURATION + QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL).isoformat() }, "qualificationPeriod": { "startDate": (now - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'active.auction': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - TENDERING_DURATION + QUESTIONS_STAND_STILL).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=1)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL).isoformat() }, "qualificationPeriod": { "startDate": (now - COMPLAINT_STAND_STILL).isoformat(), "endDate": (now).isoformat() }, "auctionPeriod": { "startDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now).isoformat() } } for i in self.initial_lots] }) elif status == 'active.awarded': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=2)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=2)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() }, "awardPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=2)).isoformat(), "endDate": (now - timedelta(days=1)).isoformat() } } for i in self.initial_lots] }) elif status == 'complete': data.update({ "enquiryPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=4)).isoformat(), "endDate": (now - QUESTIONS_STAND_STILL - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat() }, "tenderPeriod": { "startDate": (now - TENDERING_DURATION - COMPLAINT_STAND_STILL - timedelta(days=4)).isoformat(), "endDate": (now - COMPLAINT_STAND_STILL - timedelta(days=3)).isoformat() }, "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat() }, "awardPeriod": { "startDate": (now - timedelta(days=1)).isoformat(), "endDate": (now).isoformat() } }) if self.initial_lots: data.update({ 'lots': [{ "auctionPeriod": { "startDate": (now - timedelta(days=3)).isoformat(), "endDate": (now - timedelta(days=2)).isoformat() } } for i in self.initial_lots] }) if extra: data.update(extra) tender = self.db.get(self.tender_id) tender.update(apply_data_patch(tender, data)) self.db.save(tender) authorization = self.app.authorization self.app.authorization = ('Basic', ('chronograph', '')) # response = self.app.patch_json('/tenders/{}'.format(self.tender_id), {'data': {'id': self.tender_id}}) response = self.app.get('/tenders/{}'.format(self.tender_id)) self.app.authorization = authorization self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') return response