def validate_region(self, data, value): root = get_root(data['__parent__']) apply_validation = get_first_revision_date(root, default=get_now()) >= VALIDATE_ADDRESS_FROM if self.doc_type_allowed(root) and self.validation_allowed(root) and apply_validation: if data["countryName"] == "Україна": if value and value not in UA_REGIONS: raise ValidationError("field address:region not exist in ua_regions catalog")
def validate_tender_first_revision_date(request, validation_date, message="Forbidden"): tender = request.validated["tender"] tender_creation_date = get_first_revision_date(tender, default=get_now()) if tender_creation_date < validation_date: raise_operation_error(request, message)
def patch_draft_as_complaint_owner(self, data): tender = self.request.validated["tender"] rules_2020_04_19 = get_first_revision_date(tender) > RELEASE_2020_04_19 complaint_period = self.request.validated["award"].complaintPeriod is_complaint_period = ( complaint_period.startDate <= get_now() <= complaint_period.endDate if complaint_period.endDate else complaint_period.startDate <= get_now() ) if not is_complaint_period: raise_operation_error(self.request, "Can't update draft complaint not in complaintPeriod") new_status = data.get("status", self.context.status) if new_status == self.context.status: apply_patch(self.request, save=False, src=self.context.serialize()) elif ( rules_2020_04_19 and self.context.type == "complaint" and new_status == "mistaken" ): self.context.rejectReason = "cancelledByComplainant" apply_patch(self.request, save=False, src=self.context.serialize()) elif self.context.type == "claim" and new_status == "claim": self.validate_posting_claim() apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateSubmitted = get_now() elif new_status == "pending" and not rules_2020_04_19: apply_patch(self.request, save=False, src=self.context.serialize()) self.context.type = "complaint" self.context.dateSubmitted = get_now() else: raise_operation_error(self.request, "Can't update draft complaint into {} status".format(new_status))
def validate_additionalClassifications(self, data, items): plan = data["__parent__"] if not plan.classification: return plan_date = get_first_revision_date(data, default=get_now()) plan_from_2017 = plan_date > CPV_ITEMS_CLASS_FROM not_cpv = data["classification"]["id"] == "99999999-9" if not items and ( not plan_from_2017 or plan_from_2017 and not_cpv and plan_date < NOT_REQUIRED_ADDITIONAL_CLASSIFICATION_FROM ): raise ValidationError(u"This field is required.") elif ( plan_from_2017 and not_cpv and items and not any([i.scheme in ADDITIONAL_CLASSIFICATIONS_SCHEMES_2017 for i in items]) ): raise ValidationError( u"One of additional classifications should be one of [{0}].".format( ", ".join(ADDITIONAL_CLASSIFICATIONS_SCHEMES_2017) ) ) elif not plan_from_2017 and items and not any([i.scheme in ADDITIONAL_CLASSIFICATIONS_SCHEMES for i in items]): raise ValidationError( u"One of additional classifications should be one of [{0}].".format( ", ".join(ADDITIONAL_CLASSIFICATIONS_SCHEMES) ) )
def collection_post(self): cancellation = self.request.validated["cancellation"] cancellation.date = get_now() if get_first_revision_date(self.request.tender, default=get_now()) > RELEASE_2020_04_19: cancellation.status = None if cancellation.status == "active": self.cancel_tender_lot_method(self.request, cancellation) self.request.context.cancellations.append(cancellation) if save_tender(self.request): self.LOGGER.info( "Created tender cancellation {}".format(cancellation.id), extra=context_unpack( self.request, {"MESSAGE_ID": "tender_cancellation_create"}, {"cancellation_id": cancellation.id}), ) self.request.response.status = 201 self.request.response.headers["Location"] = self.request.route_url( "{}:Tender Cancellations".format( self.request.validated["tender"].procurementMethodType), tender_id=self.request.validated["tender_id"], cancellation_id=cancellation.id, ) return {"data": cancellation.serialize("view")}
def patch_as_complaint_owner(self, data): status = self.context.status new_status = data.get("status", status) tender = self.request.validated["tender"] rules_2020_04_19 = get_first_revision_date(tender, get_now()) > RELEASE_2020_04_19 if ( new_status == "cancelled" and status in ["draft", "claim", "answered"] and self.context.type == "claim" ) or ( new_status == "cancelled" and status == "draft" and self.context.type == "complaint" and not rules_2020_04_19 ) or ( new_status == "stopping" and status in ["pending", "accepted"] and not rules_2020_04_19 ): apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateCanceled = get_now() elif status == "draft": self.patch_draft_as_complaint_owner(data) elif status == "answered" and new_status == status: apply_patch(self.request, save=False, src=self.context.serialize()) else: raise_operation_error( self.request, "Can't update complaint from {} to {} status".format(status, new_status) )
def export_loop(self, model_instance, field_converter, role=None, print_none=False): """ Calls the main `export_loop` implementation because they are both supposed to operate on models. """ if isinstance(model_instance, self.model_class): model_class = model_instance.__class__ else: model_class = self.model_class tender = model_instance.__parent__ tender_date = get_first_revision_date(tender, default=get_now()) status = getattr(model_instance, "status") if tender_date > BID_UNSUCCESSFUL_FROM and role not in [ None, "plain" ] and status == "unsuccessful": role = "bid.unsuccessful" shaped = export_loop(model_class, model_instance, field_converter, role=role, print_none=print_none) if shaped and len(shaped) == 0 and self.allow_none(): return shaped elif shaped: return shaped elif print_none: return shaped
def patch(self): cancellation = self.request.context prev_status = cancellation.status apply_patch(self.request, save=False, src=cancellation.serialize()) new_rules = get_first_revision_date( self.request.tender, default=get_now()) > RELEASE_2020_04_19 if new_rules: if prev_status == "draft" and cancellation.status == "pending": validate_absence_of_pending_accepted_satisfied_complaints( self.request) tender = self.request.validated["tender"] now = get_now() cancellation.complaintPeriod = { "startDate": now.isoformat(), "endDate": calculate_complaint_business_date(now, timedelta(days=10), tender).isoformat() } 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_as_abovethresholdreviewers(self, data): context = self.context status = context.status new_status = data.get("status", status) tender = self.request.validated["tender"] old_rules = get_first_revision_date(tender) < RELEASE_2020_04_19 if (status in ["pending", "accepted", "stopping"] and new_status == status): apply_patch(self.request, save=False, src=context.serialize()) elif (status in ["pending", "stopping"] and ((old_rules and new_status in ["invalid", "mistaken"]) or (new_status == "invalid"))): apply_patch(self.request, save=False, src=context.serialize()) context.dateDecision = get_now() context.acceptance = False elif status == "pending" and new_status == "accepted": apply_patch(self.request, save=False, src=context.serialize()) context.dateAccepted = get_now() context.acceptance = True elif (status in ["accepted", "stopping"] and new_status in ["declined", "satisfied"]): apply_patch(self.request, save=False, src=context.serialize()) context.dateDecision = get_now() elif (status in ["pending", "accepted", "stopping"] and new_status == "stopped"): apply_patch(self.request, save=False, src=context.serialize()) context.dateDecision = get_now() context.dateCanceled = context.dateCanceled or get_now() else: raise_operation_error( self.request, "Can't update complaint from {} to {} status".format( status, new_status))
def calculate_tender_date(date_obj, timedelta_obj, tender, working_days, calendar=WORKING_DAYS): tender_date = get_first_revision_date(tender, default=get_now()) if working_days: midnight = tender_date > WORKING_DATE_ALLOW_MIDNIGHT_FROM return calc_working_datetime(date_obj, timedelta_obj, midnight, calendar) else: return calc_datetime(date_obj, timedelta_obj)
def validate_cause_choices(self, data, value): apply_new_negotiation_causes = get_first_revision_date(data, default=get_now()) > NEW_NEGOTIATION_CAUSES_FROM cause_choices = self._cause_choices_new \ if apply_new_negotiation_causes \ else self._cause_choices if value not in cause_choices: raise ValidationError(BaseType.MESSAGES['choices'].format(cause_choices))
def validate_change_requirement_objects(request, **kwargs): valid_statuses = ["draft"] tender = request.validated["tender"] tender_creation_date = get_first_revision_date(tender, default=get_now()) if tender_creation_date < CRITERION_REQUIREMENT_STATUSES_FROM: valid_statuses.append("active.enquiries") base_validate_operation_ecriteria_objects(request, valid_statuses)
def validate_startDate(self, data, value): tender = get_tender(data["__parent__"]) tender_date = get_first_revision_date(tender, default=get_now()) if tender_date < PERIOD_END_REQUIRED_FROM: return if value and data.get("endDate") and data.get("endDate") < value: raise ValidationError(u"period should begin before its end")
def validate_update_contracting_value_amount(request, name="value", **kwargs): schematics_document = get_schematics_document( request.validated["contract"]) validation_date = get_first_revision_date(schematics_document, default=get_now()) validate_update_contract_value_amount( request, name=name, allow_equal=validation_date < VAT_FROM)
def validate_reviewPlace(self, data, reviewPlace): tender_date = get_first_revision_date(get_tender(data["__parent__"]), default=get_now()) if tender_date < RELEASE_2020_04_19: return if not reviewPlace and data.get("status") == "accepted": raise ValidationError(u"This field is required.")
def patch_as_complaint_owner(self, data): context = self.context status = self.context.status new_status = data.get("status", status) tender = self.request.validated["tender"] apply_rules_2020_04_19 = get_first_revision_date( tender) > RELEASE_2020_04_19 if status in ["draft", "claim", "answered" ] and new_status == "cancelled": apply_patch(self.request, save=False, src=context.serialize()) context.dateCanceled = get_now() elif (apply_rules_2020_04_19 and status == "draft" and context.type == "complaint" and new_status == "mistaken"): context.rejectReason = "cancelledByComplainant" apply_patch(self.request, save=False, src=context.serialize()) elif (status in ["pending", "accepted"] and new_status == "stopping" and not apply_rules_2020_04_19): apply_patch(self.request, save=False, src=context.serialize()) context.dateCanceled = get_now() elif (tender.status == "active.tendering" and status == "draft" and new_status == status): apply_patch(self.request, save=False, src=context.serialize()) elif (tender.status == "active.tendering" and status == "draft" and new_status == "claim"): self.validate_submit_claim_time_method(self.request) apply_patch(self.request, save=False, src=context.serialize()) context.dateSubmitted = get_now() elif (tender.status == "active.tendering" and status in ["draft", "claim"] and new_status == "pending" and not apply_rules_2020_04_19): validate_submit_complaint_time(self.request) validate_complaint_type_change(self.request) apply_patch(self.request, save=False, src=context.serialize()) context.type = "complaint" context.dateSubmitted = get_now() elif status == "answered" and new_status == status: apply_patch(self.request, save=False, src=context.serialize()) elif (status == "answered" and data.get("satisfied", context.satisfied) is True and new_status == "resolved"): apply_patch(self.request, save=False, src=context.serialize()) elif (status == "answered" and data.get("satisfied", context.satisfied) is False and new_status == "pending"): validate_submit_complaint_time(self.request) validate_complaint_type_change(self.request) apply_patch(self.request, save=False, src=context.serialize()) context.type = "complaint" context.dateEscalated = get_now() else: raise_operation_error( self.request, "Can't update complaint from {} to {} status".format( status, new_status))
def validate_update_contracting_value_readonly(request, **kwargs): schematics_document = get_schematics_document( request.validated["contract"]) validation_date = get_first_revision_date(schematics_document, default=get_now()) readonly_attrs = ("currency", ) if validation_date < VAT_FROM else ( "valueAddedTaxIncluded", "currency") validate_update_contract_value(request, name="value", attrs=readonly_attrs)
def validate_currency(self, data, value): try: root = get_root(data.get("__parent__", {})) except AttributeError: root = None is_valid_date = get_first_revision_date(root, default=get_now()) >= VALIDATE_CURRENCY_FROM if is_valid_date and value not in CURRENCIES: raise ValidationError(f"Currency must be only {', '.join(CURRENCIES)}.")
def validate_only_complaint_allowed(request, **kwargs): tender = request.validated["tender"] tender_created = get_first_revision_date(tender, default=get_now()) if (tender_created > NO_DEFENSE_AWARD_CLAIMS_FROM and request.validated["complaint"]["type"] != "complaint"): raise_operation_error( request, "Can't add complaint of '{}' type".format( request.validated["complaint"]["type"]))
def validate_cause(self, data, value): required = get_first_revision_date( data, default=get_now()) >= QUICK_CAUSE_REQUIRED_FROM if required and not value: raise ValidationError(BaseType.MESSAGES["required"]) if value: NegotiationTender._validator_functions["cause_choices"](self, data, value)
def validate_scale(self, data, value): try: schematics_document = get_schematics_document(data["__parent__"]) except AttributeError: pass else: validation_date = get_first_revision_date(schematics_document, default=get_now()) if validation_date >= ORGANIZATION_SCALE_FROM and value is None: raise ValidationError(BaseType.MESSAGES["required"])
def validate_rejectReason(self, data, rejectReason): tender_date = get_first_revision_date(get_tender(data["__parent__"]), default=get_now()) if tender_date < RELEASE_2020_04_19: return if not rejectReason and data.get("status") in [ "invalid", "stopped" ] and data.get("type") == "complaint": raise ValidationError(u"This field is required.")
def patch_as_complaint_owner(self, data): tender = self.request.validated["tender"] data = self.request.validated["data"] status = self.context.status new_status = data.get("status", status) is_qualificationPeriod = tender.qualificationPeriod.startDate < get_now( ) and (not tender.qualificationPeriod.endDate or tender.qualificationPeriod.endDate > get_now()) apply_rules_2020_04_19 = get_first_revision_date( tender, get_now()) > RELEASE_2020_04_19 if (new_status == "cancelled" and status in ["draft", "claim", "answered"] and self.context.type == "claim") or (new_status == "cancelled" and status == "draft" and self.context.type == "complaint" and not apply_rules_2020_04_19): apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateCanceled = get_now() elif (apply_rules_2020_04_19 and status == "draft" and self.context.type == "complaint" and new_status == "mistaken"): self.context.rejectReason = "cancelledByComplainant" apply_patch(self.request, save=False, src=self.context.serialize()) elif (status in ["pending", "accepted"] and new_status == "stopping" and not apply_rules_2020_04_19): apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateCanceled = get_now() elif (is_qualificationPeriod and status == "draft" and new_status == status): apply_patch(self.request, save=False, src=self.context.serialize()) elif (is_qualificationPeriod and self.context.type == "claim" and status == "draft" and new_status == "claim"): if (self.request.validated["qualification"].status == "unsuccessful" and self.request.validated["qualification"].bidID != self.context.bid_id): raise_operation_error( self.request, "Can add claim only on unsuccessful qualification of your bid" ) apply_patch(self.request, save=False, src=self.context.serialize()) self.context.dateSubmitted = get_now() elif (is_qualificationPeriod and status == "draft" and new_status == "pending" and not apply_rules_2020_04_19): apply_patch(self.request, save=False, src=self.context.serialize()) self.context.type = "complaint" self.context.dateSubmitted = get_now() elif (status == "answered" and new_status == status): apply_patch(self.request, save=False, src=self.context.serialize()) else: raise_operation_error( self.request, "Can't update complaint from {} to {} status".format( status, new_status))
def validate_items(self, data, items): cpv_336_group = items[ 0].classification.id[:3] == "336" if items else False date = get_first_revision_date(data, default=get_now()) if (not cpv_336_group and date > CPV_ITEMS_CLASS_FROM and items and len(set([i.classification.id[:4] for i in items])) != 1): raise ValidationError("CPV class of items should be identical") else: validate_cpv_group(items)
def validate_procurementMethodType(self, data, procurementMethodType): _procedures = deepcopy(PROCEDURES) _parent = data['__parent__'] validation_date = get_first_revision_date(_parent, default=get_now()) if validation_date >= PLAN_ADDRESS_KIND_REQUIRED_FROM: _procedures[""] = ("centralizedProcurement", ) if procurementMethodType not in _procedures[data.get("procurementMethod")]: raise ValidationError(u"Value must be one of {!r}.".format(_procedures[data.get("procurementMethod")]))
def validate_relatedBuyer(self, data, related_buyer): tender = get_tender(data["__parent__"]) validation_date = get_first_revision_date(tender, default=get_now()) validation_enabled = all([ tender.buyers, tender.status != "draft", validation_date >= MULTI_CONTRACTS_REQUIRED_FROM ]) if validation_enabled and not related_buyer: raise ValidationError(BaseType.MESSAGES["required"])
def validate_telephone(self, data, value): try: root = get_schematics_document(data["__parent__"]) except AttributeError: pass else: apply_validation = get_first_revision_date(root, default=get_now()) >= VALIDATE_TELEPHONE_FROM if value and re.match("^(\+)?[0-9]{2,}(,( )?(\+)?[0-9]{2,})*$", value) is None and apply_validation: raise ValidationError(u"wrong telephone format (could be missed +)")
def calculate_clarifications_business_date(date_obj, timedelta_obj, tender=None, working_days=False, calendar=WORKING_DAYS): accelerator = get_tender_accelerator(tender) if accelerator: return calc_datetime(date_obj, timedelta_obj, accelerator) tender_date = get_first_revision_date(tender, default=get_now()) if tender_date > NORMALIZED_CLARIFICATIONS_PERIOD_FROM: source_date_obj = calc_normalized_datetime(date_obj, ceil=timedelta_obj > timedelta()) else: source_date_obj = date_obj return calculate_tender_date(source_date_obj, timedelta_obj, tender, working_days, calendar)
def validate_countryName(self, data, value): root = get_root(data['__parent__']) apply_validation = get_first_revision_date( root, default=get_now()) >= VALIDATE_ADDRESS_FROM if self.doc_type_allowed(root) and self.validation_allowed( root) and apply_validation: if value not in COUNTRIES: raise ValidationError( u"field address:countryName not exist in countries catalog" )
def calculate_period_start_date(date_obj, timedelta_obj, normalized_from_date_obj, tender=None): tender_date = get_first_revision_date(tender, default=get_now()) if tender_date > normalized_from_date_obj: return calc_normalized_datetime(date_obj, ceil=timedelta_obj > timedelta()) else: return date_obj