def collection_post(self): """Post a complaint """ tender = self.context complaint = self.request.validated['complaint'] if complaint.status == 'claim': validate_submit_claim_time(self.request) elif complaint.status == 'pending': validate_submit_complaint_time(self.request) complaint.dateSubmitted = get_now() complaint.type = 'complaint' else: complaint.status = 'draft' complaint.complaintID = '{}.{}{}'.format(tender.tenderID, self.server_id, self.complaints_len(tender) + 1) set_ownership(complaint, self.request) tender.complaints.append(complaint) if save_tender(self.request): self.LOGGER.info('Created tender complaint {}'.format(complaint.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_complaint_create'}, {'complaint_id': complaint.id})) self.request.response.status = 201 self.request.response.headers['Location'] = self.request.route_url('{}:Tender Complaints'.format(tender.procurementMethodType), tender_id=tender.id, complaint_id=complaint.id) return { 'data': complaint.serialize(tender.status), 'access': { 'token': complaint.owner_token } }
def post(self): """Report auction results for lot. """ apply_patch(self.request, save=False, src=self.request.validated['tender_src']) if all([i.auctionPeriod and i.auctionPeriod.endDate for i in self.request.validated['tender'].lots if i.numberOfBids > 1 and i.status == 'active']): add_next_award(self.request) if save_tender(self.request): self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_auction_post'})) return {'data': self.request.validated['tender'].serialize(self.request.validated['tender'].status)}
def delete(self): """Lot deleting """ lot = self.request.context res = lot.serialize("view") tender = self.request.validated['tender'] tender.lots.remove(lot) if self.request.authenticated_role == 'tender_owner': tender.invalidate_bids_data() if save_tender(self.request): self.LOGGER.info('Deleted tender lot {}'.format(self.request.context.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_delete'})) return {'data': res}
def patch(self): tender = self.request.validated['tender'] set_ownership(tender) if save_tender(self.request): self.LOGGER.info('Generate Tender stage2 credentials {}'.format(tender.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'})) return { 'data': tender.serialize("view"), 'access': { 'token': tender.owner_token } }
def put(self): """Tender Bid Document Update""" document = upload_file(self.request) self.request.validated['bid'].documents.append(document) if self.request.validated['tender_status'] == 'active.tendering': self.request.validated['tender'].modified = False if save_tender(self.request): self.LOGGER.info('Updated tender bid document {}'.format( self.request.context.id), extra=context_unpack( self.request, {'MESSAGE_ID': 'tender_bid_document_put'})) return {'data': document.serialize("view")}
def collection_post(self): """Tender Award Complaint Document Upload """ document = upload_file(self.request) document.author = self.request.authenticated_role self.context.documents.append(document) if save_tender(self.request): self.LOGGER.info('Created tender award complaint document {}'.format(document.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_award_complaint_document_create'}, {'document_id': document.id})) self.request.response.status = 201 document_route = self.request.matched_route.name.replace("collection_", "") self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) return {'data': document.serialize("view")}
def collection_post(self): """Add a lot """ tender = self.request.validated['tender'] lot = self.request.validated['lot'] lot.date = get_now() tender.lots.append(lot) if save_tender(self.request): self.LOGGER.info('Created tender lot {}'.format(lot.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_create'}, {'lot_id': lot.id})) self.request.response.status = 201 self.request.response.headers['Location'] = self.request.route_url('{}:Tender Lots'.format(tender.procurementMethodType), tender_id=tender.id, lot_id=lot.id) return {'data': lot.serialize("view")}
def delete(self): """Lot deleting """ tender = self.request.validated["tender"] lot = self.request.context res = lot.serialize("view") tender.lots.remove(lot) if save_tender(self.request): self.LOGGER.info( "Deleted tender lot {}".format(self.request.context.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_delete"}), ) return {"data": res}
def patch(self): tender = self.context if self.request.authenticated_role == "chronograph": apply_patch(self.request, save=False, src=self.request.validated["tender_src"]) check_status(self.request) save_tender(self.request) else: new_status = self.request.validated["data"].get("status", "") data = self.request.validated["data"] if tender.status == "draft" and new_status == "draft.publishing" and not tender.noticePublicationDate: now = get_now() self.request.validated["data"][ "noticePublicationDate"] = now.isoformat() self.request.validated["data"]["tenderPeriod"][ "startDate"] = now.isoformat() apply_patch(self.request, src=self.request.validated["tender_src"]) self.LOGGER.info("Updated tender {}".format(tender.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_patch"})) return {"data": tender.serialize(tender.status)}
def patch(self): """ Update of agreement """ apply_patch(self.request, save=False, src=self.request.context.serialize()) check_tender_status(self.request) if save_tender(self.request): self.LOGGER.info( "Updated tender agreement {}".format(self.request.context.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_agreement_patch"}), ) return {"data": self.request.context.serialize()}
def patch(self): requirement_response = self.request.context context_name = self.request.context["__parent__"].__class__.__name__.lower() apply_patch(self.request, save=False, src=requirement_response.serialize()) self.pre_save() if save_tender(self.request): self.LOGGER.info( "Updated {} requirement response {}".format(context_name, requirement_response.id), extra=context_unpack(self.request, {"MESSAGE_ID": "{}_requirement_response_patch".format(context_name)}), ) return {"data": requirement_response.serialize("view")} return
def put(self): """Tender Award Complaint Document Update""" document = upload_file(self.request) document.author = self.request.authenticated_role self.request.validated['complaint'].documents.append(document) if save_tender(self.request): self.LOGGER.info( 'Updated tender award complaint document {}'.format( self.request.context.id), extra=context_unpack( self.request, {'MESSAGE_ID': 'tender_award_complaint_document_put'})) return {'data': document.serialize("view")}
def put(self): """Tender Award Document Update""" if not self.validate_award_document('update'): return document = upload_file(self.request) self.request.validated['award'].documents.append(document) if save_tender(self.request): self.LOGGER.info('Updated tender award document {}'.format( self.request.context.id), extra=context_unpack( self.request, {'MESSAGE_ID': 'tender_award_document_put'})) return {'data': document.serialize("view")}
def post(self): complaint = self.request.context tender = self.request.validated['tender'] award_id = self.request.validated['award_id'] location = self.request.route_path('{}:Tender Award Complaints'.format( tender['procurementMethodType']), tender_id=tender.id, award_id=award_id, complaint_id=complaint.id) location = location[len(ROUTE_PREFIX):] # strips /api/<version> if change_ownership(self.request, location) and save_tender(self.request): self.LOGGER.info('Updated award {} complaint {} ownership of tender {}'.format(complaint.id, award_id, tender.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'award_complaint_ownership_update'}, {'complaint_id': complaint.id, 'award_id': award_id, 'tender_id': tender.id})) return {'data': complaint.serialize('view')}
def delete(self): rr = self.request.context context_name = rr["__parent__"].__class__.__name__.lower() res = rr.serialize("view") self.request.validated[context_name].requirementResponses.remove(rr) self.pre_save() if save_tender(self.request): self.LOGGER.info( "Deleted {} requirement response {}".format(context_name, self.request.context.id), extra=context_unpack(self.request, {"MESSAGE_ID": "{}_requirement_response_delete".format(context_name)}), ) return {"data": res}
def put(self): """Tender Cancellation Document Update""" document = upload_file(self.request) self.request.validated["cancellation"].documents.append(document) if save_tender(self.request): self.LOGGER.info( "Updated tender cancellation document {}".format( self.request.context.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_cancellation_document_put"}), ) return {"data": document.serialize("view")}
def patch(self): requirement = self.request.context apply_patch(self.request, save=False, src=requirement.serialize()) tender = self.request.validated["tender"] if self.request.authenticated_role == "tender_owner" and hasattr(tender, "invalidate_bids_data"): tender.invalidate_bids_data() if save_tender(self.request): self.LOGGER.info( "Updated {}".format(requirement.id), extra=context_unpack(self.request, {"MESSAGE_ID": "requirement_group_requirement_patch"}), ) return {"data": requirement.serialize("view")}
def put(self): """Tender Complaint Document Update""" document = upload_file(self.request) document.author = self.request.authenticated_role self.request.validated["complaint"].documents.append(document) if save_tender(self.request): self.LOGGER.info( "Updated tender complaint document {}".format( self.request.context.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_complaint_document_put"}), ) return {"data": document.serialize("view")}
def put(self): """Tender Bid Document Update""" document = upload_file(self.request) getattr(self.request.validated["bid"], self.container).append(document) if self.request.validated["tender_status"] == "active.tendering": self.request.validated["tender"].modified = False if save_tender(self.request): self.LOGGER.info( "Updated tender bid document {}".format( self.request.context.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_bid_document_put"}), ) return {"data": document.serialize("view")}
def patch(self): cancellation = self.request.context prev_status = cancellation.status apply_patch(self.request, save=False, src=cancellation.serialize()) if cancellation.status == "active" and prev_status != "active": self.cancel_tender_lot_method(self.request, cancellation) if save_tender(self.request): self.LOGGER.info( "Updated tender cancellation {}".format(cancellation.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_cancellation_patch"}), ) return {"data": cancellation.serialize("view")}
def patch(self): criterion = self.request.context tender = self.request.validated["tender"] apply_patch(self.request, save=False, src=criterion.serialize()) if self.request.authenticated_role == "tender_owner" and hasattr(tender, "invalidate_bids_data"): tender.invalidate_bids_data() if save_tender(self.request): self.LOGGER.info( "Updated tender criterion {}".format(criterion.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_criterion_patch"}), ) return {"data": criterion.serialize("view")}
def patch(self): """Post a cancellation resolution """ if not self.validate_cancellation('update'): return apply_patch(self.request, save=False, src=self.request.context.serialize()) if self.request.context.relatedLot and self.request.context.status == 'active': self.cancel_lot() elif self.request.context.status == 'active': self.cancel_tender() if save_tender(self.request): self.LOGGER.info('Updated tender cancellation {}'.format(self.request.context.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_cancellation_patch'})) return {'data': self.request.context.serialize("view")}
def collection_post(self): """Post a complaint """ tender = self.request.validated["tender"] old_rules = get_first_revision_date(tender) < RELEASE_2020_04_19 complaint = self.request.validated["complaint"] complaint.relatedLot = self.context.lotID complaint.date = get_now() complaint.bid_id = get_bid_id(self.request) if complaint.status == "claim" and complaint.type == "claim": complaint.dateSubmitted = get_now() elif old_rules and complaint.status == "pending": complaint.type = "complaint" complaint.dateSubmitted = get_now() else: complaint.status = "draft" if (self.context.status == "unsuccessful" and complaint.status == "claim" and self.context.bidID != complaint.bid_id): raise_operation_error( self.request, "Can add claim only on unsuccessful qualification of your bid") complaint.complaintID = "{}.{}{}".format( tender.tenderID, self.server_id, calculate_total_complaints(tender) + 1, ) access = set_ownership(complaint, self.request) self.context.complaints.append(complaint) if save_tender(self.request): self.LOGGER.info( "Created tender qualification complaint {}".format( complaint.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_qualification_complaint_create"}, {"complaint_id": complaint.id}, ), ) self.request.response.status = 201 self.request.response.headers["Location"] = self.request.route_url( "{}:Tender Qualification Complaints".format( tender.procurementMethodType), tender_id=tender.id, qualification_id=self.request.validated["qualification_id"], complaint_id=complaint["id"], ) return {"data": complaint.serialize("view"), "access": access}
def put(self): """Tender Contract Document Update""" if not self.validate_contract_document("update"): return document = upload_file(self.request) self.request.validated["contract"].documents.append(document) if save_tender(self.request): self.LOGGER.info( "Updated tender contract document {}".format( self.request.context.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_contract_document_put"}), ) return {"data": document.serialize("view")}
def put(self): """Tender Document Update""" if not self.validate_update_tender(): raise error_handler(self.request.errors) document = upload_file(self.request) self.request.validated['tender'].documents.append(document) if self.request.authenticated_role == 'tender_owner' and self.request.validated[ 'tender_status'] == 'active.tendering': self.request.validated['tender'].invalidate_bids_data() if save_tender(self.request): self.LOGGER.info( 'Updated tender document {}'.format(self.request.context.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_document_put'})) return {'data': document.serialize("view")}
def put(self): """Tender Document Update""" document = upload_file(self.request) tender = self.request.validated["tender"] tender.documents.append(document) status = self.request.validated["tender_status"] if self.request.authenticated_role == "tender_owner" and status == "active.tendering": tender.invalidate_bids_data() if save_tender(self.request): self.LOGGER.info( "Updated tender document {}".format(self.request.context.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_document_put"}), ) return {"data": document.serialize("view")}
def patch(self): tender = self.request.validated['tender'] set_ownership(tender) if save_tender(self.request): self.LOGGER.info( 'Generate Tender stage2 credentials {}'.format(tender.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'})) return { 'data': tender.serialize("view"), 'access': { 'token': tender.owner_token } }
def patch(self): """Post a cancellation resolution """ tender = self.request.validated['tender'] apply_patch(self.request, save=False, src=self.request.context.serialize()) if self.request.context.status == 'active': tender.status = 'cancelled' if save_tender(self.request): self.LOGGER.info('Updated tender cancellation {}'.format( self.request.context.id), extra=context_unpack( self.request, {'MESSAGE_ID': 'tender_cancellation_patch'})) return {'data': self.request.context.serialize("view")}
def patch(self): """ Update of contract """ apply_patch(self.request, save=False, src=self.request.context.serialize()) if self.request.context.status == "active" and not self.request.context.dateSigned: self.request.context.dateSigned = get_now() self.check_tender_status_method(self.request) if save_tender(self.request): self.LOGGER.info( "Updated tender contract {}".format(self.request.context.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_contract_patch"}), ) return {"data": self.request.context.serialize()}
def collection_post(self): """Add a lot """ tender = self.request.validated["tender"] lot = self.request.validated["lot"] lot.date = get_now() tender.lots.append(lot) if save_tender(self.request): self.LOGGER.info( "Created tender lot {}".format(lot.id), extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_create"}, {"lot_id": lot.id}), ) self.request.response.status = 201 self.request.response.headers["Location"] = self.request.route_url( "{}:Tender Lots".format(tender.procurementMethodType), tender_id=tender.id, lot_id=lot.id ) return {"data": lot.serialize("view")}
def put(self): old_requirement = self.request.context requirement = old_requirement if self.request.validated["data"].get("status") != "cancelled": model = type(old_requirement) data = copy(self.request.validated["data"]) for attr_name in type(old_requirement)._fields: if data.get(attr_name) is None: data[attr_name] = getattr(old_requirement, attr_name) # To avoid new version creation if no changes and only id's were regenerated if "eligibleEvidences" not in self.request.json.get("data", {}): data["eligibleEvidences"] = [ evidence.to_primitive(role="create") for evidence in getattr(old_requirement, "eligibleEvidences") ] requirement = model(data) if old_requirement.to_primitive() == requirement.to_primitive(): return {"data": (old_requirement.serialize("view"), )} requirement.datePublished = get_now() requirement.dateModified = None self.request.validated["requirement_group"].requirements.append( requirement) if old_requirement.status == "active": old_requirement.status = "cancelled" old_requirement.dateModified = get_now() tender = self.request.validated["tender"] if (self.request.authenticated_role == "tender_owner" and tender.status == "active.tendering" and hasattr(tender, "invalidate_bids_data")): tender.invalidate_bids_data() if save_tender(self.request): self.LOGGER.info( "New version of requirement {}".format(requirement.id), extra=context_unpack( self.request, {"MESSAGE_ID": "requirement_group_requirement_put"}), ) return { "data": (requirement.serialize("view"), old_requirement.serialize("view_old")) }
def post(self): """Report auction results for lot. """ apply_patch(self.request, save=False, src=self.request.validated["tender_src"]) if all( [ i.auctionPeriod and i.auctionPeriod.endDate for i in self.request.validated["tender"].lots if i.numberOfBids > 1 and i.status == "active" ] ): add_next_award(self.request) if save_tender(self.request): self.LOGGER.info( "Report auction results", extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_auction_post"}) ) return {"data": self.request.validated["tender"].serialize(self.request.validated["tender"].status)}
def patch(self): tender = self.request.validated["tender"] award = self.request.context is_awarded = [ a for a in tender.awards if a.bid_id == award.bid_id and a.id != award.id ] award_status = award.status apply_patch(self.request, save=False, src=self.request.context.serialize()) now = get_now() if is_awarded and award.status not in ('unsuccessful', 'pending'): raise_operation_error( self.request, "Can't change award status to {} from {}".format(award.status, award_status) ) if award_status == "pending" and award.status == "active": add_contracts(self.request, award, now) add_next_award(self.request) elif award_status == "active" and award.status == "cancelled": for i in tender.contracts: if i.awardID == award.id: i.status = "cancelled" add_next_award(self.request) elif award_status == "pending" and award.status == "unsuccessful": if is_awarded: tender.status = 'unsuccessful' else: add_next_award(self.request) elif self.request.authenticated_role != "Administrator" and not ( award_status == "pending" and award.status == "pending" ): raise_operation_error( self.request, "Can't update award in current ({}) status".format(award_status) ) if save_tender(self.request): self.LOGGER.info( "Updated tender award {}".format(self.request.context.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_award_patch"} ), ) return {"data": award.serialize("view")}
def stage2_bid_post(self): tender = self.request.validated['tender'] bid = self.request.validated['bid'] # TODO can't move validator because of self.allowed_bid_status_on_create if bid.status not in self.allowed_bid_status_on_create: raise_operation_error(self.request, 'Bid can be added only with status: {}.'.format(self.allowed_bid_status_on_create)) tender.modified = False api_set_ownership(bid, self.request) tender.bids.append(bid) if save_tender(self.request): self.LOGGER.info('Created tender bid {}'.format(bid.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_bid_create'}, {'bid_id': bid.id})) self.request.response.status = 201 self.request.response.headers['Location'] = self.request.route_url('{}:Tender Bids'.format(tender.procurementMethodType), tender_id=tender.id, bid_id=bid['id']) return { 'data': bid.serialize('view'), 'access': { 'token': bid.owner_token } }
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.context data = self.request.validated['data'] if self.request.authenticated_role == 'tender_owner' and \ self.request.validated['tender_status'] in ['active.tendering', STAGE2_STATUS]: if 'tenderPeriod' in data and 'endDate' in data['tenderPeriod']: self.request.validated['tender'].tenderPeriod.import_data(data['tenderPeriod']) validate_tender_period_extension(self.request) self.request.registry.notify(TenderInitializeEvent(self.request.validated['tender'])) self.request.validated['data']["enquiryPeriod"] = self.request.validated['tender'].enquiryPeriod.serialize() apply_patch(self.request, save=False, src=self.request.validated['tender_src']) if self.request.authenticated_role == 'chronograph': check_status_ua(self.request) elif self.request.authenticated_role == 'tender_owner' and tender.status == 'active.tendering': # invalidate bids on tender change tender.invalidate_bids_data() save_tender(self.request) self.LOGGER.info('Updated tender {}'.format(tender.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'})) return {'data': tender.serialize(tender.status)}
def patch_eu(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.context data = self.request.validated['data'] if self.request.authenticated_role == 'tender_owner' \ and self.request.validated['tender_status'] == 'active.tendering': if 'tenderPeriod' in data and 'endDate' in data['tenderPeriod']: self.request.validated['tender'].tenderPeriod.import_data(data['tenderPeriod']) validate_tender_period_extension(self.request) self.request.registry.notify(TenderInitializeEvent(self.request.validated['tender'])) self.request.validated['data']["enquiryPeriod"] = self.request.validated[ 'tender'].enquiryPeriod.serialize() apply_patch(self.request, save=False, src=self.request.validated['tender_src']) if self.request.authenticated_role == 'chronograph': check_status(self.request) elif self.request.authenticated_role == 'tender_owner' and tender.status == 'active.tendering': tender.invalidate_bids_data() elif self.request.authenticated_role == 'tender_owner' and \ self.request.validated['tender_status'] == 'active.pre-qualification' and \ tender.status == "active.pre-qualification.stand-still": if all_bids_are_reviewed(self.request): tender.qualificationPeriod.endDate = calculate_business_date(get_now(), COMPLAINT_STAND_STILL, self.request.validated['tender']) tender.check_auction_time() else: raise_operation_error(self.request, 'Can\'t switch to \'active.pre-qualification.stand-still\' while not all bids are qualified') elif self.request.authenticated_role == 'tender_owner' and \ self.request.validated['tender_status'] == 'active.pre-qualification' and \ tender.status != "active.pre-qualification.stand-still": raise_operation_error(self.request, 'Can\'t update tender status') save_tender(self.request) self.LOGGER.info('Updated tender {}'.format(tender.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'})) return {'data': tender.serialize(tender.status)}
def patch(self): """Post a complaint resolution """ tender = self.request.validated['tender'] data = self.request.validated['data'] # complaint_owner if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered'] and data.get('status', self.context.status) == 'cancelled': apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateCanceled = get_now() elif self.request.authenticated_role == 'complaint_owner' and self.context.status in ['pending', 'accepted'] and data.get('status', self.context.status) == 'stopping': apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateCanceled = get_now() elif self.request.authenticated_role == 'complaint_owner' and tender.status == 'active.tendering' and self.context.status == 'draft' and data.get('status', self.context.status) == self.context.status: apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'complaint_owner' and tender.status == 'active.tendering' and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim': if get_now() > calculate_business_date(tender.tenderPeriod.endDate, -CLAIM_SUBMIT_TIME, tender, True): raise_operation_error(self.request, 'Can submit claim not later than {0.days} days before tenderPeriod end'.format(CLAIM_SUBMIT_TIME)) apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateSubmitted = get_now() elif self.request.authenticated_role == 'complaint_owner' and tender.status == 'active.tendering' and self.context.status in ['draft', 'claim'] and data.get('status', self.context.status) == 'pending': if get_now() > tender.complaintPeriod.endDate: raise_operation_error(self.request, 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME)) apply_patch(self.request, save=False, src=self.context.serialize()) self.context.type = 'complaint' self.context.dateSubmitted = get_now() elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('status', self.context.status) == self.context.status: apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is True and data.get('status', self.context.status) == 'resolved': apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is False and data.get('status', self.context.status) == 'pending': if get_now() > tender.complaintPeriod.endDate: raise_operation_error(self.request, 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME)) apply_patch(self.request, save=False, src=self.context.serialize()) self.context.type = 'complaint' self.context.dateEscalated = get_now() # tender_owner elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status: now = get_now() if now > tender.enquiryPeriod.clarificationsUntil: raise_operation_error(self.request, 'Can update claim only before enquiryPeriod.clarificationsUntil') apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'satisfied' and data.get('status', self.context.status) == self.context.status: apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'claim' and data.get('resolution', self.context.resolution) and data.get('resolutionType', self.context.resolutionType) and data.get('status', self.context.status) == 'answered': now = get_now() if now > tender.enquiryPeriod.clarificationsUntil: raise_operation_error(self.request, 'Can update claim only before enquiryPeriod.clarificationsUntil') if len(data.get('resolution', self.context.resolution)) < 20: raise_operation_error(self.request, 'Can\'t update complaint: resolution too short') apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateAnswered = get_now() elif self.request.authenticated_role == 'tender_owner' and self.context.status in ['pending', 'accepted']: apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'satisfied' and data.get('tendererAction', self.context.tendererAction) and data.get('status', self.context.status) == 'resolved': apply_patch(self.request, save=False, src=self.context.serialize()) # aboveThresholdReviewers elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['pending', 'accepted', 'stopping'] and data.get('status', self.context.status) == self.context.status: apply_patch(self.request, save=False, src=self.context.serialize()) elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['pending', 'stopping'] and data.get('status', self.context.status) in ['invalid', 'mistaken']: apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateDecision = get_now() self.context.acceptance = False elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == 'accepted': apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateAccepted = get_now() self.context.acceptance = True elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['accepted', 'stopping'] and data.get('status', self.context.status) in ['declined', 'satisfied']: apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateDecision = get_now() elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['pending', 'accepted', 'stopping'] and data.get('status', self.context.status) == 'stopped': apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateDecision = get_now() self.context.dateCanceled = self.context.dateCanceled or get_now() else: raise_operation_error(self.request, 'Can\'t update complaint') if self.context.tendererAction and not self.context.tendererActionDate: self.context.tendererActionDate = get_now() if self.context.status not in ['draft', 'claim', 'answered', 'pending', 'accepted', 'stopping'] and tender.status in ['active.qualification', 'active.awarded']: check_tender_status(self.request) if save_tender(self.request): self.LOGGER.info('Updated tender complaint {}'.format(self.context.id), extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_complaint_patch'})) return {'data': self.context.serialize("view")}