Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion openprocurement/auctions/rubble/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@
)
from openprocurement.auctions.core.traversal import Root
from openprocurement.auctions.core.utils import (
get_plugins, get_procurement_method_types, get_now
get_plugins, get_procurement_method_types, get_now, migrate_all_document_of_tender
)

from openprocurement.api.migration import (
BaseMigrationsRunner,
BaseMigrationStep
)

LOGGER = logging.getLogger(__name__)
SCHEMA_VERSION = 1
SCHEMA_DOC = 'openprocurement_auctions_dgf_schema'
PACKAGE_ALIASES = {
'openprocurement.auctions.rubble': ['rubbleOther', 'rubbleFinancial']
}


def get_db_schema_version(db):
Expand Down Expand Up @@ -74,3 +82,32 @@ def __init__(self, registry):
docs = []
if docs:
registry.db.update(docs)


class RubbleMigrationsRunner(BaseMigrationsRunner):

SCHEMA_VERSION = 1
SCHEMA_DOC = SCHEMA_DOC


class DocumentOfStep(BaseMigrationStep):

def setUp(self):
self.view = 'auctions/all'
self.procurement_method_types = self.resources.aliases_info.get_package_aliases(
'openprocurement.auctions.rubble'
)

def migrate_document(self, auction):
if auction['procurementMethodType'] in self.procurement_method_types:
changed = migrate_all_document_of_tender(auction)
return auction if changed else None
return None


MIGRATION_STEPS = (DocumentOfStep, )


def migrate(resources):
runner = RubbleMigrationsRunner(resources)
runner.migrate(MIGRATION_STEPS)
32 changes: 18 additions & 14 deletions openprocurement/auctions/rubble/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@
auction_embedded_role,
calc_auction_end_time,
dgfCDB2Complaint,
dgfCDB2Document,
AuctionDocument,
dgfCDB2Item,
dgfCancellation,
AuctionCancellation,
edit_role,
get_auction,
validate_items_uniq,
validate_lots_uniq,
validate_not_available,
)
from openprocurement.auctions.core.plugins.awarding.v2_1.models import Award
from openprocurement.auctions.core.plugins.contracting.v2_1.models import Contract
from openprocurement.auctions.core.plugins.awarding.v2_1.models import Award as BaseAward
from openprocurement.auctions.core.plugins.contracting.v2_1.models import Contract as BaseContract
from openprocurement.auctions.core.utils import (
AUCTIONS_COMPLAINT_STAND_STILL_TIME as COMPLAINT_STAND_STILL_TIME,
SANDBOX_MODE,
Expand Down Expand Up @@ -79,16 +79,20 @@ class Options:
}

status = StringType(choices=['active', 'draft', 'invalid'], default='active')
documents = ListType(ModelType(dgfCDB2Document), default=list())
documents = ListType(ModelType(AuctionDocument), default=list())
qualified = BooleanType(required=True, choices=[True])

@bids_validation_wrapper
def validate_value(self, data, value):
BaseBid._validator_functions['value'](self, data, value)


class Cancellation(dgfCancellation):
documents = ListType(ModelType(dgfCDB2Document), default=list())
class Award(BaseAward):
documents = ListType(ModelType(AuctionDocument), default=list())


class Contract(BaseContract):
documents = ListType(ModelType(AuctionDocument), default=list())


def rounding_shouldStartAfter(start_after, auction, use_from=datetime(2016, 6, 1, tzinfo=TZ)):
Expand Down Expand Up @@ -187,11 +191,11 @@ def __local_roles__(self):
_internal_type = "rubbleOther"
awards = ListType(ModelType(Award), default=list())
bids = ListType(ModelType(Bid), default=list()) # A list of all the companies who entered submissions for the auction.
cancellations = ListType(ModelType(Cancellation), default=list())
cancellations = ListType(ModelType(AuctionCancellation), default=list())
complaints = ListType(ModelType(dgfCDB2Complaint), default=list())
contracts = ListType(ModelType(Contract), default=list())
dgfID = StringType()
documents = ListType(ModelType(dgfCDB2Document), default=list()) # All documents and attachments related to the auction.
documents = ListType(ModelType(AuctionDocument), default=list()) # All documents and attachments related to the auction.
enquiryPeriod = ModelType(Period) # The period during which enquiries may be made and will be answered.
rectificationPeriod = ModelType(RectificationPeriod) # The period during which editing of main procedure fields are allowed
tenderPeriod = ModelType(Period) # The period when the auction is open for submissions. The end date is the closing date for auction submissions.
Expand Down Expand Up @@ -302,7 +306,7 @@ def next_check(self):
# Rubble Financial models


