Skip to content

Commit

Permalink
Merge pull request #13 from gorserg/fix_stage2_models
Browse files Browse the repository at this point in the history
Update models for stage2
  • Loading branch information
kroman0 committed Jul 13, 2016
2 parents 8f99112 + 48582bd commit 622d5c7
Show file tree
Hide file tree
Showing 21 changed files with 283 additions and 70 deletions.
3 changes: 2 additions & 1 deletion openprocurement/tender/competitivedialogue/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ def includeme(config):
config.add_tender_procurementMethodType(CompetitiveDialogEU)
config.add_tender_procurementMethodType(TenderStage2EU)
config.add_tender_procurementMethodType(TenderStage2UA)
config.scan("openprocurement.tender.competitivedialogue.views")
config.scan("openprocurement.tender.competitivedialogue.views.stage1")
config.scan("openprocurement.tender.competitivedialogue.views.stage2")
2 changes: 1 addition & 1 deletion openprocurement/tender/competitivedialogue/databridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ def retry_put_tender_stage2(self):
new_tender = self.dialogs_stage2_retry_put_queue.get()
self._put_with_retry(new_tender)
except:
del new_tender['tender_token'] # do not reveal tender credentials in logs
del new_tender['dialogue_token'] # do not reveal tender credentials in logs
logger.warn("Can't create tender stage2 from competitive dialogue id={0}".format(new_tender['dialogueID']),
extra=journal_context({"MESSAGE_ID": DATABRIDGE_CREATE_ERROR,
"TENDER_ID": new_tender['dialogueID']}))
Expand Down
103 changes: 61 additions & 42 deletions openprocurement/tender/competitivedialogue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
from schematics.types.serializable import serializable
from openprocurement.api.models import ITender, Identifier, Model, Value
from openprocurement.api.utils import calculate_business_date, get_now
from openprocurement.tender.openua.models import SifterListType, Item as BaseItem
from openprocurement.tender.openeu.models import (Tender as TenderEU, Administrator_bid_role, view_bid_role,
from openprocurement.tender.openua.models import (SifterListType, Item as BaseItem, Tender as BaseTenderUA,
TENDER_PERIOD as TENDERING_DURATION_UA)
from openprocurement.tender.openeu.models import (Tender as BaseTenderEU, Administrator_bid_role, view_bid_role,
pre_qualifications_role, Bid as BidEU, ConfidentialDocument,
edit_role_eu, auction_patch_role, auction_view_role,
auction_post_role, QUESTIONS_STAND_STILL, ENQUIRY_STAND_STILL_TIME,
PeriodStartEndRequired, EnquiryPeriod, Lot as BaseLot,
validate_lots_uniq, embedded_lot_role, default_lot_role)
validate_lots_uniq, embedded_lot_role, default_lot_role,
TENDERING_DURATION as TENDERING_DURATION_EU)
from openprocurement.api.models import (
plain_role, create_role, edit_role, view_role, listing_role,
enquiries_role, validate_cpv_group, validate_items_uniq,
Expand Down Expand Up @@ -138,7 +140,7 @@ class Options:


@implementer(ITender)
class Tender(TenderEU):
class Tender(BaseTenderEU):
procurementMethodType = StringType(default=CD_EU_TYPE)
status = StringType(choices=['draft', 'active.tendering', 'active.pre-qualification',
'active.pre-qualification.stand-still', 'active.stage2.pending',
Expand Down Expand Up @@ -241,6 +243,7 @@ class Lot(BaseLot):
'create': (blacklist('owner_token', 'tenderPeriod', '_attachments', 'revisions', 'dateModified', 'doc_id', 'tenderID', 'bids', 'documents', 'awards', 'questions', 'complaints', 'auctionUrl', 'status', 'auctionPeriod', 'awardPeriod', 'awardCriteria', 'submissionMethod', 'cancellations') + schematics_embedded_role),
'edit': edit_role_eu + close_edit_technical_fields,
'edit_draft': edit_role_eu + close_edit_technical_fields,
'edit_'+STAGE2_STATUS: edit_role_eu + close_edit_technical_fields,
'edit_active.tendering': edit_role_eu + close_edit_technical_fields,
'edit_active.pre-qualification': whitelist('status'),
'edit_active.pre-qualification.stand-still': whitelist(),
Expand Down Expand Up @@ -275,18 +278,43 @@ class Lot(BaseLot):
}


def init_PeriodStartEndRequired():
return PeriodStartEndRequired({"startDate": get_now(),
"endDate": calculate_business_date(get_now(), timedelta(days=30))})
def init_PeriodStartEndRequired(tendering_duration):
def wrapper():
return PeriodStartEndRequired({"startDate": get_now(),
"endDate": calculate_business_date(get_now(), tendering_duration)})
return wrapper


def stage2__acl__(obj):
acl = [
(Allow, '{}_{}'.format(obj.owner, obj.dialogue_token), 'generate_credentials')
]
acl.extend([
(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_qualification_complaint')
for i in obj.bids
if i.status in ['active', 'unsuccessful']
])
acl.extend([
(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_award_complaint')
for i in obj.bids
if i.status == 'active'])
acl.extend([
(Allow, '{}_{}'.format(obj.owner, obj.owner_token), 'edit_tender'),
(Allow, '{}_{}'.format(obj.owner, obj.owner_token), 'upload_tender_documents'),
(Allow, '{}_{}'.format(obj.owner, obj.owner_token), 'edit_complaint'),
(Allow, 'g:competitive_dialogue', 'edit_tender')
])
return acl


@implementer(ITender)
class Tender(TenderEU):
class Tender(BaseTenderEU):
procurementMethodType = StringType(default=STAGE_2_EU_TYPE)
dialogue_token = StringType(required=True)
dialogueID = StringType()
shortlistedFirms = ListType(ModelType(Firms), required=True)
tenderPeriod = ModelType(PeriodStartEndRequired, required=False,
default=init_PeriodStartEndRequired)
default=init_PeriodStartEndRequired(TENDERING_DURATION_EU))
minimalStep = ModelType(Value, required=True, default=Value({'amount': 0}))
lots = ListType(ModelType(LotStage2), default=list())
status = StringType(
Expand All @@ -295,50 +323,41 @@ class Tender(TenderEU):
'unsuccessful', STAGE2_STATUS],
default='active.tendering')

create_accreditation = 'c'

class Options:
roles = stage_2_roles.copy()

def __acl__(self):
acl = [
(Allow, '{}_{}'.format(self.owner, self.dialogue_token), 'generate_credentials')
]
acl.extend([
(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_qualification_complaint')
for i in self.bids
if i.status in ['active', 'unsuccessful']
])
acl.extend([
(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_award_complaint')
for i in self.bids
if i.status == 'active'
])
acl.extend([
(Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_tender'),
(Allow, '{}_{}'.format(self.owner, self.owner_token), 'upload_tender_documents'),
(Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_complaint'),
(Allow, 'g:competitive_dialogue', 'edit_tender')
])
return acl

def initialize(self):
self.tenderPeriod = PeriodStartEndRequired(
dict(startDate=get_now(), endDate=calculate_business_date(get_now(), timedelta(days=30), self)))
endDate = calculate_business_date(self.tenderPeriod.endDate, -QUESTIONS_STAND_STILL, self)
self.enquiryPeriod = EnquiryPeriod(dict(startDate=self.tenderPeriod.startDate,
endDate=endDate,
invalidationDate=self.enquiryPeriod and self.enquiryPeriod.invalidationDate,
clarificationsUntil=calculate_business_date(endDate,
ENQUIRY_STAND_STILL_TIME,
self, True)))
return stage2__acl__(self)


TenderStage2EU = Tender


@implementer(ITender)
class Tender(TenderStage2EU):
class Tender(BaseTenderUA):
procurementMethodType = StringType(default=STAGE_2_UA_TYPE)
title_en = StringType()
dialogue_token = StringType(required=True)
dialogueID = StringType()
shortlistedFirms = ListType(ModelType(Firms), required=True)
tenderPeriod = ModelType(PeriodStartEndRequired, required=False,
default=init_PeriodStartEndRequired(TENDERING_DURATION_UA))
minimalStep = ModelType(Value, required=True, default=Value({'amount': 0}))
lots = ListType(ModelType(LotStage2), default=list())
status = StringType(
choices=['draft', 'active.tendering', 'active.pre-qualification', 'active.pre-qualification.stand-still',
'active.auction', 'active.qualification', 'active.awarded', 'complete', 'cancelled',
'unsuccessful', STAGE2_STATUS],
default='active.tendering')

create_accreditation = 'c'

class Options:
roles = stage_2_roles.copy()

def __acl__(self):
return stage2__acl__(self)


TenderStage2UA = Tender
9 changes: 8 additions & 1 deletion openprocurement/tender/competitivedialogue/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,12 @@ def validate_patch_tender_stage2_data(request):
request.errors.add('body', 'item', 'Can\'t change enquiryPeriod')
request.errors.status = 403
return None
if request.context.status == STAGE2_STATUS and data.get('status') == 'active.tendering':
data = validate_data(request, type(request.tender), True, data)
if data: # if no error then add status to validate data
request.context.status = data.get('status')
data['status'] = data.get('status')
else:
data = validate_data(request, type(request.tender), True, data)

return validate_data(request, type(request.tender), True, data)
return data
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from openprocurement.tender.competitivedialogue.utils import patch_eu, set_ownership
from openprocurement.api.utils import opresource, json_view, save_tender, context_unpack, APIResource
from openprocurement.tender.competitivedialogue.models import CD_EU_TYPE, CD_UA_TYPE, STAGE_2_EU_TYPE, STAGE_2_UA_TYPE
from openprocurement.tender.competitivedialogue.validation import validate_patch_tender_stage2_data


@opresource(name='Competitive Dialogue for EU procedure',
Expand All @@ -32,30 +31,6 @@ def patch(self):
return patch_eu(self)


@opresource(name='Tender Stage 2 for UA procedure',
path='/tenders/{tender_id}',
procurementMethodType=STAGE_2_UA_TYPE,
description="")
class TenderStage2UAResource(TenderEUResource):
""" Resource handler for tender stage 2 UA"""

@json_view(content_type="application/json", validators=(validate_patch_tender_stage2_data,), permission='edit_tender')
def patch(self):
return patch_eu(self)


@opresource(name='Tender Stage 2 for EU procedure',
path='/tenders/{tender_id}',
procurementMethodType=STAGE_2_EU_TYPE,
description="")
class TenderStage2UEResource(TenderEUResource):
""" Resource handler for tender stage 2 EU"""

@json_view(content_type="application/json", validators=(validate_patch_tender_stage2_data,), permission='edit_tender')
def patch(self):
return patch_eu(self)


@opresource(name='Tender stage2 EU credentials',
path='/tenders/{tender_id}/credentials',
procurementMethodType=STAGE_2_EU_TYPE,
Expand Down
Empty file.

0 comments on commit 622d5c7

Please sign in to comment.