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()
예제 #2
0
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")
예제 #6
0
파일: change.py 프로젝트: lttga/op2
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")
예제 #7
0
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)
예제 #8
0
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()
예제 #9
0
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))
예제 #10
0
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")
예제 #15
0
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))
예제 #16
0
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")
예제 #18
0
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")
예제 #19
0
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")
예제 #20
0
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
예제 #21
0
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')
예제 #25
0
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)
예제 #26
0
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()
예제 #28
0
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)
예제 #30
0
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")