class dgfFinCDB2Document(dgfCDB2Document):
class RubbleFinancialDocument(AuctionDocument):
documentType = StringType(choices=[
'auctionNotice', 'awardNotice', 'contractNotice',
'notice', 'biddingDocuments', 'technicalSpecifications',
Expand All @@ -315,18 +319,18 @@ class dgfFinCDB2Document(dgfCDB2Document):
'qualificationDocuments', 'eligibilityDocuments', 'tenderNotice',
'illustration', 'financialLicense', 'virtualDataRoom',
'auctionProtocol', 'x_dgfAssetFamiliarization',
'x_presentation', 'x_nda',
'x_presentation', 'x_nda', 'cancellationDetails'
])

dgfFinCDB2Document.__name__ = 'Document'
RubbleFinancialDocument.__name__ = 'Document'


class Bid(Bid):
class Options:
roles = {
'create': whitelist('value', 'tenderers', 'parameters', 'lotValues', 'status', 'qualified', 'eligible'),
}
documents = ListType(ModelType(dgfFinCDB2Document), default=list())
documents = ListType(ModelType(RubbleFinancialDocument), default=list())
tenderers = ListType(ModelType(FinancialOrganization), required=True, min_size=1, max_size=1)
eligible = BooleanType(required=True, choices=[True])

Expand All @@ -335,7 +339,7 @@ class Options:
class Auction(RubbleOther):
"""Data regarding auction process - publicly inviting prospective contractors to submit bids for evaluation and selecting a winner or winners."""
_internal_type = "rubbleFinancial"
documents = ListType(ModelType(dgfFinCDB2Document), default=list()) # All documents and attachments related to the auction.
documents = ListType(ModelType(RubbleFinancialDocument), default=list()) # All documents and attachments related to the auction.
bids = ListType(ModelType(Bid), default=list())
procurementMethodType = StringType()
eligibilityCriteria = StringType(default=u"До участі допускаються лише ліцензовані фінансові установи.")
Expand Down
125 changes: 125 additions & 0 deletions openprocurement/auctions/rubble/tests/blanks/migration_blanks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,3 +1217,128 @@ def migrate_unsuccessful_unsuccessful_active(self):
self.assertEqual(auction['awards'][1]['status'], 'unsuccessful')
self.assertEqual(auction['awards'][2]['status'], 'active')
self.assertEqual(auction['contracts'][0]['status'], 'pending')


def migrate_document_of_auction_documents(self):
auction = self.db.get(self.auction_id)
self.assertIsNone(auction.get('documents'))
auction['documents'] = [self.test_document_data]

auction.update(auction)
self.db.save(auction)

response = self.app.get('/auctions/{}'.format(self.auction_id))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data']['documents'][0]['documentOf'], 'tender')

self.runner.migrate(self.steps)

response = self.app.get('/auctions/{}'.format(self.auction_id))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data']['documents'][0]['documentOf'], 'auction')


def migrate_document_of_bids_documents(self):
auction = self.db.get(self.auction_id)
bid, bid_id = self.initial_bids[0], self.initial_bids[0]['id']

auction['bids'] = [self.initial_bids[0]]
auction['status'] = 'complete'
auction['bids'][0]['documents'] = [self.test_document_data]
auction.update(auction)
self.db.save(auction)

response = self.app.get(
'/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, bid_id, self.initial_bids_tokens[bid_id]))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data'][0]['documentOf'], 'tender')

self.runner.migrate(self.steps)

response = self.app.get(
'/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, bid_id, self.initial_bids_tokens[bid_id]))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data'][0]['documentOf'], 'auction')


def migrate_document_of_awards_documents(self):
auction = self.db.get(self.auction_id)
_id = uuid4().hex
award = {
'id': _id,
'bid_id': self.initial_bids[0]['id'],
"documents": [self.test_document_data]
}

auction['bids'] = [self.initial_bids[0]]
auction['awards'] = [award]
auction.update(auction)
self.db.save(auction)

response = self.app.get('/auctions/{}/awards/{}/documents'.format(self.auction_id, _id))
self.assertEqual(response.json['data'][0]['documentOf'], 'tender')
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')

self.runner.migrate(self.steps)

