class Agreement(Model): class Options: roles = RolesFromCsv('Agreement.csv', relative_to=__file__) id = MD5Type(required=True) agreementID = StringType() agreementNumber = StringType() contracts = ListType(ModelType(Contract)) changes = ListType(PolyModelType((ChangeTaxRate, ChangeItemPriceVariation, ChangePartyWithdrawal, ChangeThirdParty), claim_function=get_change_class), default=list()) date = IsoDateTimeType() dateSigned = IsoDateTimeType() dateModified = IsoDateTimeType() description = StringType() description_en = StringType() description_ru = StringType() documents = ListType(ModelType(Document), default=list()) items = ListType(ModelType(Item)) features = ListType(ModelType(Feature), validators=[validate_features_uniq]) mode = StringType(choices=['test']) owner = StringType() period = ModelType(Period) procuringEntity = ModelType(ProcuringEntity) status = StringType( choices=['pending', 'active', 'cancelled', 'terminated']) tender_id = MD5Type() title = StringType() title_en = StringType() title_ru = StringType() terminationDetails = StringType() numberOfContracts = IntType()
class Milestone(Model): class Options: roles = { "create": whitelist("type", "documents"), "view": blacklist("doc_type", "_id", "_rev", "__parent__"), } id = MD5Type(required=True, default=lambda: uuid4().hex) type = StringType( required=True, choices=["activation", "ban", "disqualification", "terminated"]) dueDate = IsoDateTimeType() documents = ListType(ModelType(Document, required=True), default=list()) dateModified = IsoDateTimeType(default=get_now) @serializable(serialized_name="dueDate", serialize_when_none=False) def milestone_dueDate(self): if self.type == "ban" and not self.dueDate: request = self.get_root().request agreement = request.validated["agreement_src"] dueDate = calculate_framework_date( get_now(), timedelta(days=CONTRACT_BAN_DURATION), agreement, ceil=True) return dueDate.isoformat() return self.dueDate.isoformat() if self.dueDate else None
class Change(Model): class Options: roles = { # 'edit': blacklist('id', 'date'), 'create': whitelist('rationale', 'rationale_ru', 'rationale_en', 'rationaleTypes', 'contractNumber', 'dateSigned'), 'edit': whitelist('rationale', 'rationale_ru', 'rationale_en', 'rationaleTypes', 'contractNumber', 'status', 'dateSigned'), 'view': schematics_default_role, 'embedded': schematics_embedded_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) status = StringType(choices=['pending', 'active'], default='pending') date = IsoDateTimeType(default=get_now) rationale = StringType(required=True, min_length=1) rationale_en = StringType() rationale_ru = StringType() rationaleTypes = ListType(StringType(choices=['volumeCuts', 'itemPriceVariation', 'qualityImprovement', 'thirdParty', 'durationExtension', 'priceReduction', 'taxRate', 'fiscalYearExtension'], required=True), min_size=1, required=True) contractNumber = StringType() dateSigned = IsoDateTimeType() def validate_dateSigned(self, data, value): if value and value > get_now(): raise ValidationError(u"Contract signature date can't be in the future")
class Question(Model): class Options: roles = { 'create': whitelist('author', 'title', 'description', 'questionOf', 'relatedItem'), 'edit': whitelist('answer'), 'embedded': schematics_embedded_role, 'view': schematics_default_role, 'active.enquiries': (blacklist('author') + schematics_embedded_role), 'active.tendering': (blacklist('author') + schematics_embedded_role), 'active.auction': (blacklist('author') + schematics_embedded_role), 'active.pre-qualification': (blacklist('author') + schematics_embedded_role), 'active.pre-qualification.stand-still': (blacklist('author') + schematics_embedded_role), 'active.qualification': schematics_default_role, 'active.awarded': schematics_default_role, 'complete': schematics_default_role, 'unsuccessful': schematics_default_role, 'cancelled': schematics_default_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) author = ModelType( Organization, required=True ) # who is asking question (contactPoint - person, identification - organization that person represents) title = StringType(required=True) # title of the question description = StringType() # description of the question date = IsoDateTimeType(default=get_now) # autogenerated date of posting answer = StringType() # only tender owner can post answer questionOf = StringType(required=True, choices=['tender', 'item', 'lot'], default='tender') relatedItem = StringType(min_length=1) dateAnswered = IsoDateTimeType() def validate_relatedItem(self, data, relatedItem): if not relatedItem and data.get('questionOf') in ['item', 'lot']: raise ValidationError(u'This field is required.') if relatedItem and isinstance(data['__parent__'], Model): tender = get_tender(data['__parent__']) if data.get('questionOf') == 'lot' and relatedItem not in [ i.id for i in tender.lots ]: raise ValidationError(u"relatedItem should be one of lots") if data.get('questionOf') == 'item' and relatedItem not in [ i.id for i in tender.items ]: raise ValidationError(u"relatedItem should be one of items")
class BaseTender(SchematicsDocument, Model): title = StringType(required=True) title_en = StringType() title_ru = StringType() documents = ListType( ModelType(Document), default=list()) # All documents and attachments related to the tender. description = StringType() description_en = StringType() description_ru = StringType() date = IsoDateTimeType() dateModified = IsoDateTimeType() tenderID = StringType( ) # TenderID should always be the same as the OCID. It is included to make the flattened data structure more convenient. owner = StringType() owner_token = StringType() mode = StringType(choices=['test']) procurementMethodRationale = StringType( ) # Justification of procurement method, especially in the case of Limited tendering. procurementMethodRationale_en = StringType() procurementMethodRationale_ru = StringType() if SANDBOX_MODE: procurementMethodDetails = StringType() _attachments = DictType(DictType(BaseType), default=dict()) # couchdb attachments revisions = ListType(ModelType(Revision), default=list()) def __repr__(self): return '<%s:%r@%r>' % (type(self).__name__, self.id, self.rev) @serializable(serialized_name='id') def doc_id(self): """A property that is serialized by schematics exports.""" return self._id def import_data(self, raw_data, **kw): """ Converts and imports the raw data into the instance of the model according to the fields in the model. :param raw_data: The data to be imported. """ data = self.convert(raw_data, **kw) del_keys = [ k for k in data.keys() if data[k] == self.__class__.fields[k].default or data[k] == getattr(self, k) ] for k in del_keys: del data[k] self._data.update(data) return self def validate_procurementMethodDetails(self, *args, **kw): if self.mode and self.mode == 'test' and self.procurementMethodDetails and self.procurementMethodDetails != '': raise ValidationError( u"procurementMethodDetails should be used with mode test")
class Change(Model): id = MD5Type(required=True, default=lambda: uuid4().hex) status = StringType(choices=["pending", "active"], default="pending") date = IsoDateTimeType(default=get_now) rationale = StringType(required=True, min_length=1) rationale_en = StringType() rationale_ru = StringType() dateSigned = IsoDateTimeType() def validate_dateSigned(self, data, value): if value and value > get_now(): raise ValidationError(u"Agreement signature date can't be in the future")
class Agreement(OpenprocurementSchematicsDocument, Model): """ Base agreement model """ id = MD5Type(required=True, default=lambda: uuid4().hex) agreementID = StringType() # maybe terminated ???? status = StringType(choices=["active", "terminated"], required=True) date = IsoDateTimeType() dateModified = IsoDateTimeType() description = StringType() title = StringType() revisions = ListType(ModelType(Revision, required=True), default=list()) tender_token = StringType(required=True) tender_id = StringType(required=True) owner_token = StringType(default=lambda: uuid4().hex) transfer_token = StringType(default=lambda: uuid4().hex) owner = StringType() mode = StringType(choices=["test"]) def import_data(self, raw_data, **kw): """ Converts and imports the raw data into the instance of the model according to the fields in the model. :param raw_data: The data to be imported. """ data = self.convert(raw_data, **kw) del_keys = [ k for k in data.keys() if data[k] == self.__class__.fields[k].default or data[k] == getattr(self, k) ] for k in del_keys: del data[k] self._data.update(data) return self def __local_roles__(self): return dict( [ ("{}_{}".format(self.owner, self.owner_token), "agreement_owner"), ("{}_{}".format(self.owner, self.tender_token), "tender_owner"), ] ) def __acl__(self): acl = [ (Allow, "{}_{}".format(self.owner, self.owner_token), "edit_agreement"), (Allow, "{}_{}".format(self.owner, self.tender_token), "generate_credentials"), ] return acl def __repr__(self): return "<%s:%r@%r>" % (type(self).__name__, self.id, self.rev)
class Milestone(Model): TYPE_APPROVAL = 'approval' STATUS_SCHEDULED = 'scheduled' STATUS_MET = 'met' STATUS_NOT_MET = 'notMet' STATUS_INVALID = 'invalid' ACTIVE_STATUSES = (STATUS_SCHEDULED, STATUS_MET) class Options: _edit = whitelist("status", "dueDate", "description") _create = _edit + whitelist("title", "description", "type", "author", "documents") _view = _create + whitelist("id", "owner", "dateModified", "dateMet") roles = { "create": _create, "edit": _edit, "embedded": _view, "view": _view, "plain": _view + whitelist("owner_token", "transfer_token"), } def __local_roles__(self): return { "{}_{}".format(self.owner, self.owner_token): "milestone_owner" } def __acl__(self): acl = [ (Allow, "{}_{}".format(self.owner, self.owner_token), "update_milestone"), ] return acl id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType(required=True, choices=[MILESTONE_APPROVAL_TITLE]) description = StringType(required=True, min_length=3, default=MILESTONE_APPROVAL_DESCRIPTION) type = StringType(required=True, choices=[TYPE_APPROVAL]) dueDate = IsoDateTimeType(required=True) status = StringType( required=True, choices=[STATUS_SCHEDULED, STATUS_MET, STATUS_NOT_MET, STATUS_INVALID], default=STATUS_SCHEDULED) documents = ListType(ModelType(Document, required=True), default=list()) author = ModelType(BaseOrganization, required=True) dateModified = IsoDateTimeType(default=get_now) dateMet = IsoDateTimeType() owner = StringType() owner_token = StringType()
class BudgetPeriod(Period): startDate = IsoDateTimeType(required=True) endDate = IsoDateTimeType(required=True) def validate_endDate(self, data, value): plan = data['__parent__']['__parent__'] start_date = data.get('startDate') method_type = plan.tender.procurementMethodType if method_type not in MULTI_YEAR_BUDGET_PROCEDURES and value.year != start_date.year: raise ValidationError(u"Period startDate and endDate must be within one year for {}.".format( method_type)) if method_type in MULTI_YEAR_BUDGET_PROCEDURES and value.year - start_date.year > MULTI_YEAR_BUDGET_MAX_YEARS: raise ValidationError(u"Period startDate and endDate must be within {} budget years for {}.".format( MULTI_YEAR_BUDGET_MAX_YEARS + 1, method_type))
class Contract(Model): class Options: roles = { "edit": whitelist("suppliers"), "view": blacklist("doc_type", "_id", "_rev", "__parent__") } id = MD5Type(required=True, default=lambda: uuid4().hex) qualificationID = StringType() status = StringType( choices=["active", "banned", "unsuccessful", "terminated"]) suppliers = ListType( ModelType(BusinessOrganization, required=True), required=True, min_size=1, ) milestones = ListType( ModelType(Milestone, required=True), required=True, min_size=1, ) date = IsoDateTimeType(default=get_now) def validate_suppliers(self, data, suppliers): if len(suppliers) != 1: raise ValidationError("Contract must have only one supplier")
class Cancellation(Model): class Options: roles = { "create": whitelist( "reason", "reasonType", "cancellationOf", ), "edit": whitelist("status", "reasonType"), "embedded": schematics_embedded_role, "view": schematics_default_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) reason = StringType(required=True) reason_en = StringType() reason_ru = StringType() date = IsoDateTimeType(default=get_now) status = StringType(choices=["draft", "unsuccessful", "active"], default='draft') documents = ListType(ModelType(Document, required=True), default=list()) cancellationOf = StringType(required=True, choices=["tender"], default="tender") reasonType = StringType( choices=["noDemand", "unFixable", "forceMajeure", "expensesCut"], )
class LotValue(Model): class Options: roles = { 'embedded': schematics_embedded_role, 'view': schematics_default_role, 'create': whitelist('value', 'relatedLot'), 'edit': whitelist('value', 'relatedLot'), 'auction_view': whitelist('value', 'date', 'relatedLot', 'participationUrl'), 'auction_post': whitelist('value', 'date', 'relatedLot'), 'auction_patch': whitelist('participationUrl', 'relatedLot'), } value = ModelType(Value, required=True) relatedLot = MD5Type(required=True) participationUrl = URLType() date = IsoDateTimeType(default=get_now) def validate_value(self, data, value): if value and isinstance(data['__parent__'], Model) and data['relatedLot']: validate_LotValue_value(get_tender(data['__parent__']), data['relatedLot'], value) def validate_relatedLot(self, data, relatedLot): if isinstance(data['__parent__'], Model) and relatedLot not in [ i.id for i in get_tender(data['__parent__']).lots ]: raise ValidationError(u"relatedLot should be one of lots")
class Qualification(Model): """ Pre-Qualification """ class Options: roles = { 'create': blacklist('id', 'status', 'documents', 'date'), 'edit': whitelist('status', 'title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru'), 'embedded': schematics_embedded_role, 'view': schematics_default_role, } title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType(choices=['pending', 'active', 'unsuccessful', 'cancelled'], default='pending') date = IsoDateTimeType() documents = ListType(ModelType(Document), default=list()) complaints = ListType(ModelType(Complaint), default=list()) def validate_lotID(self, data, lotID): if isinstance(data['__parent__'], Model): if not lotID and data['__parent__'].lots: raise ValidationError(u'This field is required.') if lotID and lotID not in [i.id for i in data['__parent__'].lots]: raise ValidationError(u"lotID should be one of lots")
class Cancellation(Model): class Options: roles = { 'create': whitelist('reason', 'status', 'cancellationOf', 'relatedLot'), 'edit': whitelist('status'), 'embedded': schematics_embedded_role, 'view': schematics_default_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) reason = StringType(required=True) reason_en = StringType() reason_ru = StringType() date = IsoDateTimeType(default=get_now) status = StringType(choices=['pending', 'active'], default='pending') documents = ListType(ModelType(Document), default=list()) cancellationOf = StringType(required=True, choices=['tender', 'lot'], default='tender') relatedLot = MD5Type() def validate_relatedLot(self, data, relatedLot): if not relatedLot and data.get('cancellationOf') == 'lot': raise ValidationError(u'This field is required.') if relatedLot and isinstance(data['__parent__'], Model) and relatedLot not in [ i.id for i in data['__parent__'].lots ]: raise ValidationError(u"relatedLot should be one of lots")
class Lot(Model): class Options: roles = { 'create': whitelist('id', 'title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru', 'value'), 'edit': whitelist('title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru', 'value'), 'embedded': embedded_lot_role, 'view': default_lot_role, 'default': default_lot_role, 'auction_view': default_lot_role, 'auction_patch': whitelist('id', 'auctionUrl'), 'chronograph': whitelist('id', 'auctionPeriod'), 'chronograph_view': whitelist('id', 'auctionPeriod', 'numberOfBids', 'status'), 'Administrator': whitelist('auctionPeriod'), } id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType(required=True, min_length=1) title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() date = IsoDateTimeType() value = ModelType(Value, required=True) status = StringType(choices=['active', 'cancelled', 'unsuccessful', 'complete'], default='active') @serializable(serialized_name="value", type=ModelType(Value)) def lot_value(self): return Value(dict(amount=self.value.amount, currency=self.__parent__.value.currency, valueAddedTaxIncluded=self.__parent__.value.valueAddedTaxIncluded))
class Award(Model): """ An award for the given procurement. There may be more than one award per contracting process e.g. because the contract is split amongst different providers, or because it is a standing offer. """ class Options: roles = { 'create': award_create_reporting_role, 'edit': award_edit_reporting_role, 'embedded': schematics_embedded_role, 'view': schematics_default_role, 'Administrator': whitelist('complaintPeriod'), } id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType() # Award title title_en = StringType() title_ru = StringType() subcontractingDetails = StringType() qualified = BooleanType() description = StringType() # Award description description_en = StringType() description_ru = StringType() status = StringType(required=True, choices=['pending', 'unsuccessful', 'active', 'cancelled'], default='pending') date = IsoDateTimeType(default=get_now) value = ModelType(Value) suppliers = ListType(ModelType(Organization), required=True, min_size=1, max_size=1) items = ListType(ModelType(Item)) documents = ListType(ModelType(Document), default=list()) complaints = ListType(ModelType(Complaint), default=list()) complaintPeriod = ModelType(Period)
class Award(Award): id = MD5Type(required=True, default=lambda: uuid4().hex) bid_id = MD5Type(required=True) lotID = MD5Type() title = StringType() # Award title title_en = StringType() title_ru = StringType() description = StringType() # Award description description_en = StringType() description_ru = StringType() status = StringType( required=True, choices=['pending', 'unsuccessful', 'active', 'cancelled'], default='pending') date = IsoDateTimeType(default=get_now) value = ModelType(Value) suppliers = ListType(ModelType(Organization), required=True, min_size=1, max_size=1) items = ListType(ModelType(Item)) documents = ListType(ModelType(Document), default=list()) complaints = ListType(ModelType(Complaint), default=list()) complaintPeriod = ModelType(Period) def validate_lotID(self, data, lotID): if isinstance(data['__parent__'], Model): if not lotID and data['__parent__'].lots: raise ValidationError(u'This field is required.') if lotID and lotID not in [i.id for i in data['__parent__'].lots]: raise ValidationError(u"lotID should be one of lots")
class Change(Model): class Options: roles = { # 'edit': blacklist('id', 'date'), "create": whitelist("rationale", "rationale_ru", "rationale_en", "rationaleTypes", "contractNumber", "dateSigned"), "edit": whitelist("rationale", "rationale_ru", "rationale_en", "rationaleTypes", "contractNumber", "status", "dateSigned"), "view": schematics_default_role, "embedded": schematics_embedded_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) status = StringType(choices=["pending", "active"], default="pending") date = IsoDateTimeType(default=get_now) rationale = StringType(required=True, min_length=1) rationale_en = StringType() rationale_ru = StringType() rationaleTypes = ListType( StringType( choices=[ "volumeCuts", "itemPriceVariation", "qualityImprovement", "thirdParty", "durationExtension", "priceReduction", "taxRate", "fiscalYearExtension", ], required=True, ), min_size=1, required=True, ) contractNumber = StringType() dateSigned = IsoDateTimeType() def validate_dateSigned(self, data, value): if value and value > get_now(): raise ValidationError( u"Contract signature date can't be in the future")
class Qualification(QualificationMilestoneListMixin): """ Pre-Qualification """ class Options: roles = { "create": blacklist("id", "status", "documents", "date", "requirementResponses"), "edit": whitelist( "status", "qualified", "eligible", "title", "title_en", "title_ru", "description", "description_en", "description_ru", "requirementResponses", ), "embedded": schematics_embedded_role, "view": schematics_default_role, } title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType(choices=["pending", "active", "unsuccessful", "cancelled"], default="pending") date = IsoDateTimeType() documents = ListType(ModelType(EUDocument, required=True), default=list()) complaints = ListType(ModelType(Complaint, required=True), default=list()) qualified = BooleanType(default=False) eligible = BooleanType(default=False) requirementResponses = ListType( ModelType(RequirementResponse, required=True), default=list() ) def validate_qualified(self, data, qualified): if data["status"] == "active" and not qualified: raise ValidationError("This field is required.") def validate_eligible(self, data, eligible): if data["status"] == "active" and not eligible: raise ValidationError("This field is required.") def validate_lotID(self, data, lotID): parent = data["__parent__"] if isinstance(parent, Model): if not lotID and parent.lots: raise ValidationError("This field is required.") if lotID and lotID not in [lot.id for lot in parent.lots if lot]: raise ValidationError("lotID should be one of lots")
class Agreement(Model): class Options: roles = RolesFromCsv("Agreement.csv", relative_to=__file__) id = MD5Type(required=True, default=lambda: uuid4().hex) agreementID = StringType() agreementNumber = StringType() date = IsoDateTimeType() dateSigned = IsoDateTimeType() description = StringType() description_en = StringType() description_ru = StringType() documents = ListType(ModelType(Document, required=True), default=list()) features = ListType(ModelType(Feature, required=True), validators=[validate_features_uniq]) items = ListType(ModelType(Item, required=True)) period = ModelType(Period) status = StringType(choices=["pending", "active", "cancelled", "unsuccessful"], default="pending") contracts = ListType(ModelType(Contract, required=True)) title = StringType() title_en = StringType() title_ru = StringType() def validate_dateSigned(self, data, value): parent = data["__parent__"] awards_id = [c.awardID for c in data["contracts"]] if value and isinstance(parent, Model): award = [i for i in parent.awards if i.id in awards_id][0] if ( award.complaintPeriod and award.complaintPeriod.endDate and award.complaintPeriod.endDate >= value ): raise ValidationError( u"Agreement signature date should be after award complaint period end date ({})".format( award.complaintPeriod.endDate.isoformat() ) ) if value > get_now(): raise ValidationError(u"Agreement signature date can't be in the future") def get_awards_id(self): return tuple(c.awardID for c in self.contracts) def get_lot_id(self): return self.items[0].relatedLot
class BudgetPeriod(Period): startDate = IsoDateTimeType(required=True) endDate = IsoDateTimeType(required=True) def validate_endDate(self, data, value): plan = data["__parent__"]["__parent__"] if not (isinstance(plan, Model) and plan.tender): return method_type = plan.tender.procurementMethodType start_date = data.get("startDate") if method_type not in MULTI_YEAR_BUDGET_PROCEDURES and value.year != start_date.year: raise ValidationError( "Period startDate and endDate must be within one year for {}.". format(method_type)) if method_type in MULTI_YEAR_BUDGET_PROCEDURES and value.year - start_date.year > MULTI_YEAR_BUDGET_MAX_YEARS: raise ValidationError( "Period startDate and endDate must be within {} budget years for {}." .format(MULTI_YEAR_BUDGET_MAX_YEARS + 1, method_type))
class InitialTransaction(Model): date = IsoDateTimeType(required=True) value = ModelType(Guarantee, required=True) payer = ModelType(OrganizationReference, required=True) payee = ModelType(OrganizationReference, required=True) status = StringType(required=True) class Options: roles = {"create": schematics_default_role}
class Qualification(QualificationMilestoneListMixin): """ Pre-Qualification """ class Options: _common = whitelist('eligible', 'qualified', 'title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru', 'requirementResponses') _all = _common + whitelist('status', 'lotID', 'id', 'date', 'bidID', 'complaints', 'documents', 'milestones') roles = { "edit": _common + whitelist('status', ), "default": _all, "create": _common + whitelist( 'lotID', 'bidID'), # csv also had: 'complaints', '__parent__' "embedded": _all, "view": _all } title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType( choices=["pending", "active", "unsuccessful", "cancelled"], default="pending") date = IsoDateTimeType() documents = ListType(ModelType(EUDocument, required=True), default=list()) complaints = ListType(ModelType(Complaint, required=True), default=list()) qualified = BooleanType(default=False) eligible = BooleanType(default=False) requirementResponses = ListType( ModelType(RequirementResponse, required=True), default=list(), validators=[validate_response_requirement_uniq], ) def validate_qualified(self, data, qualified): if data["status"] == "active" and not qualified: raise ValidationError("This field is required.") def validate_eligible(self, data, eligible): if data["status"] == "active" and not eligible: raise ValidationError("This field is required.") def validate_lotID(self, data, lotID): parent = data["__parent__"] if isinstance(parent, Model): if not lotID and parent.lots: raise ValidationError("This field is required.") if lotID and lotID not in [lot.id for lot in parent.lots if lot]: raise ValidationError("lotID should be one of lots")
class BaseLot(Model): id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType(required=True, min_length=1) title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() date = IsoDateTimeType() status = StringType(choices=['active', 'cancelled', 'unsuccessful', 'complete'], default='active')
class Agreement(Model): class Options: roles = RolesFromCsv('Agreement.csv', relative_to=__file__) id = MD5Type(required=True, default=lambda: uuid4().hex) agreementID = StringType() agreementNumber = StringType() date = IsoDateTimeType() dateSigned = IsoDateTimeType() description = StringType() description_en = StringType() description_ru = StringType() documents = ListType(ModelType(Document), default=list()) features = ListType(ModelType(Feature), validators=[validate_features_uniq]) items = ListType(ModelType(Item)) period = ModelType(Period) status = StringType( choices=['pending', 'active', 'cancelled', 'unsuccessful'], default='pending') contracts = ListType(ModelType(Contract)) title = StringType() title_en = StringType() title_ru = StringType() def validate_dateSigned(self, data, value): awards_id = [c.awardID for c in data['contracts']] if value and isinstance(data['__parent__'], Model): award = [ i for i in data['__parent__'].awards if i.id in awards_id ][0] if award.complaintPeriod.endDate >= value: raise ValidationError( u"Agreement signature date should be after award complaint period end date ({})" .format(award.complaintPeriod.endDate.isoformat())) if value > get_now(): raise ValidationError( u"Agreement signature date can't be in the future") def get_awards_id(self): return tuple(c.awardID for c in self.contracts)
class Transaction(Model): id = StringType(required=True) documents = ListType(ModelType(TransactionDocument), default=list()) date = IsoDateTimeType(required=True) value = ModelType(Guarantee, required=True) payer = ModelType(OrganizationReference, required=True) payee = ModelType(OrganizationReference, required=True) status = StringType(required=True) class Options: roles = { "view": schematics_default_role, }
class Contract(Contract): documents = ListType(ModelType(Document), default=list()) id = MD5Type(required=True, default=lambda: uuid4().hex) awardID = StringType(required=True) contractID = StringType() contractNumber = StringType() title = StringType() # Contract title title_en = StringType() title_ru = StringType() description = StringType() # Contract description description_en = StringType() description_ru = StringType() status = StringType( choices=['pending', 'terminated', 'active', 'cancelled'], default='pending') period = ModelType(Period) value = ModelType(Value) dateSigned = IsoDateTimeType() items = ListType(ModelType(Item)) suppliers = ListType(ModelType(Organization), min_size=1, max_size=1) date = IsoDateTimeType()
class Change(Model): class Options: roles = { "edit": blacklist("date", "id", "__parent__"), "default": blacklist("__parent__"), "create": blacklist("status", "date", "id", "__parent__"), "embedded": blacklist("__parent__"), "view": blacklist("__parent__"), } id = MD5Type(required=True, default=lambda: uuid4().hex) status = StringType(choices=["pending", "active", "cancelled"], default="pending") date = IsoDateTimeType(default=get_now) rationale = StringType(required=True, min_length=1) rationale_en = StringType() rationale_ru = StringType() dateSigned = IsoDateTimeType() agreementNumber = StringType() def validate_dateSigned(self, data, value): if value and value > get_now(): raise ValidationError(u"Agreement signature date can't be in the future")
class Inspection(BaseModel): class Options: roles = { 'plain': blacklist('_attachments', 'revisions') + schematics_embedded_role, 'revision': whitelist('revisions'), 'create': blacklist('revisions', 'dateModified', 'dateCreated', 'doc_id', '_attachments', 'inspection_id') + schematics_embedded_role, 'edit': whitelist("description", "monitoring_ids"), 'view': blacklist( '_attachments', 'revisions', ) + schematics_embedded_role, 'listing': whitelist('dateModified', 'doc_id'), 'default': schematics_default_role, } monitoring_ids = ListType(MD5Type, required=True, min_size=1) description = StringType(required=True) documents = ListType(ModelType(Document), default=list()) inspection_id = StringType() dateModified = IsoDateTimeType() dateCreated = IsoDateTimeType(default=get_now) revisions = ListType(ModelType(Revision), default=list()) _attachments = DictType(DictType(BaseType), default=dict()) def __repr__(self): return '<%s:%r-%r@%r>' % (type(self).__name__, self.inspection_id, self.id, self.rev)
class Cancellation(Model): class Options: _edit_role = whitelist("reason", "reason_en", "status") roles = { "create": _edit_role, "edit": _edit_role, "embedded": schematics_embedded_role, "view": schematics_default_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) date = IsoDateTimeType(default=get_now) reason = StringType(required=True, min_length=1) reason_en = StringType() status = StringType(choices=["pending", "active"], default="pending")