response = self.app.get('/auctions/{}/awards/{}/documents'.format(self.auction_id, _id))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data'][0]['documentOf'], 'auction')


def migrate_document_of_contracts_documents(self):
auction = self.db.get(self.auction_id)
_id = uuid4().hex
contract = {
'id': _id,
"documents": [self.test_document_data]
}

auction['contracts'] = [contract]
auction.update(auction)
self.db.save(auction)

response = self.app.get('/auctions/{}/contracts/{}/documents'.format(self.auction_id, _id))
self.assertEqual(response.json['data'][0]['documentOf'], 'tender')
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')

self.runner.migrate(self.steps)

response = self.app.get('/auctions/{}/contracts/{}/documents'.format(self.auction_id, _id))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data'][0]['documentOf'], 'auction')


def migrate_document_of_cancellations_documents(self):

auction = self.db.get(self.auction_id)
id = uuid4().hex

auction['cancellations'] = [{
"reason": "cancellation reason",
"id": id,
"documents": [self.test_document_data],
}]

auction.update(auction)
self.db.save(auction)

response = self.app.get('/auctions/{}/cancellations/{}/documents'.format(self.auction_id, id))
self.assertEqual(response.json['data'][0]['documentOf'], 'tender')
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')

self.runner.migrate(self.steps)

response = self.app.get('/auctions/{}/cancellations/{}/documents'.format(self.auction_id, id))
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['data'][0]['documentOf'], 'auction')
45 changes: 43 additions & 2 deletions openprocurement/auctions/rubble/tests/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from openprocurement.auctions.core.tests.base import snitch

from openprocurement.auctions.rubble.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION
from openprocurement.auctions.rubble.tests.base import BaseWebTest, BaseAuctionWebTest, test_bids
from openprocurement.auctions.rubble.tests.base import BaseWebTest, BaseAuctionWebTest, test_bids, test_auction_data
from openprocurement.auctions.rubble.tests.blanks.migration_blanks import (
# MigrateTestFrom1To2Bids
migrate_one_pending,
Expand All @@ -28,9 +28,20 @@
migrate_awards_number,
# MigrateTestFrom1To2WithThreeBids
migrate_unsuccessful_unsuccessful_pending,
migrate_unsuccessful_unsuccessful_active
migrate_unsuccessful_unsuccessful_active,
# MigrateDocumentOf
migrate_document_of_auction_documents,
migrate_document_of_bids_documents,
migrate_document_of_awards_documents,
migrate_document_of_contracts_documents,
migrate_document_of_cancellations_documents
)

from openprocurement.auctions.rubble.migration import (
RubbleMigrationsRunner, DocumentOfStep, PACKAGE_ALIASES
)
from openprocurement.api.tests.fixtures.mocks import MigrationResourcesDTO_mock


class MigrateTest(BaseWebTest):

Expand Down Expand Up @@ -99,12 +110,42 @@ def setUp(self):
self.db.save(auction)


class MigrateTestDocumentOf(BaseAuctionWebTest):
initial_data = test_auction_data
initial_bids = test_bids
test_document_data = {
'title': 'auction_protocol.pdf',
'hash': 'md5:' + '0' * 32,
'format': 'application/msword',
"description": "auction protocol",
"documentType": 'auctionProtocol',
'url': 'http://localhost/test',
'documentOf': 'tender'

}
test_migrate_document_of_auction_documents = snitch(migrate_document_of_auction_documents)
test_migrate_document_of_bids_documents = snitch(migrate_document_of_bids_documents)
test_migrate_document_of_awards_documents = snitch(migrate_document_of_awards_documents)
test_migrate_document_of_contracts_documents = snitch(migrate_document_of_contracts_documents)
test_migrate_document_of_cancellations_documents = snitch(migrate_document_of_cancellations_documents)

def setUp(self):
super(MigrateTestDocumentOf, self).setUp()
self.runner = RubbleMigrationsRunner(
MigrationResourcesDTO_mock(
self.db, PACKAGE_ALIASES
)
)
self.steps = (DocumentOfStep, )


def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(MigrateTest))
suite.addTest(unittest.makeSuite(MigrateTestFrom1To2Bids))
suite.addTest(unittest.makeSuite(MigrateTestFrom1To2WithTwoBids))
suite.addTest(unittest.makeSuite(MigrateTestFrom1To2WithThreeBids))
suite.addTest(unittest.makeSuiter(MigrateTestDocumentOf))
return suite


Expand Down