diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..97fcd5b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,10 @@ +[run] +omit = + *tests* + +[report] +exclude_lines = + pragma: no cover + def __repr__ + raise NotImplementedError + if __name__ == .__main__.: \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..681ea57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,99 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject + +# Buildout +bin/ +src/ + +# Local developer configuration +.mr.developer.cfg + +cover/ +output.html diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f4bf1a4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +language: python +sudo: required +before_script: + - sudo add-apt-repository ppa:chris-lea/libsodium -y + - sudo apt-get -qq update + - sudo apt-get install libsodium13 -y +python: + - "2.7" +services: + - couchdb +env: + global: + - TZ=Europe/Kiev + matrix: + - SANDBOX_MODE= + - SANDBOX_MODE=True +cache: + directories: + - eggs +before_install: + - pip install setuptools==38.5.0 + - python2 bootstrap.py +install: + - bin/buildout -N +script: + - bin/nosetests +after_success: + - bin/coveralls diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..07521cd --- /dev/null +++ b/README.rst @@ -0,0 +1,17 @@ +.. image:: https://travis-ci.org/openprocurement/openprocurement.auctions.dgf.svg?branch=master + :target: https://travis-ci.org/openprocurement/openprocurement.auctions.dgf + +.. image:: https://coveralls.io/repos/github/openprocurement/openprocurement.auctions.dgf/badge.svg + :target: https://coveralls.io/github/openprocurement/openprocurement.auctions.dgf + +.. image:: https://img.shields.io/hexpm/l/plug.svg + :target: https://github.com/openprocurement/openprocurement.auctions.dgf/blob/master/LICENSE.txt + + +Introduction +============ + +openprocurement.auctions.dgf repository contains code for Deposit Guarantee Fund auctions. + +Documentation can be found here http://dgf.api-docs.openprocurement.org/uk/latest/ + diff --git a/bootstrap.py b/bootstrap.py new file mode 100755 index 0000000..4b17570 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,212 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Bootstrap a buildout-based project + +Simply run this script in a directory containing a buildout.cfg. +The script accepts buildout command-line options, so you can +use the -c option to specify an alternate configuration file. +""" + +import os +import shutil +import sys +import tempfile + +from optparse import OptionParser + +__version__ = '2015-07-01' +# See zc.buildout's changelog if this version is up to date. + +tmpeggs = tempfile.mkdtemp(prefix='bootstrap-') + +usage = '''\ +[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] + +Bootstraps a buildout-based project. + +Simply run this script in a directory containing a buildout.cfg, using the +Python that you want bin/buildout to use. + +Note that by using --find-links to point to local resources, you can keep +this script from going over the network. +''' + +parser = OptionParser(usage=usage) +parser.add_option("--version", + action="store_true", default=False, + help=("Return bootstrap.py version.")) +parser.add_option("-t", "--accept-buildout-test-releases", + dest='accept_buildout_test_releases', + action="store_true", default=False, + help=("Normally, if you do not specify a --version, the " + "bootstrap script and buildout gets the newest " + "*final* versions of zc.buildout and its recipes and " + "extensions for you. If you use this flag, " + "bootstrap and buildout will get the newest releases " + "even if they are alphas or betas.")) +parser.add_option("-c", "--config-file", + help=("Specify the path to the buildout configuration " + "file to be used.")) +parser.add_option("-f", "--find-links", + help=("Specify a URL to search for buildout releases")) +parser.add_option("--allow-site-packages", + action="store_true", default=False, + help=("Let bootstrap.py use existing site packages")) +parser.add_option("--buildout-version", + help="Use a specific zc.buildout version") +parser.add_option("--setuptools-version", + help="Use a specific setuptools version") +parser.add_option("--setuptools-to-dir", + help=("Allow for re-use of existing directory of " + "setuptools versions")) + +options, args = parser.parse_args() +if options.version: + print("bootstrap.py version %s" % __version__) + sys.exit(0) + + +###################################################################### +# load/install setuptools + +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + +ez = {} +if os.path.exists('ez_setup.py'): + exec(open('ez_setup.py').read(), ez) +else: + exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) + +if not options.allow_site_packages: + # ez_setup imports site, which adds site packages + # this will remove them from the path to ensure that incompatible versions + # of setuptools are not in the path + import site + # inside a virtualenv, there is no 'getsitepackages'. + # We can't remove these reliably + if hasattr(site, 'getsitepackages'): + for sitepackage_path in site.getsitepackages(): + # Strip all site-packages directories from sys.path that + # are not sys.prefix; this is because on Windows + # sys.prefix is a site-package directory. + if sitepackage_path != sys.prefix: + sys.path[:] = [x for x in sys.path + if sitepackage_path not in x] + +setup_args = dict(to_dir=tmpeggs, download_delay=0) + +if options.setuptools_version is not None: + setup_args['version'] = options.setuptools_version +else: + setup_args['version'] = "7.0" +if options.setuptools_to_dir is not None: + setup_args['to_dir'] = options.setuptools_to_dir + +ez['use_setuptools'](**setup_args) +import setuptools +import pkg_resources + +# This does not (always?) update the default working set. We will +# do it. +for path in sys.path: + if path not in pkg_resources.working_set.entries: + pkg_resources.working_set.add_entry(path) + +###################################################################### +# Install buildout + +ws = pkg_resources.working_set + +setuptools_path = ws.find( + pkg_resources.Requirement.parse('setuptools')).location + +# Fix sys.path here as easy_install.pth added before PYTHONPATH +cmd = [sys.executable, '-c', + 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path + + 'from setuptools.command.easy_install import main; main()', + '-mZqNxd', tmpeggs] + +find_links = os.environ.get( + 'bootstrap-testing-find-links', + options.find_links or + ('http://downloads.buildout.org/' + if options.accept_buildout_test_releases else None) + ) +if find_links: + cmd.extend(['-f', find_links]) + +requirement = 'zc.buildout' +version = options.buildout_version or "2.2.5" +if version is None and not options.accept_buildout_test_releases: + # Figure out the most recent final version of zc.buildout. + import setuptools.package_index + _final_parts = '*final-', '*final' + + def _final_version(parsed_version): + try: + return not parsed_version.is_prerelease + except AttributeError: + # Older setuptools + for part in parsed_version: + if (part[:1] == '*') and (part not in _final_parts): + return False + return True + + index = setuptools.package_index.PackageIndex( + search_path=[setuptools_path]) + if find_links: + index.add_find_links((find_links,)) + req = pkg_resources.Requirement.parse(requirement) + if index.obtain(req) is not None: + best = [] + bestv = None + for dist in index[req.project_name]: + distv = dist.parsed_version + if _final_version(distv): + if bestv is None or distv > bestv: + best = [dist] + bestv = distv + elif distv == bestv: + best.append(dist) + if best: + best.sort() + version = best[-1].version +if version: + requirement = '=='.join((requirement, version)) +cmd.append(requirement) + +import subprocess +if subprocess.call(cmd) != 0: + raise Exception( + "Failed to execute command:\n%s" % repr(cmd)[1:-1]) + +###################################################################### +# Import and run buildout + +ws.add_entry(tmpeggs) +ws.require(requirement) +import zc.buildout.buildout + +if not [a for a in args if '=' not in a]: + args.append('bootstrap') + +# if -c was provided, we push it back into args for buildout' main function +if options.config_file is not None: + args[0:0] = ['-c', options.config_file] + +zc.buildout.buildout.main(args) +shutil.rmtree(tmpeggs) diff --git a/buildout.cfg b/buildout.cfg new file mode 100644 index 0000000..b367ec3 --- /dev/null +++ b/buildout.cfg @@ -0,0 +1,35 @@ +[buildout] +index = https://pypi.python.org/simple +extends = versions.cfg +newest = false +parts = test +develop = . +extensions = mr.developer +auto-checkout = + openprocurement.api + openprocurement.auctions.core + openprocurement.auctions.flash + openprocurement.schemas.dgf + schematics-flexible + +find-links = http://op:x9W3jZ@dist.quintagroup.com/op/ + +[test] +recipe = zc.recipe.egg:scripts +dependent-scripts = true +eggs = + openprocurement.auctions.lease + openprocurement.api [test] + nose + + +[remotes] +gh=https://github.com/ +gh_push=git@github.com: + +[sources] +openprocurement.api = git ${remotes:gh}openprocurement/openprocurement.api.git pushurl=${remotes:gh_push}openprocurement/openprocurement.api.git rev=ec18f683fb139e9185f797763e707b82cf605359 +openprocurement.auctions.core = git ${remotes:gh}openprocurement/openprocurement.auctions.core.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.core.git rev=c1b0cd75da7ec5ce31cbd70ac6e5f0a0fe101a3a +openprocurement.auctions.flash = git ${remotes:gh}openprocurement/openprocurement.auctions.flash.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.flash.git rev=fd7b70dbf09cef06bf515c93c25f63432b1c9ce6 +schematics-flexible = git https://github.com/openprocurement/schematics-flexible.git rev=ac5a680659f9990607a34660d04c8db8df927f3e +openprocurement.schemas.dgf = git https://github.com/openprocurement/openprocurement.schemas.dgf.git rev=eb10b00f1ed13e13ca82dbc4d1769db4736f7a74 diff --git a/docs.cfg b/docs.cfg new file mode 100644 index 0000000..5602bae --- /dev/null +++ b/docs.cfg @@ -0,0 +1,20 @@ +[buildout] +extends=buildout.cfg +parts= + docs + sphinx-intl + +[docs] +recipe = collective.recipe.sphinxbuilder +eggs = openprocurement.auctions.lease[docs] +source = ${buildout:directory}/docs/source +build = ${buildout:directory}/docs/_build + +[sphinx-intl] +recipe = zc.recipe.egg:scripts +eggs = + openprocurement.auctions.lease + sphinx-intl + +[versions] +sphinx-intl = 0.9.5 diff --git a/docs.py b/docs.py new file mode 100755 index 0000000..fb84f27 --- /dev/null +++ b/docs.py @@ -0,0 +1,1372 @@ + +# -*- coding: utf-8 -*- +import json +import os +from datetime import timedelta, datetime + +from openprocurement.auctions.core.utils import get_now +from openprocurement.auctions.core.tests.base import PrefixedRequestClass +import openprocurement.auctions.lease.tests.base as base_test +from openprocurement.auctions.lease.constants import DEFAULT_PROCUREMENT_METHOD_TYPE_FINANCIAL +from openprocurement.auctions.lease.tests.base import test_auction_data as base_test_auction_data, test_bids, test_financial_bids +from openprocurement.auctions.lease.tests.base import test_auction_maximum_data +from openprocurement.auctions.lease.tests.tender import BaseAuctionWebTest +from webtest import TestApp + +now = datetime.now() + +test_auction_data = base_test_auction_data.copy() +test_financial_auction_data = test_auction_data.copy() +test_financial_auction_data["procurementMethodType"] = DEFAULT_PROCUREMENT_METHOD_TYPE_FINANCIAL + +bid = { + "data": { + "tenderers": [ + { + "address": { + "countryName": "Україна", + "locality": "м. Вінниця", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33" + }, + "contactPoint": { + "email": "soleksuk@gmail.com", + "name": "Сергій Олексюк", + "telephone": "+380 (432) 21-69-30" + }, + "identifier": { + "scheme": u"UA-EDR", + "id": u"00137256", + "uri": u"http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»" + } + ], + "status": "draft", + "qualified": True, + "value": { + "amount": 500 + } + } +} + +bid2 = { + "data": { + "tenderers": [ + { + "address": { + "countryName": "Україна", + "locality": "м. Львів", + "postalCode": "79013", + "region": "м. Львів", + "streetAddress": "вул. Островського, 34" + }, + "contactPoint": { + "email": "aagt@gmail.com", + "name": "Андрій Олексюк", + "telephone": "+380 (322) 91-69-30" + }, + "identifier": { + "scheme": u"UA-EDR", + "id": u"00137226", + "uri": u"http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»" + } + ], + "qualified": True, + "value": { + "amount": 501 + } + } +} + +question = { + "data": { + "author": { + "address": { + "countryName": "Україна", + "locality": "м. Вінниця", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33" + }, + "contactPoint": { + "email": "soleksuk@gmail.com", + "name": "Сергій Олексюк", + "telephone": "+380 (432) 21-69-30" + }, + "identifier": { + "id": "00137226", + "legalName": "Державне комунальне підприємство громадського харчування «Школяр»", + "scheme": "UA-EDR", + "uri": "http://sch10.edu.vn.ua/" + }, + "name": "ДКП «Школяр»" + }, + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність" + } +} + +answer = { + "data": { + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"" + } +} + +cancellation = { + 'data': { + 'reason': 'cancellation reason' + } +} + +test_complaint_data = {'data': + { + 'title': 'complaint title', + 'description': 'complaint description', + 'author': bid["data"]["tenderers"][0] + } + } + + +class DumpsTestAppwebtest(TestApp): + def do_request(self, req, status=None, expect_errors=None): + req.headers.environ["HTTP_HOST"] = "api-sandbox.ea.openprocurement.org" + if hasattr(self, 'file_obj') and not self.file_obj.closed: + self.file_obj.write(req.as_bytes(True)) + self.file_obj.write("\n") + if req.body: + try: + self.file_obj.write( + '\n' + json.dumps(json.loads(req.body), indent=2, ensure_ascii=False).encode('utf8')) + self.file_obj.write("\n") + except: + pass + self.file_obj.write("\n") + resp = super(DumpsTestAppwebtest, self).do_request(req, status=status, expect_errors=expect_errors) + if hasattr(self, 'file_obj') and not self.file_obj.closed: + headers = [(n.title(), v) + for n, v in resp.headerlist + if n.lower() != 'content-length'] + headers.sort() + self.file_obj.write(str('\n%s\n%s\n') % ( + resp.status, + str('\n').join([str('%s: %s') % (n, v) for n, v in headers]), + )) + + if resp.testbody: + try: + self.file_obj.write('\n' + json.dumps(json.loads(resp.testbody), indent=2, ensure_ascii=False).encode('utf8')) + except: + pass + self.file_obj.write("\n\n") + return resp + + +class AuctionResourceTest(BaseAuctionWebTest): + initial_data = test_auction_data + initial_bids = test_bids + docservice = True + + def setUp(self): + self.app = DumpsTestAppwebtest( + "config:tests.ini", relative_to=os.path.dirname(base_test.__file__)) + self.app.RequestClass = PrefixedRequestClass + self.app.authorization = ('Basic', ('broker', '')) + self.couchdb_server = self.app.app.registry.couchdb_server + self.db = self.app.app.registry.db + if self.docservice: + self.setUpDS() + self.app.app.registry.docservice_url = 'http://public.docs-sandbox.ea.openprocurement.org' + + def generate_docservice_url(self): + return super(AuctionResourceTest, self).generate_docservice_url().replace('/localhost/', '/public.docs-sandbox.ea.openprocurement.org/') + + def test_docs_acceleration(self): + # SANDBOX_MODE=TRUE + data = test_auction_data.copy() + data['procurementMethodDetails'] = 'quick, accelerator=1440' + data['submissionMethodDetails'] = 'quick' + data['mode'] = 'test' + data["auctionPeriod"] = { + "startDate": (now + timedelta(days=12)).isoformat() + } + with open('docs/source/tutorial/auction-post-acceleration.http', 'w') as self.app.file_obj: + response = self.app.post_json( + '/auctions?opt_pretty=1', {"data": data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + self.auction_id = auction['id'] + owner_token = response.json['access']['token'] + + def test_docs_2pc(self): + # Creating auction in draft status + # + data = test_auction_data.copy() + data['status'] = 'draft' + + with open('docs/source/tutorial/auction-post-2pc.http', 'w') as self.app.file_obj: + response = self.app.post_json( + '/auctions?opt_pretty=1', {"data": data}) + self.assertEqual(response.status, '201 Created') + + auction = response.json['data'] + self.auction_id = auction['id'] + owner_token = response.json['access']['token'] + + # switch to 'active.tendering' + + with open('docs/source/tutorial/auction-patch-2pc.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), + {'data': {"status": 'active.tendering'}}) + self.assertEqual(response.status, '200 OK') + + def test_docs_tutorial(self): + request_path = '/auctions?opt_pretty=1' + + # Exploring basic rules + # + + with open('docs/source/tutorial/auction-listing.http', 'w') as self.app.file_obj: + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.app.file_obj.write("\n") + + with open('docs/source/tutorial/auction-post-attempt.http', 'w') as self.app.file_obj: + response = self.app.post(request_path, 'data', status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + + self.app.authorization = ('Basic', ('broker', '')) + + with open('docs/source/tutorial/auction-post-attempt-json.http', 'w') as self.app.file_obj: + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post( + request_path, 'data', content_type='application/json', status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + + # Creating auction + # + + with open('docs/source/tutorial/auction-post-attempt-json-data.http', 'w') as self.app.file_obj: + response = self.app.post_json( + '/auctions?opt_pretty=1', {"data": test_auction_data}) + self.assertEqual(response.status, '201 Created') + + auction = response.json['data'] + owner_token = response.json['access']['token'] + + data = test_auction_data.copy() + data["auctionPeriod"] = { + "startDate": (now + timedelta(days=6)).isoformat() + } + with open('docs/source/tutorial/tenderperiod-validation-error.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions?opt_pretty=1', {"data": data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + + with open('docs/source/tutorial/blank-auction-view.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertEqual(response.status, '200 OK') + + self.app.get('/auctions') + with open('docs/source/tutorial/initial-auction-listing.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/create-auction-procuringEntity.http', 'w') as self.app.file_obj: + response = self.app.post_json( + '/auctions?opt_pretty=1', {"data": test_auction_maximum_data}) + self.assertEqual(response.status, '201 Created') + + response = self.app.post_json('/auctions?opt_pretty=1', {"data": test_auction_data}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-listing-after-procuringEntity.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + + # Modifying auction + # + + tenderPeriod_endDate = get_now() + timedelta(days=15, seconds=10) + with open('docs/source/tutorial/patch-items-value-periods.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': + { + "tenderPeriod": { + "endDate": tenderPeriod_endDate.isoformat() + } + } + }) + + self.app.get(request_path) + with open('docs/source/tutorial/auction-listing-after-patch.http', 'w') as self.app.file_obj: + self.app.authorization = None + response = self.app.get(request_path) + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + self.auction_id = auction['id'] + self.go_to_rectificationPeriod_end() + data = test_auction_data.copy() + with open('docs/source/tutorial/out-of-rectification-period-editing-denied.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), + {"data": data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + + # Uploading documentation + # + + with open('docs/source/tutorial/upload-auction-notice.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'Notice.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "technicalSpecifications", + "description": "document description", + }}) + self.assertEqual(response.status, '201 Created') + + doc_id = response.json["data"]["id"] + with open('docs/source/tutorial/auction-documents.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents/{}'.format( + self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/upload-award-criteria.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'AwardCriteria.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + doc_id = response.json["data"]["id"] + + with open('docs/source/tutorial/auction-documents-2.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/update-award-criteria.http', 'w') as self.app.file_obj: + response = self.app.put_json('/auctions/{}/documents/{}?acc_token={}'.format(self.auction_id, doc_id, owner_token), + {'data': { + 'title': u'AwardCriteria-2.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/auction-documents-3.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/upload-first-auction-illustration.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'first_illustration.jpeg', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'image/jpeg', + "documentType": "illustration", + "description": "First illustration description", + "index": 1 + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-documents-4.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/upload-second-auction-illustration.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'second_illustration.jpeg', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'image/jpeg', + "documentType": "illustration", + "description": "Second illustration description", + "index": 2 + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/upload-third-auction-illustration.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'third_illustration.jpeg', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'image/jpeg', + "documentType": "illustration", + "description": "Third illustration description", + "index": 2 + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-documents-5.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/add-asset-familiarization-document.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'Familiarization with bank asset', + "documentType": "x_dgfAssetFamiliarization", + 'accessDetails': "Familiar with asset: days, time, address", + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-documents-6.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + # Enquiries + # + + with open('docs/source/tutorial/ask-question.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/questions'.format( + self.auction_id), question, status=201) + question_id = response.json['data']['id'] + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/answer-question.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/questions/{}?acc_token={}'.format( + self.auction_id, question_id, owner_token), answer, status=200) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/list-question.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/questions'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/get-answer.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/questions/{}'.format( + self.auction_id, question_id)) + self.assertEqual(response.status, '200 OK') + + # Registering bid + # + + self.app.authorization = ('Basic', ('broker', '')) + bids_access = {} + with open('docs/source/tutorial/register-bidder.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), bid) + bid1_id = response.json['data']['id'] + bids_access[bid1_id] = response.json['access']['token'] + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/activate-bidder.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format( + self.auction_id, bid1_id, bids_access[bid1_id]), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + + # Proposal Uploading + # + + with open('docs/source/tutorial/upload-bid-proposal.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, bid1_id, bids_access[bid1_id]), + {'data': { + 'title': u'Proposal.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/bidder-documents.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/bids/{}/documents?acc_token={}'.format( + self.auction_id, bid1_id, bids_access[bid1_id])) + self.assertEqual(response.status, '200 OK') + + # Second bidder registration + # + + with open('docs/source/tutorial/register-2nd-bidder.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), bid2) + bid2_id = response.json['data']['id'] + bids_access[bid2_id] = response.json['access']['token'] + self.assertEqual(response.status, '201 Created') + + # Auction + # + + self.set_status('active.auction') + self.app.authorization = ('Basic', ('auction', '')) + patch_data = { + 'auctionUrl': u'http://auction-sandbox.openprocurement.org/auctions/{}'.format(self.auction_id), + 'bids': [ + { + "id": bid1_id, + "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, bid1_id) + }, + { + "id": bid2_id, + "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, bid2_id) + } + ] + } + response = self.app.patch_json('/auctions/{}/auction?acc_token={}'.format(self.auction_id, owner_token), + {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + + with open('docs/source/tutorial/auction-url.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/bidder-participation-url.http', 'w') as self.app.file_obj: + response = self.app.get( + '/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bids_access[bid1_id])) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/bidder2-participation-url.http', 'w') as self.app.file_obj: + response = self.app.get( + '/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bids_access[bid2_id])) + self.assertEqual(response.status, '200 OK') + + # Confirming qualification + # + + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) + auction_bids_data = response.json['data']['bids'] + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': auction_bids_data}}) + + self.app.authorization = ('Basic', ('broker', '')) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + with open('docs/source/tutorial/get-awards.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 2) + + # get waiting award + award = [i for i in response.json['data'] if i['status'] == 'pending.waiting'][0] + award_id = award['id'] + + with open('docs/source/qualification/award-waiting-cancel.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id, bids_access[award['bid_id']]), {"data": {"status": "cancelled"}}) + self.assertEqual(response.status, '200 OK') + + # get pending award + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + + with open('docs/source/tutorial/bidder-auction-protocol.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format(self.auction_id, award_id, bids_access[bid2_id]), + {'data': { + 'title': u'SignedAuctionProtocol.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "auctionProtocol", + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/owner-auction-protocol.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format(self.auction_id, award_id, owner_token), + {'data': { + 'title': u'SignedAuctionProtocol.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "auctionProtocol", + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/verify-protocol.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(self.auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/confirm-qualification.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(self.auction_id, award_id, owner_token), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + + response = self.app.get('/auctions/{}/contracts'.format(self.auction_id)) + self.contract_id = response.json['data'][0]['id'] + + #### Set contract value + + auction = self.db.get(self.auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + + #### Setting contract period + + period_dates = {"period": {"startDate": (now).isoformat(), "endDate": (now + timedelta(days=365)).isoformat()}} + with open('docs/source/tutorial/auction-contract-period.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format( + self.auction_id, self.contract_id, owner_token), {'data': {'period': period_dates["period"]}}) + self.assertEqual(response.status, '200 OK') + + #### Uploading contract documentation + # + + with open('docs/source/tutorial/auction-contract-upload-document.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/contracts/{}/documents?acc_token={}'.format(self.auction_id, self.contract_id, owner_token), + {'data': { + 'title': u'contract_first_document.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-contract-get-documents.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/contracts/{}/documents'.format( + self.auction_id, self.contract_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/auction-contract-upload-second-document.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/contracts/{}/documents?acc_token={}'.format(self.auction_id, self.contract_id, owner_token), + {'data': { + 'title': u'contract_second_document.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/auction-contract-get-documents-again.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/contracts/{}/documents'.format( + self.auction_id, self.contract_id)) + self.assertEqual(response.status, '200 OK') + + #### Setting contract signature date and Contract signing + # + + auction = self.db.get(self.auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + + with open('docs/source/tutorial/auction-contract-sign.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format( + self.auction_id, self.contract_id, owner_token), {'data': {'status': 'active', "dateSigned": get_now().isoformat()}}) + self.assertEqual(response.status, '200 OK') + + + # Preparing the cancellation request + # + + self.set_status('active.awarded') + with open('docs/source/tutorial/prepare-cancellation.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/cancellations?acc_token={}'.format( + self.auction_id, owner_token), cancellation) + self.assertEqual(response.status, '201 Created') + + cancellation_id = response.json['data']['id'] + + # Filling cancellation with protocol and supplementary documentation + # + + with open('docs/source/tutorial/upload-cancellation-doc.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/cancellations/{}/documents?acc_token={}'.format(self.auction_id, cancellation_id, owner_token), + {'data': { + 'title': u'Notice.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + cancellation_doc_id = response.json['data']['id'] + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/patch-cancellation.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/cancellations/{}/documents/{}?acc_token={}'.format( + self.auction_id, cancellation_id, cancellation_doc_id, owner_token), {'data': {"description": 'Changed description'}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/update-cancellation-doc.http', 'w') as self.app.file_obj: + response = self.app.put_json('/auctions/{}/cancellations/{}/documents/{}?acc_token={}'.format(self.auction_id, cancellation_id, cancellation_doc_id, owner_token), + {'data': { + 'title': u'Notice-2.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '200 OK') + + # Activating the request and cancelling auction + # + + with open('docs/source/tutorial/active-cancellation.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/cancellations/{}?acc_token={}'.format( + self.auction_id, cancellation_id, owner_token), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + + def test_docs_disqualification(self): + + self.create_auction() + + # create bids + self.set_status('active.tendering') + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), + {'data': {"qualified": True, 'tenderers': [bid["data"]["tenderers"][0]], "value": {"amount": 450}}}) + self.initial_bids_tokens[response.json['data']['id']] = response.json['access']['token'] + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), + {'data': {"qualified": True, 'tenderers': [bid["data"]["tenderers"][0]], "value": {"amount": 475}}}) + self.initial_bids_tokens[response.json['data']['id']] = response.json['access']['token'] + # get auction info + self.set_status('active.auction') + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) + auction_bids_data = response.json['data']['bids'] + # posting auction urls + response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), + { + 'data': { + 'auctionUrl': 'https://auction.auction.url', + 'bids': [ + { + 'id': i['id'], + 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) + } + for i in auction_bids_data + ] + } + }) + # posting auction results + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': auction_bids_data}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id = award['id'] + bid_token = self.initial_bids_tokens[award['bid_id']] + + self.app.authorization = ('Basic', ('broker', '')) + + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, bid_token), {'data': { + 'title': u'auction_protocol.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + 'documentType': 'auctionProtocol', + }}) + self.assertEqual(response.status, '201 Created') + + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, self.auction_token), {'data': { + 'title': u'Unsuccessful_Reason.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id, self.auction_token), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id2 = award['id'] + bid_token = self.initial_bids_tokens[award['bid_id']] + + self.app.authorization = ('Basic', ('broker', '')) + + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id2, bid_token), {'data': { + 'title': u'auction_protocol.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + 'documentType': 'auctionProtocol', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/qualification/award-active-unsuccessful-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id2, self.auction_token), {'data': { + 'title': u'Disqualified_reason.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "description": "Disqualification reason" + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/qualification/award-active-disqualify.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id2, self.auction_token), {"data": {"status": "unsuccessful", "title": "Disqualified", "description": "Candidate didn’t sign the auction protocol in 3 business days"}}) + self.assertEqual(response.status, '200 OK') + + def _test_docs_complaints(self): + + ###################### Tender Conditions Claims/Complaints ################## + # + #### Claim Submission (with documents) + # + + self.create_auction() + + with open('docs/source/complaints/complaint-submission.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/complaints'.format( + self.auction_id), test_complaint_data) + self.assertEqual(response.status, '201 Created') + + complaint1_id = response.json['data']['id'] + complaint1_token = response.json['access']['token'] + + with open('docs/source/complaints/complaint-submission-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/complaints/{}/documents?acc_token={}'.format( + self.auction_id, complaint1_id, complaint1_token), {'data': { + 'title': u'Complaint_Attachement.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/complaints/complaint-claim.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint1_id, complaint1_token), {"data":{"status":"claim"}}) + self.assertEqual(response.status, '200 OK') + + #### Claim Submission (without documents) + # + + test_complaint_data['data']['status'] = 'claim' + + with open('docs/source/complaints/complaint-submission-claim.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/complaints'.format( + self.auction_id), test_complaint_data) + self.assertEqual(response.status, '201 Created') + + complaint2_id = response.json['data']['id'] + complaint2_token = response.json['access']['token'] + + #### Tender Conditions Claim/Complaint Retrieval + # + + with open('docs/source/complaints/complaints-list.http', 'w') as self.app.file_obj: + self.app.authorization = None + response = self.app.get('/auctions/{}/complaints'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/complaint.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/complaints/{}'.format(self.auction_id, complaint1_id)) + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + + #### Claim's Answer + # + + with open('docs/source/complaints/complaint-answer.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint1_id, self.auction_token), + { + "data": { + "status": "answered", + "resolutionType": "resolved", + "tendererAction": "Виправлено неконкурентні умови", + "resolution": "Виправлено неконкурентні умови" + } + } + ) + self.assertEqual(response.status, '200 OK') + + + #### Satisfied Claim + # + + with open('docs/source/complaints/complaint-satisfy.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint1_id, complaint1_token), {"data":{"status":"resolved","satisfied":True}}) + self.assertEqual(response.status, '200 OK') + + #### Satisfied Claim + # + + + response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint2_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/complaint-escalate.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint2_id, complaint2_token), {"data":{"status":"pending","satisfied":False}}) + self.assertEqual(response.status, '200 OK') + + #### Rejecting Tender Conditions Complaint + # + + self.app.authorization = ('Basic', ('reviewer', '')) + + with open('docs/source/complaints/complaint-reject.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}'.format( + self.auction_id, complaint2_id), {"data":{"status":"invalid"}}) + self.assertEqual(response.status, '200 OK') + + #### Submitting Tender Conditions Complaint Resolution + # + + self.app.authorization = ('Basic', ('broker', '')) + + + response = self.app.post_json('/auctions/{}/complaints'.format( + self.auction_id), test_complaint_data) + self.assertEqual(response.status, '201 Created') + complaint3_id = response.json['data']['id'] + complaint3_token = response.json['access']['token'] + self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint3_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint3_id, complaint3_token), {"data":{"status":"pending","satisfied":False}}) + + response = self.app.post_json('/auctions/{}/complaints'.format( + self.auction_id), test_complaint_data) + self.assertEqual(response.status, '201 Created') + del test_complaint_data['data']['status'] + complaint4_id = response.json['data']['id'] + complaint4_token = response.json['access']['token'] + self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint4_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format( + self.auction_id, complaint4_id, complaint4_token), {"data":{"status":"pending","satisfied":False}}) + + + self.app.authorization = ('Basic', ('reviewer', '')) + + with open('docs/source/complaints/complaint-resolution-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/complaints/{}/documents'.format( + self.auction_id, complaint3_id), {'data': { + 'title': u'ComplaintResolution.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/complaints/complaint-resolve.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}'.format( + self.auction_id, complaint3_id), {"data":{"status":"resolved"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/complaint-decline.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/complaints/{}'.format( + self.auction_id, complaint4_id), {"data":{"status":"declined"}}) + self.assertEqual(response.status, '200 OK') + + # create bids + self.set_status('active.tendering') + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), + {'data': {"qualified": True, 'tenderers': [bid["data"]["tenderers"][0]], "value": {"amount": 450}}}) + bid_id = response.json['data']['id'] + bid_token = response.json['access']['token'] + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), + {'data': {"qualified": True, 'tenderers': [bid["data"]["tenderers"][0]], "value": {"amount": 475}}}) + # get auction info + self.set_status('active.auction') + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) + auction_bids_data = response.json['data']['bids'] + # posting auction urls + response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), + { + 'data': { + 'auctionUrl': 'https://auction.auction.url', + 'bids': [ + { + 'id': i['id'], + 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) + } + for i in auction_bids_data + ] + } + }) + # posting auction results + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': auction_bids_data}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + + with open('docs/source/qualification/awards-get.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending'][0] + + with open('docs/source/qualification/award-pending-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, self.auction_token), {'data': { + 'title': u'Unsuccessful_Reason.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/qualification/award-pending-unsuccessful.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id, self.auction_token), {"data":{"status":"unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + award_id2 = [i['id'] for i in response.json['data'] if i['status'] == 'pending'][0] + + with open('docs/source/qualification/award-pending-active.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id2, self.auction_token), {"data":{"status":"active"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/qualification/award-active-get.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards/{}'.format( + self.auction_id, award_id2)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/qualification/award-active-cancel.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id2, self.auction_token), {"data":{"status":"cancelled"}}) + self.assertEqual(response.status, '200 OK') + + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(self.auction_id, self.auction_token)) + award_id3 = [i['id'] for i in response.json['data'] if i['status'] == 'pending'][0] + + with open('docs/source/qualification/award-active-cancel-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id3, self.auction_token), {'data': { + 'title': u'Disqualified_reason.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "notice", + "description": "Disqualified reason" + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/qualification/award-active-cancel-disqualify.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id3, self.auction_token), {"data":{"status":"unsuccessful", "title": "Disqualified", "description": "Candidate didn’t sign the auction protocol in 3 business days"}}) + self.assertEqual(response.status, '200 OK') + + ###################### Tender Award Claims/Complaints ################## + # + + #### Tender Award Claim Submission (with documents) + # + + with open('docs/source/complaints/award-complaint-submission.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format( + self.auction_id, award_id, bid_token), test_complaint_data) + self.assertEqual(response.status, '201 Created') + + complaint1_id = response.json['data']['id'] + complaint1_token = response.json['access']['token'] + + with open('docs/source/complaints/award-complaint-submission-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( + self.auction_id, award_id, complaint1_id, complaint1_token), {'data': { + 'title': u'Complaint_Attachement.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/complaints/award-complaint-claim.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint1_id, complaint1_token), {"data":{"status":"claim"}}) + self.assertEqual(response.status, '200 OK') + + #### Tender Award Claim Submission (without documents) + # + + test_complaint_data['data']['status'] = 'claim' + + with open('docs/source/complaints/award-complaint-submission-claim.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format( + self.auction_id, award_id, bid_token), test_complaint_data) + self.assertEqual(response.status, '201 Created') + + complaint2_id = response.json['data']['id'] + complaint2_token = response.json['access']['token'] + + #### Tender Award Claim/Complaint Retrieval + # + + with open('docs/source/complaints/award-complaints-list.http', 'w') as self.app.file_obj: + self.app.authorization = None + response = self.app.get('/auctions/{}/awards/{}/complaints'.format(self.auction_id, award_id,)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/award-complaint.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, award_id, complaint1_id)) + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + + #### Claim's Answer + # + + with open('docs/source/complaints/award-complaint-answer.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, award_id, complaint1_id, self.auction_token), + { + "data": { + "status": "answered", + "resolutionType": "resolved", + "tendererAction": "Виправлено неконкурентні умови", + "resolution": "Виправлено неконкурентні умови" + } + } + ) + self.assertEqual(response.status, '200 OK') + + + #### Satisfied Claim + # + + with open('docs/source/complaints/award-complaint-satisfy.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint1_id, complaint1_token), {"data":{"status":"resolved","satisfied":True}}) + self.assertEqual(response.status, '200 OK') + + #### Satisfied Claim + # + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint2_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/award-complaint-escalate.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint2_id, complaint2_token), {"data":{"status":"pending","satisfied":False}}) + self.assertEqual(response.status, '200 OK') + + #### Rejecting Tender Award Complaint + # + + self.app.authorization = ('Basic', ('reviewer', '')) + + with open('docs/source/complaints/award-complaint-reject.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}'.format( + self.auction_id, award_id, complaint2_id), {"data":{"status":"invalid"}}) + self.assertEqual(response.status, '200 OK') + + #### Submitting Tender Award Complaint Resolution + # + + self.app.authorization = ('Basic', ('broker', '')) + + response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format( + self.auction_id, award_id, bid_token), test_complaint_data) + self.assertEqual(response.status, '201 Created') + complaint3_id = response.json['data']['id'] + complaint3_token = response.json['access']['token'] + self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint3_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint3_id, complaint3_token), {"data":{"status":"pending","satisfied":False}}) + + + response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format( + self.auction_id, award_id, bid_token), test_complaint_data) + self.assertEqual(response.status, '201 Created') + complaint4_id = response.json['data']['id'] + complaint4_token = response.json['access']['token'] + self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint4_id, self.auction_token), {"data":{"status":"answered","resolutionType":"resolved","resolution":"Виправлено неконкурентні умови"}}) + self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format( + self.auction_id, award_id, complaint4_id, complaint4_token), {"data":{"status":"pending","satisfied":False}}) + + self.app.authorization = ('Basic', ('reviewer', '')) + + with open('docs/source/complaints/award-complaint-resolution-upload.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/awards/{}/complaints/{}/documents'.format( + self.auction_id, award_id, complaint3_id), {'data': { + 'title': u'ComplaintResolution.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/complaints/award-complaint-resolve.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}'.format( + self.auction_id, award_id, complaint3_id), {"data":{"status":"resolved"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/complaints/award-complaint-decline.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}'.format( + self.auction_id, award_id, complaint4_id), {"data":{"status":"declined"}}) + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + + with open('docs/source/qualification/awards-unsuccessful-get1.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards'.format( + self.auction_id, award_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/qualification/award-unsuccessful-cancel.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format( + self.auction_id, award_id, self.auction_token), {"data":{"status":"cancelled"}}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/qualification/awards-unsuccessful-get2.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/awards'.format( + self.auction_id, award_id)) + self.assertEqual(response.status, '200 OK') + + def test_docs_fintutorial(self): + request_path = '/auctions?opt_pretty=1' + + # Creating auction + # + + with open('docs/source/tutorial/finauction-post-attempt-json-data.http', 'w') as self.app.file_obj: + response = self.app.post_json( + '/auctions?opt_pretty=1', {"data": test_financial_auction_data}) + self.assertEqual(response.status, '201 Created') + + auction = response.json['data'] + owner_token = response.json['access']['token'] + + with open('docs/source/tutorial/blank-finauction-view.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertEqual(response.status, '200 OK') + + self.app.get('/auctions') + with open('docs/source/tutorial/initial-finauction-listing.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + + self.app.authorization = ('Basic', ('broker', '')) + self.auction_id = auction['id'] + + # Uploading documentation + # + + with open('docs/source/tutorial/upload-finauction-notice.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'Notice.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "technicalSpecifications", + "description": "technical specification" + }}) + self.assertEqual(response.status, '201 Created') + + doc_id = response.json["data"]["id"] + with open('docs/source/tutorial/finauction-documents.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents/{}'.format( + self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/finauction-upload-award-criteria.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'AwardCriteria.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '201 Created') + + doc_id = response.json["data"]["id"] + + with open('docs/source/tutorial/finauction-documents-2.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/finauction-update-award-criteria.http', 'w') as self.app.file_obj: + response = self.app.put_json('/auctions/{}/documents/{}?acc_token={}'.format(self.auction_id, doc_id, owner_token), + {'data': { + 'title': u'AwardCriteria-2.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + }}) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/finauction-documents-3.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/documents'.format( + self.auction_id)) + self.assertEqual(response.status, '200 OK') + + with open('docs/source/tutorial/finauction-adding-vdr.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/documents?acc_token={}'.format(self.auction_id, owner_token), + {'data': { + 'title': u'VDR for auction lot', + 'url': 'http://virtial-data-room.com/id_of_room', + 'documentType': 'virtualDataRoom', + }}) + self.assertEqual(response.status, '201 Created') + + # Registering bid + # + + self.app.authorization = ('Basic', ('broker', '')) + bids_access = {} + with open('docs/source/tutorial/register-finbidder.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': test_financial_bids[0]}) + bid1_id = response.json['data']['id'] + bids_access[bid1_id] = response.json['access']['token'] + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/activate-finbidder.http', 'w') as self.app.file_obj: + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format( + self.auction_id, bid1_id, bids_access[bid1_id]), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + + # Proposal Uploading + # + + with open('docs/source/tutorial/upload-finbid-financial-license.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, bid1_id, bids_access[bid1_id]), + {'data': { + 'title': u'FinancialLicense.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/pdf', + "documentType": "financialLicense", + }}) + self.assertEqual(response.status, '201 Created') + + with open('docs/source/tutorial/finbidder-documents.http', 'w') as self.app.file_obj: + response = self.app.get('/auctions/{}/bids/{}/documents?acc_token={}'.format( + self.auction_id, bid1_id, bids_access[bid1_id])) + self.assertEqual(response.status, '200 OK') + + # Second bidder registration + # + + with open('docs/source/tutorial/register-2nd-finbidder.http', 'w') as self.app.file_obj: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': test_financial_bids[1]}) + bid2_id = response.json['data']['id'] + bids_access[bid2_id] = response.json['access']['token'] + self.assertEqual(response.status, '201 Created') diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt new file mode 100644 index 0000000..fb38ee9 --- /dev/null +++ b/docs/HISTORY.txt @@ -0,0 +1,7 @@ +Changelog +========= + +0.1dev (unreleased) +------------------- + +- Initial release diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d77759c --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/openprocurementapi.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/openprocurementapi.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/openprocurementapi" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/openprocurementapi" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..668c651 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +set I18NSPHINXOPTS=%SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\openprocurementapi.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\openprocurementapi.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/docs/source/2pc.rst b/docs/source/2pc.rst new file mode 100644 index 0000000..1380895 --- /dev/null +++ b/docs/source/2pc.rst @@ -0,0 +1,19 @@ +.. _2pc: + +2 Phase Commit +============== + +.. _auction-2pc: + +Creating auction with 2 Phase Commit +------------------------------------ + +Let's create auction in `draft` status: + +.. include:: tutorial/auction-post-2pc.http + :code: + +And now let's switch to `active.tendering` status: + +.. include:: tutorial/auction-patch-2pc.http + :code: diff --git a/docs/source/acceleration.rst b/docs/source/acceleration.rst new file mode 100644 index 0000000..28a827c --- /dev/null +++ b/docs/source/acceleration.rst @@ -0,0 +1,29 @@ +.. _acceleration: + +Acceleration mode for sandbox +============================= + +If you want to experiment with auctions, you can use acceleration mode and start your auction name with "TESTING". + +Acceleration mode was developed to enable `dgfOtherAssets` procedure testing in the sandbox and to reduce time frames of this procedure. + +To enable acceleration mode you will need to: + * add additional parameter `mode` with a value ``test``; + * set ``quick, accelerator=1440`` as text value for `procurementMethodDetails`. This parameter will accelerate auction periods. The number 1440 shows that restrictions and time frames will be reduced in 1440 times. + * set ``quick`` as a value for `submissionMethodDetails`. This parameter works only with ``mode = "test"`` and will speed up auction start date. + +**This mode will work only in the sandbox**. + +.. include:: tutorial/auction-post-acceleration.http + :code: + +Synchronization +~~~~~~~~~~~~~~~ + +* During normal auction synchronization via ``/auctions`` test auctions are not visible. + +* To get test auctions synchronize via ``/auctions?mode=test``. + +* If you synchronize via ``/auctions?mode=all``, then you will get all auctions. + +* Auction mode can be set only on auction creation, it can not be set later. diff --git a/docs/source/award_workflow.rst b/docs/source/award_workflow.rst new file mode 100644 index 0000000..9bfaf1d --- /dev/null +++ b/docs/source/award_workflow.rst @@ -0,0 +1,88 @@ +.. _award_workflow: + +Award Workflow +============== + +For a more detailed information see :ref:`award` + + * :ref:`Qualification` + * :ref:`Confirming_qualification` + * :ref:`Candidate_disqualification` + * :ref:`Waiting_refusal` + + + +.. graphviz:: + + digraph G { + subgraph cluster_1 { + node [style=filled, color=lightblue]; + edge[style=dotted]; + "pending.waiting" -> cancelled; + + node [style=filled, color=lightgrey]; + edge[style=dashed]; + "pending.verification" -> unsuccessful; + edge[style=dashed]; + "pending.payment" -> active; + edge[style=dashed]; + "pending.waiting" -> "pending.verification"; + label = "Awarding Process"; + color=blue + } + edge[style=dashed]; + "pending.verification" -> "pending.payment"; + edge[style=dashed]; + active -> unsuccessful; + + } + + + +Roles +----- + +:Organizer: dashed + +:Participant: dotted + + +Procedure Description +--------------------- + +1. The awards are created for 2 participants whose bids were the highest within the auction. Note that the participants with valid bids only can be qualified. +2. The award with the highest valid bid initially receives `pending.verification` status (the second one is in `pending.waiting`). The procedure enters the verificationPeriod phase (status: `active.qualification`). When the protocol is uploaded and confirmed by the Organizer, the award should be manually switched to `pending.payment` status. Simultaneously the procedure enters the signingPeriod phase (status: `active.awarded`). +3. When the payment has been received, the Organizer should switch award to `active`. Thereby, the contract is being created for this award in `pending` status and the procedure enters the signingPeriod phase (status: `active.awarded`). Within this stage the Organizer should upload the document and switch contract to active. +4. For the next bidder to be qualified, the Organizer should check the status of the previous one to unsuccessful first and then switch the next award to pending.verification. + +Notes +----- + +1. For the bidder to be qualified and not invalidated, his/her bid should be equal to or exceed the starting price of the auction + the minimal step of the auction. + * In case the first two highest bids do not exceed the amount of starting price + the minimal step, the awards are not being formed at all, and the procedure automatically becomes “unsuccessful”. + * In case the second highest bid is smaller than the starting price + the minimal step, two awards are formed with the smaller one becoming unsuccessful immediately. The first highest bid (if larger than the starting price + minimum step) undergoes the awarding procedure and can win the auction. +2. The Organizer can disqualify the award at any stage of the awarding process up until the moment, when the contract has been uploaded and activated in the system. +3. The second highest qualifying bidder can disqualify himself/herself (switch award to `cancelled`) at any point of time BEFORE the start of his/her qualification process. +4. All of the statuses are switched manually. Start and end dates of the periods do not influence the actions available to be done (completed). +5. In case of the Organizer noted minNumberOfQualifiedBids: 1 and only one bidder submitted the proposal, the auction would be oveleaped and this participant would become the qualified one. + +Statuses +-------- + +:pending.waiting: + The second highest valid bidder awaits for the qualification of the first highest valid bidder. The former can choose to refuse to wait and withdraw his security deposit. + +:cancelled: + Terminal status. The second highest valid bidder chose to withdraw his security deposit and not to wait for the highest valid bidder to be disqualified. + +:pending.verification: + Awaiting protocol upload and confirmation by the liquidator. The highest valid bidder is able to submit the protocol as well, although it is not sufficient to move to the next status. + +:pending.payment: + Awaiting payment. Organizer can change the status to active by confirming the payment has been received. + +:active: + Awaiting for the contract to be signed (uploaded and activated in the system by the organizer). + +:unsuccessful: + Terminal status. The auction was unsuccessful. Can be switched to from any of the previous statuses by the organizer. diff --git a/docs/source/complaints/award-complaint-answer.http b/docs/source/complaints/award-complaint-answer.http new file mode 100644 index 0000000..70dcd5c --- /dev/null +++ b/docs/source/complaints/award-complaint-answer.http @@ -0,0 +1,70 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 442 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "answered", + "resolutionType": "resolved", + "tendererAction": "Виправлено неконкурентні умови", + "resolution": "Виправлено неконкурентні умови" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "answered", + "tendererActionDate": "2016-09-16T16:17:49.565691+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "id": "cf9360b712ac479ea06d6c606c9db8d1", + "dateAnswered": "2016-09-16T16:17:49.565661+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:49.578140+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ] + } +} + diff --git a/docs/source/complaints/award-complaint-claim.http b/docs/source/complaints/award-complaint-claim.http new file mode 100644 index 0000000..52affc8 --- /dev/null +++ b/docs/source/complaints/award-complaint-claim.http @@ -0,0 +1,62 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1?acc_token=8b1c57a5a0b94f61af02d31184bd2d69 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 29 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "claim" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ], + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:48.913250+03:00", + "type": "claim", + "id": "cf9360b712ac479ea06d6c606c9db8d1" + } +} + diff --git a/docs/source/complaints/award-complaint-decline.http b/docs/source/complaints/award-complaint-decline.http new file mode 100644 index 0000000..4df51e7 --- /dev/null +++ b/docs/source/complaints/award-complaint-decline.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/b7534a5af3b74f028355f2de973fd25b HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 32 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "declined" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "declined", + "dateDecision": "2016-09-16T16:17:53.230797+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:52.345519+03:00", + "dateAnswered": "2016-09-16T16:17:52.060798+03:00", + "dateSubmitted": "2016-09-16T16:17:51.765641+03:00", + "complaintID": "UA-EA-2016-09-16-000001.8", + "date": "2016-09-16T16:17:53.245306+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "b7534a5af3b74f028355f2de973fd25b" + } +} + diff --git a/docs/source/complaints/award-complaint-escalate.http b/docs/source/complaints/award-complaint-escalate.http new file mode 100644 index 0000000..52614dd --- /dev/null +++ b/docs/source/complaints/award-complaint-escalate.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/5a6fc5709c4b4eb7a1adf84c9a8a2cce?acc_token=1ea144f57b1449ac84f606e203108482 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 51 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "pending", + "satisfied": false + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "pending", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "resolutionType": "resolved", + "type": "complaint", + "title": "complaint title", + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:50.369724+03:00", + "dateAnswered": "2016-09-16T16:17:50.099347+03:00", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:50.385382+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + } +} + diff --git a/docs/source/complaints/award-complaint-reject.http b/docs/source/complaints/award-complaint-reject.http new file mode 100644 index 0000000..0a23742 --- /dev/null +++ b/docs/source/complaints/award-complaint-reject.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/5a6fc5709c4b4eb7a1adf84c9a8a2cce HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 31 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "invalid" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "invalid", + "dateDecision": "2016-09-16T16:17:50.645131+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:50.369724+03:00", + "dateAnswered": "2016-09-16T16:17:50.099347+03:00", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:50.659654+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + } +} + diff --git a/docs/source/complaints/award-complaint-resolution-upload.http b/docs/source/complaints/award-complaint-resolution-upload.http new file mode 100644 index 0000000..a165b87 --- /dev/null +++ b/docs/source/complaints/award-complaint-resolution-upload.http @@ -0,0 +1,34 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/fe684319f9dd417fa680a252363f67aa/documents HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 340 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=6yFZNaeXSfV2JDxYD330435e3Tsk5LFaxP3Ih8Ik3OxJ%2FNrlD5PhuzgAoO1rpuH7YikE2ULx8sFl4oGtgYbmAA%3D%3D", + "title": "ComplaintResolution.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/fe684319f9dd417fa680a252363f67aa/documents/ee0fbfdd6e2e4f24b7483cbc8383b520 + +{ + "data": { + "dateModified": "2016-09-16T16:17:52.615704+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=e3moEZBo6gWiPI9UAheRHa1w%2FLkWmIs1mj%2FmiMip%252BKzgLNyzIGNpShGzJ9NJOfFzh1SDbsUBIXhFoOomCGB6Dw%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:52.615675+03:00", + "title": "ComplaintResolution.pdf", + "id": "ee0fbfdd6e2e4f24b7483cbc8383b520" + } +} + diff --git a/docs/source/complaints/award-complaint-resolve.http b/docs/source/complaints/award-complaint-resolve.http new file mode 100644 index 0000000..cb4e500 --- /dev/null +++ b/docs/source/complaints/award-complaint-resolve.http @@ -0,0 +1,68 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/fe684319f9dd417fa680a252363f67aa HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 32 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "resolved" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "resolved", + "dateDecision": "2016-09-16T16:17:52.929570+03:00", + "documents": [ + { + "dateModified": "2016-09-16T16:17:52.615704+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=e3moEZBo6gWiPI9UAheRHa1w%2FLkWmIs1mj%2FmiMip%252BKzgLNyzIGNpShGzJ9NJOfFzh1SDbsUBIXhFoOomCGB6Dw%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:52.615675+03:00", + "title": "ComplaintResolution.pdf", + "id": "ee0fbfdd6e2e4f24b7483cbc8383b520" + } + ], + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:51.456780+03:00", + "dateAnswered": "2016-09-16T16:17:51.175990+03:00", + "dateSubmitted": "2016-09-16T16:17:50.911841+03:00", + "complaintID": "UA-EA-2016-09-16-000001.7", + "date": "2016-09-16T16:17:52.943580+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "fe684319f9dd417fa680a252363f67aa" + } +} + diff --git a/docs/source/complaints/award-complaint-satisfy.http b/docs/source/complaints/award-complaint-satisfy.http new file mode 100644 index 0000000..cc45118 --- /dev/null +++ b/docs/source/complaints/award-complaint-satisfy.http @@ -0,0 +1,69 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1?acc_token=8b1c57a5a0b94f61af02d31184bd2d69 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 51 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "resolved", + "satisfied": true + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "resolved", + "tendererActionDate": "2016-09-16T16:17:49.565691+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": true, + "id": "cf9360b712ac479ea06d6c606c9db8d1", + "dateAnswered": "2016-09-16T16:17:49.565661+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:49.849593+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ] + } +} + diff --git a/docs/source/complaints/award-complaint-submission-claim.http b/docs/source/complaints/award-complaint-submission-claim.http new file mode 100644 index 0000000..5d1d343 --- /dev/null +++ b/docs/source/complaints/award-complaint-submission-claim.http @@ -0,0 +1,75 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints?acc_token=684390d5a4634e7bba129476b3262a3c HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 794 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "claim", + "title": "complaint title", + "description": "complaint description", + "author": { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/5a6fc5709c4b4eb7a1adf84c9a8a2cce + +{ + "access": { + "token": "1ea144f57b1449ac84f606e203108482" + }, + "data": { + "status": "claim", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:49.137031+03:00", + "type": "claim", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + } +} + diff --git a/docs/source/complaints/award-complaint-submission-upload.http b/docs/source/complaints/award-complaint-submission-upload.http new file mode 100644 index 0000000..5b0f813 --- /dev/null +++ b/docs/source/complaints/award-complaint-submission-upload.http @@ -0,0 +1,34 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1/documents?acc_token=8b1c57a5a0b94f61af02d31184bd2d69 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 342 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=vxdYVJY%2BPFGVloVcJroPsITM7FpDzauSomukMo0GeDXZWGsoi3sGSv62lAdTOnn3GQosl5WLmeLtgYUYu61kBA%3D%3D", + "title": "Complaint_Attachement.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1/documents/1f8fc9d2042f420b92b7aaa4cba24a43 + +{ + "data": { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } +} + diff --git a/docs/source/complaints/award-complaint-submission.http b/docs/source/complaints/award-complaint-submission.http new file mode 100644 index 0000000..e099ea4 --- /dev/null +++ b/docs/source/complaints/award-complaint-submission.http @@ -0,0 +1,73 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints?acc_token=684390d5a4634e7bba129476b3262a3c HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 775 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "complaint title", + "description": "complaint description", + "author": { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1 + +{ + "access": { + "token": "8b1c57a5a0b94f61af02d31184bd2d69" + }, + "data": { + "status": "draft", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:48.324397+03:00", + "type": "claim", + "id": "cf9360b712ac479ea06d6c606c9db8d1" + } +} + diff --git a/docs/source/complaints/award-complaint.http b/docs/source/complaints/award-complaint.http new file mode 100644 index 0000000..1c177c9 --- /dev/null +++ b/docs/source/complaints/award-complaint.http @@ -0,0 +1,53 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints/cf9360b712ac479ea06d6c606c9db8d1 HTTP/1.0 +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ], + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:48.913250+03:00", + "type": "claim", + "id": "cf9360b712ac479ea06d6c606c9db8d1" + } +} + diff --git a/docs/source/complaints/award-complaints-list.http b/docs/source/complaints/award-complaints-list.http new file mode 100644 index 0000000..4a1e965 --- /dev/null +++ b/docs/source/complaints/award-complaints-list.http @@ -0,0 +1,85 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/complaints HTTP/1.0 +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ], + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:48.913250+03:00", + "type": "claim", + "id": "cf9360b712ac479ea06d6c606c9db8d1" + }, + { + "status": "claim", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:49.137031+03:00", + "type": "claim", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + } + ] +} + diff --git a/docs/source/complaints/complaint-answer.http b/docs/source/complaints/complaint-answer.http new file mode 100644 index 0000000..0fa68f4 --- /dev/null +++ b/docs/source/complaints/complaint-answer.http @@ -0,0 +1,50 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 442 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "answered", + "resolutionType": "resolved", + "tendererAction": "Виправлено неконкурентні умови", + "resolution": "Виправлено неконкурентні умови" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "answered", + "tendererActionDate": "2016-09-16T16:17:44.150526+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "id": "d6c94c116e104a55b31c77e535e292f0", + "dateAnswered": "2016-09-16T16:17:44.150502+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:43.925321+03:00", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:44.155516+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } + ] + } +} + diff --git a/docs/source/complaints/complaint-claim.http b/docs/source/complaints/complaint-claim.http new file mode 100644 index 0000000..54577d4 --- /dev/null +++ b/docs/source/complaints/complaint-claim.http @@ -0,0 +1,42 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0?acc_token=7453323f5922402892bb58ba6b9dac81 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 29 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "claim" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } + ], + "description": "complaint description", + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:43.925321+03:00", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:43.929846+03:00", + "type": "claim", + "id": "d6c94c116e104a55b31c77e535e292f0" + } +} + diff --git a/docs/source/complaints/complaint-decline.http b/docs/source/complaints/complaint-decline.http new file mode 100644 index 0000000..4dd3e9d --- /dev/null +++ b/docs/source/complaints/complaint-decline.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/eed5bd1cb41a48a2aef53a4ddf452706 HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 32 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "declined" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "declined", + "dateDecision": "2016-09-16T16:17:45.623752+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:45.226003+03:00", + "dateAnswered": "2016-09-16T16:17:45.108013+03:00", + "dateSubmitted": "2016-09-16T16:17:44.991193+03:00", + "complaintID": "UA-EA-2016-09-16-000001.4", + "date": "2016-09-16T16:17:45.631161+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "eed5bd1cb41a48a2aef53a4ddf452706" + } +} + diff --git a/docs/source/complaints/complaint-escalate.http b/docs/source/complaints/complaint-escalate.http new file mode 100644 index 0000000..a8e6d78 --- /dev/null +++ b/docs/source/complaints/complaint-escalate.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/1fd393d1afab4cb69632391afa3712e9?acc_token=4a0e201f6de541aabbcaece5cf8ef0ea HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 51 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "pending", + "satisfied": false + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "pending", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "resolutionType": "resolved", + "type": "complaint", + "title": "complaint title", + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:44.434853+03:00", + "dateAnswered": "2016-09-16T16:17:44.341476+03:00", + "dateSubmitted": "2016-09-16T16:17:44.001693+03:00", + "complaintID": "UA-EA-2016-09-16-000001.2", + "date": "2016-09-16T16:17:44.441162+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "1fd393d1afab4cb69632391afa3712e9" + } +} + diff --git a/docs/source/complaints/complaint-reject.http b/docs/source/complaints/complaint-reject.http new file mode 100644 index 0000000..f82474a --- /dev/null +++ b/docs/source/complaints/complaint-reject.http @@ -0,0 +1,55 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/1fd393d1afab4cb69632391afa3712e9 HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 31 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "invalid" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "invalid", + "dateDecision": "2016-09-16T16:17:44.554603+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:44.434853+03:00", + "dateAnswered": "2016-09-16T16:17:44.341476+03:00", + "dateSubmitted": "2016-09-16T16:17:44.001693+03:00", + "complaintID": "UA-EA-2016-09-16-000001.2", + "date": "2016-09-16T16:17:44.560110+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "1fd393d1afab4cb69632391afa3712e9" + } +} + diff --git a/docs/source/complaints/complaint-resolution-upload.http b/docs/source/complaints/complaint-resolution-upload.http new file mode 100644 index 0000000..4c23264 --- /dev/null +++ b/docs/source/complaints/complaint-resolution-upload.http @@ -0,0 +1,34 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/600bd519df7941e784bd6b93dd4962a6/documents HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 340 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bc4a51083ef34f75a8b50726d496a4fb?KeyID=278be238&Signature=%2F6TyA7KKjcHA9B62POhx8o4N5yQNRC8MH92MwT27tgMU9OWJQyUbECeyYnHaK9dy8k9eKt8hTuWLVdgJEyfkDg%3D%3D", + "title": "ComplaintResolution.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/600bd519df7941e784bd6b93dd4962a6/documents/ab4fc692e4f743e596baa2fef345bd3d + +{ + "data": { + "dateModified": "2016-09-16T16:17:45.355562+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bc4a51083ef34f75a8b50726d496a4fb?KeyID=278be238&Signature=BImMSqH2b9VKRggGMvduxLW8p2YxMd0fv5Cw7353WLOhr28oze4EXjoxh36q1ZQ3f99blx9e%2Fc1U%2F2mChPd4Dg%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:45.355533+03:00", + "title": "ComplaintResolution.pdf", + "id": "ab4fc692e4f743e596baa2fef345bd3d" + } +} + diff --git a/docs/source/complaints/complaint-resolve.http b/docs/source/complaints/complaint-resolve.http new file mode 100644 index 0000000..670a3ce --- /dev/null +++ b/docs/source/complaints/complaint-resolve.http @@ -0,0 +1,68 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/600bd519df7941e784bd6b93dd4962a6 HTTP/1.0 +Authorization: Basic cmV2aWV3ZXI6 +Content-Length: 32 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "resolved" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "resolved", + "dateDecision": "2016-09-16T16:17:45.491756+03:00", + "documents": [ + { + "dateModified": "2016-09-16T16:17:45.355562+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bc4a51083ef34f75a8b50726d496a4fb?KeyID=278be238&Signature=BImMSqH2b9VKRggGMvduxLW8p2YxMd0fv5Cw7353WLOhr28oze4EXjoxh36q1ZQ3f99blx9e%2Fc1U%2F2mChPd4Dg%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:45.355533+03:00", + "title": "ComplaintResolution.pdf", + "id": "ab4fc692e4f743e596baa2fef345bd3d" + } + ], + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:44.878755+03:00", + "dateAnswered": "2016-09-16T16:17:44.762341+03:00", + "dateSubmitted": "2016-09-16T16:17:44.652952+03:00", + "complaintID": "UA-EA-2016-09-16-000001.3", + "date": "2016-09-16T16:17:45.498110+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "600bd519df7941e784bd6b93dd4962a6" + } +} + diff --git a/docs/source/complaints/complaint-satisfy.http b/docs/source/complaints/complaint-satisfy.http new file mode 100644 index 0000000..21b0778 --- /dev/null +++ b/docs/source/complaints/complaint-satisfy.http @@ -0,0 +1,49 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0?acc_token=7453323f5922402892bb58ba6b9dac81 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 51 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "resolved", + "satisfied": true + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "resolved", + "tendererActionDate": "2016-09-16T16:17:44.150526+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "satisfied": true, + "id": "d6c94c116e104a55b31c77e535e292f0", + "dateAnswered": "2016-09-16T16:17:44.150502+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:43.925321+03:00", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:44.252650+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } + ] + } +} + diff --git a/docs/source/complaints/complaint-submission-claim.http b/docs/source/complaints/complaint-submission-claim.http new file mode 100644 index 0000000..140bc97 --- /dev/null +++ b/docs/source/complaints/complaint-submission-claim.http @@ -0,0 +1,75 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 794 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "claim", + "title": "complaint title", + "description": "complaint description", + "author": { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/1fd393d1afab4cb69632391afa3712e9 + +{ + "access": { + "token": "4a0e201f6de541aabbcaece5cf8ef0ea" + }, + "data": { + "status": "claim", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:44.001693+03:00", + "complaintID": "UA-EA-2016-09-16-000001.2", + "date": "2016-09-16T16:17:44.001670+03:00", + "type": "claim", + "id": "1fd393d1afab4cb69632391afa3712e9" + } +} + diff --git a/docs/source/complaints/complaint-submission-upload.http b/docs/source/complaints/complaint-submission-upload.http new file mode 100644 index 0000000..0b29066 --- /dev/null +++ b/docs/source/complaints/complaint-submission-upload.http @@ -0,0 +1,34 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0/documents?acc_token=7453323f5922402892bb58ba6b9dac81 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 348 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=Fn4bTfsr%2FiPx%2F9QKWbc1smtgD972pDKFPfrjCmo9UWcQPl2Naq8gE%2BVxBf%2FggZ4e5nii6FuwF9sdwXvVS64zBg%3D%3D", + "title": "Complaint_Attachement.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0/documents/fd1a6c26a5c843bf8720661fc4146b31 + +{ + "data": { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } +} + diff --git a/docs/source/complaints/complaint-submission.http b/docs/source/complaints/complaint-submission.http new file mode 100644 index 0000000..6c3a23c --- /dev/null +++ b/docs/source/complaints/complaint-submission.http @@ -0,0 +1,73 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 775 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "complaint title", + "description": "complaint description", + "author": { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0 + +{ + "access": { + "token": "7453323f5922402892bb58ba6b9dac81" + }, + "data": { + "status": "draft", + "description": "complaint description", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "title": "complaint title", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:43.750358+03:00", + "type": "claim", + "id": "d6c94c116e104a55b31c77e535e292f0" + } +} + diff --git a/docs/source/complaints/complaint.http b/docs/source/complaints/complaint.http new file mode 100644 index 0000000..349119f --- /dev/null +++ b/docs/source/complaints/complaint.http @@ -0,0 +1,33 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints/d6c94c116e104a55b31c77e535e292f0 HTTP/1.0 +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } + ], + "description": "complaint description", + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:43.925321+03:00", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:43.929846+03:00", + "type": "claim", + "id": "d6c94c116e104a55b31c77e535e292f0" + } +} + diff --git a/docs/source/complaints/complaints-list.http b/docs/source/complaints/complaints-list.http new file mode 100644 index 0000000..109eb4a --- /dev/null +++ b/docs/source/complaints/complaints-list.http @@ -0,0 +1,45 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/complaints HTTP/1.0 +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "claim", + "documents": [ + { + "dateModified": "2016-09-16T16:17:43.827070+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/f6f09773f00e4ca2818ab9fbc4684b9a?KeyID=278be238&Signature=s1NEMOHGFrqM%252BoH9%252BBMl6WrkM1Hd6OpcukJw%252BL4cmc8nDP%252BP6HhmOcZPUOyS%252Bj%252Bvz38f9mlK6OThxb3k37b4CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:43.827024+03:00", + "title": "Complaint_Attachement.pdf", + "id": "fd1a6c26a5c843bf8720661fc4146b31" + } + ], + "description": "complaint description", + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:43.925321+03:00", + "complaintID": "UA-EA-2016-09-16-000001.1", + "date": "2016-09-16T16:17:43.929846+03:00", + "type": "claim", + "id": "d6c94c116e104a55b31c77e535e292f0" + }, + { + "status": "claim", + "description": "complaint description", + "title": "complaint title", + "dateSubmitted": "2016-09-16T16:17:44.001693+03:00", + "complaintID": "UA-EA-2016-09-16-000001.2", + "date": "2016-09-16T16:17:44.001670+03:00", + "type": "claim", + "id": "1fd393d1afab4cb69632391afa3712e9" + } + ] +} + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..6c79199 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# +# openprocurement.auctions.dgf documentation build configuration file, created by +# sphinx-quickstart on Wed Oct 1 02:29:13 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import pkg_resources + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +import cornice +extensions = [ + 'cornice.ext.sphinxext', + 'sphinx.ext.intersphinx', + 'sphinx.ext.graphviz', + 'sphinxcontrib.httpdomain', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'openprocurement.auctions.dgf' +copyright = u'2016, Quintagroup, Ltd' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = pkg_resources.get_distribution(project).version +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = 'uk_UA' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'openprocurementauctionsdgfdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'openprocurementauctionsdgf.tex', u'openprocurement.auctions.dgf Documentation', + u'Myroslav Opyr', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'openprocurementauctionsdgf', u'openprocurement.auctions.dgf Documentation', + [u'Myroslav Opyr'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'openprocurementauctionsdgf', u'openprocurement.auctions.dgf Documentation', + u'Myroslav Opyr', 'openprocurementauctionsdgf', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +locale_dirs = ['locale/'] # path is example but recommended. +gettext_compact = False # optional. + +intersphinx_mapping = { + 'python': ('http://docs.python.org/dev', None), + 'openprocurementapi': ('http://api-docs.openprocurement.org/en/latest', None), + 'openprocurementtenderlimited': ('http://openprocurementtenderlimited.readthedocs.org/en/latest/', None), + 'documentservice': ('http://documentservice.api-docs.openprocurement.org/en/latest', None), +} +intersphinx_cache_limit = 1 diff --git a/docs/source/fintutorial.rst b/docs/source/fintutorial.rst new file mode 100644 index 0000000..e655323 --- /dev/null +++ b/docs/source/fintutorial.rst @@ -0,0 +1,146 @@ +.. _fintutorial: + +Fin. Tutorial +============= + +Tutorial for the `dgfFinancialAssets` procedure. + +Creating auction +---------------- + +Let's create auction with the minimal data set (only required properties): + +.. include:: tutorial/finauction-post-attempt-json-data.http + :code: + +Success! Now we can see that new object has been created. Response code is `201` +and `Location` response header reports the location of the created object. The +body of response reveals the information about the created auction: its internal +`id` (that matches the `Location` segment), its official `auctionID` and +`dateModified` datestamp stating the moment in time when auction has been last +modified. Pay attention to the `procurementMethodType`. Note that auction is +created with `active.tendering` status. + +Let's access the URL of the created object (the `Location` header of the response): + +.. include:: tutorial/blank-finauction-view.http + :code: + +We can see the same response we got after creating auction. + +Let's see what listing of auctions reveals us: + +.. include:: tutorial/initial-finauction-listing.http + :code: + +We do see the auction's internal `id` (that can be used to construct full URL by prepending `https://api-sandbox.ea.openprocurement.org/api/0/auctions/`) and its `dateModified` datestamp. + +.. index:: Document, VDR + +Uploading documentation +----------------------- + +Organizer can upload PDF files into the created auction. Uploading should +follow the :ref:`upload` rules. + +.. include:: tutorial/upload-finauction-notice.http + :code: + +`201 Created` response code and `Location` header confirm document creation. +We can additionally query the `documents` collection API endpoint to confirm the +action: + +.. include:: tutorial/finauction-documents.http + :code: + +The single array element describes the uploaded document. We can upload more documents: + +.. include:: tutorial/finauction-upload-award-criteria.http + :code: + +And again we can confirm that there are two documents uploaded. + +.. include:: tutorial/finauction-documents-2.http + :code: + +In case we made an error, we can reupload the document over the older version: + +.. include:: tutorial/finauction-update-award-criteria.http + :code: + +And we can see that it is overriding the original version: + +.. include:: tutorial/finauction-documents-3.http + :code: + +Uploading illustration +----------------------- + +Organizer can upload illustration files into the created auction. Uploading should +follow the :ref:`upload` rules. + +In order to specify illustration display order, ``index`` field can be used (for details see :ref:`document`). Since this illustration should be displayed first, it has ``"index": 1``. + +.. include:: tutorial/upload-first-auction-illustration.http + :code: + +We can check whether illustration is uploaded. + +.. include:: tutorial/auction-documents-4.http + :code: + +Organizer can upload second illustration. This illustration should be displayed second, so it has ``"index": 2``. + +.. include:: tutorial/upload-second-auction-illustration.http + :code: + +Add third illustration: + +.. include:: tutorial/upload-third-auction-illustration.http + :code: + +Note that `index` of the third illustration is the same as for the second illustration: ``"index": 2``. In such cases firstly will be displayed illustration that was uploaded earlier. + +We can check that there are three uploaded illustrations. + +.. include:: tutorial/auction-documents-5.http + :code: + +Adding virtual data room +------------------------ + +Organizer can add URL for virtual data room: + +.. include:: tutorial/finauction-adding-vdr.http + :code: + + +.. index:: Bidding + +Registering bid +--------------- + +Bidder can register a bid in `draft` status. Bidder must specify ``UA-FIN`` value for the `additionalIdentifiers` parameter. + +.. include:: tutorial/register-finbidder.http + :code: + +And activate a bid: + +.. include:: tutorial/activate-finbidder.http + :code: + +And upload license (with ``documentType: financialLicense``): + +.. include:: tutorial/upload-finbid-financial-license.http + :code: + +It is possible to check the uploaded documents: + +.. include:: tutorial/finbidder-documents.http + :code: + +For the best effect (biggest economy) auction should have multiple bidders registered: + +.. include:: tutorial/register-2nd-finbidder.http + :code: diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..68775e4 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,57 @@ +.. openprocurement.auctions.dgf documentation master file, created by + sphinx-quickstart on Wed Oct 1 02:29:13 2014. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. title:: OpenProcurement API + +.. meta:: + :google-site-verification: kmqHGqhpzgef4t5OVKoQCPa5v-CK14HOLmVrZV2QgmQ + +Welcome to openprocurement.auctions.dgf's documentation! +======================================================== + +Please report any problems or suggestions for improvement either via the +`mailing list `_ or +the `issue tracker +`_. + +Contents: + +.. toctree:: + :maxdepth: 2 + + overview + standard/index + upload + award_workflow + tutorial + fintutorial + 2pc + acceleration + +* :ref:`Authentication ` +* :ref:`Responses ` +* :ref:`Options ` +* :ref:`Date Format: ISO 8601 ` +* :ref:`Performance recommendations ` +* :ref:`API in cluster mode ` + +.. + auctions + procuring + bidding + meat + lots + qualification + questions + complaints + reference + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + +.. * :ref:`modindex` diff --git a/docs/source/locale/uk/LC_MESSAGES/2pc.po b/docs/source/locale/uk/LC_MESSAGES/2pc.po new file mode 100644 index 0000000..fd70e00 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/2pc.po @@ -0,0 +1,27 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-10-20 15:07+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "2 Phase Commit" +msgstr "Двофазний коміт" + +msgid "Creating auction with 2 Phase Commit" +msgstr "Створення закупівлі за допомогою двофазного коміта" + +msgid "Let's create auction in `draft` status:" +msgstr "Створимо аукціон у статусі `draft`:" + +msgid "And now let's switch to `active.tendering` status:" +msgstr "Переключимо у статус `active.tendering`:" diff --git a/docs/source/locale/uk/LC_MESSAGES/acceleration.po b/docs/source/locale/uk/LC_MESSAGES/acceleration.po new file mode 100644 index 0000000..ee226cf --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/acceleration.po @@ -0,0 +1,89 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-16 18:19+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Acceleration mode for sandbox" +msgstr "Режим прискорення в пісочниці" + +msgid "" +"Acceleration mode was developed to enable `dgfOtherAssets` procedure testing" +" in the sandbox and to reduce time frames of this procedure." +msgstr "" +"Для зменшення термінів і забезпечення можливості тестування `dgfOtherAssets`" +" процедури на пісочниці доступний режим прискорення." + +msgid "" +"If you want to experiment with auctions, you can use acceleration mode and " +"start your auction name with \"TESTING\"." +msgstr "" +"Якщо хочете почати експериментувати з аукціонами, використовуйте режим " +"прискорення. Також рекомендуємо починати заголовок таких аукціонів з " +"\"ТЕСТУВАННЯ\"." + +msgid "To enable acceleration mode you will need to:" +msgstr "Щоб увімкнути режим прискорення вам потрібно:" + +msgid "add additional parameter `mode` with a value ``test``;" +msgstr "додати додатковий параметр `mode` зі значенням ``test``;" + +msgid "" +"set ``quick, accelerator=1440`` as text value for " +"`procurementMethodDetails`. This parameter will accelerate auction periods. " +"The number 1440 shows that restrictions and time frames will be reduced in " +"1440 times." +msgstr "" +"встановити текстове значення ``quick, accelerator=1440`` параметру " +"`procurementMethodDetails`. Цей параметр пришвидшить проходження періодів " +"аукціону. Число 1440 показує, що часові обмеження та терміни скорочуються в " +"1440 раз. " + +msgid "" +"set ``quick`` as a value for `submissionMethodDetails`. This parameter works" +" only with ``mode = \"test\"`` and will speed up auction start date." +msgstr "" +"встановити значення ``quick`` для параметра `submissionMethodDetails`. Цей " +"параметр працює тільки з `mode` зі значенням ``test`` і пришвидшує дату " +"початку аукціону." + +msgid "**This mode will work only in the sandbox**." +msgstr "**Даний механізм діє лише на пісочниці**." + +msgid "Synchronization" +msgstr "Синхронізація" + +msgid "" +"During normal auction synchronization via ``/auctions`` test auctions are " +"not visible." +msgstr "" +"При звичайній синхронізації аукціонів через `/auctions` тестових тендерів " +"\"не видно\"." + +msgid "To get test auctions synchronize via ``/auctions?mode=test``." +msgstr "" +"Щоб отримати тестові аукціони, треба робити синхронізацію наступним чином " +"через `/auctions?mode=test`." + +msgid "" +"If you synchronize via ``/auctions?mode=all``, then you will get all " +"auctions." +msgstr "" +"Якщо синхронізуватися через `/auctions?mode=all`, то будуть віддаватися всі " +"аукціони." + +msgid "" +"Auction mode can be set only on auction creation, it can not be set later." +msgstr "" +"Режим аукціону можна встановити тільки при створенні аукціона і не можна " +"його змінити потім." diff --git a/docs/source/locale/uk/LC_MESSAGES/award_workflow.po b/docs/source/locale/uk/LC_MESSAGES/award_workflow.po new file mode 100644 index 0000000..fa97bf1 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/award_workflow.po @@ -0,0 +1,441 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 1.0.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-12-16 17:10+0200\n" +"PO-Revision-Date: 2017-02-16 13:34+0200\n" +"Last-Translator: greg \n" +"Language-Team: English \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/award_workflow.rst:4 +msgid "Award Workflow" +msgstr "Схема роботи кваліфікації" + +#: ../../source/award_workflow.rst:6 +msgid "For a more detailed information see :ref:`award`" +msgstr "Для більш детальної інформації зверніться до секції :ref:`award`" + +#: ../../source/award_workflow.rst:8 +msgid ":ref:`Qualification`" +msgstr "" + +#: ../../source/award_workflow.rst:9 +msgid ":ref:`Confirming_qualification`" +msgstr "" + +#: ../../source/award_workflow.rst:10 +msgid ":ref:`Candidate_disqualification`" +msgstr "" + +#: ../../source/award_workflow.rst:11 +msgid ":ref:`Waiting_refusal`" +msgstr "" + +#: ../../source/award_workflow.rst:62 +msgid "Roles" +msgstr "Ролі" + +#: ../../source/award_workflow.rst:66 +msgid "dashed" +msgstr "пунктирна лінія" + +#: ../../source/award_workflow.rst:90 +msgid "Statuses" +msgstr "Статуси" + +#: ../../source/award_workflow.rst:93 +msgid "" +"The second highest valid bidder awaits for the qualification of the first " +"highest valid bidder. The former can choose to refuse to wait and withdraw " +"his security deposit." +msgstr "" +"Учасник з другою найбільшою валідною ставкою чекає поки завершиться процес " +"кваліфікації учасника з найвищою валідною ставкою. Він може прийняти рішення" +" не чекати, та забрати свій гарантійний внесок, автоматично " +"дискваліфікувавшись." + +#: ../../source/award_workflow.rst:96 +msgid "" +"Terminal status. The second highest valid bidder chose to withdraw his " +"security deposit and not to wait for the highest valid bidder to be " +"disqualified." +msgstr "" +"Термінальний статус. Учасник з другою найвищою валідною ставкою вирішив " +"забрати свій гарантійний внесок та не чекати на дискваліфікацію учасника з " +"найвищою ставкою." + +#: ../../source/award_workflow.rst:99 +msgid "" +"Awaiting protocol upload and confirmation by the liquidator. The highest " +"valid bidder is able to submit the protocol as well, although it is not " +"sufficient to move to the next status." +msgstr "" +"Очікується завантаження та підтвердження протоколу ліквідатором. Учасник з " +"найвищою валідною ставкою може також завантажити протокол, але цього " +"недостатньо для переходу до наступного статусу." + +#: ../../source/award_workflow.rst:102 +msgid "" +"Awaiting payment. Organizer can change the status to active by confirming " +"the payment has been received." +msgstr "" +"Очікується оплата. Організатор (ліквідатор) може перевести в статус active " +"шляхом підтвердження оплати." + +msgid "" +"Terminal status. The auction was unsuccessful. Can be switched to either " +"automatically, from any of the previous statuses or by the organizer." +msgstr "" +"Термінальний статус. Аукціон неуспішний. Переведення в цей статус може бути " +"здійснене ліквідатором, або автоматично по закінченню відповідно-" +"передбачених періодів." + +msgid "Legend" +msgstr "Умовні Позначення" + +msgid "Blue nodes represent statuses for the 2nd award ONLY" +msgstr "Світло-сині об'єкти на рисунку відображають статуси лише для award #2" + +msgid "\\* no protocol" +msgstr "\\* протокол відсутній" + +msgid "\\*\\* protocol required" +msgstr "\\*\\* необхідний протокол аукціону" + +msgid "\\*\\*\\* payment approved by the organizer" +msgstr "\\*\\*\\* отримання оплати підтвердженно організатором" + +msgid "dotted" +msgstr "лінія з крапками" + +msgid "Procedure Description" +msgstr "Опис Процедури" + +msgid "" +"The second highest qualifying bidder, immediately after the auction ending " +"receives the \"pending.waiting\" status, in which by default he/she agrees " +"to wait for the end of the qualification of the highest qualifying bidder to" +" be eligible to go through the qualification process if the highest bidder " +"is disqualified. The only action that he/she can make is to manually cancel " +"the award decision - withdraw his security deposit and lose the chance to " +"become a winner of the auction. If he/she does that and the first highest " +"qualifying bidder becomes \"unsuccessful\" at any point in the awarding " +"process, the procedure receives the \"unsuccessful\" status. Provided that " +"first award gets disqualified while the second has not disqualified " +"himself/herself, the second award automatically changes its status from " +"\"pending.waiting\" to \"pending.verification\", after which he/she " +"undergoes the same qualification procedure as outlined above for the first " +"award." +msgstr "" +"Учасник з другою найбільшою валідною ставкою, зразу після аукціону отримує " +"статус \"pending.waiting\", що за замовчуванням означає, що він погоджується" +" зачекати до кінця кваліфікації аварду #1, щоб мати можливість пройти " +"кваліфікацію у разі дискваліфікації першого. Єдина дія, яка може бути ним " +"виконана в цей момент це ручне скасування очікування - він може забрати свій" +" гарантійний внесок так втрачає шанс стати переможцем аукціону. Якщо він це " +"зробить, а учасника з найбільшою ставкою відкидають на будь-якому етапі в " +"процесі кваліфікації, процедура отримує статус неуспішної. Якщо aвард #1 " +"дискваліфіковують, а другий не самодискваліфікувався, останній автоматично " +"змінює статус з \"pending.waiting\" на \"pending.verification\", після чого " +"він проходить процедуру кваліфікації по такому самому принципу як і перший " +"авард. " + +msgid "Notes" +msgstr "Примітки" + +#: ../../source/award_workflow.rst:108 +msgid "" +"Terminal status. The auction was unsuccessful. Can be switched to either " +"automatically, from any of the previous statuses or by the organizer." +msgstr "" +"Термінальний статус. Аукціон неуспішний. Переведення в цей статус може бути " +"здійснене ліквідатором, або автоматично по закінченню відповідно-" +"передбачених періодів." + +#: ../../source/award_workflow.rst:46 +msgid "Legend" +msgstr "Умовні Позначення" + +#: ../../source/award_workflow.rst:48 +msgid "Blue nodes represent statuses for the 2nd award ONLY" +msgstr "Світло-сині об'єкти на рисунку відображають статуси лише для award #2" + +#: ../../source/award_workflow.rst:50 +msgid "\\* no protocol" +msgstr "\\* протокол відсутній" + +#: ../../source/award_workflow.rst:52 +msgid "\\*\\* protocol required" +msgstr "\\*\\* необхідний протокол аукціону" + +#: ../../source/award_workflow.rst:54 +msgid "\\*\\*\\* payment approved by the organizer" +msgstr "\\*\\*\\* отримання оплати підтвердженно організатором" + +#: ../../source/award_workflow.rst:68 +msgid "dotted" +msgstr "лінія з крапками" + +#: ../../source/award_workflow.rst:72 +msgid "Procedure Description" +msgstr "Опис Процедури" + +msgid "" +"For the bidder to be qualified and not invalidated, his/her bid should be in" +" the amount of more or equal to the starting price of the auction + the " +"minimal step of the auction." +msgstr "" +"Щоб ставка не була інвалідована одразу по закінченню аукціону, вона повинна " +"дорівнювати або бути більшою ніж стартова ціна аукціону + мінімальний крок " +"(т.зв. валідна ставка). " + +#: ../../source/award_workflow.rst:82 +msgid "" +"1.1. In case the first two highest bids do not exceed the amount of starting" +" price + the minimal step, the awards are not being formed at all, and the " +"procedure automatically becomes \"unsuccessful\"" +msgstr "" +"1.1 У випадку коли дві найвищі ставки в аукціоні не перевищують початкової " +"ціни аукціону + мінімальний крок, рішення про кваліфікацію (аварди) не " +"формуються взагалі, а процедура кваліфікації переходить в статус неуспішної " +"(\"unsuccessful)." + +#: ../../source/award_workflow.rst:76 +msgid "" +"The second highest qualifying bidder, immediately after the auction ending " +"receives the \"pending.waiting\" status, in which by default he/she agrees " +"to wait for the end of the qualification of the highest qualifying bidder to" +" be eligible to go through the qualification process if the highest bidder " +"is disqualified. The only action that he/she can make is to manually cancel " +"the award decision - withdraw his security deposit and lose the chance to " +"become a winner of the auction. If he/she does that and the first highest " +"qualifying bidder becomes \"unsuccessful\" at any point in the awarding " +"process, the procedure receives the \"unsuccessful\" status. Provided that " +"first award gets disqualified while the second has not disqualified " +"himself/herself, the second award automatically changes its status from " +"\"pending.waiting\" to \"pending.verification\", after which he/she " +"undergoes the same qualification procedure as outlined above for the first " +"award." +msgstr "" +"Учасник з другою найбільшою валідною ставкою, зразу після аукціону отримує " +"статус \"pending.waiting\", що за замовчуванням означає, що він погоджується" +" зачекати до кінця кваліфікації аварду #1, щоб мати можливість пройти " +"кваліфікацію у разі дискваліфікації першого. Єдина дія, яка може бути ним " +"виконана в цей момент це ручне скасування очікування - він може забрати свій" +" гарантійний внесок так втрачає шанс стати переможцем аукціону. Якщо він це " +"зробить, а учасника з найбільшою ставкою відкидають на будь-якому етапі в " +"процесі кваліфікації, процедура отримує статус неуспішної. Якщо aвард #1 " +"дискваліфіковують, а другий не самодискваліфікувався, останній автоматично " +"змінює статус з \"pending.waiting\" на \"pending.verification\", після чого " +"він проходить процедуру кваліфікації по такому самому принципу як і перший " +"авард. " + +#: ../../source/award_workflow.rst:79 +msgid "Notes" +msgstr "Примітки" + +#: ../../source/award_workflow.rst:80 +msgid "" +"For the bidder to be qualified and not invalidated, his/her bid should be in" +" the amount of more or equal to the starting price of the auction + the " +"minimal step of the auction." +msgstr "" +"Щоб ставка не була інвалідована одразу по закінченню аукціону, вона повинна " +"дорівнювати або бути більшою ніж стартова ціна аукціону + мінімальний крок " +"(т.зв. валідна ставка)" + +#: ../../source/award_workflow.rst:84 +msgid "" +"1.2 In case the second highest bid is smaller than the starting price + the " +"minimal step, two awards are formed with the smaller one becoming " +"unsuccessful immediately. The first highest bid (if larger than the starting" +" price + minimum step) undergoes the awarding procedure and can win the " +"auction." +msgstr "" +"1.2 У випадку коли друга найвища валідна ставка є меншою ніж стартова ціна " +"аукціону + мінімальний крок, формуються два аварди, де вищевказана ставка " +"одразу стає неуспішною. Перша найвища ставка (тільки якщо вона рівна або " +"більша ніж стартова ціна аукціону + мінімальний крок) проходить через " +"процедуру кваліфікації та може стати переможною." + +#: ../../source/award_workflow.rst:85 +msgid "" +"The organizer can disqualify the award at any stage of the awarding process " +"up until the moment, when the contract has been uploaded and activated in " +"the system." +msgstr "" +"Організатор (ліквідатор) може дискваліфікувати авард на будь-якому етапі " +"процесу кваліфікації аж до моменту завантаження та активування контракту в " +"системі." + +#: ../../source/award_workflow.rst:86 +msgid "" +"The second highest qualifying bidder can disqualify himself/herself at any " +"point in time BEFORE the start of his/her qualification process." +msgstr "" +"Учасник з другою найвищою валідною ставкою (стартова ціна + мінімальний крок" +" аукціону) може самодискваліфікуватись в будь-який момент часу ПЕРЕД " +"початком його кваліфікації." + +#: ../../source/award_workflow.rst:64 +msgid "solid" +msgstr "суцільна лінія" + +#: ../../source/award_workflow.rst:56 +msgid "\\*\\*\\*\\* no payment approval" +msgstr "\\*\\*\\*\\* немає підтвердження оплати" + +#: ../../source/award_workflow.rst:58 +msgid "\\*\\*\\*\\*\\* contract activation = false by the end of \"signingPeriod\"" +msgstr "" +"\\*\\*\\*\\*\\* контракт не було активовано в системі до завершення періоду " +"підписання контракту" + +#: ../../source/award_workflow.rst:105 +msgid "" +"Awaiting for the contract to be signed (uploaded and activated in the system" +" by the organizer). After the end of the \"signingPeriod\", the status " +"becomes terminal." +msgstr "" +"Очікується підписання/активація контракту (завантажується та активується в " +"системі організатором). Після закінчення періоду підписання " +"(\"signingPeriod\"), статус \"active\" стає термінальним." + +#: ../../source/award_workflow.rst:75 +msgid "" +"It is then when the qualification procedure enters the \"paymentPeriod\" " +"stage, which lasts up to 20 days from the beginning of the highest bidder " +"qualification process. When the organizer confirms that the payment has been" +" received, the award enters the \"active\" status, while the procedure moves" +" to the status \"signingPeriod\". This period is the same in length as the " +"\"paymentPeriod\" - a maximum of 20 days from the start of qualification. If" +" the organizer does not confirm payment by the end of the \"paymentPeriod\"," +" the award automatically becomes \"unsuccessful\". The same is true for the " +"signingPeriod - the organizer should upload and activate the contract in the" +" system by the end of the \"signingPeriod\" in order to successfully finish " +"the qualification procedure. Otherwise - the award will become " +"\"unsuccessful\" and the qualification of the second highest qualifying " +"bidder will begin given that he/she has not disqualified himself/herself by " +"this time." +msgstr "" +"На цьому етапі процедура кваліфікації переходить в період оплати " +"(\"paymentPeriod\"), який триває до 20 днів від початку кваліфікації " +"учасника з найвищою валідною (стартова ціна + мінімальний крок аукціону) " +"ставкою. Коли організатор підтверджує отримання оплати, авард набуває " +"статусу ''Оплачено, очікується підписання договору'' (\"active\"), а " +"процедура кваліфікації входить в період підписання контракту " +"(\"signingPeriod\"). Цей період такий самий за довжиною як період оплати " +"(\"paymentPeriod\") - максимально 20 днів від початку кваліфікації. Якщо " +"організатор не підтверджує отримання оплати в часових межах окреслених " +"періодом оплати (\"paymentPeriod\"), авард автоматично переводиться в статус" +" неуспішного (\"unsuccessful\"). За такою самою логікою - в межах періоду " +"підписання контракту (\"signingPeriod\") - організатор повинен завантажити " +"та активувати контракт в системі для успішного завершення процедури " +"кваліфікації. В протилежному випадку авард стане неуспішним " +"(\"unsuccessful\"), та розпочнеться кваліфікація учасника з другою найвищою " +"валідною ставкою (у випадку якщо до того моменту другий авард не " +"самодискваліфікувався)." + +#: ../../source/award_workflow.rst:74 +msgid "" +"The award with the highest qualifying bid initially receives a " +"\"pending.verification\" status. The procedure enters the " +"\"verificationPeriod\" stage, which lasts 0-4 days. Unless the protocol is " +"uploaded and confirmed by the organizer in 4 days, the award receives an " +"\"unsuccessful\" status. Otherwise, the organizer manually switches the " +"award status to \"pending.payment\"." +msgstr "" +"Учасник з найвищою валідною (стартова ціна + мінімальний крок аукціону) " +"ставкою отримує початковий статус ''Очікується протокол'' " +"(\"pending.verification\"). Процедура кваліфікації переходить в період " +"верифікації (verificationPeriod), що триває 0-4 дні. Якщо організатор " +"(ліквідатор) не завантажує та не підтверджує протокол протягом 4 днів, авард" +" отримує статус \"unsuccessful\". В протилежному випадку, організатор " +"переключає статус аварду в \"Очікується підписання договору\" " +"(pending.payment)." + +msgid "Procedure Description" +msgstr "Опис процедури" + +msgid "The awards are created for 2 participants whose bids were the highest " +"within the auction. Note that the participants with valid bids only can be qualified." +msgstr "Award'и створюються для двох учасників з найвищими валідними ставками." + +msgid "The award with the highest valid bid initially receives `pending.verification` " +"status (the second one is in `pending.waiting`). The procedure enters the " +"verificationPeriod phase (status: `active.qualification`). When the protocol " +"is uploaded and confirmed by the Organizer, the award should be manually switched " +"to `pending.payment` status. Simultaneously the procedure enters the signingPeriod " +"phase (status: `active.awarded`)." +msgstr "Award з найвищою валідною ставкою початково отримує статус `pending.verification` " +"(award для другого учасника - `pending.waiting`). Процедура входить у фазу verificationPeriod " +"(статус: `active.qualification`). Після завантаження та підтвердження протоколу Організатором, " +"award потрібно вручну перевести в статус `pending.payment`. Водночас " +"процедура входить в фазу signingPeriod (статус: `active.awarded`)." + +msgid "When the payment has been received, the Organizer should switch award to `active`. " +"Thereby, the contract is being created for this award in `pending` status and " +"the procedure enters the signingPeriod phase (status: `active.awarded`). " +"Within this stage the Organizer should upload the document and switch contract to active." +msgstr "Після отримання платежу, Організатор має перевести award в статус `active`." +"Тим самим, для цього award'у створюєьтся контракт у статусі `pending` і процедура " +"входить в фазу signingPeriod (статус: `active.awarded`). На цьому етапі Організатор " +"має завантажити документ та переключити котракт в статус `active`." + +msgid "For the next bidder to be qualified, the Organizer should check the status of " +"the previous one to unsuccessful first and then switch the next award to pending.verification." +msgstr "Для того, щоб кваліфікувати наступного учасника, Організатор має спочатку " +"перевести попереднього в статус unsuccessful і перевести наступний award в pending.verification." + +msgid "Notes" +msgstr "Примітки" + +msgid "For the bidder to be qualified and not invalidated, his/her bid should be " +"equal to or exceed the starting price of the auction + the minimal step of the auction." +msgstr "Для того, щоб кваліфікувати учасника та не інвалідувати його ставку, його ставка " +"має бути рівною або більшою за суму початкової ціни аукціону та мінімального кроку аукціону." + +msgid "In case the first two highest bids do not exceed the amount of starting price " +"+ the minimal step, the awards are not being formed at all, and the procedure automatically " +"becomes “unsuccessful”." +msgstr "Якщо дві найвищі ставки не перевищують суму початкової ціни аукціону та мінімального кроку, " +"award'и не сформуються і процедура стане “unsuccessful”." + +msgid "In case the second highest bid is smaller than the starting price + the minimal " +"step, two awards are formed with the smaller one becoming unsuccessful immediately. " +"The first highest bid (if larger than the starting price + minimum step) undergoes " +"the awarding procedure and can win the auction." +msgstr "Якщо друга найвища ставка є меншою за суму початкової ціни аукціону та мінімального кроку " +"формуються два award'и, але другий award відразу переходить в статус unsuccessful. Учасник з першою " +"найвищою ставкою, значення якої більше або рівне сумі початкової ціни аукціону та мінімального кроку, " +"проходить процедуру кваліфікації і може виграти аукціон." + +msgid "The second highest qualifying bidder can disqualify himself/herself " +"(switch award to `cancelled`) at any point of time BEFORE the start of his/her qualification process." +msgstr "Другий кваліфікований учасник може дискваліфікувати себе (перевести award в статус `cancelled`) " +"у будь-який момент перед початком його кваліфікації." + +msgid "All of the statuses are switched manually. Start and end dates of " +"the periods do not influence the actions available to be done (completed)." +msgstr "Усі статуси перемикаються автоматично. Дати початку чи кінця періоду " +"не впливають на дії, які можуть бути виконані (завершені)." + +msgid "In case of the Organizer noted minNumberOfQualifiedBids: 1 and " +"only one bidder submitted the proposal, the auction would be oveleaped " +"and this participant would become the qualified one." +msgstr "Якщо Організатор передає значення у поле minNumberOfQualifiedBids: 1 " +"і тільки один учасник підтвердив пропозицію, тоді аукціон буде пропущено " +"і почнеться етап кваліфікації цього учасника." + +msgid "The Organizer can disqualify the award at any stage of the awarding " +"process up until the moment, when the contract has been uploaded and activated in the system." +msgstr "Організатор може дискваліфікувати кваліфікованого учасника на будь-якому етапі" +"кваліфікації до моменту, коли контракт буде завантажено і активовано в системі." + diff --git a/docs/source/locale/uk/LC_MESSAGES/fintutorial.po b/docs/source/locale/uk/LC_MESSAGES/fintutorial.po new file mode 100644 index 0000000..d02e6c9 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/fintutorial.po @@ -0,0 +1,188 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-16 16:42+0300\n" +"PO-Revision-Date: 2016-09-20 17:47+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Fin. Tutorial" +msgstr "Фін. туторіал" + +msgid "Creating auction" +msgstr "Створення аукціону" + +msgid "" +"Let's create auction with the minimal data set (only required properties):" +msgstr "" +"Створимо аукціон з мінімально допустимим (обовязковим для заповнення) " +"набором даних:" + +msgid "" +"Success! Now we can see that new object has been created. Response code is " +"`201` and `Location` response header reports the location of the created " +"object. The body of response reveals the information about the created " +"auction: its internal `id` (that matches the `Location` segment), its " +"official `auctionID` and `dateModified` datestamp stating the moment in time" +" when auction has been last modified. Pay attention to the " +"`procurementMethodType`. Note that auction is created with " +"`active.tendering` status." +msgstr "" +"Успіх! Тепер ми бачимо, що новий об’єкт було створено. Код відповіді `201` " +"та заголовок відповіді `Location` вказує місцерозташування створеного " +"об’єкта. Тіло відповіді показує інформацію про створений аукціон, його " +"внутрішнє `id` (яке співпадає з сегментом `Location`), його офіційне " +"`auctionID` та `dateModified` дату, що показує час, коли аукціон востаннє " +"модифікувався. Зверніть увагу на `procurementMethodType`, а також на те, що " +"аукціон створюється зі статусом `active.tendering`." + +msgid "" +"Let's access the URL of the created object (the `Location` header of the " +"response):" +msgstr "Використаємо URL створеного об’єкта (заголовок відповіді `Location`):" + +msgid "We can see the same response we got after creating auction." +msgstr "Ми бачимо ту ж відповідь, що і після створення аукціону." + +msgid "Let's see what listing of auctions reveals us:" +msgstr "Подивимось, що показує список аукціонів:" + +msgid "" +"We do see the auction's internal `id` (that can be used to construct full " +"URL by prepending `https://api-" +"sandbox.ea.openprocurement.org/api/0/auctions/`) and its `dateModified` " +"datestamp." +msgstr "" +"Ми бачимо внутрішнє `id` аукціону (що може бути використано для побудови " +"повної URL-адреси, якщо додати `http://api-" +"sandbox.openprocurement.org/api/0/auctions/`) та його `dateModified` дату." + +msgid "Uploading documentation" +msgstr "Завантаження документації" + +msgid "" +"Organizer can upload PDF files into the created auction. Uploading should " +"follow the :ref:`upload` rules." +msgstr "" +"Замовник може завантажити PDF файл у створений аукціон. Завантаження повинно" +" відбуватись згідно правил :ref:`upload`." + +msgid "" +"`201 Created` response code and `Location` header confirm document creation." +" We can additionally query the `documents` collection API endpoint to " +"confirm the action:" +msgstr "" +"Код відповіді `201 Created` та заголовок `Location` підтверджують, що " +"документ було створено. Додатково можна зробити запит точки входу API " +"колекції `документів`, щоб підтвердити дію:" + +msgid "" +"The single array element describes the uploaded document. We can upload more" +" documents:" +msgstr "" +"Один елемент масиву описує завантажений документ. Ми можемо завантажити " +"більше документів:" + +msgid "And again we can confirm that there are two documents uploaded." +msgstr "І знову можна перевірити, що є два завантажених документа." + +msgid "" +"In case we made an error, we can reupload the document over the older " +"version:" +msgstr "" +"Якщо сталась помилка, ми можемо ще раз завантажити документ поверх старої " +"версії:" + +msgid "And we can see that it is overriding the original version:" +msgstr "І ми бачимо, що вона перекриває оригінальну версію:" + +msgid "Adding virtual data room" +msgstr "Додавання віртуальної кімнати для роботи з конфіденційними даними" + +msgid "Registering bid" +msgstr "Реєстрація пропозиції" + +msgid "And activate a bid:" +msgstr "І активувати пропозицію:" + +msgid "It is possible to check the uploaded documents:" +msgstr "Можна перевірити завантажені документи:" + +msgid "" +"For the best effect (biggest economy) auction should have multiple bidders " +"registered:" +msgstr "" +"Для найкращого результату (найбільшої економії) аукціон повинен мати багато " +"зареєстрованих учасників." + +msgid "Organizer can add URL for virtual data room:" +msgstr "" +"Організатор може додати URL-адресу віртуальної кімнати для роботи з " +"конфіденційними даними:" + +msgid "And upload license (with ``documentType: financialLicense``):" +msgstr "І завантажити ліцензію (вказавши ``documentType: financialLicense``):" + +msgid "Uploading illustration" +msgstr "Завантаження ілюстрації" + +msgid "" +"Organizer can upload illustration files into the created auction. Uploading " +"should follow the :ref:`upload` rules." +msgstr "" +"Організатор може завантажити файли з ілюстраціями у створений аукціон. " +"Завантаження повинно відповідати правилам :ref:`upload`." + +msgid "We can check whether illustration is uploaded." +msgstr "Ми можемо перевірити, чи завантажилась ілюстрація." + +msgid "Tutorial for the `dgfFinancialAssets` procedure." +msgstr "" +"Туторіал для процедури `dgfFinancialAssets` - продаж права вимоги за " +"кредитними договорами." + +msgid "" +"In order to specify illustration display order, ``index`` field can be used " +"(for details see :ref:`document`). Since this illustration should be " +"displayed first, it has ``\"index\": 1``." +msgstr "" +"Для того, щоб вказати порядок відображення ілюстрацій, використовується поле" +" `index` (див. :ref:`document`). Оскільки ця ілюстрація повинна бути " +"відображена першою, то вказується ``\"index\": 1``" + +msgid "" +"Organizer can upload second illustration. This illustration should be " +"displayed second, so it has ``\"index\": 2``." +msgstr "" +"Організатор може завантажити ще одну ілюстрацію. Ця ілюстрація повинна бути " +"відображена другою, тому має параметр ``\"index\": 2``." + +msgid "Add third illustration:" +msgstr "Додаємо третю ілюстрацію:" + +msgid "" +"Note that `index` of the third illustration is the same as for the second " +"illustration: ``\"index\": 2``. In such cases firstly will be displayed " +"illustration that was uploaded earlier." +msgstr "" +"Зверніть увагу, що параметр `index` третьої ілюстрації такий же як і у " +"другої: ``\"index\": 2``. У таких випадках спочатку відображатиметься " +"ілюстрація з ранішою датою публікації." + +msgid "We can check that there are three uploaded illustrations." +msgstr "Можемо перевірити, що є три завантажені ілюстрації." + +msgid "" +"Bidder can register a bid in `draft` status. Bidder must specify ``UA-FIN`` " +"value for the `additionalIdentifiers` parameter." +msgstr "" +"Учасник може зареєструвати пропозицію у статусі `draft` (чернетка). Учасник " +"повинен вказати значення ``UA-FIN`` для параметра `additionalIdentifiers`." diff --git a/docs/source/locale/uk/LC_MESSAGES/index.po b/docs/source/locale/uk/LC_MESSAGES/index.po new file mode 100644 index 0000000..0dd014e --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/index.po @@ -0,0 +1,59 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-13 12:12+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Welcome to openprocurement.auctions.dgf's documentation!" +msgstr "Вітаємо на сайті документації по openprocurement.auctions.dgf!" + +msgid "" +"Please report any problems or suggestions for improvement either via the " +"`mailing list `_ or" +" the `issue tracker " +"`_." +msgstr "" +"Будь ласка повідомляйте про всі проблеми та поради покращень або через " +"`розсилку `_ , або " +"через `issue tracker " +"`_." + +msgid "Contents:" +msgstr "Зміст:" + +msgid ":ref:`Authentication `" +msgstr ":ref:`Аутентифікація `" + +msgid ":ref:`Responses `" +msgstr ":ref:`Відповіді `" + +msgid ":ref:`Options `" +msgstr ":ref:`Опції `" + +msgid ":ref:`Date Format: ISO 8601 `" +msgstr ":ref:`Формат дати: ISO 8601 `" + +msgid ":ref:`Performance recommendations `" +msgstr ":ref:`Рекомендації для роботи `" + +msgid ":ref:`API in cluster mode `" +msgstr ":ref:`Робота з API в режимі кластеру `" + +msgid "Indices and tables" +msgstr "Індекси та таблиці" + +msgid ":ref:`genindex`" +msgstr ":ref:`genindex`" + +msgid ":ref:`search`" +msgstr ":ref:`search`" diff --git a/docs/source/locale/uk/LC_MESSAGES/overview.po b/docs/source/locale/uk/LC_MESSAGES/overview.po new file mode 100644 index 0000000..5a128af --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/overview.po @@ -0,0 +1,218 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-11-18 13:51+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Overview" +msgstr "Огляд" + +msgid "Conventions" +msgstr "Домовленості" + +msgid "" +"If something went wrong during the request, we'll get a different status " +"code and the JSON returned will have an `errors` field at the top level " +"containing a list of problems. We look at the first one and print out its " +"message." +msgstr "" +"Якщо під час запиту виникли труднощі, ми отримаємо інший код стану та JSON, " +"який при поверненні міститиме `errors` поле на верхньому рівні зі списком " +"проблем. Ми дивимось на першу з них і видруковуємо її повідомлення." + +msgid "Main responsibilities" +msgstr "Основні задачі" + +msgid "Business logic" +msgstr "Бізнес логіка" + +msgid "Project status" +msgstr "Стан проекту" + +msgid "The project has pre alpha status." +msgstr "Статус цього проекту - перед-альфа" + +msgid "" +"The source repository for this project is on GitHub: " +"https://github.com/openprocurement/openprocurement.auctions.dgf" +msgstr "" +"Репозиторій джерельних текстів цього проекту є на `GitHub " +"`_." + +msgid "" +"You can leave feedback by raising a new issue on the `issue tracker " +"`_ " +"(GitHub registration necessary)." +msgstr "" +"Повідомляйте про всі проблеми та поради через `issue tracker " +"`_ " +"(реєстрація на GitHub обов’язкова)." + +msgid "Documentation of related packages" +msgstr "Документація пов’язаних пакетів" + +msgid "`OpenProcurement API `_" +msgstr "" +"`OpenProcurement API `_" + +msgid "API stability" +msgstr "Стабільність API" + +msgid "" +"API is highly unstable, and while API endpoints are expected to remain " +"relatively stable the data exchange formats are expected to be changed a " +"lot. The changes in the API are communicated via `Open Procurement API " +"`_ maillist." +msgstr "" +"API є дуже нестабільним. Хоча точки входу API будуть відносно стабільними, " +"формати обміну даними будуть часно змінюватись. Зміни в API обговорюються " +"через `Open Procurement API `_ розсилку." + +msgid "Change log" +msgstr "Звіт про зміни" + +msgid "0.1" +msgstr "0.1" + +msgid "Released: not released" +msgstr "Випущено: не випущено" + +msgid "Next steps" +msgstr "Наступні кроки" + +msgid "" +"openprocurement.auctions.dgf contains documentaion for Deposit Guarantee " +"Fund auctions." +msgstr "" +"openprocurement.auctions.dgf містить документацію по аукціонах Фонду " +"гарантування вкладів." + +msgid "Features" +msgstr "Особливості" + +msgid "" +"No need to specify enquiries period (there is no *active.enquiries* status)," +" since it overlaps with *active.tendering* period." +msgstr "" +"Відсутність необхідності вказання періоду уточнень (тут немає окремого " +"статусу *active.enquiries*), оскільки він накладається на період прийому " +"пропозицій *active.tendering*." + +msgid "`tenderPeriod` must be at least 7 calendar days." +msgstr "`tenderPeriod` має складати щонайменше 7 календарних днів." + +msgid "Organizer can edit procedure only during *rectificationPeriod*." +msgstr "Організатор може редагувати аукціон тільки впродовж *rectificationPeriod*." + +msgid "Organizer can add and edit documents only during *rectificationPeriod*." +msgstr "Організатор може додавати та редагувати документи аукціону тільки впродовж *rectificationPeriod*. " + +msgid "Optionally Organizer can set *enquiryPeriod.endDate*." +msgstr "Також додатково Організатор має можливість встановити *enquiryPeriod.endDate*." + +msgid "As soon as the action is edited, the status of all of the submitted bids will be switched to `invalid`." +msgstr "Кожного разу після редагування аукціону статус всіх ставок перемикається на `invalid`." + +msgid "If *enquiryPeriod.endDate* is not provided it will be calculated automatically." +msgstr "Якщо *enquiryPeriod.endDate* не передано, ця дата встановлюється автоматично." + +msgid "Procedure can be switched from *draft* status to *active.tendering*." +msgstr "Процедура переходить зі статусу *draft* до *active.tendering*." + +msgid "" +"During *active.tendering* period participants can ask questions, submit " +"proposals, and upload documents." +msgstr "" +"Протягом періоду *active.tendering* учасники можуть задавати питання, " +"подавати пропозиції, завантажувати документи." + +msgid "" +"There is obligatory participant qualification (*Bid.selfQualified*) via " +"guarantee payment." +msgstr "" +"Обов’язкова кваліфікація учасника (*Bid.selfQualified*) через гарантійний " +"платіж." + +msgid "You might find it helpful to look at the :ref:`tutorial`." +msgstr "Можливо вам буде цікаво прочитати :ref:`tutorial`." + +msgid "" +"All API POST and PUT requests expect a top-level object with a single " +"element in it named `data`. Successful responses will mirror this format. " +"The data element should itself be an object, containing the parameters for " +"the request. In the case of creating a new auction, these are the fields we" +" want to set on the auction itself." +msgstr "" +"Всі API POST та PUT запити очікують об'єкт верхнього рівня з єдиним " +"елементом з назвою `data`. Відповіді з повідомленням про успіх будуть " +"віддзеркалювати цей формат. Елемент data повинен сам бути об’єктом, що " +"містить параметри запиту. Якщо створюється новий аукціон, то це ті поля, які" +" ми хочемо встановити на самому аукціоні." + +msgid "" +"If the request was successful, we will get a response code of `201` " +"indicating the object was created. That response will have a data field at " +"its top level, which will contain complete information on the new auction, " +"including its ID." +msgstr "" +"Якщо запит був успішним, ми отримаємо код відповіді `201`, який вказує, що " +"об’єкт був створений. Ця відповідь буде мати data поле на верхньому рівні, " +"яке вміщуватиме повну інформацію про новий аукціон, включно з ID." + +msgid "" +"Organizer can both increase and decrease `value.amount`, `guarantee.amount`, `minimalStep.amount`." +msgstr "" +"Організатор може як зменшувати, так і збільшувати `value.amount`, `guarantee.amount`, `minimalStep.amount`." + +msgid "" +"Organizer can't edit procedure's significant properties (*Auction.value*, " +"etc.)." +msgstr "" +"Організатор не може редагувати суттєвих властивостей процедури, наприклад, " +"*Auction.value*." + +msgid "" +"The only date Organizer has to provide is *Tender.auctionPeriod.startDate*, the rest will be calculated automatically." +msgstr "" +"Організатор може передати тільки дату початку аукціону " +"*Tender.auctionPeriod.startDate*. Всі решта дати будуть обраховані на її " +"основі." + +msgid "" +"The only currency (*Value.currency*) for this procedure is hryvnia (UAH)." +msgstr "Єдина валюта (*Value.currency*) цієї процедури - гривня UAH." + +msgid "" +"API accepts `JSON `_ or form-encoded content in requests." +" It returns JSON content in all of its responses, including errors. Only " +"the UTF-8 character encoding is supported for both requests and responses." +msgstr "" +"API приймає `JSON `_ або form-encoded вміст у запитах. Він" +" повертає JSON вміст у всіх свої відповідях, включно з помилками. " +"Підтримується лише UTF-8 кодування і для запитів, і для відповідей." + +msgid "There are two procedures:" +msgstr "Є дві процедури:" + +msgid "dgfOtherAssets - sale of the insolvent bank property." +msgstr "dgfOtherAssets - продаж майна банків, що ліквідуються." + +msgid "dgfFinancialAssets - sale of the creditor claim right." +msgstr "dgfFinancialAssets - продаж права вимоги за кредитними договорами." + +msgid "" +"The items within an auction are allowed to be from different CAV groups." +msgstr "Аукціон може містити елементи з різних CAV груп." + diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/auction.po b/docs/source/locale/uk/LC_MESSAGES/standard/auction.po new file mode 100644 index 0000000..26f2235 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/auction.po @@ -0,0 +1,392 @@ +# +# Zoriana Zaiats , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-13 15:36+0300\n" +"PO-Revision-Date: 2016-10-19 12:51+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Auction" +msgstr "Auction" + +msgid "Schema" +msgstr "Схема" + +msgid "string, multilingual" +msgstr "рядок, багатомовний" + +msgid "string, auto-generated, read-only" +msgstr "рядок, генерується автоматично, лише для читання" + +msgid "string, multilingual, editable during enquiryPeriod" +msgstr "рядок, багатомовний, доступний для редагування впродовж enquiryPeriod" + +msgid "string, editable during enquiryPeriod" +msgstr "рядок, доступний для редагування впродовж enquiryPeriod" + +msgid "The auction identifier to refer auction to in \"paper\" documentation." +msgstr "Ідентифікатор аукціону, щоб знайти його у \"паперовій\" документації" + +msgid ":ref:`ProcuringEntity`, required" +msgstr ":ref:`ProcuringEntity`, обов'язково" + +msgid "Organization conducting the auction." +msgstr "Організатор (організація, що проводить аукціон)." + +msgid ":ref:`value`, required, editable during enquiryPeriod" +msgstr ":ref:`value`, обов'язково, доступне для редагування впродовж enquiryPeriod" + +msgid ":ref:`Guarantee`, editable during enquiryPeriod" +msgstr ":ref:`Guarantee`, доступне для редагування впродовж enquiryPeriod" + +msgid "minNumberOfQualifiedBids" +msgstr "minNumberOfQualifiedBids" + +msgid "integer, optional" +msgstr "ціле число, не обов’язково" + +msgid "" +"The field that indicates the minimal number of qualified bids. " +"The possible values for the field are 1 or 2." +msgstr "" +"Поле, що вказує на мінімальну кількість кваліфікованих пропозицій. " +"Можливі значення, що можна присвоїти: 1 або 2." + +msgid "" +"In case of the field has been remained blank, the workflow will be similar to the auction with 2 bids." +msgstr "" +"Якщо поле залишилось незаповненим, то порядок дій такий же, як і при наявності двох учасників." + +msgid "" +"You can also fill in the field, assigning the value "1". This will show " +"that the only one bidder is needed for the procedure to be successful. " +"Therewith the auction is omitted and that bid turns to a qualified award." +msgstr "" +"При присвоєнні полю значення "1" пропозиція учасника торгів автоматично стає " +"award'ом, що пройшов етап кваліфікації. Сам же аукціон в такому випадку відсутній. Процедура вважається успішною." + +msgid "Bid guarantee" +msgstr "Гарантійний внесок" + +msgid "list of :ref:`item` objects, required, editable during enquiryPeriod" +msgstr "список об’єктів :ref:`item`, обов’язково, доступне для редагування впродовж enquiryPeriod" + +msgid "" +"|ocdsDescription| The goods and services to be purchased, broken into line " +"items wherever possible. Items should not be duplicated, but a quantity of 2" +" specified instead." +msgstr "" +"|ocdsDescription| Товари та послуги, що будуть закуплені, поділені на " +"спискові елементи, де це можливо. Елементи не повинні дублюватись, замість " +"цього вкажіть кількість 2." + +#: ../../source/standard/auction.rst:69 +msgid "list of :ref:`Feature` objects" +msgstr "список об’єктів :ref:`Feature`" + +#: ../../source/standard/auction.rst:71 +msgid "Features of auction." +msgstr "Властивості аукціону." + +#: ../../source/standard/auction.rst:74 +msgid "List of :ref:`document` objects" +msgstr "Список об’єктів :ref:`document`" + +#: ../../source/standard/auction.rst:76 +msgid "|ocdsDescription| All documents and attachments related to the auction." +msgstr "|ocdsDescription| Всі документи та додатки пов’язані із аукціоном." + +#: ../../source/standard/auction.rst:80 +msgid "List of :ref:`question` objects" +msgstr "Список об’єктів :ref:`question`" + +#: ../../source/standard/auction.rst:82 +msgid "Questions to ``procuringEntity`` and answers to them." +msgstr "Питання до організатора ``procuringEntity`` і відповіді на них." + +#: ../../source/standard/auction.rst:85 +msgid "List of :ref:`complaint` objects" +msgstr "Список об’єктів :ref:`complaint`" + +#: ../../source/standard/auction.rst:87 +msgid "Complaints to auction conditions and their resolutions." +msgstr "Скарги на умови аукціону та їх вирішення." + +#: ../../source/standard/auction.rst:90 +msgid "List of :ref:`bid` objects" +msgstr "Список об’єктів :ref:`bid`" + +#: ../../source/standard/auction.rst:94 +msgid "" +"|ocdsDescription| A list of all the companies who entered submissions for " +"the auction." +msgstr "" +"|ocdsDescription| Список усіх компаній, які подали заявки для участі в " +"аукціоні." + +#: ../../source/standard/auction.rst:103 +msgid "`currency` should either be absent or match `Auction.value.currency`" +msgstr "" +"Значення `currency` повинно бути або відсутнім, або співпадати з " +"`Auction.value.currency`" + +#: ../../source/standard/auction.rst:104 +msgid "" +"`valueAddedTaxIncluded` should either be absent or match " +"`Auction.value.valueAddedTaxIncluded`" +msgstr "" +"Значення `valueAddedTaxIncluded` повинно бути або відсутнім, або співпадати " +"з `Auction.value.valueAddedTaxIncluded`" + +#: ../../source/standard/auction.rst:107 +msgid "List of :ref:`award` objects" +msgstr "Список об’єктів :ref:`award`" + +#: ../../source/standard/auction.rst:109 +msgid "All qualifications (disqualifications and awards)." +msgstr "Всі кваліфікації (дискваліфікації та визначення переможця)." + +#: ../../source/standard/auction.rst:112 +msgid "List of :ref:`Contract` objects" +msgstr "Список об’єктів :ref:`Contract`" + +#: ../../source/standard/auction.rst:131 +msgid ":ref:`period`, required" +msgstr ":ref:`period`, обов'язково" + +#: ../../source/standard/auction.rst:119 +msgid "" +"|ocdsDescription| The period during which enquiries may be made and will be " +"answered." +msgstr "" +"|ocdsDescription| Період, коли можна задати питання (уточнення) та отримати " +"відповіді на них." + +#: ../../source/standard/auction.rst:127 +msgid "" +"|ocdsDescription| The period when the auction is open for submissions. The " +"end date is the closing date for auction submissions." +msgstr "" +"|ocdsDescription| Період, коли аукціон відкритий для подачі пропозицій. " +"Кінцева дата - це дата, коли перестають прийматись пропозиції." + +#: ../../source/standard/auction.rst:141 +msgid ":ref:`period`, read-only" +msgstr ":ref:`period`, лише для читання" + +#: ../../source/standard/auction.rst:136 +msgid "url" +msgstr "URL-адреса" + +#: ../../source/standard/auction.rst:143 +msgid "Awarding process period." +msgstr "Період, коли відбувається визначення переможця." + +#: ../../source/standard/auction.rst:145 +msgid "" +"|ocdsDescription| The date or period on which an award is anticipated to be " +"made." +msgstr "" +"|ocdsDescription| Дата або період, коли очікується визначення переможця." + +#: ../../source/standard/auction.rst:32 ../../source/standard/auction.rst:149 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/auction.rst:152 +msgid "Tendering period (tendering)" +msgstr "Очікування пропозицій (пропозиції)" + +#: ../../source/standard/auction.rst:154 +msgid "Auction period (auction)" +msgstr "Період аукціону (аукціон)" + +#: ../../source/standard/auction.rst:156 +msgid "Winner qualification (qualification)" +msgstr "Кваліфікація переможця (кваліфікація)" + +#: ../../source/standard/auction.rst:158 +msgid "Standstill period (standstill)" +msgstr "Пропозиції розглянуто (розглянуто)" + +#: ../../source/standard/auction.rst:160 +msgid "Unsuccessful auction (unsuccessful)" +msgstr "Аукціон не відбувся (не відбувся)" + +#: ../../source/standard/auction.rst:162 +msgid "Complete auction (complete)" +msgstr "Завершений аукціон (завершений)" + +#: ../../source/standard/auction.rst:164 +msgid "Cancelled auction (cancelled)" +msgstr "Відмінений аукціон (відмінений)" + +#: ../../source/standard/auction.rst:187 +msgid "List of :ref:`cancellation` objects." +msgstr "Список об’єктів :ref:`cancellation`." + +#: ../../source/standard/auction.rst:189 +msgid "Contains 1 object with `active` status in case of cancelled Auction." +msgstr "" +"Містить 1 об’єкт зі статусом `active` на випадок, якщо аукціон буде " +"відмінено." + +#: ../../source/standard/auction.rst:195 +msgid "List of :ref:`revision` objects, auto-generated" +msgstr "" +"Список об’єктів :ref:`revision`, генерується автоматично, лише для читання" + +#: ../../source/standard/auction.rst:50 +msgid "" +"Total available auction budget. Bids lower than ``value`` will be rejected." +msgstr "" +"Повний доступний бюджет аукціону. Пропозиції, що нижчі за ``value`` будуть " +"відхилені." + +#: ../../source/standard/auction.rst:102 +msgid "`amount` should be greater than `Auction.value.amount`" +msgstr "`amount` повинна бути більша за `Auction.value.amount`" + +#: ../../source/standard/auction.rst:63 +msgid "List that contains single item being sold." +msgstr "Список містить елементи, що продаються." + +#: ../../source/standard/auction.rst:21 +msgid "Detailed auction description." +msgstr "Детальний опис аукціону." + +#: ../../source/standard/auction.rst:92 +msgid "" +"A list of all bids placed in the auction with information about " +"participants, their proposals and other qualification documentation." +msgstr "" +"Список усіх пропозицій поданих до аукціону разом із інформацією про " +"учасників аукціону, їхні пропозиції та інша кваліфікаційна документація." + +#: ../../source/standard/auction.rst:100 +msgid "The minimal step of auction. Validation rules:" +msgstr "Мінімальний крок аукціону. Правила валідації:" + +#: ../../source/standard/auction.rst:138 +msgid "A web address where auction is accessible for view." +msgstr "Веб-адреса для перегляду аукціону." + +#: ../../source/standard/auction.rst:166 +msgid "Auction status." +msgstr "Статус аукціону." + +#: ../../source/standard/auction.rst:191 +msgid "" +"The :ref:`cancellation` object describes the reason of auction cancellation " +"and contains accompanying documents if there are any." +msgstr "" +"Об’єкт :ref:`cancellation` описує причину скасування аукціону та надає " +"відповідні документи, якщо такі є." + +#: ../../source/standard/auction.rst:197 +msgid "Historical changes to `Auction` object properties." +msgstr "Зміни властивостей об’єктів `Auction`." + +#: ../../source/standard/auction.rst:28 +msgid "" +"|ocdsDescription| AuctionID should always be the same as the OCID. It is " +"included to make the flattened data structure more convenient." +msgstr "" +"|ocdsDescription| Ідентифікатор аукціону `AuctionID` повинен завжди " +"співпадати з OCID. Його включають, щоб зробити структуру даних більш " +"зручною." + +#: ../../source/standard/auction.rst:43 +msgid "" +"|ocdsDescription| The entity managing the procurement, which may be " +"different from the buyer who is paying / using the items being procured." +msgstr "" +"|ocdsDescription| Об’єкт, що управляє закупівлею. Він не обов’язково є " +"покупцем, який платить / використовує закуплені елементи." + +#: ../../source/standard/auction.rst:52 +msgid "|ocdsDescription| The total estimated value of the procurement." +msgstr "|ocdsDescription| Загальна кошторисна вартість закупівлі." + +#: ../../source/standard/auction.rst:115 ../../source/standard/auction.rst:123 +msgid ":ref:`period`" +msgstr ":ref:`period`" + +#: ../../source/standard/auction.rst:117 +msgid "Period when questions are allowed." +msgstr "Період, коли дозволено задавати питання." + +#: ../../source/standard/auction.rst:125 +msgid "Period when bids can be submitted." +msgstr "Період, коли подаються пропозиції." + +#: ../../source/standard/auction.rst:133 +msgid "Period when Auction is conducted. `startDate` should be provided." +msgstr "" +"Період, коли проводиться аукціон. Значення `startDate` (дата початку торгів)" +" повинно бути вказано обов'язково." + +#: ../../source/standard/auction.rst:169 +msgid "string, read-only" +msgstr "рядок, лише для читання" + +#: ../../source/standard/auction.rst:171 +msgid "Required for `dgfFinancialAssets` procedure." +msgstr "" +"Обов'язково для `dgfFinancialAssets` процедури (продаж права вимоги за " +"кредитними договорами)." + +#: ../../source/standard/auction.rst:173 +msgid "This field is multilingual:" +msgstr "Це поле багатомовне:" + +#: ../../source/standard/auction.rst:175 +msgid "" +"Ukrainian by default - До участі допускаються лише ліцензовані фінансові " +"установи." +msgstr "" +"За замовчуванням українською мовою - До участі допускаються лише ліцензовані" +" фінансові установи." + +#: ../../source/standard/auction.rst:177 +msgid "" +"``eligibilityCriteria_ru`` (Russian) - К участию допускаются только " +"лицензированные финансовые учреждения." +msgstr "" +"``eligibilityCriteria_ru`` (російською) - К участию допускаются только " +"лицензированные финансовые учреждения." + +#: ../../source/standard/auction.rst:179 +msgid "" +"``eligibilityCriteria_en`` (English) - Only licensed financial institutions " +"are eligible to participate." +msgstr "" +"``eligibilityCriteria_en`` (англійською) - Only licensed financial " +"institutions are eligible to participate." + +#: ../../source/standard/auction.rst:14 +msgid "string, multilingual, read-only" +msgstr "рядок, багатомовний, лише для читання" + +#: ../../source/standard/auction.rst:16 +msgid "Auction number in the Deposit Guarantee Fund." +msgstr "Номер аукціону у Фонді Гарантування Вкладів." + +#: ../../source/standard/auction.rst:34 +msgid "" +"Identification number of the auction (also referred to as `lot`) in the XLS " +"of Deposit Guarantee Fund." +msgstr "Номер аукціону (або `лота`) у XLS Фонду Гарантування." + +#~ msgid "The name of the auction, displayed in listings." +#~ msgstr "Назва аукціону, яка відображається у списках." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/award.po b/docs/source/locale/uk/LC_MESSAGES/standard/award.po new file mode 100644 index 0000000..da40243 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/award.po @@ -0,0 +1,151 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 13:26+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/award.rst:8 +msgid "Award" +msgstr "Award" + +#: ../../source/standard/award.rst:11 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/award.rst:14 ../../source/standard/award.rst:20 +msgid "string, auto-generated, read-only" +msgstr "рядок, генерується автоматично, лише для читання" + +#: ../../source/standard/award.rst:25 ../../source/standard/award.rst:31 +msgid "string, multilingual" +msgstr "рядок, багатомовний" + +#: ../../source/standard/award.rst:27 +msgid "|ocdsDescription| Award title." +msgstr "|ocdsDescription| Назва рішення." + +#: ../../source/standard/award.rst:33 +msgid "|ocdsDescription| Award description." +msgstr "|ocdsDescription| Опис рішення." + +#: ../../source/standard/award.rst:37 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/award.rst:39 +msgid "" +"|ocdsDescription| The current status of the award drawn from the " +"`awardStatus` codelist." +msgstr "" +"|ocdsDescription| Поточний статус рішення, взятий зі списку кодів " +"`awardStatus`." + +#: ../../source/standard/award.rst:42 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/award.rst:44 +msgid "`pending` - the award is under review of qualification committee" +msgstr "`pending` - переможець розглядається кваліфікаційною комісією" + +#: ../../source/standard/award.rst:45 +msgid "" +"`unsuccessful` - the award has been rejected by qualification committee" +msgstr "`unsuccessful` - кваліфікаційна комісія відмовила переможцю" + +#: ../../source/standard/award.rst:46 +msgid "`active` - the auction is awarded to the bidder from the `bid_id`" +msgstr "`active` - аукціон виграв учасник з пропозицією `bid_id`" + +#: ../../source/standard/award.rst:47 +msgid "`cancelled` - the award has been cancelled by complaint review body" +msgstr "" +"`cancelled` - орган, що розглядає скарги, відмінив результати закупівлі" + +#: ../../source/standard/award.rst:50 +msgid "string, :ref:`Date`, auto-generated, read-only" +msgstr "рядок, :ref:`Date`, генерується автоматично, лише для читання" + +#: ../../source/standard/award.rst:52 +msgid "|ocdsDescription| The date of the contract award." +msgstr "|ocdsDescription| Дата рішення про підписання договору." + +#: ../../source/standard/award.rst:56 +msgid "`Value` object, auto-generated, read-only" +msgstr "О’єкт :ref:`Value`, генерується автоматично, лише для читання" + +#: ../../source/standard/award.rst:58 +msgid "|ocdsDescription| The total value of this award." +msgstr "|ocdsDescription| Загальна вартість згідно цього рішення." + +#: ../../source/standard/award.rst:62 +msgid "List of :ref:`Organization` objects, auto-generated, read-only" +msgstr "" +"Список об’єктів :ref:`Organization`, генерується автоматично, лише для " +"читання" + +#: ../../source/standard/award.rst:64 +msgid "|ocdsDescription| The suppliers awarded with this award." +msgstr "" +"|ocdsDescription| Постачальники, що були визнані переможцями згідно цього " +"рішення." + +#: ../../source/standard/award.rst:68 +msgid "List of :ref:`Item` objects, auto-generated, read-only" +msgstr "" +"Список об’єктів :ref:`Item`, генерується автоматично, лише для читання" + +#: ../../source/standard/award.rst:74 +msgid "List of :ref:`Document` objects" +msgstr "Список об’єктів :ref:`Document`" + +#: ../../source/standard/award.rst:76 +msgid "" +"|ocdsDescription| All documents and attachments related to the award, " +"including any notices." +msgstr "" +"|ocdsDescription| Усі документи та додатки пов’язані з рішенням, включно з " +"будь-якими повідомленнями." + +#: ../../source/standard/award.rst:80 +msgid "List of :ref:`Complaint` objects" +msgstr "Список об’єктів :ref:`Complaint`" + +#: ../../source/standard/award.rst:83 +msgid ":ref:`period`" +msgstr ":ref:`period`" + +#: ../../source/standard/award.rst:16 +msgid "|ocdsDescription| Identifier for this award." +msgstr "|ocdsDescription| Ідентифікатор цього рішення." + +#: ../../source/standard/award.rst:22 +msgid "The ID of a bid that the award relates to." +msgstr "ID пропозиції, що виграла закупівлю" + +#: ../../source/standard/award.rst:70 +msgid "" +"|ocdsDescription| The goods and services awarded in this award, broken into " +"line items wherever possible. Items should not be duplicated, but the " +"quantity should be specified instead." +msgstr "" +"|ocdsDescription| Товари та послуги, що розглядались цим рішенням, поділені " +"на окремі рядки, де це можливо. Елементи не повинні бути продубльовані, а " +"повинні мати вказану кількість." + +#: ../../source/standard/award.rst:85 +msgid "The time frame when complaints can be submitted." +msgstr "Період часу, під час якого можна подавати скарги." + +#~ msgid "ID of related :ref:`lot`." +#~ msgstr "ID пов’язаного :ref:`lot`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/bid.po b/docs/source/locale/uk/LC_MESSAGES/standard/bid.po new file mode 100644 index 0000000..6c23beb --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/bid.po @@ -0,0 +1,160 @@ +# Zoriana Zaiats , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-10-13 17:52+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/bid.rst:8 +msgid "Bid" +msgstr "Bid" + +#: ../../source/standard/bid.rst:11 ../../source/standard/bid.rst:69 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/bid.rst:14 +msgid "List of :ref:`Organization` objects" +msgstr "Список об’єктів :ref:`Organization` " + +#: ../../source/standard/bid.rst:17 +msgid "string, :ref:`date`, auto-generated" +msgstr "рядок, :ref:`date`, генерується автоматично" + +#: ../../source/standard/bid.rst:25 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/bid.rst:27 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/bid.rst:29 +msgid "`draft`" +msgstr "`draft` - чернетка" + +#: ../../source/standard/bid.rst:30 +msgid "`active`" +msgstr "`active` - активна ставка" + +#: ../../source/standard/bid.rst:33 +msgid ":ref:`Value`, required" +msgstr ":ref:`Value`, обов’язково" + +#: ../../source/standard/bid.rst:35 +msgid "Validation rules:" +msgstr "Правила валідації:" + +#: ../../source/standard/bid.rst:37 +msgid "`amount` should be less than `Auction.value.amout`" +msgstr "`amount` повинно бути меншим, ніж `Auction.value.amount`" + +#: ../../source/standard/bid.rst:38 +msgid "`currency` should either be absent or match `Auction.value.currency`" +msgstr "" +"`currency` повинно або бути відсутнім, або відповідати " +"`Auction.value.currency`" + +#: ../../source/standard/bid.rst:39 +msgid "" +"`valueAddedTaxIncluded` should either be absent or match " +"`Auction.value.valueAddedTaxIncluded`" +msgstr "" +"Значення `valueAddedTaxIncluded` повинно бути або відсутнім, або співпадати " +"з `Auction.value.valueAddedTaxIncluded`" + +#: ../../source/standard/bid.rst:42 +msgid "List of :ref:`Document` objects" +msgstr "Список об’єктів :ref:`Document`" + +#: ../../source/standard/bid.rst:45 +msgid "List of :ref:`Parameter` objects" +msgstr "Список об’єктів :ref:`Parameter`" + +#: ../../source/standard/bid.rst:53 +msgid "A web address for participation in auction." +msgstr "Веб-адреса для участі в аукціоні." + +#: ../../source/standard/bid.rst:66 +msgid "Parameter" +msgstr "Parameter" + +#: ../../source/standard/bid.rst:72 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/bid.rst:77 +msgid "float, required" +msgstr "float, обов’язково" + +#: ../../source/standard/bid.rst:22 +msgid "UID, auto-generated" +msgstr "UID, генерується автоматично" + +#: ../../source/standard/bid.rst:51 +msgid "URL" +msgstr "URL-адреса" + +#: ../../source/standard/bid.rst:74 +msgid "Feature code." +msgstr "Код критерію." + +#: ../../source/standard/bid.rst:79 +msgid "Feature value." +msgstr "Значення критерію." + +#: ../../source/standard/bid.rst:56 +msgid "bool, required" +msgstr "булеве значення, обов'язково" + +#: ../../source/standard/bid.rst:59 +msgid "bool" +msgstr "булеве значення" + +#: ../../source/standard/bid.rst:19 +msgid "Date when bid has been submitted." +msgstr "Дата подачі пропозиції." + +#: ../../source/standard/bid.rst:61 +msgid "Required for `dgfFinancialAssets` procedure." +msgstr "" +"Необхідно для `dgfFinancialAssets` процедури (продаж права вимоги за " +"кредитними договорами)." + +#~ msgid "List of :ref:`LotValue` objects" +#~ msgstr "Список об’єктів :ref:`LotValue`" + +#~ msgid "required for dgfFinancialAssets procedure" +#~ msgstr "" +#~ "обов'язково для dgfFinancialAssets процедури (продаж права вимоги за " +#~ "кредитними договорами)" + +#~ msgid "LotValue" +#~ msgstr "LotValue" + +#~ msgid "`amount` should be less than `Lot.value.amout`" +#~ msgstr "Значення `amount` повинно бути меншим за `Lot.value.amout`" + +#~ msgid "`currency` should either be absent or match `Lot.value.currency`" +#~ msgstr "" +#~ "Значення `currency` повинно бути або відсутнім, або співпадати з " +#~ "`Lot.value.currency`" + +#~ msgid "" +#~ "`valueAddedTaxIncluded` should either be absent or match " +#~ "`Lot.value.valueAddedTaxIncluded`" +#~ msgstr "" +#~ "`valueAddedTaxIncluded` повинно або бути відсутнім, або відповідати " +#~ "`Lot.value.valueAddedTaxIncluded`" + +#~ msgid "ID of related :ref:`lot`." +#~ msgstr "ID пов’язаного :ref:`lot`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/cancellation.po b/docs/source/locale/uk/LC_MESSAGES/standard/cancellation.po new file mode 100644 index 0000000..2820dab --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/cancellation.po @@ -0,0 +1,83 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 14:36+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/cancellation.rst:8 +msgid "Cancellation" +msgstr "Cancellation" + +#: ../../source/standard/cancellation.rst:11 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/cancellation.rst:17 +msgid "string, multilingual, required" +msgstr "рядок, багатомовний, обов’язковий" + +#: ../../source/standard/cancellation.rst:22 +#: ../../source/standard/cancellation.rst:42 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/cancellation.rst:28 +#: ../../source/standard/cancellation.rst:44 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/cancellation.rst:26 +msgid "Default. The request is being prepared." +msgstr "За замовчуванням. Запит оформляється." + +#: ../../source/standard/cancellation.rst:28 +msgid "Cancellation activated." +msgstr "Скасування активоване." + +#: ../../source/standard/cancellation.rst:31 +msgid "List of :ref:`Document` objects" +msgstr "Список об’єктів :ref:`Document`" + +#: ../../source/standard/cancellation.rst:33 +msgid "" +"Documents accompanying the Cancellation: Protocol of Auction Committee with " +"decision to cancel the Auction." +msgstr "" +"Супровідна документація скасування: Протокол рішення Аукціонного комітету " +"організатора про скасування аукціону." + +#: ../../source/standard/cancellation.rst:37 +msgid "string, :ref:`date`" +msgstr "рядок, :ref:`date`" + +#: ../../source/standard/cancellation.rst:39 +msgid "Cancellation date." +msgstr "Дата скасування" + +#: ../../source/standard/cancellation.rst:46 +msgid "`auction`" +msgstr "`auction`" + +#: ../../source/standard/cancellation.rst:14 +msgid "UID, auto-generated" +msgstr "UID, генерується автоматично" + +#: ../../source/standard/cancellation.rst:19 +msgid "The reason, why auction is being cancelled." +msgstr "Причина, з якої скасовується аукціон." + +#~ msgid "`lot`" +#~ msgstr "`lot`" + +#~ msgid "ID of related :ref:`lot`." +#~ msgstr "ID пов’язаного :ref:`lot`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/complaint.po b/docs/source/locale/uk/LC_MESSAGES/standard/complaint.po new file mode 100644 index 0000000..1fd0060 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/complaint.po @@ -0,0 +1,182 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 14:25+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/complaint.rst:9 +msgid "Complaint" +msgstr "Complaint" + +#: ../../source/standard/complaint.rst:12 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/complaint.rst:18 +msgid ":ref:`Organization`, required" +msgstr ":ref:`Organization`, обов’язково" + +#: ../../source/standard/complaint.rst:20 +msgid "" +"Organization filing a complaint (contactPoint - person, identification - " +"organization that person represents)." +msgstr "" +"Організація, яка подає скаргу (contactPoint - людина, identification - " +"організація, яку ця людина представляє)." + +#: ../../source/standard/complaint.rst:23 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/complaint.rst:25 +msgid "Title of the complaint." +msgstr "Заголовок скарги." + +#: ../../source/standard/complaint.rst:28 +msgid "Description of the issue." +msgstr "Опис запитання." + +#: ../../source/standard/complaint.rst:31 +#: ../../source/standard/complaint.rst:36 +#: ../../source/standard/complaint.rst:41 +#: ../../source/standard/complaint.rst:46 +#: ../../source/standard/complaint.rst:51 +#: ../../source/standard/complaint.rst:56 +#: ../../source/standard/complaint.rst:125 +msgid "string, :ref:`date`, auto-generated" +msgstr "рядок, :ref:`date`, генерується автоматично" + +#: ../../source/standard/complaint.rst:33 +msgid "Date of posting." +msgstr "Дата подання." + +#: ../../source/standard/complaint.rst:38 +msgid "Date when claim was submitted." +msgstr "Дата, коли вимога була подана." + +#: ../../source/standard/complaint.rst:48 +msgid "Date of claim to complaint escalation." +msgstr "Дата ескалації (перетворення вимоги на скаргу)." + +#: ../../source/standard/complaint.rst:53 +msgid "Date of complaint decision." +msgstr "День прийняття рішення по скарзі." + +#: ../../source/standard/complaint.rst:58 +msgid "Date of cancelling." +msgstr "Дата відхилення." + +#: ../../source/standard/complaint.rst:61 +#: ../../source/standard/complaint.rst:75 +#: ../../source/standard/complaint.rst:83 +#: ../../source/standard/complaint.rst:88 +#: ../../source/standard/complaint.rst:102 +#: ../../source/standard/complaint.rst:107 +#: ../../source/standard/complaint.rst:120 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/complaint.rst:63 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/complaint.rst:65 +msgid "`draft`" +msgstr "`draft` - чорновик, початковий етап" + +#: ../../source/standard/complaint.rst:66 +#: ../../source/standard/complaint.rst:79 +msgid "`claim`" +msgstr "`claim` - вимога" + +#: ../../source/standard/complaint.rst:67 +msgid "`answered`" +msgstr "`answered` - дано відповідь" + +#: ../../source/standard/complaint.rst:68 +msgid "`pending`" +msgstr "`pending` - не вирішено, ще обробляється" + +#: ../../source/standard/complaint.rst:69 +#: ../../source/standard/complaint.rst:92 +msgid "`invalid`" +msgstr "`invalid` - недійсно" + +#: ../../source/standard/complaint.rst:70 +#: ../../source/standard/complaint.rst:93 +msgid "`declined`" +msgstr "`declined` - відхилено" + +#: ../../source/standard/complaint.rst:71 +#: ../../source/standard/complaint.rst:94 +msgid "`resolved`" +msgstr "`resolved` - вирішено" + +#: ../../source/standard/complaint.rst:72 +msgid "`cancelled`" +msgstr "`cancelled` - скасовано" + +#: ../../source/standard/complaint.rst:77 +msgid "Possible values of type are:" +msgstr "Можливі значення типу:" + +#: ../../source/standard/complaint.rst:80 +msgid "`complaint`" +msgstr "`complaint` - скарга" + +#: ../../source/standard/complaint.rst:90 +msgid "Possible values of resolution type are:" +msgstr "Можливі значення типу вирішення:" + +#: ../../source/standard/complaint.rst:97 +msgid "bool" +msgstr "булеве значення" + +#: ../../source/standard/complaint.rst:99 +msgid "Claim is satisfied?" +msgstr "Вимога задовільнена?" + +#: ../../source/standard/complaint.rst:109 +msgid "Cancellation reason." +msgstr "Причини відхилення." + +#: ../../source/standard/complaint.rst:112 +msgid "List of :ref:`Document` objects" +msgstr "Список об’єктів :ref:`Document`" + +#: ../../source/standard/complaint.rst:43 +msgid "Date when Organizer answered the claim." +msgstr "Дата, коли організатор відповів на вимогу." + +#: ../../source/standard/complaint.rst:85 +msgid "Organizer's resolution." +msgstr "Рішення організатора." + +#: ../../source/standard/complaint.rst:122 +msgid "Participants's action." +msgstr "Дія учасника." + +#: ../../source/standard/complaint.rst:127 +msgid "Date of participant's action." +msgstr "Дата дії учасника." + +#: ../../source/standard/complaint.rst:15 +msgid "UID, auto-generated" +msgstr "UID, генерується автоматично" + +#: ../../source/standard/complaint.rst:104 +msgid "Reviewer's decision." +msgstr "Рішення органу оскарження." + +#~ msgid "ID of related :ref:`lot`." +#~ msgstr "ID пов’язаного :ref:`lot`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/contract.po b/docs/source/locale/uk/LC_MESSAGES/standard/contract.po new file mode 100644 index 0000000..c5bfaf2 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/contract.po @@ -0,0 +1,162 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 13:28+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/contract.rst:8 +msgid "Contract" +msgstr "Contract" + +#: ../../source/standard/contract.rst:11 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/contract.rst:16 +msgid "|ocdsDescription| The identifier for this contract." +msgstr "|ocdsDescription| Ідентифікатор цього договору." + +#: ../../source/standard/contract.rst:20 ../../source/standard/contract.rst:32 +#: ../../source/standard/contract.rst:59 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/contract.rst:22 +msgid "" +"|ocdsDescription| The `Award.id` against which this contract is being " +"issued." +msgstr "" +"|ocdsDescription| `Award.id` вказує на рішення, згідно якого видається " +"договір." + +#: ../../source/standard/contract.rst:26 +msgid "string, auto-generated, read-only" +msgstr "рядок, генерується автоматично, лише для читання" + +#: ../../source/standard/contract.rst:29 ../../source/standard/contract.rst:38 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/contract.rst:34 +msgid "|ocdsDescription| Contract title" +msgstr "|ocdsDescription| Назва договору" + +#: ../../source/standard/contract.rst:40 +msgid "|ocdsDescription| Contract description" +msgstr "|ocdsDescription| Опис договору" + +#: ../../source/standard/contract.rst:44 +msgid "`Value` object, auto-generated, read-only" +msgstr "Об’єкт `Value`, генерується автоматично, лише для читання" + +#: ../../source/standard/contract.rst:46 +msgid "|ocdsDescription| The total value of this contract." +msgstr "|ocdsDescription| Загальна вартість договору." + +#: ../../source/standard/contract.rst:50 +msgid "List of :ref:`Item` objects, auto-generated, read-only" +msgstr "" +"Список об’єктів :ref:`Item`, генерується автоматично, лише для читання" + +#: ../../source/standard/contract.rst:56 +msgid "List of :ref:`Organization` objects, auto-generated, read-only" +msgstr "" +"Список об’єктів :ref:`Organization`, генерується автоматично, лише для " +"читання" + +#: ../../source/standard/contract.rst:61 +msgid "|ocdsDescription| The current status of the contract." +msgstr "|ocdsDescription| Поточний статус договору." + +#: ../../source/standard/contract.rst:64 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/contract.rst:66 +msgid "" +"`pending` - this contract has been proposed, but is not yet in force. It may" +" be awaiting signature." +msgstr "" +"`pending` - цей договір запропоновано, але він ще не діє. Можливо очікується" +" його підписання." + +#: ../../source/standard/contract.rst:68 +msgid "" +"`active` - this contract has been signed by all the parties, and is now " +"legally in force." +msgstr "" +"`active` - цей договір підписаний всіма учасниками, і зараз діє на законних " +"підставах." + +#: ../../source/standard/contract.rst:70 +msgid "`cancelled` - this contract has been cancelled prior to being signed." +msgstr "`cancelled` - цей договір було скасовано до підписання." + +#: ../../source/standard/contract.rst:71 +msgid "" +"`terminated` - this contract was signed and in force, and has now come to a " +"close. This may be due to a successful completion of the contract, or may " +"be early termination due to some non-completion issue." +msgstr "" +"`terminated` - цей договір був підписаний та діяв, але вже завершився. Це " +"може бути пов'язано з виконанням договору, або з достроковим припиненням " +"через якусь незавершеність." + +#: ../../source/standard/contract.rst:76 +msgid ":ref:`Period`" +msgstr ":ref:`Period`" + +#: ../../source/standard/contract.rst:78 +msgid "|ocdsDescription| The start and end date for the contract." +msgstr "|ocdsDescription| Дата початку та завершення договору." + +#: ../../source/standard/contract.rst:82 ../../source/standard/contract.rst:88 +msgid "string, :ref:`date`" +msgstr "рядок, :ref:`date`" + +#: ../../source/standard/contract.rst:84 +msgid "" +"|ocdsDescription| The date the contract was signed. In the case of multiple " +"signatures, the date of the last signature." +msgstr "" +"|ocdsDescription| Дата підписання договору. Якщо було декілька підписань, то" +" береться дата останнього підписання." + +#: ../../source/standard/contract.rst:90 +msgid "The date when the contract was changed or activated." +msgstr "Дата, коли договір був змінений або активований." + +#: ../../source/standard/contract.rst:93 +msgid "List of :ref:`Document` objects" +msgstr "Список об’єктів :ref:`Document`" + +#: ../../source/standard/contract.rst:95 +msgid "" +"|ocdsDescription| All documents and attachments related to the contract, " +"including any notices." +msgstr "" +"|ocdsDescription| Усі документи та додатки пов’язані з договором, включно з " +"будь-якими повідомленнями." + +#: ../../source/standard/contract.rst:14 +msgid "UID, auto-generated" +msgstr "UID, генерується автоматично" + +#: ../../source/standard/contract.rst:52 +msgid "" +"|ocdsDescription| The goods, services, and any intangible outcomes in this " +"contract. Note: If the items are the same as the award, do not repeat." +msgstr "" +"|ocdsDescription| Товари, послуги та інші нематеріальні результати у цій " +"угоді. Зверніть увагу: Якщо список співпадає з визначенням переможця " +"`award`, то його не потрібно повторювати." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/document.po b/docs/source/locale/uk/LC_MESSAGES/standard/document.po new file mode 100644 index 0000000..3bccc20 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/document.po @@ -0,0 +1,341 @@ +# Zoriana Zaiats , 2016. +# greg , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-12-05 10:50+0200\n" +"Last-Translator: greg \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Document" +msgstr "Document" + +msgid "Schema" +msgstr "Схема" + +msgid "string, auto-generated" +msgstr "рядок, генерується автоматично" + +msgid "string" +msgstr "рядок" + +msgid "Possible values for :ref:`auction`" +msgstr "Можливі значення для :ref:`auction`" + +msgid "`notice` - **Auction notice**" +msgstr "`notice` - **Повідомлення про аукціон**" + +msgid "`technicalSpecifications` - **Technical Specifications**" +msgstr "`technicalSpecifications` - **Технічні специфікації**" + +msgid "Detailed technical information about goods or services to be provided." +msgstr "" +"Детальна технічна інформація про товари або послуги, що повинні бути надані." + +msgid "`evaluationCriteria` - **Evaluation Criteria**" +msgstr "`evaluationCriteria` - **Критерії оцінки**" + +msgid "Information about how bids will be evaluated." +msgstr "Інформація про те, як будуть оцінюватись пропозиції." + +msgid "`clarifications` - **Clarifications to bidders questions**" +msgstr "`clarifications` - **Пояснення до питань заданих учасниками**" + +msgid "Including replies to issues raised in pre-bid conferences." +msgstr "Включає відповіді на питання, підняті на передтендерних конференціях." + +msgid "`bidders` - **Information on bidders**" +msgstr "`bidders` - **Інформація про учасників**" + +msgid "" +"Information on bidders or participants, their validation documents and any " +"procedural exemptions for which they qualify." +msgstr "" +"Інформація про учасників, їхні документи для перевірки та будь-які " +"процесуальні пільги, на які вони можуть претендувати." + +msgid "Possible values for :ref:`award`" +msgstr "Можливі значення для :ref:`award`" + +msgid "`winningBid` - **Winning Bid**" +msgstr "`winningBid` - **Пропозиція, що перемогла**" + +msgid "Possible values for :ref:`contract`" +msgstr "Можливі значення для :ref:`contract`" + +msgid "`notice` - **Contract notice**" +msgstr "`notice` - **Повідомлення про договір**" + +msgid "" +"The formal notice that gives details of a contract being signed and valid to" +" start implementation. This may be a link to a downloadable document, to a " +"web page, or to an official gazette in which the notice is contained." +msgstr "" +"Офіційне повідомлення, що містить деталі закупівлі. Це може бути посилання " +"на документ, веб-сторінку, чи на офіційний бюлетень, де розміщено " +"повідомлення." + +msgid "`contractSigned` - **Signed Contract**" +msgstr "`contractSigned` - **Підписаний договір**" + +msgid "`contractAnnexe` - **Annexes to the Contract**" +msgstr "`contractAnnexe` - **Додатки до договору**" + +msgid "Possible values for :ref:`bid`" +msgstr "Можливі значення для :ref:`bid`" + +msgid "`commercialProposal` - **Сommercial proposal**" +msgstr "`commercialProposal` - **Цінова пропозиція**" + +msgid "`qualificationDocuments` - **Qualification documents**" +msgstr "" +"`qualificationDocuments` - **Документи, що підтверджують кваліфікацію**" + +msgid "`eligibilityDocuments` - **Eligibility documents**" +msgstr "" +"`eligibilityDocuments` - **Документи, що підтверджують відповідність** (в " +"тому числі, відповідність вимогам ст. 17)" + +msgid "string, multilingual" +msgstr "рядок, багатомовний" + +msgid "|ocdsDescription| The document title." +msgstr "|ocdsDescription| Назва документа." + +msgid "" +"|ocdsDescription| A short description of the document. In the event the " +"document is not accessible online, the description field can be used to " +"describe arrangements for obtaining a copy of the document." +msgstr "" +"|ocdsDescription| Короткий опис документа. Якщо документ не буде доступний " +"онлайн, то поле опису можна використати для вказання способу отримання копії" +" документа." + +msgid "" +"|ocdsDescription| The format of the document taken from the `IANA Media " +"Types code list `_, with the " +"addition of one extra value for 'offline/print', used when this document " +"entry is being used to describe the offline publication of a document." +msgstr "" +"|ocdsDescription| Формат документа зі `списку кодів IANA Media Types " +"`_, з одним додатковим " +"значенням 'offline/print', що буде використовуватись, коли запис цього " +"документа використовується для опису офлайнової публікації документа." + +msgid "|ocdsDescription| Direct link to the document or attachment." +msgstr "|ocdsDescription| Пряме посилання на документ чи додаток." + +msgid "string, :ref:`date`" +msgstr "рядок, :ref:`date`" + +msgid "|ocdsDescription| The date on which the document was first published." +msgstr "|ocdsDescription| Дата, коли документ був опублікований вперше." + +msgid "|ocdsDescription| Date that the document was last modified" +msgstr "|ocdsDescription| Дата, коли документ був змінений востаннє." + +msgid "" +"|ocdsDescription| Specifies the language of the linked document using either" +" two-digit `ISO 639-1 " +"`_, or extended " +"`BCP47 language tags `_." +msgstr "" +"|ocdsDescription| Вказує мову документа, використовуючи або двоцифровий код " +"`ISO 639-1 `_, або " +"розширений `BCP47 language tags `_." + +msgid "Possible values are:" +msgstr "Можливі значення:" + +msgid "`auction`" +msgstr "`auction`" + +msgid "`item`" +msgstr "`item`" + +msgid "" +"The formal notice that gives details of an auction. This may be a link to a " +"downloadable document, to a web page, or to an official gazette in which the" +" notice is contained." +msgstr "" +"Офіційне повідомлення, що містить деталі аукціону. Це може бути посилання на" +" документ, веб-сторінку, чи на офіційний бюлетень, де розміщено " +"повідомлення." + +msgid "`illustration` - **Illustrations**" +msgstr "`illustration` - **Ілюстрації**" + +msgid "" +"`virtualDataRoom` - **Virtual Data Room** (available only for the " +"`dgfFinancialAssets` procedure, see :ref:`fintutorial`)" +msgstr "" +"`virtualDataRoom` - **Віртуальна кімната для роботи з конфіденційними " +"даними** (доступно лише для `dgfFinancialAssets` процедури, див. " +":ref:`fintutorial`)" + +msgid "" +"`financialLicense` - **License** (available only for the " +"`dgfFinancialAssets` procedure, see :ref:`fintutorial`)" +msgstr "" +"`financialLicense` - **Ліцензія** (доступно лише для `dgfFinancialAssets` " +"процедури, див. :ref:`fintutorial`)" + +msgid "integer" +msgstr "ціле число" + +msgid "" +"Sorting (display order) parameter used for illustrations. The smaller number" +" is, the higher illustration is in the sorting. If index is not specified, " +"illustration will be displayed the last. If two illustrations have the same " +"index, they will be sorted depending on their publishing date." +msgstr "" +"Пареметр сортування (порядку відображення), що використовується для " +"ілюстрацій. Чим менше число, тим вище ілюстрація буде при сортуванні. Якщо " +"параметр не зазначений, то ілюстрація відображатиметься останньою. Якщо дві " +"ілюстрації мають однакове значення параметру, то порядок сортування буде " +"залежати від дати публікації." + +msgid "`auctionProtocol` - **Auction protocol**" +msgstr "`auctionProtocol` - **Протокол торгів**" + +msgid "" +"Auction protocol describes all participants and determines the candidate " +"(participant that has submitted the highest bid proposal during the " +"auction)." +msgstr "" +"Протокол торгів описує всіх учасників та визначає переможцем того учасника, " +"що під час аукціону подав найбільшу цінову пропозицію, а при однакових " +"цінових пропозиціях, того, що подав пропозицію раніше." + +msgid "ID of related :ref:`item`." +msgstr "Ідентифікатор пов'язаних об'єктів :ref:`item`." + +msgid "`x_dgfAssetFamiliarization` - **Asset Familiarization**" +msgstr "" + +msgid "Required for `x_dgfAssetFamiliarization` document." +msgstr "" + +msgid "" +"Goods examination procedure rules / Asset familiarization procedure in data " +"room. Contains information on where and when a given document can be " +"examined offline." +msgstr "" +"Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті" +" даних. Містить інформацію про те де і коли певний документ можна переглянути" +" вживу." + +#~ msgid "" +#~ "Goods examination procedure rules / Asset familiarization procedure in data " +#~ "room. Contains information on where and when a given document/information " +#~ "can be reviewed offline." +#~ msgstr "" +#~ "Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті " +#~ "даних. Містить інформацію про те де і коли певний документ можна переглянути" +#~ " вживу." + +msgid "`x_presentation` - **Presentation**" +msgstr "`x_presentation` - **Презентація**" + +msgid "Presentation about an asset that is being sold." +msgstr "Презентація активу виставленого на продаж." + +msgid "`x_nda` - **Non-disclosure Agreement (NDA)**" +msgstr "`x_nda` - **Договір про нерозголошення (NDA)**" + +msgid "" +"A non-disclosure agreement between a participant and a bank/Deposit " +"Guarantee Fund." +msgstr "" +"Договір про нерозголошення між учасником та банком/Фондом Гарантування" +" Вкладів." + +#~ msgid "`biddingDocuments` - **Bidding Documents**" +#~ msgstr "`biddingDocuments` - **Документи закупівлі**" + +#~ msgid "`eligibilityCriteria` - **Eligibility Criteria**" +#~ msgstr "`eligibilityCriteria` - **Критерії прийнятності**" + +#~ msgid "Detailed documents about the eligibility of bidders." +#~ msgstr "Докладні документи про критерії відбору." + +#~ msgid "`shortlistedFirms` - **Shortlisted Firms**" +#~ msgstr "`shortlistedFirms` - **Фірми у короткому списку**" + +#~ msgid "" +#~ "`riskProvisions` - **Provisions for management of risks and liabilities**" +#~ msgstr "" +#~ "`riskProvisions` - **Положення для управління ризиками та зобов'язаннями**" + +#~ msgid "`billOfQuantity` - **Bill Of Quantity**" +#~ msgstr "`billOfQuantity` - **Кошторис**" + +#~ msgid "`conflictOfInterest` - **Conflicts of interest uncovered**" +#~ msgstr "`conflictOfInterest` - **Виявлені конфлікти інтересів**" + +#~ msgid "`debarments` - **Debarments issued**" +#~ msgstr "`debarments` - **Відмова у допуску до закупівлі**" + +#~ msgid "`contractProforma` - **Draft contract**" +#~ msgstr "`contractProforma` - **Проект договору**" + +#~ msgid "`notice` - **Award Notice**" +#~ msgstr "`notice` - **Повідомлення про рішення**" + +#~ msgid "" +#~ "The formal notice that gives details of the contract award. This may be a " +#~ "link to a downloadable document, to a web page, or to an official gazette in" +#~ " which the notice is contained." +#~ msgstr "" +#~ "Офіційне повідомлення, що містить деталі рішення про визначення переможця. " +#~ "Це може бути посилання на документ, веб-сторінку, чи на офіційний бюлетень, " +#~ "де розміщено повідомлення." + +#~ msgid "`evaluationReports` - **Evaluation report**" +#~ msgstr "`evaluationReports` - **Звіт про оцінку**" + +#~ msgid "" +#~ "Report on the evaluation of the bids and the application of the evaluation " +#~ "criteria, including the justification fo the award." +#~ msgstr "" +#~ "Звіт про оцінку пропозицій і застосування критеріїв оцінки, у тому числі, " +#~ "обґрунтування рішення про визначення переможця." + +#~ msgid "`complaints` - **Complaints and decisions**" +#~ msgstr "`complaints` - **Скарги та рішення**" + +#~ msgid "`contractArrangements` - **Arrangements for ending contract**" +#~ msgstr "`contractArrangements` - **Заходи для припинення договору**" + +#~ msgid "`contractSchedule` - **Schedules and milestones**" +#~ msgstr "`contractSchedule` - **Розклад та етапи**" + +#~ msgid "`contractGuarantees` - **Guarantees**" +#~ msgstr "`contractGuarantees` - **Забезпечення тендерних пропозицій**" + +#~ msgid "`subContract` - **Subcontracts**" +#~ msgstr "`subContract` - **Субпідряд**" + +#~ msgid "" +#~ "Information for potential participants, describing the goals of the contract" +#~ " (e.g. goods and services to be sold), and the bidding process." +#~ msgstr "" +#~ "Інформація для потенційних учасників, що описує цілі договору (наприклад, " +#~ "товари та послуги, які будуть продані) і процес торгів." + +#~ msgid "`lot`" +#~ msgstr "`lot`" + +#~ msgid "ID of related :ref:`lot` or :ref:`item`." +#~ msgstr "Ідентифікатор пов'язаних об'єктів :ref:`lot` або :ref:`item`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/index.po b/docs/source/locale/uk/LC_MESSAGES/standard/index.po new file mode 100644 index 0000000..851404b --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/index.po @@ -0,0 +1,32 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 13:34+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/index.rst:5 +msgid "Data Standard" +msgstr "Стандарт даних" + +#: ../../source/standard/index.rst:7 +msgid "" +"Data standard is modelled along the `Open Contracting Standard " +"`_ with extensions in areas that were" +" not covered by it." +msgstr "" +"Стандарт даних змодельований згідно `Open Contracting Standard `_ з розширеннями в тих областях, які він не " +"покриває." + + diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/item.po b/docs/source/locale/uk/LC_MESSAGES/standard/item.po new file mode 100644 index 0000000..7abe7a3 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/item.po @@ -0,0 +1,224 @@ +# Zoriana Zaiats , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-10-13 17:22+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/item.rst:9 +msgid "Item" +msgstr "Item" + +#: ../../source/standard/item.rst:12 ../../source/standard/item.rst:91 +#: ../../source/standard/item.rst:128 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/item.rst:15 +msgid "string, auto-generated" +msgstr "рядок, генерується автоматично" + +#: ../../source/standard/item.rst:18 +msgid "string, multilingual, required" +msgstr "рядок, багатомовний, обов’язковий" + +#: ../../source/standard/item.rst:20 +msgid "|ocdsDescription| A description of the goods, services to be provided." +msgstr "|ocdsDescription| Опис товарів та послуг, які повинні бути надані." + +#: ../../source/standard/item.rst:26 +msgid ":ref:`Classification`" +msgstr ":ref:`Classification`" + +#: ../../source/standard/item.rst:37 +msgid "List of :ref:`Classification` objects" +msgstr "Список об’єктів :ref:`Classification`" + +#: ../../source/standard/item.rst:48 +msgid ":ref:`Unit`" +msgstr ":ref:`Unit`" + +#: ../../source/standard/item.rst:50 +msgid "" +"|ocdsDescription| Description of the unit which the good comes in e.g. " +"hours, kilograms. Made up of a unit name, and the value of a single unit." +msgstr "" +"|ocdsDescription| Опис одиниці виміру товару, наприклад, години, кілограми. " +"Складається з назви одиниці та значення однієї одиниці." + +#: ../../source/standard/item.rst:55 +msgid "integer" +msgstr "ціле число" + +#: ../../source/standard/item.rst:57 +msgid "|ocdsDescription| The number of units required" +msgstr "|ocdsDescription| Кількість необхідних одиниць." + +#: ../../source/standard/item.rst:61 +msgid ":ref:`Address`" +msgstr ":ref:`Address`" + +#: ../../source/standard/item.rst:66 +msgid "dictionary" +msgstr "словник" + +#: ../../source/standard/item.rst:71 ../../source/standard/item.rst:73 +#: ../../source/standard/item.rst:131 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/item.rst:75 +msgid "string, optional, usually not used" +msgstr "рядок, не обов’язково, переважно не використовується" + +#: ../../source/standard/item.rst:94 ../../source/standard/item.rst:103 +#: ../../source/standard/item.rst:109 ../../source/standard/item.rst:136 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/item.rst:88 +msgid "Classification" +msgstr "Classification" + +#: ../../source/standard/item.rst:96 +msgid "" +"|ocdsDescription| A classification should be drawn from an existing scheme " +"or list of codes. This field is used to indicate the scheme/codelist from " +"which the classification is drawn. For line item classifications, this " +"value should represent a known Item Classification Scheme wherever possible." +msgstr "" +"|ocdsDescription| Класифікація повинна бути взята з існуючої схеми або " +"списку кодів. Це поле використовується, щоб вказати схему/список кодів, з " +"яких буде братись класифікація. Для класифікацій лінійних елементів це " +"значення повинно представляти відому Схему Класифікації Елементів, де це " +"можливо." + +#: ../../source/standard/item.rst:105 +msgid "" +"|ocdsDescription| The classification code drawn from the selected scheme." +msgstr "|ocdsDescription| Код класифікації взятий з вибраної схеми." + +#: ../../source/standard/item.rst:111 +msgid "|ocdsDescription| A textual description or title for the code." +msgstr "|ocdsDescription| Текстовий опис або назва коду." + +#: ../../source/standard/item.rst:115 +msgid "uri" +msgstr "uri" + +#: ../../source/standard/item.rst:117 +msgid "" +"|ocdsDescription| A URI to identify the code. In the event individual URIs " +"are not available for items in the identifier scheme this value should be " +"left blank." +msgstr "" +"|ocdsDescription| URI для ідентифікації коду. Якщо індивідуальні URI не " +"доступні для елементів у схемі ідентифікації, це значення треба залишити " +"пустим." + +#: ../../source/standard/item.rst:125 +msgid "Unit" +msgstr "Unit" + +#: ../../source/standard/item.rst:133 +msgid "UN/CEFACT Recommendation 20 unit code." +msgstr "Код одиниці виміру в UN/CEFACT Recommendation 20." + +#: ../../source/standard/item.rst:138 +msgid "|ocdsDescription| Name of the unit" +msgstr "|ocdsDescription| Назва одиниці виміру" + +#: ../../source/standard/item.rst:63 +msgid "" +"Address, where the item is located. " +"Classification codes (CAV-PS) for which `item.address` object is optional are given below:" +msgstr "" +"Адреса, де розташований елемент. " +"Класифікатори (CAV-PS) для яких заповнення полів `item.address` є необов'язковим, знаходяться за посиланням нижче:" + +#: ../../source/standard/item.rst:68 +msgid "" +"Geographical coordinates of the location. Element consists of the following " +"items:" +msgstr "" +"Географічні координати місця розташування. Складається з таких компонентів:" + +#: ../../source/standard/item.rst:77 +msgid "" +"`location` usually takes precedence over `address` if both are present." +msgstr "" +"Параметр `location` зазвичай має вищий пріоритет ніж `address`, якщо вони " +"обидва вказані." + +#: ../../source/standard/item.rst:28 +msgid "" +"|ocdsDescription| The primary classification for the item. See " +"the `itemClassificationScheme` to identify preferred classification lists." +msgstr "" +"|ocdsDescription| Початкова класифікація елемента. Дивіться " +"у `itemClassificationScheme`, щоб визначити бажані списки класифікації." + +#: ../../source/standard/item.rst:32 +msgid "" +"Possible variants of available primary classifiers are CPV and CAV-PS. " +"Additionally, there is a validation for the input of these classifiers due to which " +"the accuracy of at least a class has to be used." +msgstr "" +"Класифікатори, що можуть використовуватись при заведенні закупівлі як основні, - CPV та CAV-PS. " +"Додатково здійснюється валідація введення CAV-PS та CPV з точністю не менше класу." + +#: ../../source/standard/item.rst:39 +msgid "" +"|ocdsDescription| An array of additional classifications for the item. See " +"the `itemClassificationScheme` codelist for common options to use in OCDS." +msgstr "" +"|ocdsDescription| Масив додаткових класифікацій для елемента. Дивіться у " +"список кодів `itemClassificationScheme`, щоб використати поширені варіанти в OCDS." + +msgid "Auction subject / asset description." +msgstr "Опис активу / предмету торгів" + +msgid "contractPeriod" +msgstr "contractPeriod" + +msgid "" +"The period which is used to indicate the duration of a contract within which it is valid. " +"Contract period represents the start and end date for the contract signed after the property or asset has been sold. " +"It is also can be used to specify the timeframe of a contact for a lease." +msgstr "" +"Період, що вказує на тривалість дії укладеного договору. " +"СontractPeriod ідентифікує дату початку та завершення договору, підписаного під час проведення торгів з продажу майна (активів) банку. " +"Також, contractPeriod може використовуватись для детермінування часового проміжку дії аренди." + +msgid "Additional classifier is CPVS. The property can be leased, when entering value PA01-7 " +"in the classifier CPVS field." +msgstr "Додатковим класифікатором є CPVS. Майно може бути здане в оренду, при передачі " +"значення PA01-7 в полі класифікатора CPVS." + +#~ msgid "ID of related :ref:`lot`." +#~ msgstr "ID пов’язаного :ref:`lot`." + +#~ msgid "" +#~ "|ocdsDescription| The primary classification for the item. See the " +#~ "`itemClassificationScheme` to identify preferred classification lists, " +#~ "including CPV and GSIN." +#~ msgstr "" +#~ "|ocdsDescription| Початкова класифікація елемента. Дивіться у " +#~ "`itemClassificationScheme`, щоб визначити бажані списки класифікації, " +#~ "включно з CPV та GSIN." + +#~ msgid "" +#~ "It is required for `classification.scheme` to be `CPV`. The " +#~ "`classification.id` should be valid CPV code." +#~ msgstr "" +#~ "Класифікація `classification.scheme` обов’язково повинна бути `CPV`. " +#~ "`classification.id` повинно бути дійсним CPV кодом." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/organization.po b/docs/source/locale/uk/LC_MESSAGES/standard/organization.po new file mode 100644 index 0000000..81f1e8d --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/organization.po @@ -0,0 +1,209 @@ +# +# Zoriana Zaiats , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-10-13 17:23+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/organization.rst:9 +msgid "Organization" +msgstr "Organization" + +#: ../../source/standard/organization.rst:12 +#: ../../source/standard/organization.rst:40 +#: ../../source/standard/organization.rst:89 +#: ../../source/standard/organization.rst:130 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/organization.rst:15 +#: ../../source/standard/organization.rst:64 +msgid "string, multilingual" +msgstr "рядок, багатомовний" + +#: ../../source/standard/organization.rst:20 +msgid ":ref:`Identifier`" +msgstr ":ref:`Identifier`" + +#: ../../source/standard/organization.rst:25 +msgid "List of :ref:`identifier` objects" +msgstr "Список об’єктів :ref:`identifier`" + +#: ../../source/standard/organization.rst:27 +msgid ":ref:`Address`, required" +msgstr ":ref:`Address`, обов’язково" + +#: ../../source/standard/organization.rst:29 +msgid ":ref:`ContactPoint`, required" +msgstr ":ref:`ContactPoint`, обов’язково" + +#: ../../source/standard/organization.rst:37 +msgid "Identifier" +msgstr "Identifier" + +#: ../../source/standard/organization.rst:43 +#: ../../source/standard/organization.rst:92 +#: ../../source/standard/organization.rst:98 +#: ../../source/standard/organization.rst:104 +#: ../../source/standard/organization.rst:110 +#: ../../source/standard/organization.rst:145 +#: ../../source/standard/organization.rst:151 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/organization.rst:45 +msgid "" +"|ocdsDescription| Organization identifiers be drawn from an existing " +"identification scheme. This field is used to indicate the scheme or codelist" +" in which the identifier will be found. This value should be drawn from the" +" Organization Identifier Scheme." +msgstr "" +"|ocdsDescription| Ідентифікатори організації беруться з існуючої схеми " +"ідентифікації. Це поле вказує схему або список кодів, де можна знайти " +"ідентифікатор організації. Це значення повинно братись зі Схеми " +"Ідентифікації Організацій." + +#: ../../source/standard/organization.rst:52 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/organization.rst:54 +msgid "" +"|ocdsDescription| The identifier of the organization in the selected scheme." +msgstr "|ocdsDescription| Ідентифікатор організації у вибраній схемі." + +#: ../../source/standard/organization.rst:57 +msgid "" +"The allowed codes are the ones found in `\"Organisation Registration " +"Agency\" codelist of IATI Standard " +"`_ with " +"addition of `UA-EDR` code for organizations registered in Ukraine (EDRPOU " +"and IPN)." +msgstr "" +"Дозволеними є коди зі `спику кодів \"Organisation Registration Agency\" " +"Стандарту IATI " +"`_ з " +"додаванням коду `UA-EDR` для організацій, зареєстрованих в Україні (ЄДРПОУ " +"та ІПН)." + +#: ../../source/standard/organization.rst:66 +msgid "|ocdsDescription| The legally registered name of the organization." +msgstr "|ocdsDescription| Легально зареєстрована назва організації." + +#: ../../source/standard/organization.rst:72 +msgid "uri" +msgstr "uri" + +#: ../../source/standard/organization.rst:74 +msgid "" +"|ocdsDescription| A URI to identify the organization, such as those provided" +" by Open Corporates or some other relevant URI provider. This is not for " +"listing the website of the organization: that can be done through the url " +"field of the Organization contact point." +msgstr "" +"|ocdsDescription| URI для ідентифікації організації, наприклад, ті, які " +"надають Open Corporates або інші постачальники URI. Це не для вебсайту " +"організації, його можна надати в полі url в ContactPoint організації." + +#: ../../source/standard/organization.rst:86 +msgid "Address" +msgstr "Address" + +#: ../../source/standard/organization.rst:94 +msgid "" +"|ocdsDescription| The street address. For example, 1600 Amphitheatre Pkwy." +msgstr "|ocdsDescription| Вулиця. Наприклад, вул.Хрещатик, 22." + +#: ../../source/standard/organization.rst:100 +msgid "|ocdsDescription| The locality. For example, Mountain View." +msgstr "|ocdsDescription| Населений пункт. Наприклад, Київ." + +#: ../../source/standard/organization.rst:106 +msgid "|ocdsDescription| The region. For example, CA." +msgstr "|ocdsDescription| Область. Наприклад, Київська." + +#: ../../source/standard/organization.rst:112 +msgid "|ocdsDescription| The postal code. For example, 94043." +msgstr "|ocdsDescription| Поштовий індекс, Наприклад, 78043." + +#: ../../source/standard/organization.rst:116 +#: ../../source/standard/organization.rst:133 +msgid "string, multilingual, required" +msgstr "рядок, багатомовний, обов’язковий" + +#: ../../source/standard/organization.rst:118 +msgid "|ocdsDescription| The country name. For example, United States." +msgstr "|ocdsDescription| Назва країни. Наприклад, Україна." + +#: ../../source/standard/organization.rst:127 +msgid "ContactPoint" +msgstr "ContactPoint" + +#: ../../source/standard/organization.rst:135 +msgid "" +"|ocdsDescription| The name of the contact person, department, or contact " +"point, for correspondence relating to this contracting process." +msgstr "" +"|ocdsDescription| Ім’я контактної особи, назва відділу чи контактного пункту" +" для листування, що стосується цього процесу укладання договору." + +#: ../../source/standard/organization.rst:139 +msgid "email" +msgstr "email" + +#: ../../source/standard/organization.rst:141 +msgid "|ocdsDescription| The e-mail address of the contact point/person." +msgstr "|ocdsDescription| Адреса електронної пошти контактної особи/пункту." + +#: ../../source/standard/organization.rst:147 +msgid "" +"|ocdsDescription| The telephone number of the contact point/person. This " +"should include the international dialling code." +msgstr "" +"|ocdsDescription| Номер телефону контактної особи/пункту. Повинен включати " +"міжнародний телефонний код." + +#: ../../source/standard/organization.rst:153 +msgid "" +"|ocdsDescription| The fax number of the contact point/person. This should " +"include the international dialling code." +msgstr "" +"|ocdsDescription| Номер факсу контактної особи/пункту. Повинен включати " +"міжнародний телефонний код." + +#: ../../source/standard/organization.rst:159 +msgid "|ocdsDescription| A web address for the contact point/person." +msgstr "|ocdsDescription| Веб адреса контактної особи/пункту." + +#: ../../source/standard/organization.rst:163 +msgid "Either `email` or `telephone` field has to be provided." +msgstr "" +"Повинне бути заповнене хоча б одне з полів: або `email`, або `telephone`." + +#: ../../source/standard/organization.rst:17 +msgid "Name of the organization." +msgstr "Назва організації." + +#: ../../source/standard/organization.rst:22 +msgid "The primary identifier for this organization." +msgstr "Ідентифікатор цієї організації." + +#: ../../source/standard/organization.rst:157 +msgid "URL" +msgstr "URL-адреса" + +#: ../../source/standard/organization.rst:69 +msgid "Full legal name (e.g. Nadra Bank)." +msgstr "Повна юридична назва (наприклад - “Надра Банк”)." + diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/procuringentity.po b/docs/source/locale/uk/LC_MESSAGES/standard/procuringentity.po new file mode 100644 index 0000000..44ff3c3 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/procuringentity.po @@ -0,0 +1,90 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 14:36+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/procuringentity.rst:12 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/procuringentity.rst:15 +msgid "string, multilingual" +msgstr "рядок, багатомовний" + +#: ../../source/standard/procuringentity.rst:17 +msgid "|ocdsDescription| The common name of the organization." +msgstr "|ocdsDescription| Назва організації." + +#: ../../source/standard/procuringentity.rst:21 +msgid ":ref:`Identifier`" +msgstr ":ref:`Identifier`" + +#: ../../source/standard/procuringentity.rst:23 +msgid "|ocdsDescription| The primary identifier for this organization." +msgstr "|ocdsDescription| Ідентифікатор цієї організації." + +#: ../../source/standard/procuringentity.rst:27 +msgid "List of :ref:`identifier` objects" +msgstr "Список об’єктів :ref:`identifier`" + +#: ../../source/standard/procuringentity.rst:30 +msgid ":ref:`Address`, required" +msgstr ":ref:`Address`, обов’язково" + +#: ../../source/standard/procuringentity.rst:33 +msgid ":ref:`ContactPoint`, required" +msgstr ":ref:`ContactPoint`, обов’язково" + +#: ../../source/standard/procuringentity.rst:36 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/procuringentity.rst:43 +msgid "Possible values:" +msgstr "Можливі значення:" + +#: ../../source/standard/procuringentity.rst:9 +msgid "ProcuringEntity (Organizer)" +msgstr "ProcuringEntity (Організатор)" + +#: ../../source/standard/procuringentity.rst:38 +msgid "Type of organizer" +msgstr "Тип організатора" + +#: ../../source/standard/procuringentity.rst:41 +msgid "``general`` - Organizer (general)" +msgstr "``general`` - Організатор (загальний)" + +#: ../../source/standard/procuringentity.rst:42 +msgid "" +"``special`` - Organizer that operates in certain spheres of economic " +"activity" +msgstr "" +"``special`` - Організатор, що здійснює діяльність в окремих сферах " +"господарювання" + +#: ../../source/standard/procuringentity.rst:43 +msgid "" +"``other`` - Legal persons that are not organizers in the sense of the Law, " +"but are state, utility, public enterprises, economic partnerships or " +"associations of enterprises in which state or public utility share is 50 " +"percent or more" +msgstr "" +"``other`` - Юридичні особи, які не є організаторами в розумінні Закону, але" +" є державними, комунальними, казенними підприємствами, господарськими " +"товариствами чи об'єднаннями підприємств, у яких державна чи комунальна " +"частка складає 50 і більше відсотків" + + diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/question.po b/docs/source/locale/uk/LC_MESSAGES/standard/question.po new file mode 100644 index 0000000..6fb64d8 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/question.po @@ -0,0 +1,92 @@ +# +# Zoriana Zaiats , 2016. +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-10-13 18:08+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/question.rst:7 +msgid "Question" +msgstr "Question" + +#: ../../source/standard/question.rst:10 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/question.rst:16 +msgid ":ref:`Organization`, required" +msgstr ":ref:`Organization`, обов’язково" + +#: ../../source/standard/question.rst:18 +msgid "" +"Who is asking a question (contactPoint - person, identification - " +"organization that person represents)." +msgstr "" +"Хто задає питання (contactPoint - людина, identification - організація, яку " +"ця людина представляє)." + +#: ../../source/standard/question.rst:21 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/question.rst:23 +msgid "Title of the question." +msgstr "Назва запитання." + +#: ../../source/standard/question.rst:26 ../../source/standard/question.rst:36 +#: ../../source/standard/question.rst:41 ../../source/standard/question.rst:50 +msgid "string" +msgstr "рядок" + +#: ../../source/standard/question.rst:28 +msgid "Description of the question." +msgstr "Опис запитання." + +#: ../../source/standard/question.rst:31 +msgid "string, :ref:`date`, auto-generated" +msgstr "рядок, :ref:`date`, генерується автоматично" + +#: ../../source/standard/question.rst:33 +msgid "Date of posting." +msgstr "Дата публікації." + +#: ../../source/standard/question.rst:43 +msgid "Possible values are:" +msgstr "Можливі значення:" + +#: ../../source/standard/question.rst:45 +msgid "`auction`" +msgstr "`auction`" + +#: ../../source/standard/question.rst:46 +msgid "`item`" +msgstr "`item`" + +#: ../../source/standard/question.rst:13 +msgid "UID, auto-generated" +msgstr "UID, генерується автоматично" + +#: ../../source/standard/question.rst:38 +msgid "Answer for the question." +msgstr "Відповідь на задане питання." + +#: ../../source/standard/question.rst:52 +msgid "ID of related :ref:`item`." +msgstr "Ідентифікатор пов'язаних об'єктів :ref:`item`." + +#~ msgid "`lot`" +#~ msgstr "`lot`" + +#~ msgid "ID of related :ref:`lot` or :ref:`item`." +#~ msgstr "Ідентифікатор пов'язаних об'єктів :ref:`lot` або :ref:`item`." diff --git a/docs/source/locale/uk/LC_MESSAGES/standard/util.po b/docs/source/locale/uk/LC_MESSAGES/standard/util.po new file mode 100644 index 0000000..64f0b1c --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/standard/util.po @@ -0,0 +1,100 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 14:35+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: ../../source/standard/util.rst:8 +msgid "Period" +msgstr "Period" + +#: ../../source/standard/util.rst:11 ../../source/standard/util.rst:41 +#: ../../source/standard/util.rst:67 ../../source/standard/util.rst:84 +msgid "Schema" +msgstr "Схема" + +#: ../../source/standard/util.rst:14 ../../source/standard/util.rst:20 +#: ../../source/standard/util.rst:70 +msgid "string, :ref:`date`" +msgstr "рядок, :ref:`date`" + +#: ../../source/standard/util.rst:16 +msgid "|ocdsDescription| The start date for the period." +msgstr "|ocdsDescription| Початкова дата періоду." + +#: ../../source/standard/util.rst:22 +msgid "|ocdsDescription| The end date for the period." +msgstr "|ocdsDescription| Кінцева дата періоду." + +#: ../../source/standard/util.rst:25 +msgid "`startDate` should always precede `endDate`." +msgstr "Значення `startDate` завжди повинно йти перед `endDate`." + +#: ../../source/standard/util.rst:30 +msgid "Date" +msgstr "Date" + +#: ../../source/standard/util.rst:32 +msgid "Date/time in :ref:`date-format`." +msgstr "Дата/час у :ref:`date-format`." + +#: ../../source/standard/util.rst:38 +msgid "Value" +msgstr "Value" + +#: ../../source/standard/util.rst:44 ../../source/standard/util.rst:87 +msgid "float, required" +msgstr "float, обов’язково" + +#: ../../source/standard/util.rst:46 ../../source/standard/util.rst:89 +msgid "|ocdsDescription| Amount as a number." +msgstr "|ocdsDescription| Кількість як число." + +#: ../../source/standard/util.rst:49 ../../source/standard/util.rst:92 +msgid "Should be positive." +msgstr "Повинно бути додатнім." + +#: ../../source/standard/util.rst:52 +msgid "string, required" +msgstr "рядок, обов’язковий" + +#: ../../source/standard/util.rst:54 ../../source/standard/util.rst:97 +msgid "|ocdsDescription| The currency in 3-letter ISO 4217 format." +msgstr "|ocdsDescription| Валюта у трибуквенному форматі ISO 4217." + +#: ../../source/standard/util.rst:58 +msgid "bool, required" +msgstr "булеве значення, обов’язково" + +#: ../../source/standard/util.rst:64 +msgid "Revision" +msgstr "Revision" + +#: ../../source/standard/util.rst:72 +msgid "Date when changes were recorded." +msgstr "Дата, коли зміни були записані." + +#: ../../source/standard/util.rst:75 +msgid "List of `Change` objects" +msgstr "Список об’єктів `Change`" + +#: ../../source/standard/util.rst:81 +msgid "Guarantee" +msgstr "Guarantee" + +#: ../../source/standard/util.rst:95 +msgid "string, required, default = `UAH`" +msgstr "рядок, обов’язковий, за замовчуванням = `UAH`" + + diff --git a/docs/source/locale/uk/LC_MESSAGES/tutorial.po b/docs/source/locale/uk/LC_MESSAGES/tutorial.po new file mode 100644 index 0000000..05ee640 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/tutorial.po @@ -0,0 +1,534 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-26 11:24+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Tutorial" +msgstr "Туторіал" + +msgid "Exploring basic rules" +msgstr "Базові правила" + +msgid "Let's try exploring the `/auctions` endpoint:" +msgstr "Подивимось як працює точка входу `/auctions`:" + +msgid "Just invoking it reveals empty set." +msgstr "При виклику видає пустий набір." + +msgid "Now let's attempt creating some auction:" +msgstr "Спробуймо створити новий аукціон:" + +msgid "" +"Error states that the only accepted Content-Type is `application/json`." +msgstr "" +"Помилка вказує, що єдиний прийнятний тип вмісту це `application/json`." + +msgid "Let's satisfy the Content-type requirement:" +msgstr "Задовільнимо вимогу типу вмісту:" + +msgid "Error states that no `data` has been found in JSON body." +msgstr "Помилка вказує, що `data` не знайдено у тілі JSON." + +msgid "Creating auction" +msgstr "Створення аукціону" + +msgid "" +"Let's access the URL of the created object (the `Location` header of the " +"response):" +msgstr "Використаємо URL створеного об’єкта (заголовок відповіді `Location`):" + +msgid "We can see the same response we got after creating auction." +msgstr "Ми бачимо ту ж відповідь, що і після створення аукціону." + +msgid "Let's see what listing of auctions reveals us:" +msgstr "Подивимось, що показує список аукціонів:" + +msgid "" +"The previous auction contained only required fields. Let's try creating " +"auction with more data (auction has status `created`):" +msgstr "" +"Попередній аукціон був створений лише з обов’язковими полями. Тепер додамо " +"аукціон з максимально допустимим набором даних при створенні (аукціон " +"повинен бути у статусі `created`)." + +msgid "" +"And again we have `201 Created` response code, `Location` header and body " +"with extra `id`, `auctionID`, and `dateModified` properties." +msgstr "" +"І знову код відповіді `201 Created`, заголовок `Location` і тіло з " +"додатковим `id`, `auctionID`, та властивість `dateModified`." + +msgid "Let's check what auction registry contains:" +msgstr "Перевіримо, що містить реєстр аукціонів:" + +msgid "And indeed we have 2 auctions now." +msgstr "Дійсно, в нас зараз є дві аукціони." + +msgid "Modifying auction" +msgstr "Модифікація аукціону" + +msgid "" +"Let's update auction by supplementing it with all other essential " +"properties:" +msgstr "Оновимо аукціон шляхом надання йому усіх інших важливих властивостей:" + +msgid "" +"We see the added properies have merged with existing auction data. " +"Additionally, the `dateModified` property was updated to reflect the last " +"modification datestamp." +msgstr "" +"Ми бачимо, що додаткові властивості об’єднані з існуючими даними аукціону. " +"Додатково оновлена властивість `dateModified`, щоб відображати останню дату " +"модифікації." + +msgid "Keep in mind, that every time Organizer edits the auction all bids will be switched to `invalid` status." +msgstr "Пам'ятайте, що кожного разу, коли Організатор редагує аукціон, статус всіх ставок перемикається на `invalid`." + +msgid "Bidders can reactivate their bids." +msgstr "Після цього учасники можуть наново активувати власні ставки." + +msgid "Checking the listing again reflects the new modification date:" +msgstr "Ще одна перевірка списку відображає нову дату модифікації:" + +msgid "Organizer can edit procedure only during *enquiryPeriod*." +msgstr "Організатор може редагувати аукціон тільки впродовж *enquiryPeriod*. " + +msgid "When this period ends 403 error will be returned on editing attempt:" +msgstr "Після закінчення цього періоду на спробу редагування буде повернуто помилку 403: " + +msgid "Organizer can set *enquiryPeriod.endDate*. The difference between the given date and *tenderPeriod.endDate* should not be less than 5 working days." +msgstr "Організатор має можливість встановити *enquiryPeriod.endDate*. Ця дата повинна бути не пізніша, ніж за 5 днів до *tenderPeriod.endDate*." + +msgid "If the duration between *enquiryPeriod.endDate* provided by Organizer and *tenderPeriod.endDate* is less than 5 days `422 Unprocessable Entity` response will be returned with the error message '*enquiryPeriod.endDate* should come at least 5 working days earlier than tenderPeriod.endDate.'" +msgstr "Якщо *enquiryPeriod.endDate*, яку передав Організатор, буде ближчою, ніж 5 днів до *tenderPeriod.endDate*, " +"згенерується помилка `422 Unprocessable Entity` та у JSON відповіді буде передано повідомлення " +"'*enquiryPeriod.endDate* should come at least 5 working days earlier than tenderPeriod.endDate.'" + +msgid "If Organizer does not set *enquiryPeriod.endDate* it will be calculated automatically as *tenderPeriod.endDate* minus 5 working days." +msgstr "Якщо *enquiryPeriod.endDate* не передано Організатором, кінцева дата періоду встановлюється автоматично на дату за 5 робочих днів до *tenderPeriod.endDate*." + +msgid "Uploading documentation" +msgstr "Завантаження документації" + +msgid "" +"`201 Created` response code and `Location` header confirm document creation." +" We can additionally query the `documents` collection API endpoint to " +"confirm the action:" +msgstr "" +"Код відповіді `201 Created` та заголовок `Location` підтверджують, що " +"документ було створено. Додатково можна зробити запит точки входу API " +"колекції `документів`, щоб підтвердити дію:" + +msgid "" +"The single array element describes the uploaded document. We can upload more" +" documents:" +msgstr "" +"Один елемент масиву описує завантажений документ. Ми можемо завантажити " +"більше документів:" + +msgid "And again we can confirm that there are two documents uploaded." +msgstr "І знову можна перевірити, що є два завантажених документа." + +msgid "" +"In case we made an error, we can reupload the document over the older " +"version:" +msgstr "" +"Якщо сталась помилка, ми можемо ще раз завантажити документ поверх старої " +"версії:" + +msgid "And we can see that it is overriding the original version:" +msgstr "І ми бачимо, що вона перекриває оригінальну версію:" + +msgid "Enquiries" +msgstr "Уточнення (питання)" + +msgid "" +"When auction is in `active.tendering` status, interested parties can ask " +"questions:" +msgstr "" +"Коли закупівля має статус `active.tendering`, зацікавлені сторони можуть " +"задавати питання:" + +msgid "Registering bid" +msgstr "Реєстрація пропозиції" + +msgid "Bidder can register a bid in `draft` status:" +msgstr "Учасник може зареєструвати пропозицію у статусі `draft` (чернетка):" + +msgid "And activate a bid:" +msgstr "І активувати пропозицію:" + +msgid "And upload proposal document:" +msgstr "І завантажити документ пропозиції:" + +msgid "It is possible to check the uploaded documents:" +msgstr "Можна перевірити завантажені документи:" + +msgid "Auction" +msgstr "Аукціон" + +msgid "" +"After auction is scheduled anybody can visit it to watch. The auction can be" +" reached at `Auction.auctionUrl`:" +msgstr "" +"Після того, як аукціон заплановано, будь-хто може його відвідати для " +"перегляду. Аукціон можна подивитись за допомогою `Auction.auctionUrl`:" + +msgid "And bidders can find out their participation URLs via their bids:" +msgstr "" +"Учасники можуть дізнатись свої URL-адреси для участі через свої пропозиції:" + +msgid "" +"See the `Bid.participationUrl` in the response. Similar, but different, URL " +"can be retrieved for other participants:" +msgstr "" +"Дивіться на `Bid.participationUrl` у відповіді. Схожу, але іншу, URL-адресу " +"можна отримати для інших учасників." + +msgid "Uploading contract documentation" +msgstr "Завантаження документів щодо укладання угоди" + +msgid "You can upload contract documents. Let's upload contract document:" +msgstr "Спробуємо завантажити документ пов’язаний з угодою:" + +msgid "Let's see the list of contract documents:" +msgstr "Переглянемо список завантажених документів:" + +msgid "We can add another contract document:" +msgstr "Тепер спробуємо додати ще один документ щодо укладанням угоди:" + +msgid "Let's see the list of all added contract documents:" +msgstr "Тепер переглянемо знову усі документи пов’язані із укладанням угоди:" + +msgid "Contract registration" +msgstr "Реєстрація угоди" + +msgid "Cancelling auction" +msgstr "Скасування закупівлі" + +msgid "The following steps should be applied:" +msgstr "Для цього потрібно виконати наступні кроки:" + +msgid "Cancel the auction with the reasons prepared." +msgstr "Скасуйте закупівлю через подані причини" + +msgid "" +"Only the request that has been activated (3rd step above) has power to " +"cancel auction. I.e. you have to not only prepare cancellation request but" +" to activate it as well." +msgstr "" +"Запит на скасування, який не пройшов активації (3-й крок), не матиме сили, " +"тобто, для скасування закупівлі буде обов’язковим не тільки створити заявку," +" але і активувати її." + +msgid "See :ref:`cancellation` data structure for details." +msgstr "" +"Див. структуру запиту :ref:`cancellation` для більш детальної інформації." + +msgid "Preparing the cancellation request" +msgstr "Формування запиту на скасування" + +msgid "" +"You should pass `reason`, `status` defaults to `pending`. `id` is " +"autogenerated and passed in the `Location` header of response." +msgstr "" +"Ви повинні передати змінні `reason`, `status` у стані `pending`. `id` " +"генерується автоматично і повертається у додатковому заголовку відповіді " +"`Location`:" + +msgid "Filling cancellation with protocol and supplementary documentation" +msgstr "Наповнення протоколом та іншою супровідною документацією" + +msgid "Activating the request and cancelling auction" +msgstr "Активація запиту та скасування аукціону" + +msgid "" +"Organizer can upload PDF files into the created auction. Uploading should " +"follow the :ref:`upload` rules." +msgstr "" +"Замовник може завантажити PDF файл у створений аукціон. Завантаження повинно" +" відбуватись згідно правил :ref:`upload`." + +msgid "Organizer can answer them:" +msgstr "Організатор може на них відповісти:" + +msgid "" +"We do see the auction's internal `id` (that can be used to construct full " +"URL by prepending `https://api-" +"sandbox.ea.openprocurement.org/api/0/auctions/`) and its `dateModified` " +"datestamp." +msgstr "" +"Ми бачимо внутрішнє `id` аукціону (що може бути використано для побудови " +"повної URL-адреси, якщо додати `http://api-" +"sandbox.openprocurement.org/api/0/auctions/`) та його `dateModified` дату." + +msgid "" +"Let's create auction with the minimal data set (only required properties):" +msgstr "" +"Створимо аукціон з мінімально допустимим набором даних (тільки параметри " +"обовязкові для заповнення) :" + +msgid "" +"Success! Now we can see that new object has been created. Response code is " +"`201` and `Location` response header reports the location of the created " +"object. The body of response reveals the information about the created " +"auction: its internal `id` (that matches the `Location` segment), its " +"official `auctionID` and `dateModified` datestamp stating the moment in time" +" when auction has been last modified. Pay attention to the " +"`procurementMethodType`. Note that auction is created with " +"`active.tendering` status." +msgstr "" +"Успіх! Тепер ми бачимо, що новий об’єкт було створено. Код відповіді `201` " +"та заголовок відповіді `Location` вказує місцерозташування створеного " +"об’єкта. Тіло відповіді показує інформацію про створений аукціон, його " +"внутрішнє `id` (яке співпадає з сегментом `Location`), його офіційне " +"`auctionID` та `dateModified` дату, що показує час, коли аукціон востаннє " +"модифікувався. Зверніть увагу на `procurementMethodType`, а також на те, що " +"аукціон створюється зі статусом `active.tendering`." + +msgid "Keep in mind that `tenderPeriod` must be at least 7 calendar days." +msgstr "" +"Пам'ятайте, що `tenderPeriod` має складати щонайменше 7 календарних днів." + +msgid "" +"When `auctionPeriod.startDate` has an incorrect date, 422 Unprocessable " +"Entity error is raised and \"tenderPeriod should be greater than 6 days\" " +"message is returned in JSON response." +msgstr "" +"Якщо у `auctionPeriod.startDate` передано некоректну дату, генерується " +"помилка `422` `Unprocessable Entity` та у JSON відповіді повертається " +"повідомлення \"tenderPeriod should be greater than 6 days\"." + +msgid "" +"Let's set `auctionPeriod.startDate` to `now + timedelta(days=6)` and " +"ValidationError will be returned:" +msgstr "" +"Встановимо `auctionPeriod.startDate` у значення `now + timedelta(days=6)` - " +"у відповідь ми отримаємо помилку `ValidationError`." + +msgid "And one can retrieve the question list:" +msgstr "Можна отримати список запитань:" + +msgid "Or an individual answer:" +msgstr "або окрему відповідь:" + +msgid "" +"For the best effect (biggest economy) auction should have multiple bidders " +"registered:" +msgstr "" +"Для найкращого результату (найбільшої економії) аукціон повинен мати багато " +"зареєстрованих учасників." + +msgid "" +"`201 Created` response code and `Location` header confirm that document has " +"been added." +msgstr "" +"Код відповіді `201 Created` та заголовок `Location` підтверджують, що " +"документ додано." + +msgid "" +"`201 Created` response code and `Location` header confirm that the second " +"document has been uploaded." +msgstr "" +"Код відповіді `201 Created` та заголовок `Location` підтверджують, що ще " +"один документ було додано." + +msgid "Prepare cancellation request." +msgstr "Приготуйте запит на скасування." + +msgid "Fill it with the protocol describing the cancellation reasons." +msgstr "Наповніть його протоколом про причини скасування." + +msgid "Upload the file contents:" +msgstr "Завантаження вмісту файлу:" + +msgid "Change the document description and other properties:" +msgstr "Зміна опису документа та інших властивостей:" + +msgid "Upload new version of the document:" +msgstr "Завантаження нової версії документа:" + +msgid "Qualification" +msgstr "Кваліфікація" + +msgid "Confirming qualification" +msgstr "Підтвердження кваліфікації" + +msgid "Signing contract" +msgstr "Підписання угоди" + +msgid "" +"There is a possibility to set custom contract signature date. If the date is" +" not set it will be generated on contract registration. You can register " +"contract:" +msgstr "" +"Є можливість встановити дату підписання договору. Якщо дата не встановлена, " +"то вона буде згенерована під час реєстрації угоди. Ви можете зареєструвати " +"угоду:" + +msgid "Uploading illustration" +msgstr "Завантаження ілюстрації" + +msgid "" +"Organizer can upload illustration files into the created auction. Uploading " +"should follow the :ref:`upload` rules." +msgstr "" +"Організатор може завантажити файли з ілюстраціями у створений аукціон. " +"Завантаження повинно відповідати правилам :ref:`upload`." + +msgid "We can check whether illustration is uploaded." +msgstr "Ми можемо перевірити, чи завантажилась ілюстрація." + +msgid "And disqualify candidate:" +msgstr "Та дискваліфікувати кандидата:" + +msgid "" +"In order to specify illustration display order, `index` field can be used " +"(for details see :ref:`document`). Since this illustration should be " +"displayed first, it has ``\"index\": 1``." +msgstr "" +"Для того, щоб вказати порядок відображення ілюстрацій, використовується поле" +" `index` (див. :ref:`document`). Оскільки ця ілюстрація повинна бути " +"відображена першою, то вказується ``\"index\": 1``." + +msgid "" +"Organizer can upload second illustration. This illustration should be " +"displayed second, so it has ``\"index\": 2``." +msgstr "" +"Організатор може завантажити ще одну ілюстрацію. Ця ілюстрація повинна бути " +"відображена другою, тому має параметр ``\"index\": 2``." + +msgid "Add third illustration:" +msgstr "Додаємо третю ілюстрацію:" + +msgid "" +"Note that `index` of the third illustration is the same as for the second " +"illustration: ``\"index\": 2``. In such cases firstly will be displayed " +"illustration that was uploaded earlier." +msgstr "" +"Зверніть увагу, що параметр `index` третьої ілюстрації такий же як і у " +"другої: ``\"index\": 2``. У таких випадках спочатку відображатиметься " +"ілюстрація з ранішою датою публікації." + +msgid "We can check that there are three uploaded illustrations." +msgstr "Можемо перевірити, що є три завантажені ілюстрації." + +msgid "Add Asset Familiarization" +msgstr "" + +msgid "" +"Organizer can upload asset familiarization document into the created " +"auction." +msgstr "" + +msgid "We can check whether asset familiarization document is added." +msgstr "" + +msgid "After the competitive auction `awards` are created:" +msgstr "Після аукціону створюються `awards`:" + +msgid "" +"for the first candidate (a participant that has submitted the highest bid at" +" the auction) - initially has a `pending.verification` status and awaits " +"auction protocol to be uploaded by the organizer;" +msgstr "" +"перший кандидат (учасник, який поставив найвищу ставку на аукціоні) - " +"спочатку перебуває у статусі `pending.verification` і очікує, поки " +"Організатор завантажить протокол аукціону." + +msgid "for the rest of the candidates." +msgstr "інші кандидати." + +msgid "" +"The organizer **must** upload and confirm the auction protocol " +"`auctionProtocol` and add it to the award within **6 business days after the" +" start of the qualification procedure**. The candidate still has a " +"possibility to upload the protocol, but it is neither mandatory, nor " +"sufficient to move to the next status. In order to switch `award` to the " +"next status, Organizer should come and change its status manually." +msgstr "" +"Організатор має завантажити та підтвердити протокол аукціону " +"`auctionProtocol` і додати його в award протягом **6 робочих днів після " +"початку періоду кваліфікації**. Кандидат має можливість завантажити " +"протокол, але це є необов'язковим і недостатнім для переходу в наступний " +"статус. Для того, щоб перевести `award` в наступний статус, Організатор має " +"змінити його вручну." + +msgid "" +"It is the Organizer's duty to upload and confirm the protocol, although the " +"award will not be switched to the status 'pending.payment' automatically." +msgstr "" +"Обов'язком Організатора є завантаження та затвердження протоколу при тому, " +"що `award` не перейде в статус 'pending.payment' автоматично." + +msgid "" +"Within **20 business days after becoming a candidate** he/she must provide " +"payment and Organizer has the same time to confirm the payment. After the " +"payment was received, Organizer can optionally switch the award's status to " +"`active`." +msgstr "" +"Протягом **20 робочих днів після оголошення учасника кандидатом** він/вона " +"має провести оплату й Організатор має підтвердити оплату. Коли платіж " +"отримано, Організатор може перевести `award` в статус `active`, але ця дія " +"не є обов'язковою." + +msgid "Disqualification of a candidate" +msgstr "Дискваліфікація кандидата" + +msgid "" +"In case of manual disqualification, the organizer has to upload file with " +"cancellation reason:" +msgstr "" +"У випадаку ручної дискваліфікації, Організатор має завантажити документ з " +"причинами: " + +msgid "" +"Within 20 business days since becoming candidate a new candidate must " +"confirm qualification with steps described above (:ref:`Qualification`)." +msgstr "" +"Через 20 робочих днів після того, як став кандидатом, новий кандидат має " +"підтвердити кваліфікацію за допомогою кроків, описаних вище " +"(:ref:`Qualification`)." + +msgid "Refusal of waiting by another participant" +msgstr "Відмова очікування іншого учасника" + +msgid "" +"Organizer can cancel auction anytime (except when auction has terminal " +"status e.g. `unsuccesfull`, `canceled`, `complete`)." +msgstr "" +"Організатор може скасувати аукціон будь-коли (крім тих випадків, коли " +"аукціон перебуває в термінальному статусі, наприклад, `unsuccesfull`, " +"`canceled`, `complete`)." + +msgid "" +"The rest of the candidates can refuse to wait for the disqualification of " +"the first candidate:" +msgstr "" +"Решта кандидатів можуть відомовитись чекати на дискваліфікацію першого " +"кандидата:" + +msgid "" +"The candidate has **20 business days after becoming a candidate** to " +"conclude a contract with the bank based on the results of electronic " +"auction. When the organizer confirms that the payment has been received, the" +" `award` may be switched to the `active` status (`signingPeriod` of the " +"procedure). Within this stage the organizer should upload and activate the " +"contract in the system." +msgstr "" +"Кандидат має **20 робочих днів після того, як став кандидатом,** укласти " +"договір з банком за результатами електронного аукціону. Після того, як " +"Організатор підтвердить платіж кандидата (на вибір), `award` перейде в статус " +"`active` (singingPeriod для процедури). Протягом цього часу " +"Організатор має завантажити та активувати контракт у системі." diff --git a/docs/source/locale/uk/LC_MESSAGES/upload.po b/docs/source/locale/uk/LC_MESSAGES/upload.po new file mode 100644 index 0000000..f658201 --- /dev/null +++ b/docs/source/locale/uk/LC_MESSAGES/upload.po @@ -0,0 +1,54 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: openprocurement.auctions.dgf 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-12 15:36+0300\n" +"PO-Revision-Date: 2016-09-15 13:24+0200\n" +"Last-Translator: Zoriana Zaiats \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 2.0\n" + +msgid "Documents Uploading" +msgstr "Завантаження документа" + +msgid "" +"All of the document uploading API endpoints follow the same set of rules." +msgstr "" +"Всі точки входу API для завантаження документів застосовують однакові " +"правила." + +msgid "Upload document with registration" +msgstr "Зареєструвати завантаження документа" + +msgid "" +":ref:`Register document upload in document service `." +msgstr "" +":ref:`Зареєструвати завантаження документа `." + +msgid "Add document in API:" +msgstr "Додати документ в API:" + +msgid "" +":ref:`Upload document in document service `." +msgstr "" +":ref:`Завантажити документ в document service `." + +msgid "Upload document without registration" +msgstr "Завантажити документ без реєстрації" + +msgid "" +":ref:`Upload document without registration `." +msgstr "" +":ref:`Завантажити документ без реєстрації `." diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 0000000..7c8cf6f --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,95 @@ +Overview +======== + +openprocurement.auctions.dgf contains documentaion for Deposit Guarantee Fund auctions. + +There are two procedures: + + * dgfOtherAssets - sale of the insolvent bank property. + + * dgfFinancialAssets - sale of the creditor claim right. + + +Features +-------- + +* The only date Organizer has to provide is *Tender.auctionPeriod.startDate*, the rest will be calculated automatically. +* Optionally Organizer can set *enquiryPeriod.endDate*. +* If *enquiryPeriod.endDate* is not provided it will be calculated automatically. +* Organizer can both increase and decrease `value.amount`, `guarantee.amount`, `minimalStep.amount`. +* `tenderPeriod` must be at least 7 calendar days. +* Organizer can edit procedure only during *rectificationPeriod*. +* Organizer can add and edit documents only during *rectificationPeriod*. +* As soon as the action is edited, the status of all of the submitted bids will be switched to `invalid`. +* Procedure can be switched from *draft* status to *active.tendering*. +* During *active.tendering* period participants can ask questions, submit proposals, and upload documents. +* There is obligatory participant qualification (*Bid.selfQualified*) via guarantee payment. +* The only currency (*Value.currency*) for this procedure is hryvnia (UAH). +* The items within an auction are allowed to be from different CAV groups. + +Conventions +----------- + +API accepts `JSON `_ or form-encoded content in +requests. It returns JSON content in all of its responses, including +errors. Only the UTF-8 character encoding is supported for both requests +and responses. + +All API POST and PUT requests expect a top-level object with a single +element in it named `data`. Successful responses will mirror this format. +The data element should itself be an object, containing the parameters for +the request. In the case of creating a new auction, these are the fields we +want to set on the auction itself. + +If the request was successful, we will get a response code of `201` +indicating the object was created. That response will have a data field at +its top level, which will contain complete information on the new auction, +including its ID. + +If something went wrong during the request, we'll get a different status +code and the JSON returned will have an `errors` field at the top level +containing a list of problems. We look at the first one and print out its +message. + +Main responsibilities +--------------------- + +Business logic +-------------- + +Project status +-------------- + +The project has pre alpha status. + +The source repository for this project is on GitHub: https://github.com/openprocurement/openprocurement.auctions.dgf + +You can leave feedback by raising a new issue on the `issue tracker +`_ (GitHub +registration necessary). + +Documentation of related packages +--------------------------------- + +* `OpenProcurement API `_ + +API stability +------------- + +API is highly unstable, and while API endpoints are expected to remain +relatively stable the data exchange formats are expected to be changed a +lot. The changes in the API are communicated via `Open Procurement API +`_ maillist. + +Change log +---------- + +0.1 +~~~ + +Released: not released + + +Next steps +---------- +You might find it helpful to look at the :ref:`tutorial`. diff --git a/docs/source/qualification/award-active-cancel-disqualify.http b/docs/source/qualification/award-active-cancel-disqualify.http new file mode 100644 index 0000000..1b681dd --- /dev/null +++ b/docs/source/qualification/award-active-cancel-disqualify.http @@ -0,0 +1,74 @@ +PATCH /api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/ad468ef737c34ac2b2ae65a80b2ca8e1?acc_token=9575071a6c92489782d67ec29cbcc30f HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 146 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "unsuccessful", + "description": "Candidate didn’t sign the auction protocol in 3 business days", + "title": "Disqualified" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/9d25afbaccdb43b7b0de63e172fa9437 + +{ + "data": { + "status": "unsuccessful", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/eebd2b6d4c7b4e1497dcbf6b1791585a?KeyID=18f3f87d&Signature=NH89p3ErX15HXsSQldd2va7q1Qz6coZnuMgw5tpE7dWXLoXh5M5oEAGNTMRXS%252B9uzvEEMPI1Tv%2FZTMg6YhRBDQ%253D%253D", + "title": "Disqualified_reason.pdf", + "documentOf": "tender", + "datePublished": "2017-03-29T15:47:31.285744+03:00", + "dateModified": "2017-03-29T15:47:31.285770+03:00", + "id": "76a5b88495ea4ee6a777c5ce9d9d2d37" + } + ], + "description": "Candidate didn’t sign the auction protocol in 3 business days", + "complaintPeriod": { + "startDate": "2017-03-29T15:47:31.134325+03:00", + "endDate": "2017-03-29T15:47:31.417212+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "title": "Disqualified", + "bid_id": "9dba89da1a4b4a179940243cda57bb7a", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-03-29T15:47:31.432934+03:00", + "id": "ad468ef737c34ac2b2ae65a80b2ca8e1" + } +} + diff --git a/docs/source/qualification/award-active-cancel-upload.http b/docs/source/qualification/award-active-cancel-upload.http new file mode 100644 index 0000000..dac4dcb --- /dev/null +++ b/docs/source/qualification/award-active-cancel-upload.http @@ -0,0 +1,35 @@ +POST /api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/ad468ef737c34ac2b2ae65a80b2ca8e1/documents?acc_token=9575071a6c92489782d67ec29cbcc30f HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 384 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/eebd2b6d4c7b4e1497dcbf6b1791585a?KeyID=18f3f87d&Signature=z7WjUFfhIWueIQVv9vBzcE%2FX2HlEAnfPwVEGhASkoPMb2F8ddBmupq9UeDjJaA3Mufs%2FwW23te0ROWICx53tCg%3D%3D", + "title": "Disqualified_reason.pdf", + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/ad468ef737c34ac2b2ae65a80b2ca8e1/documents/76a5b88495ea4ee6a777c5ce9d9d2d37 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/eebd2b6d4c7b4e1497dcbf6b1791585a?KeyID=18f3f87d&Signature=NH89p3ErX15HXsSQldd2va7q1Qz6coZnuMgw5tpE7dWXLoXh5M5oEAGNTMRXS%252B9uzvEEMPI1Tv%2FZTMg6YhRBDQ%253D%253D", + "title": "Disqualified_reason.pdf", + "documentOf": "tender", + "datePublished": "2017-03-29T15:47:31.285744+03:00", + "dateModified": "2017-03-29T15:47:31.285770+03:00", + "id": "76a5b88495ea4ee6a777c5ce9d9d2d37" + } +} + diff --git a/docs/source/qualification/award-active-cancel.http b/docs/source/qualification/award-active-cancel.http new file mode 100644 index 0000000..0632a82 --- /dev/null +++ b/docs/source/qualification/award-active-cancel.http @@ -0,0 +1,57 @@ +PATCH /api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/2361d4a5feeb4b51b401ed0941d79d2b?acc_token=9575071a6c92489782d67ec29cbcc30f HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 33 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "cancelled" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/e697023cacc24697a8d03c234753bbd0/awards/ad468ef737c34ac2b2ae65a80b2ca8e1 + +{ + "data": { + "status": "cancelled", + "complaintPeriod": { + "startDate": "2017-03-29T15:47:30.888919+03:00", + "endDate": "2017-03-29T15:47:31.021223+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "9dba89da1a4b4a179940243cda57bb7a", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-03-29T15:47:31.142649+03:00", + "id": "2361d4a5feeb4b51b401ed0941d79d2b" + } +} + diff --git a/docs/source/qualification/award-active-disqualify.http b/docs/source/qualification/award-active-disqualify.http new file mode 100644 index 0000000..2ca18ed --- /dev/null +++ b/docs/source/qualification/award-active-disqualify.http @@ -0,0 +1,99 @@ +PATCH /api/2.3/auctions/9ccb1169681a4b9a814a70faa17b1d96/awards/d8337e5253024539ad07414008d58913?acc_token=ebb7d8c3a9bb49628b630721b2ff2fee HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 146 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "unsuccessful", + "description": "Candidate didn’t sign the auction protocol in 3 business days", + "title": "Disqualified" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/9ccb1169681a4b9a814a70faa17b1d96/awards/00fb536c33254038ae8034d3e10a6ee8 + +{ + "data": { + "status": "unsuccessful", + "paymentPeriod": { + "startDate": "2017-11-30T16:56:22.318120+02:00", + "endDate": "2017-11-30T16:56:22.787355+02:00" + }, + "documents": [ + { + "dateModified": "2017-11-30T16:56:22.492463+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/c93c3c57873e4c39b205730e7168c9a7?KeyID=abd28e21&Signature=h5sEpdO0WwgNvLznoP73EevycNuLkysJ5fCrl5di6ZItM2rmLGrMYQSN6Lxu%252BdT9VNI1SXrim1MLa9%2F050blAw%253D%253D", + "author": "bid_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:22.492435+02:00", + "documentType": "auctionProtocol", + "title": "auction_protocol.pdf", + "id": "4fee5118ccf84458833fb9f9bcc0e09e" + }, + { + "dateModified": "2017-11-30T16:56:22.626178+02:00", + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "author": "auction_owner", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b4b306e1106b4bfa9c94727106b0bf6e?KeyID=abd28e21&Signature=KwbVPZXVni%252B%2FUN0hhgWEjKSV8ZFB4hmlD%252BfYQrN7Iwd6WEv7elzrwbEzDIV97WLu%252BNJPOKJgmFrN1Gpkrx6xDA%253D%253D", + "format": "application/pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:22.626152+02:00", + "title": "Disqualified_reason.pdf", + "id": "79ac5290dfb94bd0bedeebbf92201e14" + } + ], + "verificationPeriod": { + "startDate": "2017-11-30T16:56:22.318120+02:00", + "endDate": "2017-11-30T16:56:22.787355+02:00" + }, + "description": "Candidate didn’t sign the auction protocol in 3 business days", + "title": "Disqualified", + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "complaintPeriod": { + "startDate": "2017-11-30T16:56:21.878582+02:00", + "endDate": "2017-11-30T16:56:22.787355+02:00" + }, + "bid_id": "0bf6b005db2a4069898facc0892d3701", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:22.796624+02:00", + "id": "d8337e5253024539ad07414008d58913", + "signingPeriod": { + "startDate": "2017-11-30T16:56:22.318120+02:00", + "endDate": "2017-11-30T16:56:22.787355+02:00" + } + } +} + diff --git a/docs/source/qualification/award-active-get.http b/docs/source/qualification/award-active-get.http new file mode 100644 index 0000000..da82cc7 --- /dev/null +++ b/docs/source/qualification/award-active-get.http @@ -0,0 +1,48 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/153fcdbbcfd64ab38b2279cc474787f8 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.102502+03:00", + "endDate": "2016-09-20T16:17:47.350460+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.360413+03:00", + "id": "153fcdbbcfd64ab38b2279cc474787f8" + } +} + diff --git a/docs/source/qualification/award-active-unsuccessful-upload.http b/docs/source/qualification/award-active-unsuccessful-upload.http new file mode 100644 index 0000000..90e95a8 --- /dev/null +++ b/docs/source/qualification/award-active-unsuccessful-upload.http @@ -0,0 +1,36 @@ +POST /api/2.3/auctions/9ccb1169681a4b9a814a70faa17b1d96/awards/d8337e5253024539ad07414008d58913/documents?acc_token=ebb7d8c3a9bb49628b630721b2ff2fee HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 386 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b4b306e1106b4bfa9c94727106b0bf6e?KeyID=abd28e21&Signature=ri55p6U9BbZIaDsRALjXGihRUGfb7%2BDQJPiv7GjLpfOQRqR2xUQ%2B3gYD8sgnQGJXevhGM6B877t0lFe%2BuqZXDw%3D%3D", + "title": "Disqualified_reason.pdf", + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/9ccb1169681a4b9a814a70faa17b1d96/awards/d8337e5253024539ad07414008d58913/documents/79ac5290dfb94bd0bedeebbf92201e14 + +{ + "data": { + "dateModified": "2017-11-30T16:56:22.626178+02:00", + "hash": "md5:00000000000000000000000000000000", + "description": "Disqualification reason", + "author": "auction_owner", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b4b306e1106b4bfa9c94727106b0bf6e?KeyID=abd28e21&Signature=KwbVPZXVni%252B%2FUN0hhgWEjKSV8ZFB4hmlD%252BfYQrN7Iwd6WEv7elzrwbEzDIV97WLu%252BNJPOKJgmFrN1Gpkrx6xDA%253D%253D", + "format": "application/pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:22.626152+02:00", + "title": "Disqualified_reason.pdf", + "id": "79ac5290dfb94bd0bedeebbf92201e14" + } +} + diff --git a/docs/source/qualification/award-pending-active.http b/docs/source/qualification/award-pending-active.http new file mode 100644 index 0000000..3f624c6 --- /dev/null +++ b/docs/source/qualification/award-pending-active.http @@ -0,0 +1,56 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/153fcdbbcfd64ab38b2279cc474787f8?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 30 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.102502+03:00", + "endDate": "2016-09-20T16:17:47.350460+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.360413+03:00", + "id": "153fcdbbcfd64ab38b2279cc474787f8" + } +} + diff --git a/docs/source/qualification/award-pending-unsuccessful.http b/docs/source/qualification/award-pending-unsuccessful.http new file mode 100644 index 0000000..e861085 --- /dev/null +++ b/docs/source/qualification/award-pending-unsuccessful.http @@ -0,0 +1,68 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 36 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "unsuccessful" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/153fcdbbcfd64ab38b2279cc474787f8 + +{ + "data": { + "status": "unsuccessful", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=GSt%2FNNdHL%252BgkEhjgxHCBjmWNNVMei%2FQA%252BZ65LBLXAxaZbYdfeLDwfvaGA0Wi%2FwCkAczFZKDsUkK0m5NItNxtDQ%253D%253D", + "title": "Unsuccessful_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:46.934420+03:00", + "dateModified": "2016-09-16T16:17:46.934449+03:00", + "id": "b52b77a5e21b4f7cafd0c9f44ca7932f" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:46.702347+03:00", + "endDate": "2016-09-20T16:17:47.101766+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.113324+03:00", + "id": "0be2b9c4dc4b43a8a203b239d726a74f" + } +} + diff --git a/docs/source/qualification/award-pending-upload.http b/docs/source/qualification/award-pending-upload.http new file mode 100644 index 0000000..f790fdf --- /dev/null +++ b/docs/source/qualification/award-pending-upload.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/documents?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 344 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=xuIgYzql%2By8kTVjeTDgkirEqWHJXVgwjw17fzyw3vmwlejlibzdpjPJyDqKEm6E0xilYrz%2Fq%2FSe4oeTMnF2DCg%3D%3D", + "title": "Unsuccessful_Reason.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f/documents/b52b77a5e21b4f7cafd0c9f44ca7932f + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=GSt%2FNNdHL%252BgkEhjgxHCBjmWNNVMei%2FQA%252BZ65LBLXAxaZbYdfeLDwfvaGA0Wi%2FwCkAczFZKDsUkK0m5NItNxtDQ%253D%253D", + "title": "Unsuccessful_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:46.934420+03:00", + "dateModified": "2016-09-16T16:17:46.934449+03:00", + "id": "b52b77a5e21b4f7cafd0c9f44ca7932f" + } +} + diff --git a/docs/source/qualification/award-unsuccessful-cancel.http b/docs/source/qualification/award-unsuccessful-cancel.http new file mode 100644 index 0000000..350c42f --- /dev/null +++ b/docs/source/qualification/award-unsuccessful-cancel.http @@ -0,0 +1,240 @@ +PATCH /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/0be2b9c4dc4b43a8a203b239d726a74f?acc_token=fa248967de2244439451050d2499166d HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 33 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "cancelled" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards/f61c70311cfd453687654723e3a333b6 + +{ + "data": { + "status": "cancelled", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=GSt%2FNNdHL%252BgkEhjgxHCBjmWNNVMei%2FQA%252BZ65LBLXAxaZbYdfeLDwfvaGA0Wi%2FwCkAczFZKDsUkK0m5NItNxtDQ%253D%253D", + "title": "Unsuccessful_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:46.934420+03:00", + "dateModified": "2016-09-16T16:17:46.934449+03:00", + "id": "b52b77a5e21b4f7cafd0c9f44ca7932f" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:46.702347+03:00", + "endDate": "2016-09-16T16:17:53.699559+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:53.717039+03:00", + "complaints": [ + { + "status": "resolved", + "tendererActionDate": "2016-09-16T16:17:49.565691+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": true, + "id": "cf9360b712ac479ea06d6c606c9db8d1", + "dateAnswered": "2016-09-16T16:17:49.565661+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:49.849593+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ] + }, + { + "status": "invalid", + "dateDecision": "2016-09-16T16:17:50.645131+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:50.369724+03:00", + "dateAnswered": "2016-09-16T16:17:50.099347+03:00", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:50.659654+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + }, + { + "status": "resolved", + "dateDecision": "2016-09-16T16:17:52.929570+03:00", + "documents": [ + { + "dateModified": "2016-09-16T16:17:52.615704+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=e3moEZBo6gWiPI9UAheRHa1w%2FLkWmIs1mj%2FmiMip%252BKzgLNyzIGNpShGzJ9NJOfFzh1SDbsUBIXhFoOomCGB6Dw%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:52.615675+03:00", + "title": "ComplaintResolution.pdf", + "id": "ee0fbfdd6e2e4f24b7483cbc8383b520" + } + ], + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:51.456780+03:00", + "dateAnswered": "2016-09-16T16:17:51.175990+03:00", + "dateSubmitted": "2016-09-16T16:17:50.911841+03:00", + "complaintID": "UA-EA-2016-09-16-000001.7", + "date": "2016-09-16T16:17:52.943580+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "fe684319f9dd417fa680a252363f67aa" + }, + { + "status": "declined", + "dateDecision": "2016-09-16T16:17:53.230797+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:52.345519+03:00", + "dateAnswered": "2016-09-16T16:17:52.060798+03:00", + "dateSubmitted": "2016-09-16T16:17:51.765641+03:00", + "complaintID": "UA-EA-2016-09-16-000001.8", + "date": "2016-09-16T16:17:53.245306+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "b7534a5af3b74f028355f2de973fd25b" + } + ], + "id": "0be2b9c4dc4b43a8a203b239d726a74f" + } +} + diff --git a/docs/source/qualification/award-waiting-cancel.http b/docs/source/qualification/award-waiting-cancel.http new file mode 100644 index 0000000..b702f53 --- /dev/null +++ b/docs/source/qualification/award-waiting-cancel.http @@ -0,0 +1,56 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/14f4c1774be847098f247565c4871574?acc_token=a94a2b6627aa46f3bbb83ff885e3beae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 33 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "cancelled" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "cancelled", + "complaintPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:56:27.920508+02:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "afaa508128da4829b9202fe300965bf4", + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:27.927179+02:00", + "id": "14f4c1774be847098f247565c4871574" + } +} + diff --git a/docs/source/qualification/awards-get.http b/docs/source/qualification/awards-get.http new file mode 100644 index 0000000..17f311e --- /dev/null +++ b/docs/source/qualification/awards-get.http @@ -0,0 +1,48 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "pending", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:46.702347+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:46.702331+03:00", + "id": "0be2b9c4dc4b43a8a203b239d726a74f" + } + ] +} + diff --git a/docs/source/qualification/awards-unsuccessful-get1.http b/docs/source/qualification/awards-unsuccessful-get1.http new file mode 100644 index 0000000..0ad8559 --- /dev/null +++ b/docs/source/qualification/awards-unsuccessful-get1.http @@ -0,0 +1,354 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "unsuccessful", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=GSt%2FNNdHL%252BgkEhjgxHCBjmWNNVMei%2FQA%252BZ65LBLXAxaZbYdfeLDwfvaGA0Wi%2FwCkAczFZKDsUkK0m5NItNxtDQ%253D%253D", + "title": "Unsuccessful_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:46.934420+03:00", + "dateModified": "2016-09-16T16:17:46.934449+03:00", + "id": "b52b77a5e21b4f7cafd0c9f44ca7932f" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:46.702347+03:00", + "endDate": "2016-09-20T16:17:47.101766+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.113324+03:00", + "complaints": [ + { + "status": "resolved", + "tendererActionDate": "2016-09-16T16:17:49.565691+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": true, + "id": "cf9360b712ac479ea06d6c606c9db8d1", + "dateAnswered": "2016-09-16T16:17:49.565661+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:49.849593+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ] + }, + { + "status": "invalid", + "dateDecision": "2016-09-16T16:17:50.645131+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:50.369724+03:00", + "dateAnswered": "2016-09-16T16:17:50.099347+03:00", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:50.659654+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + }, + { + "status": "resolved", + "dateDecision": "2016-09-16T16:17:52.929570+03:00", + "documents": [ + { + "dateModified": "2016-09-16T16:17:52.615704+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=e3moEZBo6gWiPI9UAheRHa1w%2FLkWmIs1mj%2FmiMip%252BKzgLNyzIGNpShGzJ9NJOfFzh1SDbsUBIXhFoOomCGB6Dw%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:52.615675+03:00", + "title": "ComplaintResolution.pdf", + "id": "ee0fbfdd6e2e4f24b7483cbc8383b520" + } + ], + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:51.456780+03:00", + "dateAnswered": "2016-09-16T16:17:51.175990+03:00", + "dateSubmitted": "2016-09-16T16:17:50.911841+03:00", + "complaintID": "UA-EA-2016-09-16-000001.7", + "date": "2016-09-16T16:17:52.943580+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "fe684319f9dd417fa680a252363f67aa" + }, + { + "status": "declined", + "dateDecision": "2016-09-16T16:17:53.230797+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:52.345519+03:00", + "dateAnswered": "2016-09-16T16:17:52.060798+03:00", + "dateSubmitted": "2016-09-16T16:17:51.765641+03:00", + "complaintID": "UA-EA-2016-09-16-000001.8", + "date": "2016-09-16T16:17:53.245306+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "b7534a5af3b74f028355f2de973fd25b" + } + ], + "id": "0be2b9c4dc4b43a8a203b239d726a74f" + }, + { + "status": "cancelled", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.102502+03:00", + "endDate": "2016-09-16T16:17:47.604907+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.618541+03:00", + "id": "153fcdbbcfd64ab38b2279cc474787f8" + }, + { + "status": "unsuccessful", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/3a466f0d94db439d8c8101d08daa2001?KeyID=278be238&Signature=rnqjeIKX%2Fjs%2FJBDBtX2ONiH%2FsmCXAxZ0KTysX4bBmVIAnsEgiyyzXDqW%2FvS8ieJSOq7X9c4p%252B2m7J%252BS8ojciAg%253D%253D", + "title": "Cancellation_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:47.879554+03:00", + "dateModified": "2016-09-16T16:17:47.879596+03:00", + "id": "9f51c6c34f2d48e3b7ea2ccab830b315" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.605645+03:00", + "endDate": "2016-09-20T16:17:48.096369+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:48.110685+03:00", + "id": "5a24fa05c3004635956eff4976fc2f0a" + }, + { + "status": "pending", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:48.097263+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "3a11ec2af43d4b948e2c9cfaa40daf4c", + "value": { + "currency": "UAH", + "amount": 469.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:48.097243+03:00", + "id": "edeea22a4c284fc795f9e0003e54ff32" + } + ] +} + diff --git a/docs/source/qualification/awards-unsuccessful-get2.http b/docs/source/qualification/awards-unsuccessful-get2.http new file mode 100644 index 0000000..1a7966b --- /dev/null +++ b/docs/source/qualification/awards-unsuccessful-get2.http @@ -0,0 +1,390 @@ +GET /api/2.3/auctions/6428763175bc491b9514dc7de4771281/awards HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "cancelled", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/ceec00f1e1fe45d4823b6cff73a5e6e2?KeyID=278be238&Signature=GSt%2FNNdHL%252BgkEhjgxHCBjmWNNVMei%2FQA%252BZ65LBLXAxaZbYdfeLDwfvaGA0Wi%2FwCkAczFZKDsUkK0m5NItNxtDQ%253D%253D", + "title": "Unsuccessful_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:46.934420+03:00", + "dateModified": "2016-09-16T16:17:46.934449+03:00", + "id": "b52b77a5e21b4f7cafd0c9f44ca7932f" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:46.702347+03:00", + "endDate": "2016-09-16T16:17:53.699559+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:53.717039+03:00", + "complaints": [ + { + "status": "resolved", + "tendererActionDate": "2016-09-16T16:17:49.565691+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "claim", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": true, + "id": "cf9360b712ac479ea06d6c606c9db8d1", + "dateAnswered": "2016-09-16T16:17:49.565661+03:00", + "tendererAction": "Виправлено неконкурентні умови", + "dateSubmitted": "2016-09-16T16:17:48.899601+03:00", + "complaintID": "UA-EA-2016-09-16-000001.5", + "date": "2016-09-16T16:17:49.849593+03:00", + "resolution": "Виправлено неконкурентні умови", + "documents": [ + { + "dateModified": "2016-09-16T16:17:48.648245+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/e9e1c7c580e747439db62314cee0c630?KeyID=278be238&Signature=PkGIj3rCf9L6lh1r0ErzGghZY4ghfWLkaRr6c5iTN6sUi%252BF2OYjnZ3VVTIgJ5oxhNtL0EwQmTu0eLbATexD1CQ%253D%253D", + "author": "complaint_owner", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:48.648216+03:00", + "title": "Complaint_Attachement.pdf", + "id": "1f8fc9d2042f420b92b7aaa4cba24a43" + } + ] + }, + { + "status": "invalid", + "dateDecision": "2016-09-16T16:17:50.645131+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:50.369724+03:00", + "dateAnswered": "2016-09-16T16:17:50.099347+03:00", + "dateSubmitted": "2016-09-16T16:17:49.137058+03:00", + "complaintID": "UA-EA-2016-09-16-000001.6", + "date": "2016-09-16T16:17:50.659654+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "5a6fc5709c4b4eb7a1adf84c9a8a2cce" + }, + { + "status": "resolved", + "dateDecision": "2016-09-16T16:17:52.929570+03:00", + "documents": [ + { + "dateModified": "2016-09-16T16:17:52.615704+03:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/10b2098547f941858fa63609dfefe02d?KeyID=278be238&Signature=e3moEZBo6gWiPI9UAheRHa1w%2FLkWmIs1mj%2FmiMip%252BKzgLNyzIGNpShGzJ9NJOfFzh1SDbsUBIXhFoOomCGB6Dw%253D%253D", + "author": "reviewers", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:52.615675+03:00", + "title": "ComplaintResolution.pdf", + "id": "ee0fbfdd6e2e4f24b7483cbc8383b520" + } + ], + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:51.456780+03:00", + "dateAnswered": "2016-09-16T16:17:51.175990+03:00", + "dateSubmitted": "2016-09-16T16:17:50.911841+03:00", + "complaintID": "UA-EA-2016-09-16-000001.7", + "date": "2016-09-16T16:17:52.943580+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "fe684319f9dd417fa680a252363f67aa" + }, + { + "status": "declined", + "dateDecision": "2016-09-16T16:17:53.230797+03:00", + "description": "complaint description", + "title": "complaint title", + "resolutionType": "resolved", + "type": "complaint", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "satisfied": false, + "dateEscalated": "2016-09-16T16:17:52.345519+03:00", + "dateAnswered": "2016-09-16T16:17:52.060798+03:00", + "dateSubmitted": "2016-09-16T16:17:51.765641+03:00", + "complaintID": "UA-EA-2016-09-16-000001.8", + "date": "2016-09-16T16:17:53.245306+03:00", + "resolution": "Виправлено неконкурентні умови", + "id": "b7534a5af3b74f028355f2de973fd25b" + } + ], + "id": "0be2b9c4dc4b43a8a203b239d726a74f" + }, + { + "status": "cancelled", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.102502+03:00", + "endDate": "2016-09-16T16:17:53.699559+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:47.618541+03:00", + "id": "153fcdbbcfd64ab38b2279cc474787f8" + }, + { + "status": "cancelled", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/3a466f0d94db439d8c8101d08daa2001?KeyID=278be238&Signature=rnqjeIKX%2Fjs%2FJBDBtX2ONiH%2FsmCXAxZ0KTysX4bBmVIAnsEgiyyzXDqW%2FvS8ieJSOq7X9c4p%252B2m7J%252BS8ojciAg%253D%253D", + "title": "Cancellation_Reason.pdf", + "documentOf": "tender", + "datePublished": "2016-09-16T16:17:47.879554+03:00", + "dateModified": "2016-09-16T16:17:47.879596+03:00", + "id": "9f51c6c34f2d48e3b7ea2ccab830b315" + } + ], + "complaintPeriod": { + "startDate": "2016-09-16T16:17:47.605645+03:00", + "endDate": "2016-09-16T16:17:53.699559+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "3025ae6f8d824e92bd539db93f8a1956", + "value": { + "currency": "UAH", + "amount": 475.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:53.717039+03:00", + "id": "5a24fa05c3004635956eff4976fc2f0a" + }, + { + "status": "cancelled", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:48.097263+03:00", + "endDate": "2016-09-16T16:17:53.699559+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "3a11ec2af43d4b948e2c9cfaa40daf4c", + "value": { + "currency": "UAH", + "amount": 469.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:53.717039+03:00", + "id": "edeea22a4c284fc795f9e0003e54ff32" + }, + { + "status": "pending", + "complaintPeriod": { + "startDate": "2016-09-16T16:17:53.700355+03:00" + }, + "suppliers": [ + { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "bid_id": "5e687c10e6964f3087d491a63b692a02", + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2016-09-16T16:17:53.700338+03:00", + "id": "f61c70311cfd453687654723e3a333b6" + } + ] +} + diff --git a/docs/source/standard/auction.rst b/docs/source/standard/auction.rst new file mode 100644 index 0000000..ece47dc --- /dev/null +++ b/docs/source/standard/auction.rst @@ -0,0 +1,207 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Auction, Auction +.. _auction: + +Auction +======= + +Schema +------ + +:title: + string, multilingual, read-only, editable during enquiryPeriod + + Auction number in the Deposit Guarantee Fund. + +:description: + string, multilingual, editable during enquiryPeriod + + Detailed auction description. + +:auctionID: + string, auto-generated, read-only + + The auction identifier to refer auction to in "paper" documentation. + + |ocdsDescription| + AuctionID should always be the same as the OCID. It is included to make the flattened data structure more convenient. + +:dgfID: + string, editable during enquiryPeriod + + Identification number of the auction (also referred to as `lot`) in the XLS of Deposit Guarantee Fund. + + +:procuringEntity: + :ref:`ProcuringEntity`, required + + Organization conducting the auction. + + + |ocdsDescription| + The entity managing the procurement, which may be different from the buyer who is paying / using the items being procured. + + +:value: + :ref:`value`, required, editable during enquiryPeriod + + Total available auction budget. Bids lower than ``value`` will be rejected. + + |ocdsDescription| + The total estimated value of the procurement. + +:guarantee: + :ref:`Guarantee`, editable during enquiryPeriod + + Bid guarantee + +:items: + list of :ref:`item` objects, required, editable during enquiryPeriod + + List that contains single item being sold. + + |ocdsDescription| + The goods and services to be purchased, broken into line items wherever possible. Items should not be duplicated, but a quantity of 2 specified instead. + +:features: + list of :ref:`Feature` objects + + Features of auction. + +:documents: + List of :ref:`document` objects + + |ocdsDescription| + All documents and attachments related to the auction. + +:questions: + List of :ref:`question` objects + + Questions to ``procuringEntity`` and answers to them. + +:complaints: + List of :ref:`complaint` objects + + Complaints to auction conditions and their resolutions. + +:bids: + List of :ref:`bid` objects + + A list of all bids placed in the auction with information about participants, their proposals and other qualification documentation. + + |ocdsDescription| + A list of all the companies who entered submissions for the auction. + +:minNumberOfQualifiedBids: + integer, optional + + The field that indicates the minimal number of qualified bids. The possible values for the field are 1 or 2. + + In case of the field has been remained blank, the workflow will be similar to the auction with 2 bids. + + You can also fill in the field, assigning the value "1". This will show that the only one bidder is needed + for the procedure to be successful. Therewith the auction is omitted and that bid turns to a qualified award. + +:minimalStep: + :ref:`value`, required, editable during enquiryPeriod + + The minimal step of auction. Validation rules: + + * `amount` should be greater than `Auction.value.amount` + * `currency` should either be absent or match `Auction.value.currency` + * `valueAddedTaxIncluded` should either be absent or match `Auction.value.valueAddedTaxIncluded` + +:awards: + List of :ref:`award` objects + + All qualifications (disqualifications and awards). + +:contracts: + List of :ref:`Contract` objects + +:enquiryPeriod: + :ref:`period` + + Period when questions are allowed. + + |ocdsDescription| + The period during which enquiries may be made and will be answered. + +:tenderPeriod: + :ref:`period` + + Period when bids can be submitted. + + |ocdsDescription| + The period when the auction is open for submissions. The end date is the closing date for auction submissions. + +:auctionPeriod: + :ref:`period`, required + + Period when Auction is conducted. `startDate` should be provided. + +:auctionUrl: + url + + A web address where auction is accessible for view. + +:awardPeriod: + :ref:`period`, read-only + + Awarding process period. + + |ocdsDescription| + The date or period on which an award is anticipated to be made. + +:status: + string + + :`active.tendering`: + Tendering period (tendering) + :`active.auction`: + Auction period (auction) + :`active.qualification`: + Winner qualification (qualification) + :`active.awarded`: + Standstill period (standstill) + :`unsuccessful`: + Unsuccessful auction (unsuccessful) + :`complete`: + Complete auction (complete) + :`cancelled`: + Cancelled auction (cancelled) + + Auction status. + +:eligibilityCriteria: + string, read-only + + Required for `dgfFinancialAssets` procedure. + + This field is multilingual: + + * Ukrainian by default - До участі допускаються лише ліцензовані фінансові установи. + + * ``eligibilityCriteria_ru`` (Russian) - К участию допускаются только лицензированные финансовые учреждения. + + * ``eligibilityCriteria_en`` (English) - Only licensed financial institutions are eligible to participate. + +.. :lots: + List of :ref:`lot` objects. + + Contains all auction lots. + +:cancellations: + List of :ref:`cancellation` objects. + + Contains 1 object with `active` status in case of cancelled Auction. + + The :ref:`cancellation` object describes the reason of auction cancellation and contains accompanying + documents if there are any. + +:revisions: + List of :ref:`revision` objects, auto-generated + + Historical changes to `Auction` object properties. diff --git a/docs/source/standard/award.rst b/docs/source/standard/award.rst new file mode 100644 index 0000000..b4d7cc7 --- /dev/null +++ b/docs/source/standard/award.rst @@ -0,0 +1,90 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Award +.. _award: + +Award +===== + +Schema +------ + +:id: + string, auto-generated, read-only + + |ocdsDescription| + Identifier for this award. + +:bid_id: + string, auto-generated, read-only + + The ID of a bid that the award relates to. + +:title: + string, multilingual + + |ocdsDescription| + Award title. + +:description: + string, multilingual + + |ocdsDescription| + Award description. + +:status: + string + + |ocdsDescription| + The current status of the award drawn from the `awardStatus` codelist. + + Possible values are: + + * `pending` - the award is under review of qualification committee + * `unsuccessful` - the award has been rejected by qualification committee + * `active` - the auction is awarded to the bidder from the `bid_id` + * `cancelled` - the award has been cancelled by complaint review body + +:date: + string, :ref:`Date`, auto-generated, read-only + + |ocdsDescription| + The date of the contract award. + +:value: + `Value` object, auto-generated, read-only + + |ocdsDescription| + The total value of this award. + +:suppliers: + List of :ref:`Organization` objects, auto-generated, read-only + + |ocdsDescription| + The suppliers awarded with this award. + +:items: + List of :ref:`Item` objects, auto-generated, read-only + + |ocdsDescription| + The goods and services awarded in this award, broken into line items wherever possible. Items should not be duplicated, but the quantity should be specified instead. + +:documents: + List of :ref:`Document` objects + + |ocdsDescription| + All documents and attachments related to the award, including any notices. + +:complaints: + List of :ref:`Complaint` objects + +:complaintPeriod: + :ref:`period` + + The time frame when complaints can be submitted. + +.. :lotID: + string + + ID of related :ref:`lot`. diff --git a/docs/source/standard/bid.rst b/docs/source/standard/bid.rst new file mode 100644 index 0000000..a4a655d --- /dev/null +++ b/docs/source/standard/bid.rst @@ -0,0 +1,109 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 + +.. index:: Bid, Parameter, LotValue, bidder, participant, pretendent + +.. _bid: + +Bid +=== + +Schema +------ + +:tenderers: + List of :ref:`Organization` objects + +:date: + string, :ref:`date`, auto-generated + + Date when bid has been submitted. + +:id: + UID, auto-generated + +:status: + string + + Possible values are: + + * `draft` + * `active` + +:value: + :ref:`Value`, required + + Validation rules: + + * `amount` should be less than `Auction.value.amout` + * `currency` should either be absent or match `Auction.value.currency` + * `valueAddedTaxIncluded` should either be absent or match `Auction.value.valueAddedTaxIncluded` + +:documents: + List of :ref:`Document` objects + +:parameters: + List of :ref:`Parameter` objects + +.. :lotValues: + List of :ref:`LotValue` objects + +:participationUrl: + URL + + A web address for participation in auction. + +:qualified: + bool, required + +:eligible: + bool + + Required for `dgfFinancialAssets` procedure. + +.. _Parameter: + +Parameter +========= + +Schema +------ + +:code: + string, required + + Feature code. + +:value: + float, required + + Feature value. + +.. _LotValue: + +.. LotValue + ======== + + Schema + ------ + + :value: + :ref:`Value`, required + + Validation rules: + + * `amount` should be less than `Lot.value.amout` + * `currency` should either be absent or match `Lot.value.currency` + * `valueAddedTaxIncluded` should either be absent or match `Lot.value.valueAddedTaxIncluded` + + :relatedLot: + string + + ID of related :ref:`lot`. + + :date: + string, :ref:`date`, auto-generated + + :participationUrl: + URL + + A web address for participation in auction. diff --git a/docs/source/standard/cancellation.rst b/docs/source/standard/cancellation.rst new file mode 100644 index 0000000..bc12005 --- /dev/null +++ b/docs/source/standard/cancellation.rst @@ -0,0 +1,52 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Cancellation +.. _cancellation: + +Cancellation +============ + +Schema +------ + +:id: + UID, auto-generated + +:reason: + string, multilingual, required + + The reason, why auction is being cancelled. + +:status: + string + + Possible values are: + :`pending`: + Default. The request is being prepared. + :`active`: + Cancellation activated. + +:documents: + List of :ref:`Document` objects + + Documents accompanying the Cancellation: Protocol of Auction Committee + with decision to cancel the Auction. + +:date: + string, :ref:`date` + + Cancellation date. + +:cancellationOf: + string + + Possible values are: + + * `auction` +.. * `lot` + +.. :relatedLot: + string + + ID of related :ref:`lot`. diff --git a/docs/source/standard/complaint.rst b/docs/source/standard/complaint.rst new file mode 100644 index 0000000..d751ee9 --- /dev/null +++ b/docs/source/standard/complaint.rst @@ -0,0 +1,127 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Complaint, dispute + +.. _complaint: + +Complaint +========= + +Schema +------ + +:id: + UID, auto-generated + +:author: + :ref:`Organization`, required + + Organization filing a complaint (contactPoint - person, identification - organization that person represents). + +:title: + string, required + + Title of the complaint. + +:description: + Description of the issue. + +:date: + string, :ref:`date`, auto-generated + + Date of posting. + +:dateSubmitted: + string, :ref:`date`, auto-generated + + Date when claim was submitted. + +:dateAnswered: + string, :ref:`date`, auto-generated + + Date when Organizer answered the claim. + +:dateEscalated: + string, :ref:`date`, auto-generated + + Date of claim to complaint escalation. + +:dateDecision: + string, :ref:`date`, auto-generated + + Date of complaint decision. + +:dateCanceled: + string, :ref:`date`, auto-generated + + Date of cancelling. + +:status: + string + + Possible values are: + + * `draft` + * `claim` + * `answered` + * `pending` + * `invalid` + * `declined` + * `resolved` + * `cancelled` + +:type: + string + + Possible values of type are: + + * `claim` + * `complaint` + +:resolution: + string + + Organizer's resolution. + +:resolutionType: + string + + Possible values of resolution type are: + + * `invalid` + * `declined` + * `resolved` + +:satisfied: + bool + + Claim is satisfied? + +:decision: + string + + Reviewer's decision. + +:cancellationReason: + string + + Cancellation reason. + +:documents: + List of :ref:`Document` objects + +.. :relatedLot: + string + + ID of related :ref:`lot`. + +:auctionerAction: + string + + Participants's action. + +:auctionerActionDate: + string, :ref:`date`, auto-generated + + Date of participant's action. diff --git a/docs/source/standard/contract.rst b/docs/source/standard/contract.rst new file mode 100644 index 0000000..f20aadf --- /dev/null +++ b/docs/source/standard/contract.rst @@ -0,0 +1,96 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Contract +.. _Contract: + +Contract +======== + +Schema +------ + +:id: + UID, auto-generated + + |ocdsDescription| + The identifier for this contract. + +:awardID: + string, required + + |ocdsDescription| + The `Award.id` against which this contract is being issued. + +:contractID: + string, auto-generated, read-only + +:contractNumber: + string + +:title: + string, required + + |ocdsDescription| + Contract title + +:description: + string + + |ocdsDescription| + Contract description + +:value: + `Value` object, auto-generated, read-only + + |ocdsDescription| + The total value of this contract. + +:items: + List of :ref:`Item` objects, auto-generated, read-only + + |ocdsDescription| + The goods, services, and any intangible outcomes in this contract. Note: If the items are the same as the award, do not repeat. + +:suppliers: + List of :ref:`Organization` objects, auto-generated, read-only + +:status: + string, required + + |ocdsDescription| + The current status of the contract. + + Possible values are: + + * `pending` - this contract has been proposed, but is not yet in force. + It may be awaiting signature. + * `active` - this contract has been signed by all the parties, and is + now legally in force. + * `cancelled` - this contract has been cancelled prior to being signed. + * `terminated` - this contract was signed and in force, and has now come + to a close. This may be due to a successful completion of the contract, + or may be early termination due to some non-completion issue. + +:period: + :ref:`Period` + + |ocdsDescription| + The start and end date for the contract. + +:dateSigned: + string, :ref:`date` + + |ocdsDescription| + The date the contract was signed. In the case of multiple signatures, the date of the last signature. + +:date: + string, :ref:`date` + + The date when the contract was changed or activated. + +:documents: + List of :ref:`Document` objects + + |ocdsDescription| + All documents and attachments related to the contract, including any notices. diff --git a/docs/source/standard/defs.hrst b/docs/source/standard/defs.hrst new file mode 100644 index 0000000..453b652 --- /dev/null +++ b/docs/source/standard/defs.hrst @@ -0,0 +1 @@ +.. |ocdsDescription| replace:: OpenContracting Description: \ No newline at end of file diff --git a/docs/source/standard/document.rst b/docs/source/standard/document.rst new file mode 100644 index 0000000..1d1ac2e --- /dev/null +++ b/docs/source/standard/document.rst @@ -0,0 +1,196 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Document, Attachment, File, Notice, Bidding Documents, Technical Specifications, Evaluation Criteria, Clarifications + +.. _Document: + +Document +======== + +Schema +------ + +:id: + string, auto-generated + +:documentType: + string + + Possible values for :ref:`auction` + + + * `notice` - **Auction notice** + + The formal notice that gives details of an auction. This may be a link to a downloadable document, to a web page, or to an official gazette in which the notice is contained. + + * `technicalSpecifications` - **Technical Specifications** + + Detailed technical information about goods or services to be provided. + + * `evaluationCriteria` - **Evaluation Criteria** + + Information about how bids will be evaluated. + + * `clarifications` - **Clarifications to bidders questions** + + Including replies to issues raised in pre-bid conferences. + + * `bidders` - **Information on bidders** + + Information on bidders or participants, their validation documents and any procedural exemptions for which they qualify. + + * `virtualDataRoom` - **Virtual Data Room** (available only for the `dgfFinancialAssets` procedure, see :ref:`fintutorial`) + + * `illustration` - **Illustrations** + + * `x_dgfAssetFamiliarization` - **Asset Familiarization** + + Goods examination procedure rules / Asset familiarization procedure in data room. Contains information on where and when a given document can be examined offline. + + * `x_presentation` - **Presentation** + + Presentation about an asset that is being sold. + + * `x_nda` - **Non-disclosure Agreement (NDA)** + + A non-disclosure agreement between a participant and a bank/Deposit Guarantee Fund. + + Possible values for :ref:`award` + + + * `winningBid` - **Winning Bid** + + Possible values for :ref:`contract` + + + * `notice` - **Contract notice** + + The formal notice that gives details of a contract being signed and valid to start implementation. This may be a link to a downloadable document, to a web page, or to an official gazette in which the notice is contained. + + * `contractSigned` - **Signed Contract** + + * `contractAnnexe` - **Annexes to the Contract** + + + Possible values for :ref:`bid` + + + * `commercialProposal` - **Сommercial proposal** + + * `qualificationDocuments` - **Qualification documents** + + * `eligibilityDocuments` - **Eligibility documents** + + * `financialLicense` - **License** (available only for the `dgfFinancialAssets` procedure, see :ref:`fintutorial`) + + * `auctionProtocol` - **Auction protocol** + + Auction protocol describes all participants and determines the candidate (participant that has submitted the highest bid proposal during the auction). + + +:title: + string, multilingual + + |ocdsDescription| + The document title. + +:description: + string, multilingual + + |ocdsDescription| + A short description of the document. In the event the document is not accessible online, the description field can be used to describe arrangements for obtaining a copy of the document. + +:index: + integer + + Sorting (display order) parameter used for illustrations. The smaller number is, the higher illustration is in the sorting. If index is not specified, illustration will be displayed the last. If two illustrations have the same index, they will be sorted depending on their publishing date. + +:format: + string + + |ocdsDescription| + The format of the document taken from the `IANA Media Types code list `_, with the addition of one extra value for 'offline/print', used when this document entry is being used to describe the offline publication of a document. + +:url: + string, auto-generated + + |ocdsDescription| + Direct link to the document or attachment. + +:datePublished: + string, :ref:`date` + + |ocdsDescription| + The date on which the document was first published. + +:dateModified: + string, :ref:`date` + + |ocdsDescription| + Date that the document was last modified + +:language: + string + + |ocdsDescription| + Specifies the language of the linked document using either two-digit `ISO 639-1 `_, or extended `BCP47 language tags `_. + +:documentOf: + string + + Possible values are: + + * `auction` + * `item` +.. * `lot` + +:relatedItem: + string + + ID of related :ref:`item`. + +.. ID of related :ref:`lot` or :ref:`item`. + + * `biddingDocuments` - **Bidding Documents** + + Information for potential participants, describing the goals of the contract (e.g. goods and services to be sold), and the bidding process. + + * `eligibilityCriteria` - **Eligibility Criteria** + + Detailed documents about the eligibility of bidders. + + * `shortlistedFirms` - **Shortlisted Firms** + + * `riskProvisions` - **Provisions for management of risks and liabilities** + + * `billOfQuantity` - **Bill Of Quantity** + + * `conflictOfInterest` - **Conflicts of interest uncovered** + + * `debarments` - **Debarments issued** + + * `evaluationReports` - **Evaluation report** + + Report on the evaluation of the bids and the application of the evaluation criteria, including the justification fo the award. + + * `complaints` - **Complaints and decisions** + + * `notice` - **Award Notice** + + The formal notice that gives details of the contract award. This may be a link to a downloadable document, to a web page, or to an official gazette in which the notice is contained. + + * `contractProforma` - **Draft contract** + + * `contractArrangements` - **Arrangements for ending contract** + + * `contractGuarantees` - **Guarantees** + + * `subContract` - **Subcontracts** + + * `contractSchedule` - **Schedules and milestones** + +:accessDetails: + string + + Required for `x_dgfAssetFamiliarization` document. diff --git a/docs/source/standard/index.rst b/docs/source/standard/index.rst new file mode 100644 index 0000000..eab5b5f --- /dev/null +++ b/docs/source/standard/index.rst @@ -0,0 +1,25 @@ +.. Kicking page rebuild 2014-10-30 17:00:08 +.. _standard: + +Data Standard +============= + +Data standard is modelled along the `Open Contracting Standard +`_ with extensions in +areas that were not covered by it. + +.. toctree:: + :maxdepth: 1 + + auction + organization + item + document + bid + award + question + complaint + contract + util + cancellation + procuringentity diff --git a/docs/source/standard/item.rst b/docs/source/standard/item.rst new file mode 100644 index 0000000..2ac96c7 --- /dev/null +++ b/docs/source/standard/item.rst @@ -0,0 +1,151 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Item, Parameter, Classification, CAV, Unit + +.. _Item: + +Item +==== + +Schema +------ + +:id: + string, auto-generated + +:description: + string, multilingual, required + + |ocdsDescription| + A description of the goods, services to be provided. + + Auction subject / asset description. + +:classification: + :ref:`Classification` + + |ocdsDescription| + The primary classification for the item. See the `itemClassificationScheme` to + identify preferred classification lists. + + Possible variants of available primary classifiers are CPV and CAV-PS. + Additionally, there is a validation for the input of these classifiers due to which + the accuracy of at least a class has to be used. + +:additionalClassifications: + List of :ref:`Classification` objects + + Additional classifier is CPVS. The property can be leased, when entering value PA01-7 + in the classifier CPVS field. + + |ocdsDescription| + An array of additional classifications for the item. See the + `itemClassificationScheme` codelist for common options to use in OCDS. + +:unit: + :ref:`Unit` + + |ocdsDescription| + Description of the unit which the good comes in e.g. hours, kilograms. + Made up of a unit name, and the value of a single unit. + +:quantity: + integer + + |ocdsDescription| + The number of units required + +:contractPeriod: + :ref:`Period` + + The period which is used to indicate the duration of a contract within which it is valid. + Contract period represents the start and end date for the contract signed after the property or asset has been sold. + It is also can be used to specify the timeframe of a contact for a lease. + +:address: + :ref:`Address` + + Address, where the item is located. + Classification codes (CAV-PS) for which `item.address` object is optional are given below: + + :download:`CPV <../tutorial/cpv_codes_item_address_optional.json>` + + :download:`CAV_v2 <../tutorial/cav_v2_codes_item_address_optional.json>` + + +:location: + dictionary + + Geographical coordinates of the location. Element consists of the following items: + + :latitude: + string, required + :longitude: + string, required + :elevation: + string, optional, usually not used + + `location` usually takes precedence over `address` if both are present. + +.. :relatedLot: + string + + ID of related :ref:`lot`. + + +.. _Classification: + +Classification +============== + +Schema +------ + +:scheme: + string + + |ocdsDescription| + A classification should be drawn from an existing scheme or list of + codes. This field is used to indicate the scheme/codelist from which + the classification is drawn. For line item classifications, this value + should represent a known Item Classification Scheme wherever possible. + +:id: + string + + |ocdsDescription| + The classification code drawn from the selected scheme. + +:description: + string + + |ocdsDescription| + A textual description or title for the code. + +:uri: + uri + + |ocdsDescription| + A URI to identify the code. In the event individual URIs are not + available for items in the identifier scheme this value should be left + blank. + +.. _Unit: + +Unit +==== + +Schema +------ + +:code: + string, required + + UN/CEFACT Recommendation 20 unit code. + +:name: + string + + |ocdsDescription| + Name of the unit diff --git a/docs/source/standard/organization.rst b/docs/source/standard/organization.rst new file mode 100644 index 0000000..fda6bd4 --- /dev/null +++ b/docs/source/standard/organization.rst @@ -0,0 +1,163 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Organization, Company + +.. _Organization: + +Organization +============ + +Schema +------ + +:name: + string, multilingual + + Name of the organization. + +:identifier: + :ref:`Identifier` + + The primary identifier for this organization. + +:additionalIdentifiers: + List of :ref:`identifier` objects +:address: + :ref:`Address`, required +:contactPoint: + :ref:`ContactPoint`, required + + +.. index:: Company, id + +.. _Identifier: + +Identifier +========== + +Schema +------ + +:scheme: + string + + |ocdsDescription| + Organization identifiers be drawn from an existing identification scheme. + This field is used to indicate the scheme or codelist in which the + identifier will be found. This value should be drawn from the + Organization Identifier Scheme. + +:id: + string, required + + |ocdsDescription| The identifier of the organization in the selected + scheme. + + The allowed codes are the ones found in `"Organisation Registration Agency" + codelist of IATI + Standard `_ + with addition of `UA-EDR` code for organizations registered in Ukraine + (EDRPOU and IPN). + +:legalName: + string, multilingual + + |ocdsDescription| + The legally registered name of the organization. + + Full legal name (e.g. Nadra Bank). + +:uri: + uri + + |ocdsDescription| + A URI to identify the organization, such as those provided by Open + Corporates or some other relevant URI provider. This is not for listing + the website of the organization: that can be done through the url field + of the Organization contact point. + + +.. index:: Address, City, Street, Country + +.. _Address: + +Address +======= + +Schema +------ + +:streetAddress: + string + + |ocdsDescription| + The street address. For example, 1600 Amphitheatre Pkwy. + +:locality: + string + + |ocdsDescription| + The locality. For example, Mountain View. + +:region: + string + + |ocdsDescription| + The region. For example, CA. + +:postalCode: + string + + |ocdsDescription| + The postal code. For example, 94043. + +:countryName: + string, multilingual, required + + |ocdsDescription| + The country name. For example, United States. + + +.. index:: Person, Phone, Email, Website, ContactPoint + +.. _ContactPoint: + +ContactPoint +============ + +Schema +------ + +:name: + string, multilingual, required + + |ocdsDescription| + The name of the contact person, department, or contact point, for correspondence relating to this contracting process. + +:email: + email + + |ocdsDescription| + The e-mail address of the contact point/person. + +:telephone: + string + + |ocdsDescription| + The telephone number of the contact point/person. This should include the international dialling code. + +:faxNumber: + string + + |ocdsDescription| + The fax number of the contact point/person. This should include the international dialling code. + +:url: + URL + + |ocdsDescription| + A web address for the contact point/person. + + +Either `email` or `telephone` field has to be provided. diff --git a/docs/source/standard/procuringentity.rst b/docs/source/standard/procuringentity.rst new file mode 100644 index 0000000..6972aae --- /dev/null +++ b/docs/source/standard/procuringentity.rst @@ -0,0 +1,44 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: ProcuringEntity + +.. _ProcuringEntity: + +ProcuringEntity (Organizer) +=========================== + +Schema +------ + +:name: + string, multilingual + + |ocdsDescription| + The common name of the organization. + +:identifier: + :ref:`Identifier` + + |ocdsDescription| + The primary identifier for this organization. + +:additionalIdentifiers: + List of :ref:`identifier` objects + +:address: + :ref:`Address`, required + +:contactPoint: + :ref:`ContactPoint`, required + +:kind: + string + + Type of organizer + + Possible values: + - ``general`` - Organizer (general) + - ``special`` - Organizer that operates in certain spheres of economic activity + - ``other`` - Legal persons that are not organizers in the sense of the Law, but are state, utility, public enterprises, economic partnerships or associations of enterprises in which state or public utility share is 50 percent or more + diff --git a/docs/source/standard/question.rst b/docs/source/standard/question.rst new file mode 100644 index 0000000..0c2a539 --- /dev/null +++ b/docs/source/standard/question.rst @@ -0,0 +1,55 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 + +.. index:: Question, Answer, Author +.. _question: + +Question +======== + +Schema +------ + +:id: + UID, auto-generated + +:author: + :ref:`Organization`, required + + Who is asking a question (contactPoint - person, identification - organization that person represents). + +:title: + string, required + + Title of the question. + +:description: + string + + Description of the question. + +:date: + string, :ref:`date`, auto-generated + + Date of posting. + +:answer: + string + + Answer for the question. + +:questionOf: + string + + Possible values are: + + * `auction` + * `item` +.. * `lot` + +:relatedItem: + string + + ID of related :ref:`item`. + +.. ID of related :ref:`lot` or :ref:`item`. + diff --git a/docs/source/standard/util.rst b/docs/source/standard/util.rst new file mode 100644 index 0000000..39d3e17 --- /dev/null +++ b/docs/source/standard/util.rst @@ -0,0 +1,99 @@ +.. . Kicking page rebuild 2014-10-30 17:00:08 +.. include:: defs.hrst + +.. index:: Period, startDate, endDate +.. _period: + +Period +====== + +Schema +------ + +:startDate: + string, :ref:`date` + + |ocdsDescription| + The start date for the period. + +:endDate: + string, :ref:`date` + + |ocdsDescription| + The end date for the period. + +`startDate` should always precede `endDate`. + +.. _Date: + +Date +==== + +Date/time in :ref:`date-format`. + +.. index:: Value, Currency, VAT +.. _value: + +Value +===== + +Schema +------ + +:amount: + float, required + + |ocdsDescription| + Amount as a number. + + Should be positive. + +:currency: + string, required + + |ocdsDescription| + The currency in 3-letter ISO 4217 format. + +:valueAddedTaxIncluded: + bool, required + +.. index:: Revision, Change Tracking +.. _revision: + +Revision +======== + +Schema +------ + +:date: + string, :ref:`date` + + Date when changes were recorded. + +:changes: + List of `Change` objects + + +.. _guarantee: + +Guarantee +========= + +Schema +------ + +:amount: + float, required + + |ocdsDescription| + Amount as a number. + + Should be positive. + +:currency: + string, required, default = `UAH` + + |ocdsDescription| + The currency in 3-letter ISO 4217 format. + diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst new file mode 100644 index 0000000..abba785 --- /dev/null +++ b/docs/source/tutorial.rst @@ -0,0 +1,453 @@ +.. _tutorial: + +Tutorial +======== + +Exploring basic rules +--------------------- + +Let's try exploring the `/auctions` endpoint: + +.. include:: tutorial/auction-listing.http + :code: + +Just invoking it reveals empty set. + +Now let's attempt creating some auction: + +.. include:: tutorial/auction-post-attempt.http + :code: + +Error states that the only accepted Content-Type is `application/json`. + +Let's satisfy the Content-type requirement: + +.. include:: tutorial/auction-post-attempt-json.http + :code: + +Error states that no `data` has been found in JSON body. + + +.. index:: Auction + +Creating auction +---------------- + +Let's create auction with the minimal data set (only required properties): + +.. include:: tutorial/auction-post-attempt-json-data.http + :code: + +Success! Now we can see that new object has been created. Response code is `201` +and `Location` response header reports the location of the created object. The +body of response reveals the information about the created auction: its internal +`id` (that matches the `Location` segment), its official `auctionID` and +`dateModified` datestamp stating the moment in time when auction has been last +modified. Pay attention to the `procurementMethodType`. Note that auction is +created with `active.tendering` status. + +Keep in mind that `tenderPeriod` must be at least 7 calendar days. + +When `auctionPeriod.startDate` has an incorrect date, 422 Unprocessable Entity +error is raised and "tenderPeriod should be greater than 6 days" message is +returned in JSON response. + +Let's set `auctionPeriod.startDate` to `now + timedelta(days=6)` and ValidationError +will be returned: + +.. include:: tutorial/tenderperiod-validation-error.http + :code: + +Organizer can set *enquiryPeriod.endDate*. The difference between the given date and *tenderPeriod.endDate* should not be less than 5 working days. + +If the duration between *enquiryPeriod.endDate* provided by Organizer and *tenderPeriod.endDate* is less than 5 days `422 Unprocessable Entity` response will be returned with the error message '*enquiryPeriod.endDate* should come at least 5 working days earlier than tenderPeriod.endDate.' + +If Organizer does not set *enquiryPeriod.endDate* it will be calculated automatically as *tenderPeriod.endDate* minus 5 working days. + +Let's access the URL of the created object (the `Location` header of the response): + +.. include:: tutorial/blank-auction-view.http + :code: + +We can see the same response we got after creating auction. + +Let's see what listing of auctions reveals us: + +.. include:: tutorial/initial-auction-listing.http + :code: + +We do see the auction's internal `id` (that can be used to construct full URL by prepending `https://api-sandbox.ea.openprocurement.org/api/0/auctions/`) and its `dateModified` datestamp. + +The previous auction contained only required fields. Let's try creating auction with more data +(auction has status `created`): + +.. include:: tutorial/create-auction-procuringEntity.http + :code: + +And again we have `201 Created` response code, `Location` header and body with extra `id`, `auctionID`, and `dateModified` properties. + +Let's check what auction registry contains: + +.. include:: tutorial/auction-listing-after-procuringEntity.http + :code: + +And indeed we have 2 auctions now. + + +Modifying auction +----------------- + +Let's update auction by supplementing it with all other essential properties: + +.. include:: tutorial/patch-items-value-periods.http + :code: + +.. XXX body is empty for some reason (printf fails) + +We see the added properies have merged with existing auction data. Additionally, the `dateModified` property was updated to reflect the last modification datestamp. + +Checking the listing again reflects the new modification date: + +.. include:: tutorial/auction-listing-after-patch.http + :code: + +Keep in mind, that every time Organizer edits the auction all bids will be switched to `invalid` status. + +Bidders can reactivate their bids. + +Organizer can edit procedure only during *enquiryPeriod*. + +When this period ends 403 error will be returned on editing attempt: + +.. include:: tutorial/out-of-enquiryperiod-editing-denied.http + :code: + + +.. index:: Document + +Uploading documentation +----------------------- + +Organizer can upload PDF files into the created auction. Uploading should +follow the :ref:`upload` rules. + +.. include:: tutorial/upload-auction-notice.http + :code: + +`201 Created` response code and `Location` header confirm document creation. +We can additionally query the `documents` collection API endpoint to confirm the +action: + +.. include:: tutorial/auction-documents.http + :code: + +The single array element describes the uploaded document. We can upload more documents: + +.. include:: tutorial/upload-award-criteria.http + :code: + +And again we can confirm that there are two documents uploaded. + +.. include:: tutorial/auction-documents-2.http + :code: + +In case we made an error, we can reupload the document over the older version: + +.. include:: tutorial/update-award-criteria.http + :code: + +And we can see that it is overriding the original version: + +.. include:: tutorial/auction-documents-3.http + :code: + + +.. index:: Enquiries, Question, Answer + +Uploading illustration +----------------------- + +Organizer can upload illustration files into the created auction. Uploading should +follow the :ref:`upload` rules. + +In order to specify illustration display order, `index` field can be used (for details see :ref:`document`). Since this illustration should be displayed first, it has ``"index": 1``. + +.. include:: tutorial/upload-first-auction-illustration.http + :code: + +We can check whether illustration is uploaded. + +.. include:: tutorial/auction-documents-4.http + :code: + +Organizer can upload second illustration. This illustration should be displayed second, so it has ``"index": 2``. + +.. include:: tutorial/upload-second-auction-illustration.http + :code: + +Add third illustration: + +.. include:: tutorial/upload-third-auction-illustration.http + :code: + +Note that `index` of the third illustration is the same as for the second illustration: ``"index": 2``. In such cases firstly will be displayed illustration that was uploaded earlier. + +We can check that there are three uploaded illustrations. + +.. include:: tutorial/auction-documents-5.http + :code: + +Add Asset Familiarization +------------------------- + +Organizer can upload asset familiarization document into the created auction. + +.. include:: tutorial/add-asset-familiarization-document.http + :code: + +We can check whether asset familiarization document is added. + +.. include:: tutorial/auction-documents-6.http + :code: + +Enquiries +--------- + +When auction is in `active.tendering` status, interested parties can ask questions: + +.. include:: tutorial/ask-question.http + :code: + +Organizer can answer them: + +.. include:: tutorial/answer-question.http + :code: + +And one can retrieve the question list: + +.. include:: tutorial/list-question.http + :code: + +Or an individual answer: + +.. include:: tutorial/get-answer.http + :code: + + +.. index:: Bidding + +Registering bid +--------------- + +Bidder can register a bid in `draft` status: + +.. include:: tutorial/register-bidder.http + :code: + +And activate a bid: + +.. include:: tutorial/activate-bidder.http + :code: + +And upload proposal document: + +.. include:: tutorial/upload-bid-proposal.http + :code: + +It is possible to check the uploaded documents: + +.. include:: tutorial/bidder-documents.http + :code: + +For the best effect (biggest economy) auction should have multiple bidders registered: + +.. include:: tutorial/register-2nd-bidder.http + :code: + + +.. index:: Awarding, Qualification + +Auction +------- + +After auction is scheduled anybody can visit it to watch. The auction can be reached at `Auction.auctionUrl`: + +.. include:: tutorial/auction-url.http + :code: + +And bidders can find out their participation URLs via their bids: + +.. include:: tutorial/bidder-participation-url.http + :code: + +See the `Bid.participationUrl` in the response. Similar, but different, URL can be retrieved for other participants: + +.. include:: tutorial/bidder2-participation-url.http + :code: + +.. _Qualification: + +Qualification +------------- +After the competitive auction `awards` are created: + * for the first candidate (a participant that has submitted the highest bid at the auction) - initially has a `pending.verification` status and awaits auction protocol to be uploaded by the organizer; + * for the rest of the candidates. + + +.. include:: tutorial/get-awards.http + :code: + + +.. _Confirming_qualification: + + +Confirming qualification +~~~~~~~~~~~~~~~~~~~~~~~~ + +The organizer **must** upload and confirm the auction protocol `auctionProtocol` and add it to the award within **6 business days after the start of the qualification procedure**. The candidate still has a possibility to upload the protocol, but it is neither mandatory, nor sufficient to move to the next status. In order to switch `award` to the next status, Organizer should come and change its status manually. + + +.. include:: tutorial/bidder-auction-protocol.http + :code: + +.. include:: tutorial/owner-auction-protocol.http + :code: + + + +It is the Organizer's duty to upload and confirm the protocol, although the award will not be switched to the status 'pending.payment' automatically. + + +.. include:: tutorial/verify-protocol.http + :code: + + +Within **20 business days after becoming a candidate** he/she must provide payment and Organizer has the same time to confirm the payment. After the payment was received, Organizer can optionally switch the award's status to `active`. + + +.. include:: tutorial/confirm-qualification.http + :code: + +.. _Candidate_disqualification: + +Disqualification of a candidate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case of manual disqualification, the organizer has to upload file with cancellation reason: + + +.. include:: qualification/award-active-unsuccessful-upload.http + :code: + + +And disqualify candidate: + + +.. include:: qualification/award-active-disqualify.http + :code: + + +Within 20 business days since becoming candidate a new candidate must confirm qualification with steps described above (:ref:`Qualification`). + +.. _Waiting_refusal: + +Refusal of waiting by another participant +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The rest of the candidates can refuse to wait for the disqualification of the first candidate: + + +.. include:: qualification/award-waiting-cancel.http + :code: + +Signing contract +---------------- + +The candidate has **20 business days after becoming a candidate** to conclude a contract with the bank based on the results of electronic auction. When the organizer confirms that the payment has been received, the `award` may be switched to the `active` status, while the procedure moves to the status `signingPeriod`. Within this stage the organizer should upload and activate the contract in the system. + +Uploading contract documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can upload contract documents. Let's upload contract document: + +.. include:: tutorial/auction-contract-upload-document.http + :code: + +`201 Created` response code and `Location` header confirm that document has been added. + +Let's see the list of contract documents: + +.. include:: tutorial/auction-contract-get-documents.http + :code: + +We can add another contract document: + +.. include:: tutorial/auction-contract-upload-second-document.http + :code: + +`201 Created` response code and `Location` header confirm that the second document has been uploaded. + +Let's see the list of all added contract documents: + +.. include:: tutorial/auction-contract-get-documents-again.http + :code: + +Contract registration +~~~~~~~~~~~~~~~~~~~~~ + +There is a possibility to set custom contract signature date. +If the date is not set it will be generated on contract registration. +You can register contract: + +.. include:: tutorial/auction-contract-sign.http + :code: + +Cancelling auction +------------------ + +Organizer can cancel auction anytime (except when auction has terminal status e.g. `unsuccesfull`, `canceled`, `complete`). + +The following steps should be applied: + +1. Prepare cancellation request. +2. Fill it with the protocol describing the cancellation reasons. +3. Cancel the auction with the reasons prepared. + +Only the request that has been activated (3rd step above) has power to +cancel auction. I.e. you have to not only prepare cancellation request but +to activate it as well. + +See :ref:`cancellation` data structure for details. + +Preparing the cancellation request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You should pass `reason`, `status` defaults to `pending`. `id` is +autogenerated and passed in the `Location` header of response. + +.. include:: tutorial/prepare-cancellation.http + :code: + + +Filling cancellation with protocol and supplementary documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Upload the file contents: + +.. include:: tutorial/upload-cancellation-doc.http + :code: + +Change the document description and other properties: + +.. include:: tutorial/patch-cancellation.http + :code: + +Upload new version of the document: + +.. include:: tutorial/update-cancellation-doc.http + :code: + +Activating the request and cancelling auction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: tutorial/active-cancellation.http + :code: diff --git a/docs/source/tutorial/activate-bidder.http b/docs/source/tutorial/activate-bidder.http new file mode 100644 index 0000000..f5d8b82 --- /dev/null +++ b/docs/source/tutorial/activate-bidder.http @@ -0,0 +1,53 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4?acc_token=a94a2b6627aa46f3bbb83ff885e3beae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 30 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:26.821209+02:00", + "qualified": true, + "tenderers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "owner": "broker", + "id": "afaa508128da4829b9202fe300965bf4" + } +} + diff --git a/docs/source/tutorial/activate-finbidder.http b/docs/source/tutorial/activate-finbidder.http new file mode 100644 index 0000000..6718ac9 --- /dev/null +++ b/docs/source/tutorial/activate-finbidder.http @@ -0,0 +1,18 @@ +PATCH /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca?acc_token=b6c5e3c4087848a08703ae24889033a7 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 30 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +null + diff --git a/docs/source/tutorial/active-cancellation.http b/docs/source/tutorial/active-cancellation.http new file mode 100644 index 0000000..0c30cd7 --- /dev/null +++ b/docs/source/tutorial/active-cancellation.http @@ -0,0 +1,50 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 30 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "Changed description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/02dd9977d20e4b409d307bc67ee6ca36?KeyID=8473a74a&Signature=5WtHn%252BXf4U2eKnBY5mwdZNifHaf%2FMoApsRroJSOzQBI%252BdJ5ZwCkP%252BTZmjkZ%2FDOh1M4U5JY7u1MJE8%252Bp7YQOSBw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.945693+02:00", + "dateModified": "2017-11-30T16:56:29.945720+02:00", + "id": "6aebbc98305a4847830bdc40863a4d6b" + }, + { + "hash": "md5:00000000000000000000000000000000", + "description": "Changed description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1981cae19a6d4577bf343cf0b7d813f5?KeyID=8473a74a&Signature=6PDYxf6GgOgkJuoH%2FR4qtBFHx%2FEcXKpV9NJ0lWVPu7IBKLdQ8%252ByiK5kIQk5YZ9aebaDik0e4JNDdJihcZVA%252BBg%253D%253D", + "title": "Notice-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.945693+02:00", + "dateModified": "2017-11-30T16:56:30.284752+02:00", + "id": "6aebbc98305a4847830bdc40863a4d6b" + } + ], + "reason": "cancellation reason", + "date": "2017-11-30T16:56:30.483484+02:00", + "cancellationOf": "tender", + "id": "3fd26d96a4454abf9a875bef110dba4e" + } +} + diff --git a/docs/source/tutorial/add-asset-familiarization-document.http b/docs/source/tutorial/add-asset-familiarization-document.http new file mode 100644 index 0000000..d23f4b7 --- /dev/null +++ b/docs/source/tutorial/add-asset-familiarization-document.http @@ -0,0 +1,32 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 160 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "Familiarization with bank asset", + "accessDetails": "Familiar with asset: days, time, address", + "documentType": "x_dgfAssetFamiliarization" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/b31139eea309435592a725e115dc90ed + +{ + "data": { + "title": "Familiarization with bank asset", + "format": "offline/on-site-examination", + "accessDetails": "Familiar with asset: days, time, address", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.520040+02:00", + "documentType": "x_dgfAssetFamiliarization", + "dateModified": "2017-11-30T16:56:26.520067+02:00", + "id": "b31139eea309435592a725e115dc90ed" + } +} + diff --git a/docs/source/tutorial/answer-question.http b/docs/source/tutorial/answer-question.http new file mode 100644 index 0000000..ab98065 --- /dev/null +++ b/docs/source/tutorial/answer-question.http @@ -0,0 +1,27 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/questions/e966c8cdacc14655907b34713b141d18?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 162 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність", + "date": "2017-11-30T16:56:26.610507+02:00", + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"", + "id": "e966c8cdacc14655907b34713b141d18", + "questionOf": "tender" + } +} + diff --git a/docs/source/tutorial/ask-question.http b/docs/source/tutorial/ask-question.http new file mode 100644 index 0000000..0ff5ede --- /dev/null +++ b/docs/source/tutorial/ask-question.http @@ -0,0 +1,70 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/questions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1506 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "author": { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "legalName": "Державне комунальне підприємство громадського харчування «Школяр»", + "id": "00137226", + "uri": "http://sch10.edu.vn.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + }, + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/questions/e966c8cdacc14655907b34713b141d18 + +{ + "data": { + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність", + "author": { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "legalName": "Державне комунальне підприємство громадського харчування «Школяр»", + "uri": "http://sch10.edu.vn.ua/", + "id": "00137226" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + }, + "date": "2017-11-30T16:56:26.610507+02:00", + "id": "e966c8cdacc14655907b34713b141d18", + "questionOf": "tender" + } +} + diff --git a/docs/source/tutorial/auction-contract-get-documents-again.http b/docs/source/tutorial/auction-contract-get-documents-again.http new file mode 100644 index 0000000..9b908eb --- /dev/null +++ b/docs/source/tutorial/auction-contract-get-documents-again.http @@ -0,0 +1,33 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/5bd3f7a02ff44727b232621207f1b851?KeyID=8473a74a&Signature=JQHt0PL4w47AD3VLzHc10HkPeKF1%252BHLSabNSU66N7xOOgzeZ5ABgvszpMW%252Bf1dAvGCTqIVBaD2EYUV1iUuYZAQ%253D%253D", + "title": "contract_first_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.913379+02:00", + "dateModified": "2017-11-30T16:56:28.913410+02:00", + "id": "1702fe06543e4c10b6f0bcb0aa694e8c" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/4d1df678191e499cbb764244f4469b22?KeyID=8473a74a&Signature=jAmAX7MaWviKJdsUEYM2RR8oXbt8vNobcDP6zqadHWj%252BoQKkUnjVwDry6HmSExDU7DJCqVN9ReLo4mMzNmibBQ%253D%253D", + "title": "contract_second_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.118456+02:00", + "dateModified": "2017-11-30T16:56:29.118484+02:00", + "id": "5c42650d4e074aae85732d8655eec1b7" + } + ] +} + diff --git a/docs/source/tutorial/auction-contract-get-documents.http b/docs/source/tutorial/auction-contract-get-documents.http new file mode 100644 index 0000000..74fa6c8 --- /dev/null +++ b/docs/source/tutorial/auction-contract-get-documents.http @@ -0,0 +1,23 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/5bd3f7a02ff44727b232621207f1b851?KeyID=8473a74a&Signature=JQHt0PL4w47AD3VLzHc10HkPeKF1%252BHLSabNSU66N7xOOgzeZ5ABgvszpMW%252Bf1dAvGCTqIVBaD2EYUV1iUuYZAQ%253D%253D", + "title": "contract_first_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.913379+02:00", + "dateModified": "2017-11-30T16:56:28.913410+02:00", + "id": "1702fe06543e4c10b6f0bcb0aa694e8c" + } + ] +} + diff --git a/docs/source/tutorial/auction-contract-period.http b/docs/source/tutorial/auction-contract-period.http new file mode 100644 index 0000000..114401d --- /dev/null +++ b/docs/source/tutorial/auction-contract-period.http @@ -0,0 +1,83 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 106 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "period": { + "startDate": "2017-11-30T16:56:17.205813", + "endDate": "2018-11-30T16:56:17.205813" + } + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "pending", + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "suppliers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "period": { + "startDate": "2017-11-30T16:56:17.205813+02:00", + "endDate": "2018-11-30T16:56:17.205813+02:00" + }, + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:28.528529+02:00", + "awardID": "add0cbb7aa114e7cb6f5e127071f8b53", + "id": "ada81c2080f143a387863faae3db1f81", + "contractID": "UA-PS-2017-11-30-000001-1" + } +} + diff --git a/docs/source/tutorial/auction-contract-sign.http b/docs/source/tutorial/auction-contract-sign.http new file mode 100644 index 0000000..5deddf5 --- /dev/null +++ b/docs/source/tutorial/auction-contract-sign.http @@ -0,0 +1,104 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 80 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active", + "dateSigned": "2017-11-30T16:56:29.280738+02:00" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/5bd3f7a02ff44727b232621207f1b851?KeyID=8473a74a&Signature=JQHt0PL4w47AD3VLzHc10HkPeKF1%252BHLSabNSU66N7xOOgzeZ5ABgvszpMW%252Bf1dAvGCTqIVBaD2EYUV1iUuYZAQ%253D%253D", + "title": "contract_first_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.913379+02:00", + "dateModified": "2017-11-30T16:56:28.913410+02:00", + "id": "1702fe06543e4c10b6f0bcb0aa694e8c" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/4d1df678191e499cbb764244f4469b22?KeyID=8473a74a&Signature=jAmAX7MaWviKJdsUEYM2RR8oXbt8vNobcDP6zqadHWj%252BoQKkUnjVwDry6HmSExDU7DJCqVN9ReLo4mMzNmibBQ%253D%253D", + "title": "contract_second_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.118456+02:00", + "dateModified": "2017-11-30T16:56:29.118484+02:00", + "id": "5c42650d4e074aae85732d8655eec1b7" + } + ], + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "suppliers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "period": { + "startDate": "2017-11-30T16:56:17.205813+02:00", + "endDate": "2018-11-30T16:56:17.205813+02:00" + }, + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "dateSigned": "2017-11-30T16:56:29.280738+02:00", + "date": "2017-11-30T16:56:29.382454+02:00", + "awardID": "add0cbb7aa114e7cb6f5e127071f8b53", + "id": "ada81c2080f143a387863faae3db1f81", + "contractID": "UA-PS-2017-11-30-000001-1" + } +} + diff --git a/docs/source/tutorial/auction-contract-upload-document.http b/docs/source/tutorial/auction-contract-upload-document.http new file mode 100644 index 0000000..2d57e46 --- /dev/null +++ b/docs/source/tutorial/auction-contract-upload-document.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 357 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/5bd3f7a02ff44727b232621207f1b851?KeyID=8473a74a&Signature=Ndscn5Uq%2Bs%2BeHLny6kCKT3nDq1M6MVzfBivwV%2FXJduW%2B5%2FpdvbQHPew9U9II8HSPns9p2S7vEM3CtUBL91%2B2Dg%3D%3D", + "title": "contract_first_document.doc", + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents/1702fe06543e4c10b6f0bcb0aa694e8c + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/5bd3f7a02ff44727b232621207f1b851?KeyID=8473a74a&Signature=JQHt0PL4w47AD3VLzHc10HkPeKF1%252BHLSabNSU66N7xOOgzeZ5ABgvszpMW%252Bf1dAvGCTqIVBaD2EYUV1iUuYZAQ%253D%253D", + "title": "contract_first_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.913379+02:00", + "dateModified": "2017-11-30T16:56:28.913410+02:00", + "id": "1702fe06543e4c10b6f0bcb0aa694e8c" + } +} + diff --git a/docs/source/tutorial/auction-contract-upload-second-document.http b/docs/source/tutorial/auction-contract-upload-second-document.http new file mode 100644 index 0000000..3e6ecc1 --- /dev/null +++ b/docs/source/tutorial/auction-contract-upload-second-document.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 350 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/4d1df678191e499cbb764244f4469b22?KeyID=8473a74a&Signature=PIMLosfRw8Ru4sWIwgpHMjPorBzBQnIcamxeDNhK7vK%2F9dLDNtYYRfBrrEqaWzmb%2Bq5jApq1Pn2mUSQcS6pgAg%3D%3D", + "title": "contract_second_document.doc", + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/contracts/ada81c2080f143a387863faae3db1f81/documents/5c42650d4e074aae85732d8655eec1b7 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/msword", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/4d1df678191e499cbb764244f4469b22?KeyID=8473a74a&Signature=jAmAX7MaWviKJdsUEYM2RR8oXbt8vNobcDP6zqadHWj%252BoQKkUnjVwDry6HmSExDU7DJCqVN9ReLo4mMzNmibBQ%253D%253D", + "title": "contract_second_document.doc", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.118456+02:00", + "dateModified": "2017-11-30T16:56:29.118484+02:00", + "id": "5c42650d4e074aae85732d8655eec1b7" + } +} + diff --git a/docs/source/tutorial/auction-documents-2.http b/docs/source/tutorial/auction-documents-2.http new file mode 100644 index 0000000..5073593 --- /dev/null +++ b/docs/source/tutorial/auction-documents-2.http @@ -0,0 +1,35 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/68fe48f4593a4de9844e6548344b2696?KeyID=8473a74a&Signature=QZwWxRCYJDGM8BwdJ%252Bh%2FZ7EfjK1tSuHstIWY7Phw8MUeywT2GsNNucpnf2UGZGud5EPLKF1xOz9hX%252BWHtaSeBw%253D%253D", + "title": "AwardCriteria.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.157192+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + } + ] +} + diff --git a/docs/source/tutorial/auction-documents-3.http b/docs/source/tutorial/auction-documents-3.http new file mode 100644 index 0000000..d9eae88 --- /dev/null +++ b/docs/source/tutorial/auction-documents-3.http @@ -0,0 +1,35 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + } + ] +} + diff --git a/docs/source/tutorial/auction-documents-4.http b/docs/source/tutorial/auction-documents-4.http new file mode 100644 index 0000000..3db20c7 --- /dev/null +++ b/docs/source/tutorial/auction-documents-4.http @@ -0,0 +1,48 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + }, + { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=CTN%2FyvXW3%252Bz7lGcIGWXJGAYdUUudzcpWk1%2F9TldffuMmRChRSJJsi%2F%2FHBzjXb%252B0f4DuzUiUbq8bqD%2FP70jlFAQ%253D%253D", + "title": "first_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.293411+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.293438+02:00", + "id": "f143cdc5fef246f59d11cd3bc7c72d46" + } + ] +} + diff --git a/docs/source/tutorial/auction-documents-5.http b/docs/source/tutorial/auction-documents-5.http new file mode 100644 index 0000000..c779295 --- /dev/null +++ b/docs/source/tutorial/auction-documents-5.http @@ -0,0 +1,74 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + }, + { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=CTN%2FyvXW3%252Bz7lGcIGWXJGAYdUUudzcpWk1%2F9TldffuMmRChRSJJsi%2F%2FHBzjXb%252B0f4DuzUiUbq8bqD%2FP70jlFAQ%253D%253D", + "title": "first_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.293411+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.293438+02:00", + "id": "f143cdc5fef246f59d11cd3bc7c72d46" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Second illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bfd750de3e7b49b5a991b6cdaf2c208e?KeyID=8473a74a&Signature=nXLYMy2OkK2aIJDwV6kn7z3BkQD4wMe1ccc9%252BSvKDcUemJGUcmxtcGPn57JUQ6AJznS4IfCvaHVyDo5Aez7pDA%253D%253D", + "title": "second_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.376954+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.376981+02:00", + "id": "eb64e2d0457e42c89aed5861301d3d06" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Third illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2d40e8da608c4f10b9432671cf47c9aa?KeyID=8473a74a&Signature=AGnUbHWEz4OOa7kxT1%2Fj4Ml7cNOw%252BcsUiDVX9HQhwqAdi4UGtaxWqeAZ2YhsI20lzMp67Fq%252BUo6jPmWdLdWuAQ%253D%253D", + "title": "third_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.434267+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.434293+02:00", + "id": "fdafece528e54fe5a7b38f025be993c3" + } + ] +} + diff --git a/docs/source/tutorial/auction-documents-6.http b/docs/source/tutorial/auction-documents-6.http new file mode 100644 index 0000000..68ba735 --- /dev/null +++ b/docs/source/tutorial/auction-documents-6.http @@ -0,0 +1,84 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + }, + { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=CTN%2FyvXW3%252Bz7lGcIGWXJGAYdUUudzcpWk1%2F9TldffuMmRChRSJJsi%2F%2FHBzjXb%252B0f4DuzUiUbq8bqD%2FP70jlFAQ%253D%253D", + "title": "first_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.293411+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.293438+02:00", + "id": "f143cdc5fef246f59d11cd3bc7c72d46" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Second illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bfd750de3e7b49b5a991b6cdaf2c208e?KeyID=8473a74a&Signature=nXLYMy2OkK2aIJDwV6kn7z3BkQD4wMe1ccc9%252BSvKDcUemJGUcmxtcGPn57JUQ6AJznS4IfCvaHVyDo5Aez7pDA%253D%253D", + "title": "second_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.376954+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.376981+02:00", + "id": "eb64e2d0457e42c89aed5861301d3d06" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Third illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2d40e8da608c4f10b9432671cf47c9aa?KeyID=8473a74a&Signature=AGnUbHWEz4OOa7kxT1%2Fj4Ml7cNOw%252BcsUiDVX9HQhwqAdi4UGtaxWqeAZ2YhsI20lzMp67Fq%252BUo6jPmWdLdWuAQ%253D%253D", + "title": "third_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.434267+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.434293+02:00", + "id": "fdafece528e54fe5a7b38f025be993c3" + }, + { + "title": "Familiarization with bank asset", + "format": "offline/on-site-examination", + "accessDetails": "Familiar with asset: days, time, address", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.520040+02:00", + "documentType": "x_dgfAssetFamiliarization", + "dateModified": "2017-11-30T16:56:26.520067+02:00", + "id": "b31139eea309435592a725e115dc90ed" + } + ] +} + diff --git a/docs/source/tutorial/auction-documents.http b/docs/source/tutorial/auction-documents.http new file mode 100644 index 0000000..bfda73c --- /dev/null +++ b/docs/source/tutorial/auction-documents.http @@ -0,0 +1,24 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/418d8f99150a4b92a57b81cc18cd968a HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "previousVersions": [], + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + } +} + diff --git a/docs/source/tutorial/auction-listing-after-patch.http b/docs/source/tutorial/auction-listing-after-patch.http new file mode 100644 index 0000000..6d6b2ae --- /dev/null +++ b/docs/source/tutorial/auction-listing-after-patch.http @@ -0,0 +1,25 @@ +GET /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "next_page": { + "path": "/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.873102%2B02%3A00", + "uri": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.873102%2B02%3A00", + "offset": "2017-11-30T16:56:25.873102+02:00" + }, + "data": [ + { + "id": "301d66e275cb4861ba502c1eaafa88ae", + "dateModified": "2017-11-30T16:56:25.621767+02:00" + }, + { + "id": "dbcc98fdc3f64c6aaabe25f09a2c64d1", + "dateModified": "2017-11-30T16:56:25.873102+02:00" + } + ] +} + diff --git a/docs/source/tutorial/auction-listing-after-procuringEntity.http b/docs/source/tutorial/auction-listing-after-procuringEntity.http new file mode 100644 index 0000000..65b7ba5 --- /dev/null +++ b/docs/source/tutorial/auction-listing-after-procuringEntity.http @@ -0,0 +1,22 @@ +GET /api/2.3/auctions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "next_page": { + "path": "/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.621767%2B02%3A00", + "uri": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.621767%2B02%3A00", + "offset": "2017-11-30T16:56:25.621767+02:00" + }, + "data": [ + { + "id": "301d66e275cb4861ba502c1eaafa88ae", + "dateModified": "2017-11-30T16:56:25.621767+02:00" + } + ] +} + diff --git a/docs/source/tutorial/auction-listing.http b/docs/source/tutorial/auction-listing.http new file mode 100644 index 0000000..68c2d83 --- /dev/null +++ b/docs/source/tutorial/auction-listing.http @@ -0,0 +1,18 @@ +GET /api/2.3/auctions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "next_page": { + "path": "/api/2.3/auctions?offset=", + "uri": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions?offset=", + "offset": "" + }, + "data": [] +} + + diff --git a/docs/source/tutorial/auction-patch-2pc.http b/docs/source/tutorial/auction-patch-2pc.http new file mode 100644 index 0000000..4e28b42 --- /dev/null +++ b/docs/source/tutorial/auction-patch-2pc.http @@ -0,0 +1,99 @@ +PATCH /api/2.3/auctions/58ad76271332425694531cbfe1aa6723?acc_token=a3781f686544479b9060df012b8db196 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 40 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active.tendering" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:19.163266+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "58ad76271332425694531cbfe1aa6723", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:19.212525+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:19.163266+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:19.212525+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "c2fb6cf42caf4621b4bcac1deff95286", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/auction-post-2pc.http b/docs/source/tutorial/auction-post-2pc.http new file mode 100644 index 0000000..c1fe905 --- /dev/null +++ b/docs/source/tutorial/auction-post-2pc.http @@ -0,0 +1,156 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1987 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "draft", + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "dgfID": "219560", + "auctionPeriod": { + "startDate": "2017-12-14" + }, + "items": [ + { + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "quantity": 5, + "description": "Земля для військовослужбовців", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + } + } + ], + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/58ad76271332425694531cbfe1aa6723 + +{ + "access": { + "token": "a3781f686544479b9060df012b8db196" + }, + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:19.163266+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "submissionMethod": "electronicAuction", + "date": "2017-11-30T16:56:19.163266+02:00", + "status": "draft", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "dgfID": "219560", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:19.163266+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "owner": "broker", + "dateModified": "2017-11-30T16:56:19.166771+02:00", + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "c2fb6cf42caf4621b4bcac1deff95286", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "id": "58ad76271332425694531cbfe1aa6723", + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/auction-post-acceleration.http b/docs/source/tutorial/auction-post-acceleration.http new file mode 100644 index 0000000..ff6b02c --- /dev/null +++ b/docs/source/tutorial/auction-post-acceleration.http @@ -0,0 +1,165 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 2036 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + }, + "submissionMethodDetails": "quick", + "mode": "test", + "auctionPeriod": { + "startDate": "2017-11-30T17:01:17.205813" + }, + "items": [ + { + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "quantity": 5, + "description": "Земля для військовослужбовців", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + } + } + ], + "dgfID": "219560" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/731dc3a4c39a4e0fa97816efac9797d4 + +{ + "access": { + "token": "0a74311e81c84f619214161e9a0dd1ef" + }, + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:20.188830+02:00", + "endDate": "2017-11-30T17:00:24.652197+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-11-30T17:00:24.652197+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "title_en": "[TESTING] ", + "id": "731dc3a4c39a4e0fa97816efac9797d4", + "title": "[ТЕСТУВАННЯ] футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:20.192610+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:20.188830+02:00", + "endDate": "2017-11-30T17:00:24.652197+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-11-30T17:00:24.652197+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:20.188830+02:00", + "submissionMethodDetails": "quick", + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "27e42212d979407a84f6ff1a6ed55e4e", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "mode": "test", + "title_ru": "[ТЕСТИРОВАНИЕ] ", + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/auction-post-attempt-json-data.http b/docs/source/tutorial/auction-post-attempt-json-data.http new file mode 100644 index 0000000..46201e7 --- /dev/null +++ b/docs/source/tutorial/auction-post-attempt-json-data.http @@ -0,0 +1,159 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1968 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "dgfID": "219560", + "auctionPeriod": { + "startDate": "2017-12-14" + }, + "items": [ + { + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "quantity": 5, + "description": "Земля для військовослужбовців", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + } + } + ], + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae + +{ + "access": { + "token": "ccf4d45ff9524ec9ae87f38c43d7b0a3" + }, + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "301d66e275cb4861ba502c1eaafa88ae", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:25.621767+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:25.617199+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/auction-post-attempt-json.http b/docs/source/tutorial/auction-post-attempt-json.http new file mode 100644 index 0000000..492d538 --- /dev/null +++ b/docs/source/tutorial/auction-post-attempt-json.http @@ -0,0 +1,21 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 4 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + + +422 Unprocessable Entity +Content-Type: application/json; charset=UTF-8 + +{ + "status": "error", + "errors": [ + { + "description": "Expecting value: line 1 column 1 (char 0)", + "location": "body", + "name": "data" + } + ] +} + diff --git a/docs/source/tutorial/auction-post-attempt.http b/docs/source/tutorial/auction-post-attempt.http new file mode 100644 index 0000000..8ff9d41 --- /dev/null +++ b/docs/source/tutorial/auction-post-attempt.http @@ -0,0 +1,21 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 4 +Content-Type: application/x-www-form-urlencoded +Host: api-sandbox.ea.openprocurement.org + + +415 Unsupported Media Type +Content-Type: application/json; charset=UTF-8 + +{ + "status": "error", + "errors": [ + { + "description": "Content-Type header should be one of ['application/json']", + "location": "header", + "name": "Content-Type" + } + ] +} + diff --git a/docs/source/tutorial/auction-url.http b/docs/source/tutorial/auction-url.http new file mode 100644 index 0000000..9c5fb7b --- /dev/null +++ b/docs/source/tutorial/auction-url.http @@ -0,0 +1,186 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "auctionUrl": "http://auction-sandbox.openprocurement.org/auctions/301d66e275cb4861ba502c1eaafa88ae", + "enquiryPeriod": { + "startDate": "2017-11-23T16:56:17.202736+02:00", + "endDate": "2017-11-30T16:56:17.202736+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-11-30T17:40:17.202736+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "questions": [ + { + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність", + "date": "2017-11-30T16:56:26.610507+02:00", + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"", + "id": "e966c8cdacc14655907b34713b141d18", + "questionOf": "tender" + } + ], + "owner": "broker", + "id": "301d66e275cb4861ba502c1eaafa88ae", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/68fe48f4593a4de9844e6548344b2696?KeyID=8473a74a&Signature=QZwWxRCYJDGM8BwdJ%252Bh%2FZ7EfjK1tSuHstIWY7Phw8MUeywT2GsNNucpnf2UGZGud5EPLKF1xOz9hX%252BWHtaSeBw%253D%253D", + "title": "AwardCriteria.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.157192+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + }, + { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=CTN%2FyvXW3%252Bz7lGcIGWXJGAYdUUudzcpWk1%2F9TldffuMmRChRSJJsi%2F%2FHBzjXb%252B0f4DuzUiUbq8bqD%2FP70jlFAQ%253D%253D", + "title": "first_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.293411+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.293438+02:00", + "id": "f143cdc5fef246f59d11cd3bc7c72d46" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Second illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bfd750de3e7b49b5a991b6cdaf2c208e?KeyID=8473a74a&Signature=nXLYMy2OkK2aIJDwV6kn7z3BkQD4wMe1ccc9%252BSvKDcUemJGUcmxtcGPn57JUQ6AJznS4IfCvaHVyDo5Aez7pDA%253D%253D", + "title": "second_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.376954+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.376981+02:00", + "id": "eb64e2d0457e42c89aed5861301d3d06" + }, + { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Third illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2d40e8da608c4f10b9432671cf47c9aa?KeyID=8473a74a&Signature=AGnUbHWEz4OOa7kxT1%2Fj4Ml7cNOw%252BcsUiDVX9HQhwqAdi4UGtaxWqeAZ2YhsI20lzMp67Fq%252BUo6jPmWdLdWuAQ%253D%253D", + "title": "third_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.434267+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.434293+02:00", + "id": "fdafece528e54fe5a7b38f025be993c3" + }, + { + "title": "Familiarization with bank asset", + "format": "offline/on-site-examination", + "accessDetails": "Familiar with asset: days, time, address", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.520040+02:00", + "documentType": "x_dgfAssetFamiliarization", + "dateModified": "2017-11-30T16:56:26.520067+02:00", + "id": "b31139eea309435592a725e115dc90ed" + } + ], + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:27.371645+02:00", + "status": "active.auction", + "tenderPeriod": { + "startDate": "2017-11-23T16:56:17.202736+02:00", + "endDate": "2017-11-30T16:56:17.202736+02:00" + }, + "auctionPeriod": { + "startDate": "2017-11-30T16:56:17.202736+02:00", + "shouldStartAfter": "2017-12-01T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:25.617199+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/bidder-auction-protocol.http b/docs/source/tutorial/bidder-auction-protocol.http new file mode 100644 index 0000000..cf6b551 --- /dev/null +++ b/docs/source/tutorial/bidder-auction-protocol.http @@ -0,0 +1,36 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53/documents?acc_token=73842c515600468a8829fea44817fce1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 385 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/326d29c8df4744149f6082d061e6492e?KeyID=8473a74a&Signature=4cNJZ9v3X0JCIiaW9cFX2nbH10INN6%2B%2FLVLrM4p%2FwQQo%2FBU2JD1ryXuz6r6SxP7hcfQpgAtoL%2F2WB5QRENZvCA%3D%3D", + "title": "SignedAuctionProtocol.pdf", + "format": "application/pdf", + "hash": "md5:00000000000000000000000000000000", + "documentType": "auctionProtocol" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53/documents/de5b4f4f5aa04ef6a16606d1152b061a + +{ + "data": { + "dateModified": "2017-11-30T16:56:28.083997+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/326d29c8df4744149f6082d061e6492e?KeyID=8473a74a&Signature=W07o9qqLEOV3dvjZZVzBFeolqx4QEUoFCZPnHeu4xyBsP7NJma%252BZINjCbfVSmXeRHYiAnDikplownjV%2FJE%252B6BQ%253D%253D", + "author": "bid_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.083969+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "de5b4f4f5aa04ef6a16606d1152b061a" + } +} + diff --git a/docs/source/tutorial/bidder-documents.http b/docs/source/tutorial/bidder-documents.http new file mode 100644 index 0000000..e6b1c52 --- /dev/null +++ b/docs/source/tutorial/bidder-documents.http @@ -0,0 +1,23 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents?acc_token=a94a2b6627aa46f3bbb83ff885e3beae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents/3bd15f6db7764b7e9651fdf15dde6316?download=4accad3bd17a4f0baa9f6a8ea96397f7", + "title": "Proposal.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.994147+02:00", + "dateModified": "2017-11-30T16:56:26.994175+02:00", + "id": "3bd15f6db7764b7e9651fdf15dde6316" + } + ] +} + diff --git a/docs/source/tutorial/bidder-participation-url.http b/docs/source/tutorial/bidder-participation-url.http new file mode 100644 index 0000000..72e9ba4 --- /dev/null +++ b/docs/source/tutorial/bidder-participation-url.http @@ -0,0 +1,58 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4?acc_token=a94a2b6627aa46f3bbb83ff885e3beae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "documents": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents/3bd15f6db7764b7e9651fdf15dde6316?download=4accad3bd17a4f0baa9f6a8ea96397f7", + "title": "Proposal.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.994147+02:00", + "dateModified": "2017-11-30T16:56:26.994175+02:00", + "id": "3bd15f6db7764b7e9651fdf15dde6316" + } + ], + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:26.821209+02:00", + "qualified": true, + "tenderers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "owner": "broker", + "id": "afaa508128da4829b9202fe300965bf4", + "participationUrl": "http://auction-sandbox.openprocurement.org/auctions/301d66e275cb4861ba502c1eaafa88ae?key_for_bid=afaa508128da4829b9202fe300965bf4" + } +} + diff --git a/docs/source/tutorial/bidder2-participation-url.http b/docs/source/tutorial/bidder2-participation-url.http new file mode 100644 index 0000000..72473e7 --- /dev/null +++ b/docs/source/tutorial/bidder2-participation-url.http @@ -0,0 +1,46 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/0d76a3f619044106b9bcdc0e57e93dad?acc_token=73842c515600468a8829fea44817fce1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:27.113380+02:00", + "qualified": true, + "tenderers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "owner": "broker", + "id": "0d76a3f619044106b9bcdc0e57e93dad", + "participationUrl": "http://auction-sandbox.openprocurement.org/auctions/301d66e275cb4861ba502c1eaafa88ae?key_for_bid=0d76a3f619044106b9bcdc0e57e93dad" + } +} + diff --git a/docs/source/tutorial/blank-auction-view.http b/docs/source/tutorial/blank-auction-view.http new file mode 100644 index 0000000..7c16573 --- /dev/null +++ b/docs/source/tutorial/blank-auction-view.http @@ -0,0 +1,91 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "301d66e275cb4861ba502c1eaafa88ae", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:25.621767+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:25.617199+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/blank-finauction-view.http b/docs/source/tutorial/blank-finauction-view.http new file mode 100644 index 0000000..6166dde --- /dev/null +++ b/docs/source/tutorial/blank-finauction-view.http @@ -0,0 +1,94 @@ +GET /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:23.942831+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "73e1598288054eb98e8153ee9e69bb28", + "eligibilityCriteria_ru": "К участию допускаются только лицензированные финансовые учреждения.", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "eligibilityCriteria_en": "Only licensed financial institutions are eligible to participate.", + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:23.946137+02:00", + "status": "active.tendering", + "eligibilityCriteria": "До участі допускаються лише ліцензовані фінансові установи.", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:23.942831+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfFinancialAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:23.942831+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "e16351a78632484e8756b1dea38e6201", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/cav_v2_codes_item_address_optional.json b/docs/source/tutorial/cav_v2_codes_item_address_optional.json new file mode 100644 index 0000000..085b27a --- /dev/null +++ b/docs/source/tutorial/cav_v2_codes_item_address_optional.json @@ -0,0 +1 @@ +["07000000-9", "07100000-0", "07110000-3", "07120000-6", "07121000-3", "07122000-0", "07123000-7", "07124000-4", "07125000-1", "07126000-8", "07127000-5", "07200000-1", "07210000-4", "07220000-7", "07221000-4", "07222000-1", "07223000-8", "07224000-5", "07225000-2", "07226000-9", "07227000-6", "08100000-7", "08110000-0", "08120000-3", "08130000-6", "08140000-9", "08150000-2", "08160000-5"] diff --git a/docs/source/tutorial/confirm-qualification.http b/docs/source/tutorial/confirm-qualification.http new file mode 100644 index 0000000..01d7eb8 --- /dev/null +++ b/docs/source/tutorial/confirm-qualification.http @@ -0,0 +1,94 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 30 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "active" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "active", + "paymentPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:56:28.528529+02:00" + }, + "documents": [ + { + "dateModified": "2017-11-30T16:56:28.083997+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/326d29c8df4744149f6082d061e6492e?KeyID=8473a74a&Signature=W07o9qqLEOV3dvjZZVzBFeolqx4QEUoFCZPnHeu4xyBsP7NJma%252BZINjCbfVSmXeRHYiAnDikplownjV%2FJE%252B6BQ%253D%253D", + "author": "bid_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.083969+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "de5b4f4f5aa04ef6a16606d1152b061a" + }, + { + "dateModified": "2017-11-30T16:56:28.217417+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/79f7d75e9ff34c1d94289241ebd04a46?KeyID=8473a74a&Signature=ZZf5dIDTAFetGGoNyGHK0TaTX%2FMo%2FTcKq%2FTatSSpuIZleTjJFvbciSiMq9MNq3mZGWRdK%2FYKfT0lkoOKYooXDA%253D%253D", + "author": "auction_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.217384+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "edc7c486de494ac3bdcc0b456d006e4a" + } + ], + "verificationPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:56:28.375177+02:00" + }, + "complaintPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:56:28.528529+02:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "signingPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T17:16:29.509749+02:00" + }, + "bid_id": "0d76a3f619044106b9bcdc0e57e93dad", + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:28.536946+02:00", + "id": "add0cbb7aa114e7cb6f5e127071f8b53" + } +} + diff --git a/docs/source/tutorial/cpv_codes_item_address_optional.json b/docs/source/tutorial/cpv_codes_item_address_optional.json new file mode 100644 index 0000000..a9f9499 --- /dev/null +++ b/docs/source/tutorial/cpv_codes_item_address_optional.json @@ -0,0 +1 @@ +["45000000-7", "45100000-8", "45110000-1", "45111000-8", "45111100-9", "45111200-0", "45111210-3", "45111211-0", "45111212-7", "45111213-4", "45111214-1", "45111220-6", "45111230-9", "45111240-2", "45111250-5", "45111260-8", "45111290-7", "45111291-4", "45111300-1", "45111310-4", "45111320-7", "45112000-5", "45112100-6", "45112200-7", "45112210-0", "45112300-8", "45112310-1", "45112320-4", "45112330-7", "45112340-0", "45112350-3", "45112360-6", "45112400-9", "45112410-2", "45112420-5", "45112440-1", "45112441-8", "45112450-4", "45112500-0", "45112600-1", "45112700-2", "45112710-5", "45112711-2", "45112712-9", "45112713-6", "45112714-3", "45112720-8", "45112721-5", "45112722-2", "45112723-9", "45112730-1", "45112740-4", "45113000-2", "45120000-4", "45121000-1", "45122000-8", "45200000-9", "45210000-2", "45211000-9", "45211100-0", "45211200-1", "45211300-2", "45211310-5", "45211320-8", "45211340-4", "45211341-1", "45211350-7", "45211360-0", "45211370-3", "45212000-6", "45212100-7", "45212110-0", "45212120-3", "45212130-6", "45212140-9", "45212150-2", "45212160-5", "45212170-8", "45212171-5", "45212172-2", "45212180-1", "45212190-4", "45212200-8", "45212210-1", "45212211-8", "45212212-5", "45212213-2", "45212220-4", "45212221-1", "45212222-8", "45212223-5", "45212224-2", "45212225-9", "45212230-7", "45212290-5", "45212300-9", "45212310-2", "45212311-9", "45212312-6", "45212313-3", "45212314-0", "45212320-5", "45212321-2", "45212322-9", "45212330-8", "45212331-5", "45212340-1", "45212350-4", "45212351-1", "45212352-8", "45212353-5", "45212354-2", "45212360-7", "45212361-4", "45212400-0", "45212410-3", "45212411-0", "45212412-7", "45212413-4", "45212420-6", "45212421-3", "45212422-0", "45212423-7", "45212500-1", "45212600-2", "45213000-3", "45213100-4", "45213110-7", "45213111-4", "45213112-1", "45213120-0", "45213130-3", "45213140-6", "45213141-3", "45213142-0", "45213150-9", "45213200-5", "45213210-8", "45213220-1", "45213221-8", "45213230-4", "45213240-7", "45213241-4", "45213242-1", "45213250-0", "45213251-7", "45213252-4", "45213260-3", "45213270-6", "45213280-9", "45213300-6", "45213310-9", "45213311-6", "45213312-3", "45213313-0", "45213314-7", "45213315-4", "45213316-1", "45213320-2", "45213321-9", "45213322-6", "45213330-5", "45213331-2", "45213332-9", "45213333-6", "45213340-8", "45213341-5", "45213342-2", "45213350-1", "45213351-8", "45213352-5", "45213353-2", "45213400-7", "45214000-0", "45214100-1", "45214200-2", "45214210-5", "45214220-8", "45214230-1", "45214300-3", "45214310-6", "45214320-9", "45214400-4", "45214410-7", "45214420-0", "45214430-3", "45214500-5", "45214600-6", "45214610-9", "45214620-2", "45214630-5", "45214631-2", "45214640-8", "45214700-7", "45214710-0", "45214800-8", "45215000-7", "45215100-8", "45215110-1", "45215120-4", "45215130-7", "45215140-0", "45215141-7", "45215142-4", "45215143-1", "45215144-8", "45215145-5", "45215146-2", "45215147-9", "45215148-6", "45215200-9", "45215210-2", "45215212-6", "45215213-3", "45215214-0", "45215215-7", "45215220-5", "45215221-2", "45215222-9", "45215300-0", "45215400-1", "45215500-2", "45216000-4", "45216100-5", "45216110-8", "45216111-5", "45216112-2", "45216113-9", "45216114-6", "45216120-1", "45216121-8", "45216122-5", "45216123-2", "45216124-9", "45216125-6", "45216126-3", "45216127-0", "45216128-7", "45216129-4", "45216200-6", "45216220-2", "45216230-5", "45216250-1", "45217000-1", "45220000-5", "45221000-2", "45221100-3", "45221110-6", "45221111-3", "45221112-0", "45221113-7", "45221114-4", "45221115-1", "45221117-5", "45221118-2", "45221119-9", "45221120-9", "45221121-6", "45221122-3", "45221200-4", "45221210-7", "45221211-4", "45221213-8", "45221214-5", "45221220-0", "45221230-3", "45221240-6", "45221241-3", "45221242-0", "45221243-7", "45221244-4", "45221245-1", "45221246-8", "45221247-5", "45221248-2", "45221250-9", "45222000-9", "45222100-0", "45222110-3", "45222200-1", "45222300-2", "45223000-6", "45223100-7", "45223110-0", "45223200-8", "45223210-1", "45223220-4", "45223300-9", "45223310-2", "45223320-5", "45223400-0", "45223500-1", "45223600-2", "45223700-3", "45223710-6", "45223720-9", "45223800-4", "45223810-7", "45223820-0", "45223821-7", "45223822-4", "45230000-8", "45231000-5", "45231100-6", "45231110-9", "45231111-6", "45231112-3", "45231113-0", "45231200-7", "45231210-0", "45231220-3", "45231221-0", "45231222-7", "45231223-4", "45231300-8", "45231400-9", "45231500-0", "45231510-3", "45231600-1", "45232000-2", "45232100-3", "45232120-9", "45232121-6", "45232130-2", "45232140-5", "45232141-2", "45232142-9", "45232150-8", "45232151-5", "45232152-2", "45232153-9", "45232154-6", "45232200-4", "45232210-7", "45232220-0", "45232221-7", "45232300-5", "45232310-8", "45232311-5", "45232320-1", "45232330-4", "45232331-1", "45232332-8", "45232340-7", "45232400-6", "45232410-9", "45232411-6", "45232420-2", "45232421-9", "45232422-6", "45232423-3", "45232424-0", "45232430-5", "45232431-2", "45232440-8", "45232450-1", "45232451-8", "45232452-5", "45232453-2", "45232454-9", "45232460-4", "45232470-7", "45233000-9", "45233100-0", "45233110-3", "45233120-6", "45233121-3", "45233122-0", "45233123-7", "45233124-4", "45233125-1", "45233126-8", "45233127-5", "45233128-2", "45233129-9", "45233130-9", "45233131-6", "45233139-3", "45233140-2", "45233141-9", "45233142-6", "45233144-0", "45233150-5", "45233160-8", "45233161-5", "45233162-2", "45233200-1", "45233210-4", "45233220-7", "45233221-4", "45233222-1", "45233223-8", "45233224-5", "45233225-2", "45233226-9", "45233227-6", "45233228-3", "45233229-0", "45233250-6", "45233251-3", "45233252-0", "45233253-7", "45233260-9", "45233261-6", "45233262-3", "45233270-2", "45233280-5", "45233290-8", "45233291-5", "45233292-2", "45233293-9", "45233294-6", "45233300-2", "45233310-5", "45233320-8", "45233330-1", "45233340-4", "45234000-6", "45234100-7", "45234110-0", "45234111-7", "45234112-4", "45234113-1", "45234114-8", "45234115-5", "45234116-2", "45234120-3", "45234121-0", "45234122-7", "45234123-4", "45234124-1", "45234125-8", "45234126-5", "45234127-2", "45234128-9", "45234129-6", "45234130-6", "45234140-9", "45234160-5", "45234170-8", "45234180-1", "45234181-8", "45234200-8", "45234210-1", "45234220-4", "45234230-7", "45234240-0", "45234250-3", "45235000-3", "45235100-4", "45235110-7", "45235111-4", "45235200-5", "45235210-8", "45235300-6", "45235310-9", "45235311-6", "45235320-2", "45236000-0", "45236100-1", "45236110-4", "45236111-1", "45236112-8", "45236113-5", "45236114-2", "45236119-7", "45236200-2", "45236210-5", "45236220-8", "45236230-1", "45236250-7", "45236290-9", "45236300-3", "45237000-7", "45240000-1", "45241000-8", "45241100-9", "45241200-0", "45241300-1", "45241400-2", "45241500-3", "45241600-4", "45242000-5", "45242100-6", "45242110-9", "45242200-7", "45242210-0", "45243000-2", "45243100-3", "45243110-6", "45243200-4", "45243300-5", "45243400-6", "45243500-7", "45243510-0", "45243600-8", "45244000-9", "45244100-0", "45244200-1", "45245000-6", "45246000-3", "45246100-4", "45246200-5", "45246400-7", "45246410-0", "45246500-8", "45246510-1", "45247000-0", "45247100-1", "45247110-4", "45247111-1", "45247112-8", "45247120-7", "45247130-0", "45247200-2", "45247210-5", "45247211-2", "45247212-9", "45247220-8", "45247230-1", "45247240-4", "45247270-3", "45248000-7", "45248100-8", "45248200-9", "45248300-0", "45248400-1", "45248500-2", "45250000-4", "45251000-1", "45251100-2", "45251110-5", "45251111-2", "45251120-8", "45251140-4", "45251141-1", "45251142-8", "45251143-5", "45251150-7", "45251160-0", "45251200-3", "45251220-9", "45251230-2", "45251240-5", "45251250-8", "45252000-8", "45252100-9", "45252110-2", "45252120-5", "45252121-2", "45252122-9", "45252123-6", "45252124-3", "45252125-0", "45252126-7", "45252127-4", "45252130-8", "45252140-1", "45252150-4", "45252200-0", "45252210-3", "45252300-1", "45253000-5", "45253100-6", "45253200-7", "45253300-8", "45253310-1", "45253320-4", "45253400-9", "45253500-0", "45253600-1", "45253700-2", "45253800-3", "45254000-2", "45254100-3", "45254110-6", "45254200-4", "45255000-9", "45255100-0", "45255110-3", "45255120-6", "45255121-3", "45255200-1", "45255210-4", "45255300-2", "45255400-3", "45255410-6", "45255420-9", "45255430-2", "45255500-4", "45255600-5", "45255700-6", "45255800-7", "45259000-7", "45259100-8", "45259200-9", "45259300-0", "45259900-6", "45260000-7", "45261000-4", "45261100-5", "45261200-6", "45261210-9", "45261211-6", "45261212-3", "45261213-0", "45261214-7", "45261215-4", "45261220-2", "45261221-9", "45261222-6", "45261300-7", "45261310-0", "45261320-3", "45261400-8", "45261410-1", "45261420-4", "45261900-3", "45261910-6", "45261920-9", "45262000-1", "45262100-2", "45262110-5", "45262120-8", "45262200-3", "45262210-6", "45262211-3", "45262212-0", "45262213-7", "45262220-9", "45262300-4", "45262310-7", "45262311-4", "45262320-0", "45262321-7", "45262330-3", "45262340-6", "45262350-9", "45262360-2", "45262370-5", "45262400-5", "45262410-8", "45262420-1", "45262421-8", "45262422-5", "45262423-2", "45262424-9", "45262425-6", "45262426-3", "45262500-6", "45262510-9", "45262511-6", "45262512-3", "45262520-2", "45262521-9", "45262522-6", "45262600-7", "45262610-0", "45262620-3", "45262630-6", "45262640-9", "45262650-2", "45262660-5", "45262670-8", "45262680-1", "45262690-4", "45262700-8", "45262710-1", "45262800-9", "45262900-0", "45300000-0", "45310000-3", "45311000-0", "45311100-1", "45311200-2", "45312000-7", "45312100-8", "45312200-9", "45312300-0", "45312310-3", "45312311-0", "45312320-6", "45312330-9", "45313000-4", "45313100-5", "45313200-6", "45313210-9", "45314000-1", "45314100-2", "45314120-8", "45314200-3", "45314300-4", "45314310-7", "45314320-0", "45315000-8", "45315100-9", "45315200-0", "45315300-1", "45315400-2", "45315500-3", "45315600-4", "45315700-5", "45316000-5", "45316100-6", "45316110-9", "45316200-7", "45316210-0", "45316211-7", "45316212-4", "45316213-1", "45316220-3", "45316230-6", "45317000-2", "45317100-3", "45317200-4", "45317300-5", "45317400-6", "45320000-6", "45321000-3", "45323000-7", "45324000-4", "45330000-9", "45331000-6", "45331100-7", "45331110-0", "45331200-8", "45331210-1", "45331211-8", "45331220-4", "45331221-1", "45331230-7", "45331231-4", "45332000-3", "45332200-5", "45332300-6", "45332400-7", "45333000-0", "45333100-1", "45333200-2", "45340000-2", "45341000-9", "45342000-6", "45343000-3", "45343100-4", "45343200-5", "45343210-8", "45343220-1", "45343230-4", "45350000-5", "45351000-2", "45400000-1", "45410000-4", "45420000-7", "45421000-4", "45421100-5", "45421110-8", "45421111-5", "45421112-2", "45421120-1", "45421130-4", "45421131-1", "45421132-8", "45421140-7", "45421141-4", "45421142-1", "45421143-8", "45421144-5", "45421145-2", "45421146-9", "45421147-6", "45421148-3", "45421150-0", "45421151-7", "45421152-4", "45421153-1", "45421160-3", "45422000-1", "45422100-2", "45430000-0", "45431000-7", "45431100-8", "45431200-9", "45432000-4", "45432100-5", "45432110-8", "45432111-5", "45432112-2", "45432113-9", "45432114-6", "45432120-1", "45432121-8", "45432130-4", "45432200-6", "45432210-9", "45432220-2", "45440000-3", "45441000-0", "45442000-7", "45442100-8", "45442110-1", "45442120-4", "45442121-1", "45442180-2", "45442190-5", "45442200-9", "45442210-2", "45442300-0", "45443000-4", "45450000-6", "45451000-3", "45451100-4", "45451200-5", "45451300-6", "45452000-0", "45452100-1", "45453000-7", "45453100-8", "45454000-4", "45454100-5", "45500000-2", "45510000-5", "45520000-8", "48000000-8", "48100000-9", "48110000-2", "48120000-5", "48121000-2", "48130000-8", "48131000-5", "48132000-2", "48140000-1", "48150000-4", "48151000-1", "48160000-7", "48161000-4", "48170000-0", "48180000-3", "48190000-6", "48200000-0", "48210000-3", "48211000-0", "48212000-7", "48213000-4", "48214000-1", "48215000-8", "48216000-5", "48217000-2", "48217100-3", "48217200-4", "48217300-5", "48218000-9", "48219000-6", "48219100-7", "48219200-8", "48219300-9", "48219400-0", "48219500-1", "48219600-2", "48219700-3", "48219800-4", "48220000-6", "48221000-3", "48222000-0", "48223000-7", "48224000-4", "48300000-1", "48310000-4", "48311000-1", "48311100-2", "48312000-8", "48313000-5", "48313100-6", "48314000-2", "48315000-9", "48316000-6", "48317000-3", "48318000-0", "48319000-7", "48320000-7", "48321000-4", "48321100-5", "48322000-1", "48323000-8", "48324000-5", "48325000-2", "48326000-9", "48326100-0", "48327000-6", "48328000-3", "48329000-0", "48330000-0", "48331000-7", "48332000-4", "48333000-1", "48400000-2", "48410000-5", "48411000-2", "48412000-9", "48420000-8", "48421000-5", "48422000-2", "48430000-1", "48440000-4", "48441000-1", "48442000-8", "48443000-5", "48444000-2", "48444100-3", "48445000-9", "48450000-7", "48451000-4", "48460000-0", "48461000-7", "48462000-4", "48463000-1", "48470000-3", "48480000-6", "48481000-3", "48482000-0", "48490000-9", "48500000-3", "48510000-6", "48511000-3", "48512000-0", "48513000-7", "48514000-4", "48515000-1", "48516000-8", "48517000-5", "48518000-2", "48519000-9", "48520000-9", "48521000-6", "48522000-3", "48600000-4", "48610000-7", "48611000-4", "48612000-1", "48613000-8", "48614000-5", "48620000-0", "48621000-7", "48622000-4", "48623000-1", "48624000-8", "48625000-5", "48626000-2", "48627000-9", "48628000-9", "48700000-5", "48710000-8", "48720000-1", "48730000-4", "48731000-1", "48732000-8", "48740000-7", "48750000-0", "48760000-3", "48761000-0", "48770000-6", "48771000-3", "48772000-0", "48773000-7", "48773100-8", "48780000-9", "48781000-6", "48782000-3", "48783000-0", "48790000-2", "48800000-6", "48810000-9", "48811000-6", "48812000-3", "48813000-0", "48813100-1", "48813200-2", "48814000-7", "48814100-8", "48814200-9", "48814300-0", "48814400-1", "48814500-2", "48820000-2", "48821000-9", "48822000-6", "48823000-3", "48824000-0", "48825000-7", "48900000-7", "48910000-0", "48911000-7", "48912000-4", "48913000-1", "48920000-3", "48921000-0", "48930000-6", "48931000-3", "48932000-0", "48940000-9", "48941000-6", "48942000-3", "48950000-2", "48951000-9", "48952000-6", "48960000-5", "48961000-2", "48962000-9", "48970000-8", "48971000-5", "48972000-2", "48980000-1", "48981000-8", "48982000-5", "48983000-2", "48984000-9", "48985000-6", "48986000-3", "48987000-0", "48990000-4", "48991000-1", "50000000-5", "50100000-6", "50110000-9", "50111000-6", "50111100-7", "50111110-0", "50112000-3", "50112100-4", "50112110-7", "50112111-4", "50112120-0", "50112200-5", "50112300-6", "50113000-0", "50113100-1", "50113200-2", "50114000-7", "50114100-8", "50114200-9", "50115000-4", "50115100-5", "50115200-6", "50116000-1", "50116100-2", "50116200-3", "50116300-4", "50116400-5", "50116500-6", "50116510-9", "50116600-7", "50117000-8", "50117100-9", "50117200-0", "50117300-1", "50118000-5", "50118100-6", "50118110-9", "50118200-7", "50118300-8", "50118400-9", "50118500-0", "50190000-3", "50200000-7", "50210000-0", "50211000-7", "50211100-8", "50211200-9", "50211210-2", "50211211-9", "50211212-6", "50211300-0", "50211310-3", "50212000-4", "50220000-3", "50221000-0", "50221100-1", "50221200-2", "50221300-3", "50221400-4", "50222000-7", "50222100-8", "50223000-4", "50224000-1", "50224100-2", "50224200-3", "50225000-8", "50229000-6", "50230000-6", "50232000-0", "50232100-1", "50232110-4", "50232200-2", "50240000-9", "50241000-6", "50241100-7", "50241200-8", "50242000-3", "50243000-0", "50244000-7", "50245000-4", "50246000-1", "50246100-2", "50246200-3", "50246300-4", "50246400-5", "50300000-8", "50310000-1", "50311000-8", "50311400-2", "50312000-5", "50312100-6", "50312110-9", "50312120-2", "50312200-7", "50312210-0", "50312220-3", "50312300-8", "50312310-1", "50312320-4", "50312400-9", "50312410-2", "50312420-5", "50312600-1", "50312610-4", "50312620-7", "50313000-2", "50313100-3", "50313200-4", "50314000-9", "50315000-6", "50316000-3", "50317000-0", "50320000-4", "50321000-1", "50322000-8", "50323000-5", "50323100-6", "50323200-7", "50324000-2", "50324100-3", "50324200-4", "50330000-7", "50331000-4", "50332000-1", "50333000-8", "50333100-9", "50333200-0", "50334000-5", "50334100-6", "50334110-9", "50334120-2", "50334130-5", "50334140-8", "50334200-7", "50334300-8", "50334400-9", "50340000-0", "50341000-7", "50341100-8", "50341200-9", "50342000-4", "50343000-1", "50344000-8", "50344100-9", "50344200-0", "50400000-9", "50410000-2", "50411000-9", "50411100-0", "50411200-1", "50411300-2", "50411400-3", "50411500-4", "50412000-6", "50413000-3", "50413100-4", "50413200-5", "50420000-5", "50421000-2", "50421100-3", "50421200-4", "50422000-9", "50430000-8", "50431000-5", "50432000-2", "50433000-9", "50500000-0", "50510000-3", "50511000-0", "50511100-1", "50511200-2", "50512000-7", "50513000-4", "50514000-1", "50514100-2", "50514200-3", "50514300-4", "50530000-9", "50531000-6", "50531100-7", "50531200-8", "50531300-9", "50531400-0", "50531500-1", "50531510-4", "50532000-3", "50532100-4", "50532200-5", "50532300-6", "50532400-7", "50600000-1", "50610000-4", "50620000-7", "50630000-0", "50640000-3", "50650000-6", "50660000-9", "50700000-2", "50710000-5", "50711000-2", "50712000-9", "50720000-8", "50721000-5", "50730000-1", "50740000-4", "50750000-7", "50760000-0", "50800000-3", "50810000-6", "50820000-9", "50821000-6", "50822000-3", "50830000-2", "50840000-5", "50841000-2", "50842000-9", "50850000-8", "50860000-1", "50870000-4", "50880000-7", "50881000-4", "50882000-1", "50883000-8", "50884000-5", "51000000-9", "51100000-3", "51110000-6", "51111000-3", "51111100-4", "51111200-5", "51111300-6", "51112000-0", "51112100-1", "51112200-2", "51120000-9", "51121000-6", "51122000-3", "51130000-2", "51131000-9", "51133000-3", "51133100-4", "51134000-0", "51135000-7", "51135100-8", "51135110-1", "51140000-5", "51141000-2", "51142000-9", "51143000-6", "51144000-3", "51145000-0", "51146000-7", "51200000-4", "51210000-7", "51211000-4", "51212000-1", "51213000-8", "51214000-5", "51215000-2", "51216000-9", "51220000-0", "51221000-7", "51230000-3", "51240000-6", "51300000-5", "51310000-8", "51311000-5", "51312000-2", "51313000-9", "51314000-6", "51320000-1", "51321000-8", "51322000-5", "51330000-4", "51340000-7", "51350000-0", "51400000-6", "51410000-9", "51411000-6", "51412000-3", "51413000-0", "51414000-7", "51415000-4", "51416000-1", "51420000-2", "51430000-5", "51500000-7", "51510000-0", "51511000-7", "51511100-8", "51511110-1", "51511200-9", "51511300-0", "51511400-1", "51514000-8", "51514100-9", "51514110-2", "51520000-3", "51521000-0", "51522000-7", "51530000-6", "51540000-9", "51541000-6", "51541100-7", "51541200-8", "51541300-9", "51541400-0", "51542000-3", "51542100-4", "51542200-5", "51542300-6", "51543000-0", "51543100-1", "51543200-2", "51543300-3", "51543400-4", "51544000-7", "51544100-8", "51544200-9", "51545000-4", "51550000-2", "51600000-8", "51610000-1", "51611000-8", "51611100-9", "51611110-2", "51611120-5", "51612000-5", "51620000-4", "51700000-9", "51800000-0", "51810000-3", "51820000-6", "51900000-1", "55000000-0", "55100000-1", "55110000-4", "55120000-7", "55130000-0", "55200000-2", "55210000-5", "55220000-8", "55221000-5", "55240000-4", "55241000-1", "55242000-8", "55243000-5", "55250000-7", "55260000-0", "55270000-3", "55300000-3", "55310000-6", "55311000-3", "55312000-0", "55320000-9", "55321000-6", "55322000-3", "55330000-2", "55400000-4", "55410000-7", "55500000-5", "55510000-8", "55511000-5", "55512000-2", "55520000-1", "55521000-8", "55521100-9", "55521200-0", "55522000-5", "55523000-2", "55523100-3", "55524000-9", "55900000-9", "60000000-8", "60100000-9", "60112000-6", "60120000-5", "60130000-8", "60140000-1", "60150000-4", "60160000-7", "60161000-4", "60170000-0", "60171000-7", "60172000-4", "60180000-3", "60181000-0", "60182000-7", "60183000-4", "60200000-0", "60210000-3", "60220000-6", "60300000-1", "60400000-2", "60410000-5", "60411000-2", "60420000-8", "60421000-5", "60423000-9", "60424000-6", "60424100-7", "60424110-0", "60424120-3", "60440000-4", "60441000-1", "60442000-8", "60443000-5", "60443100-6", "60444000-2", "60444100-3", "60445000-9", "60500000-3", "60510000-6", "60520000-9", "60600000-4", "60610000-7", "60620000-0", "60630000-3", "60640000-6", "60650000-9", "60651000-6", "60651100-7", "60651200-8", "60651300-9", "60651400-0", "60651500-1", "60651600-2", "60653000-0", "63000000-9", "63100000-0", "63110000-3", "63111000-0", "63112000-7", "63112100-8", "63112110-1", "63120000-6", "63121000-3", "63121100-4", "63121110-7", "63122000-0", "63500000-4", "63510000-7", "63511000-4", "63512000-1", "63513000-8", "63514000-5", "63515000-2", "63516000-9", "63520000-0", "63521000-7", "63522000-4", "63523000-1", "63524000-8", "63700000-6", "63710000-9", "63711000-6", "63711100-7", "63711200-8", "63712000-3", "63712100-4", "63712200-5", "63712210-8", "63712300-6", "63712310-9", "63712311-6", "63712320-2", "63712321-9", "63712400-7", "63712500-8", "63712600-9", "63712700-0", "63712710-3", "63720000-2", "63721000-9", "63721100-0", "63721200-1", "63721300-2", "63721400-3", "63721500-4", "63722000-6", "63723000-3", "63724000-0", "63724100-1", "63724110-4", "63724200-2", "63724300-3", "63724310-6", "63724400-4", "63725000-7", "63725100-8", "63725200-9", "63725300-0", "63726000-4", "63726100-5", "63726200-6", "63726300-7", "63726400-8", "63726500-9", "63726600-0", "63726610-3", "63726620-6", "63726700-1", "63726800-2", "63726900-3", "63727000-1", "63727100-2", "63727200-3", "63730000-5", "63731000-2", "63731100-3", "63732000-9", "63733000-6", "63734000-3", "64000000-6", "64100000-7", "64110000-0", "64111000-7", "64112000-4", "64113000-1", "64114000-8", "64115000-5", "64116000-2", "64120000-3", "64121000-0", "64121100-1", "64121200-2", "64122000-7", "64200000-8", "64210000-1", "64211000-8", "64211100-9", "64211200-0", "64212000-5", "64212100-6", "64212200-7", "64212300-8", "64212400-9", "64212500-0", "64212600-1", "64212700-2", "64212800-3", "64212900-4", "64213000-2", "64214000-9", "64214100-0", "64214200-1", "64214400-3", "64215000-6", "64216000-3", "64216100-4", "64216110-7", "64216120-0", "64216130-3", "64216140-6", "64216200-5", "64216210-8", "64216300-6", "64220000-4", "64221000-1", "64222000-8", "64223000-5", "64224000-2", "64225000-9", "64226000-6", "64227000-3", "64228000-0", "64228100-1", "64228200-2", "65000000-3", "65100000-4", "65110000-7", "65111000-4", "65120000-0", "65121000-7", "65122000-0", "65123000-3", "65130000-3", "65200000-5", "65210000-8", "65300000-6", "65310000-9", "65320000-2", "65400000-7", "65410000-0", "65500000-8", "66000000-0", "66100000-1", "66110000-4", "66111000-1", "66112000-8", "66113000-5", "66113100-6", "66114000-2", "66115000-9", "66120000-7", "66121000-4", "66122000-1", "66130000-0", "66131000-7", "66131100-8", "66132000-4", "66133000-1", "66140000-3", "66141000-0", "66150000-6", "66151000-3", "66151100-4", "66152000-0", "66160000-9", "66161000-6", "66162000-3", "66170000-2", "66171000-9", "66172000-6", "66180000-5", "66190000-8", "66500000-5", "66510000-8", "66511000-5", "66512000-2", "66512100-3", "66512200-4", "66512210-7", "66512220-0", "66513000-9", "66513100-0", "66513200-1", "66514000-6", "66514100-7", "66514110-0", "66514120-3", "66514130-6", "66514140-9", "66514150-2", "66514200-8", "66515000-3", "66515100-4", "66515200-5", "66515300-6", "66515400-7", "66515410-0", "66515411-7", "66516000-0", "66516100-1", "66516200-2", "66516300-3", "66516400-4", "66516500-5", "66517000-7", "66517100-8", "66517200-9", "66517300-0", "66518000-4", "66518100-5", "66518200-6", "66518300-7", "66519000-1", "66519100-2", "66519200-3", "66519300-4", "66519310-7", "66519400-5", "66519500-6", "66519600-7", "66519700-8", "66520000-1", "66521000-8", "66522000-5", "66523000-2", "66523100-3", "66600000-6", "66700000-7", "66710000-0", "66720000-3", "71000000-8", "71200000-0", "71210000-3", "71220000-6", "71221000-3", "71222000-0", "71222100-1", "71222200-2", "71223000-7", "71230000-9", "71240000-2", "71241000-9", "71242000-6", "71243000-3", "71244000-0", "71245000-7", "71246000-4", "71247000-1", "71248000-8", "71250000-5", "71251000-2", "71300000-1", "71310000-4", "71311000-1", "71311100-2", "71311200-3", "71311210-6", "71311220-9", "71311230-2", "71311240-5", "71311300-4", "71312000-8", "71313000-5", "71313100-6", "71313200-7", "71313400-9", "71313410-2", "71313420-5", "71313430-8", "71313440-1", "71313450-4", "71314000-2", "71314100-3", "71314200-4", "71314300-5", "71314310-8", "71315000-9", "71315100-0", "71315200-1", "71315210-4", "71315300-2", "71315400-3", "71315410-6", "71316000-6", "71317000-3", "71317100-4", "71317200-5", "71317210-8", "71318000-0", "71318100-1", "71319000-7", "71320000-7", "71321000-4", "71321100-5", "71321200-6", "71321300-7", "71321400-8", "71322000-1", "71322100-2", "71322200-3", "71322300-4", "71322400-5", "71322500-6", "71323000-8", "71323100-9", "71323200-0", "71324000-5", "71325000-2", "71326000-9", "71327000-6", "71328000-3", "71330000-0", "71331000-7", "71332000-4", "71333000-1", "71334000-8", "71335000-5", "71336000-2", "71337000-9", "71340000-3", "71350000-6", "71351000-3", "71351100-4", "71351200-5", "71351210-8", "71351220-1", "71351300-6", "71351400-7", "71351500-8", "71351600-9", "71351610-2", "71351611-9", "71351612-6", "71351700-0", "71351710-3", "71351720-6", "71351730-9", "71351800-1", "71351810-4", "71351811-1", "71351820-7", "71351900-2", "71351910-5", "71351911-2", "71351912-9", "71351913-6", "71351914-3", "71351920-2", "71351921-2", "71351922-2", "71351923-2", "71351924-2", "71352000-0", "71352100-1", "71352110-4", "71352120-7", "71352130-0", "71352140-3", "71352300-3", "71353000-7", "71353100-8", "71353200-9", "71354000-4", "71354100-5", "71354200-6", "71354300-7", "71354400-8", "71354500-9", "71355000-1", "71355100-2", "71355200-3", "71356000-8", "71356100-9", "71356200-0", "71356300-1", "71356400-2", "71400000-2", "71410000-5", "71420000-8", "71421000-5", "71500000-3", "71510000-6", "71520000-9", "71521000-6", "71530000-2", "71540000-5", "71541000-2", "71550000-8", "71600000-4", "71610000-7", "71620000-0", "71621000-7", "71630000-3", "71631000-0", "71631100-1", "71631200-2", "71631300-3", "71631400-4", "71631420-0", "71631430-3", "71631440-6", "71631450-9", "71631460-2", "71631470-5", "71631480-8", "71631490-1", "71632000-7", "71632100-8", "71632200-9", "71700000-5", "71730000-4", "71731000-1", "71800000-6", "71900000-7", "72000000-5", "72100000-6", "72110000-9", "72120000-2", "72130000-5", "72140000-8", "72150000-1", "72200000-7", "72210000-0", "72211000-7", "72212000-4", "72212100-0", "72212110-3", "72212120-6", "72212121-3", "72212130-9", "72212131-6", "72212132-3", "72212140-2", "72212150-5", "72212160-8", "72212170-1", "72212180-4", "72212190-7", "72212200-1", "72212210-4", "72212211-1", "72212212-8", "72212213-5", "72212214-2", "72212215-9", "72212216-6", "72212217-3", "72212218-0", "72212219-7", "72212220-7", "72212221-4", "72212222-1", "72212223-8", "72212224-5", "72212300-2", "72212310-5", "72212311-2", "72212312-9", "72212313-6", "72212314-3", "72212315-0", "72212316-7", "72212317-4", "72212318-1", "72212320-8", "72212321-5", "72212322-2", "72212323-9", "72212324-6", "72212325-3", "72212326-0", "72212327-7", "72212328-4", "72212330-1", "72212331-8", "72212332-5", "72212333-2", "72212400-3", "72212410-6", "72212411-3", "72212412-0", "72212420-9", "72212421-6", "72212422-3", "72212430-2", "72212440-5", "72212441-2", "72212442-9", "72212443-6", "72212445-0", "72212450-8", "72212451-5", "72212460-1", "72212461-8", "72212462-5", "72212463-2", "72212470-4", "72212480-7", "72212481-4", "72212482-1", "72212490-0", "72212500-4", "72212510-7", "72212511-4", "72212512-1", "72212513-8", "72212514-5", "72212515-2", "72212516-9", "72212517-6", "72212518-3", "72212519-0", "72212520-0", "72212521-7", "72212522-4", "72212600-5", "72212610-8", "72212620-1", "72212630-4", "72212640-7", "72212650-0", "72212660-3", "72212670-6", "72212700-6", "72212710-9", "72212720-2", "72212730-5", "72212731-2", "72212732-9", "72212740-8", "72212750-1", "72212760-4", "72212761-1", "72212770-7", "72212771-4", "72212772-1", "72212780-0", "72212781-7", "72212782-4", "72212783-1", "72212790-3", "72212900-8", "72212910-1", "72212911-8", "72212920-4", "72212930-7", "72212931-4", "72212932-1", "72212940-0", "72212941-7", "72212942-4", "72212960-6", "72212970-9", "72212971-6", "72212972-3", "72212980-2", "72212981-9", "72212982-6", "72212983-3", "72212984-0", "72212985-7", "72212990-5", "72212991-2", "72220000-3", "72221000-0", "72222000-7", "72222100-8", "72222200-9", "72222300-0", "72223000-4", "72224000-1", "72224100-2", "72224200-3", "72225000-8", "72226000-5", "72227000-2", "72228000-9", "72230000-6", "72231000-3", "72232000-0", "72240000-9", "72241000-6", "72242000-3", "72243000-0", "72244000-7", "72245000-4", "72246000-1", "72250000-2", "72251000-9", "72252000-6", "72253000-3", "72253100-4", "72253200-5", "72254000-0", "72254100-1", "72260000-5", "72261000-2", "72262000-9", "72263000-6", "72264000-3", "72265000-0", "72266000-7", "72267000-4", "72267100-0", "72267200-1", "72268000-1", "72300000-8", "72310000-1", "72311000-8", "72311100-9", "72311200-0", "72311300-1", "72312000-5", "72312100-6", "72312200-7", "72313000-2", "72314000-9", "72315000-6", "72315100-7", "72315200-8", "72316000-3", "72317000-0", "72318000-7", "72319000-4", "72320000-4", "72321000-1", "72322000-8", "72330000-2", "72400000-4", "72410000-7", "72411000-4", "72412000-1", "72413000-8", "72414000-5", "72415000-2", "72416000-9", "72417000-6", "72420000-0", "72421000-7", "72422000-4", "72500000-0", "72510000-3", "72511000-0", "72512000-7", "72513000-4", "72514000-1", "72514100-2", "72514200-3", "72514300-4", "72540000-2", "72541000-9", "72541100-0", "72590000-7", "72591000-4", "72600000-6", "72610000-9", "72611000-6", "72700000-7", "72710000-0", "72720000-3", "72800000-8", "72810000-1", "72820000-4", "72900000-9", "72910000-2", "72920000-5", "73000000-2", "73100000-3", "73110000-6", "73111000-3", "73112000-0", "73120000-9", "73200000-4", "73210000-7", "73220000-0", "73300000-5", "73400000-6", "73410000-9", "73420000-2", "73421000-9", "73422000-6", "73423000-3", "73424000-0", "73425000-7", "73426000-4", "73430000-5", "73431000-2", "73432000-9", "73433000-6", "73434000-3", "73435000-0", "73436000-7", "75000000-6", "75100000-7", "75110000-0", "75111000-7", "75111100-8", "75111200-9", "75112000-4", "75112100-5", "75120000-3", "75121000-0", "75122000-7", "75123000-4", "75124000-1", "75125000-8", "75130000-6", "75131000-3", "75131100-4", "75200000-8", "75210000-1", "75211000-8", "75211100-9", "75211110-2", "75211200-0", "75211300-1", "75220000-4", "75221000-1", "75222000-8", "75230000-7", "75231000-4", "75231100-5", "75231200-6", "75231210-9", "75231220-2", "75231230-5", "75231240-8", "75240000-0", "75241000-7", "75241100-8", "75242000-4", "75242100-5", "75242110-8", "75250000-3", "75251000-0", "75251100-1", "75251110-4", "75251120-7", "75252000-7", "75300000-9", "75310000-2", "75311000-9", "75312000-6", "75313000-3", "75313100-4", "75314000-0", "75320000-5", "75330000-8", "75340000-1", "76000000-3", "76100000-4", "76110000-7", "76111000-4", "76120000-0", "76121000-7", "76200000-5", "76210000-8", "76211000-5", "76211100-6", "76211110-9", "76211120-2", "76211200-7", "76300000-6", "76310000-9", "76320000-2", "76330000-5", "76331000-2", "76340000-8", "76400000-7", "76410000-0", "76411000-7", "76411100-8", "76411200-9", "76411300-0", "76411400-1", "76420000-3", "76421000-0", "76422000-7", "76423000-4", "76430000-6", "76431000-3", "76431100-4", "76431200-5", "76431300-6", "76431400-7", "76431500-8", "76431600-9", "76440000-9", "76441000-6", "76442000-3", "76443000-0", "76450000-2", "76460000-5", "76470000-8", "76471000-5", "76472000-2", "76473000-9", "76480000-1", "76490000-4", "76491000-1", "76492000-8", "76500000-8", "76510000-1", "76520000-4", "76521000-1", "76522000-8", "76530000-7", "76531000-4", "76532000-1", "76533000-8", "76534000-5", "76535000-2", "76536000-9", "76537000-6", "76537100-7", "76600000-9", "77000000-0", "77100000-1", "77110000-4", "77111000-1", "77112000-8", "77120000-7", "77200000-2", "77210000-5", "77211000-2", "77211100-3", "77211200-4", "77211300-5", "77211400-6", "77211500-7", "77211600-8", "77220000-8", "77230000-1", "77231000-8", "77231100-9", "77231200-0", "77231300-1", "77231400-2", "77231500-3", "77231600-4", "77231700-5", "77231800-6", "77231900-7", "77300000-3", "77310000-6", "77311000-3", "77312000-0", "77312100-1", "77313000-7", "77314000-4", "77314100-5", "77315000-1", "77320000-9", "77330000-2", "77340000-5", "77341000-2", "77342000-9", "77400000-4", "77500000-5", "77510000-8", "77600000-6", "77610000-9", "77700000-7", "77800000-8", "77810000-1", "77820000-4", "77830000-7", "77840000-0", "77850000-3", "77900000-9", "79000000-4", "79100000-5", "79110000-8", "79111000-5", "79112000-2", "79112100-3", "79120000-1", "79121000-8", "79121100-9", "79130000-4", "79131000-1", "79132000-8", "79132100-9", "79140000-7", "79200000-6", "79210000-9", "79211000-6", "79211100-7", "79211110-0", "79211120-3", "79211200-8", "79212000-3", "79212100-4", "79212110-7", "79212200-5", "79212300-6", "79212400-7", "79212500-8", "79220000-2", "79221000-9", "79222000-6", "79223000-3", "79300000-7", "79310000-0", "79311000-7", "79311100-8", "79311200-9", "79311210-2", "79311300-0", "79311400-1", "79311410-4", "79312000-4", "79313000-1", "79314000-8", "79315000-5", "79320000-3", "79330000-6", "79340000-9", "79341000-6", "79341100-7", "79341200-8", "79341400-0", "79341500-1", "79342000-3", "79342100-4", "79342200-5", "79342300-6", "79342310-9", "79342311-6", "79342320-2", "79342321-9", "79342400-7", "79342410-4", "79400000-8", "79410000-1", "79411000-8", "79411100-9", "79412000-5", "79413000-2", "79414000-9", "79415000-6", "79415200-8", "79416000-3", "79416100-4", "79416200-5", "79417000-0", "79418000-7", "79419000-4", "79420000-4", "79421000-1", "79421100-2", "79421200-3", "79422000-8", "79430000-7", "79500000-9", "79510000-2", "79511000-9", "79512000-6", "79520000-5", "79521000-2", "79530000-8", "79540000-1", "79550000-4", "79551000-1", "79552000-8", "79553000-5", "79560000-7", "79570000-0", "79571000-7", "79600000-0", "79610000-3", "79611000-0", "79612000-7", "79613000-4", "79620000-6", "79621000-3", "79622000-0", "79623000-7", "79624000-4", "79625000-1", "79630000-9", "79631000-6", "79632000-3", "79633000-0", "79634000-7", "79635000-4", "79700000-1", "79710000-4", "79711000-1", "79713000-5", "79714000-2", "79714100-3", "79714110-6", "79715000-9", "79716000-6", "79720000-7", "79721000-4", "79722000-1", "79723000-8", "79800000-2", "79810000-5", "79811000-2", "79812000-9", "79820000-8", "79821000-5", "79821100-6", "79822000-2", "79822100-3", "79822200-4", "79822300-5", "79822400-6", "79822500-7", "79823000-9", "79824000-6", "79900000-3", "79910000-6", "79920000-9", "79921000-6", "79930000-2", "79931000-9", "79932000-6", "79933000-3", "79934000-0", "79940000-5", "79941000-2", "79950000-8", "79951000-5", "79952000-2", "79952100-3", "79953000-9", "79954000-6", "79955000-3", "79956000-0", "79957000-7", "79960000-1", "79961000-8", "79961100-9", "79961200-0", "79961300-1", "79961310-4", "79961320-7", "79961330-0", "79961340-3", "79961350-6", "79962000-5", "79963000-2", "79970000-4", "79971000-1", "79971100-2", "79971200-3", "79972000-8", "79972100-9", "79980000-7", "79990000-0", "79991000-7", "79992000-4", "79993000-1", "79993100-2", "79994000-8", "79995000-5", "79995100-6", "79995200-7", "79996000-2", "79996100-3", "79997000-9", "79998000-6", "79999000-3", "79999100-4", "79999200-5", "80000000-4", "80100000-5", "80110000-8", "80200000-6", "80210000-9", "80211000-6", "80212000-3", "80300000-7", "80310000-0", "80320000-3", "80330000-6", "80340000-9", "80400000-8", "80410000-1", "80411000-8", "80411100-9", "80411200-0", "80412000-5", "80413000-2", "80414000-9", "80415000-6", "80420000-4", "80430000-7", "80490000-5", "80500000-9", "80510000-2", "80511000-9", "80512000-6", "80513000-3", "80520000-5", "80521000-2", "80522000-9", "80530000-8", "80531000-5", "80531100-6", "80531200-7", "80532000-2", "80533000-9", "80533100-0", "80533200-1", "80540000-1", "80550000-4", "80560000-7", "80561000-4", "80562000-1", "80570000-0", "80580000-3", "80590000-6", "80600000-0", "80610000-3", "80620000-6", "80630000-9", "80640000-2", "80650000-5", "80660000-8", "85000000-9", "85100000-0", "85110000-3", "85111000-0", "85111100-1", "85111200-2", "85111300-3", "85111310-6", "85111320-9", "85111400-4", "85111500-5", "85111600-6", "85111700-7", "85111800-8", "85111810-1", "85111820-4", "85111900-9", "85112000-7", "85112100-8", "85112200-9", "85120000-6", "85121000-3", "85121100-4", "85121200-5", "85121210-8", "85121220-1", "85121230-4", "85121231-1", "85121232-8", "85121240-7", "85121250-0", "85121251-7", "85121252-4", "85121270-6", "85121271-3", "85121280-9", "85121281-6", "85121282-3", "85121283-0", "85121290-2", "85121291-9", "85121292-6", "85121300-6", "85130000-9", "85131000-6", "85131100-7", "85131110-0", "85140000-2", "85141000-9", "85141100-0", "85141200-1", "85141210-4", "85141211-1", "85141220-7", "85142000-6", "85142100-7", "85142200-8", "85142300-9", "85142400-0", "85143000-3", "85144000-0", "85144100-1", "85145000-7", "85146000-4", "85146100-5", "85146200-6", "85147000-1", "85148000-8", "85149000-5", "85150000-5", "85160000-8", "85170000-1", "85171000-8", "85172000-5", "85200000-1", "85210000-3", "85300000-2", "85310000-5", "85311000-2", "85311100-3", "85311200-4", "85311300-5", "85312000-9", "85312100-0", "85312110-3", "85312120-6", "85312200-1", "85312300-2", "85312310-5", "85312320-8", "85312330-1", "85312400-3", "85312500-4", "85312510-7", "85320000-8", "85321000-5", "85322000-2", "85323000-9", "90000000-7", "90400000-1", "90410000-4", "90420000-7", "90430000-0", "90440000-3", "90450000-6", "90460000-9", "90470000-2", "90480000-5", "90481000-2", "90490000-8", "90491000-5", "90492000-2", "90500000-2", "90510000-5", "90511000-2", "90511100-3", "90511200-4", "90511300-5", "90511400-6", "90512000-9", "90513000-6", "90513100-7", "90513200-8", "90513300-9", "90513400-0", "90513500-1", "90513600-2", "90513700-3", "90513800-4", "90513900-5", "90514000-3", "90520000-8", "90521000-5", "90521100-6", "90521200-7", "90521300-8", "90521400-9", "90521410-2", "90521420-5", "90521500-0", "90521510-3", "90521520-6", "90522000-2", "90522100-3", "90522200-4", "90522300-5", "90522400-6", "90523000-9", "90523100-0", "90523200-1", "90523300-2", "90524000-6", "90524100-7", "90524200-8", "90524300-9", "90524400-0", "90530000-1", "90531000-8", "90532000-5", "90533000-2", "90600000-3", "90610000-6", "90611000-3", "90612000-0", "90620000-9", "90630000-2", "90640000-5", "90641000-2", "90642000-9", "90650000-8", "90660000-1", "90670000-4", "90680000-7", "90690000-0", "90700000-4", "90710000-7", "90711000-4", "90711100-5", "90711200-6", "90711300-7", "90711400-8", "90711500-9", "90712000-1", "90712100-2", "90712200-3", "90712300-4", "90712400-5", "90712500-6", "90713000-8", "90713100-9", "90714000-5", "90714100-6", "90714200-7", "90714300-8", "90714400-9", "90714500-0", "90714600-1", "90715000-2", "90715100-3", "90715110-6", "90715120-9", "90715200-4", "90715210-7", "90715220-0", "90715230-3", "90715240-6", "90715250-9", "90715260-2", "90715270-5", "90715280-8", "90720000-0", "90721000-7", "90721100-8", "90721200-9", "90721300-0", "90721400-1", "90721500-2", "90721600-3", "90721700-4", "90721800-5", "90722000-4", "90722100-5", "90722200-6", "90722300-7", "90730000-3", "90731000-0", "90731100-1", "90731200-2", "90731210-5", "90731300-3", "90731400-4", "90731500-5", "90731600-6", "90731700-7", "90731800-8", "90731900-9", "90732000-7", "90732100-8", "90732200-9", "90732300-0", "90732400-1", "90732500-2", "90732600-3", "90732700-4", "90732800-5", "90732900-6", "90732910-9", "90732920-2", "90733000-4", "90733100-5", "90733200-6", "90733300-7", "90733400-8", "90733500-9", "90733600-0", "90733700-1", "90733800-2", "90733900-3", "90740000-6", "90741000-3", "90741100-4", "90741200-5", "90741300-6", "90742000-0", "90742100-1", "90742200-2", "90742300-3", "90742400-4", "90743000-7", "90743100-8", "90743200-9", "90900000-6", "90910000-9", "90911000-6", "90911100-7", "90911200-8", "90911300-9", "90912000-3", "90913000-0", "90913100-1", "90913200-2", "90914000-7", "90915000-4", "90916000-1", "90917000-8", "90918000-5", "90919000-2", "90919100-3", "90919200-4", "90919300-5", "90920000-2", "90921000-9", "90922000-6", "90923000-3", "90924000-0", "92000000-1", "92100000-2", "92110000-5", "92111000-2", "92111100-3", "92111200-4", "92111210-7", "92111220-0", "92111230-3", "92111240-6", "92111250-9", "92111260-2", "92111300-5", "92111310-8", "92111320-1", "92112000-9", "92120000-8", "92121000-5", "92122000-2", "92130000-1", "92140000-4", "92200000-3", "92210000-6", "92211000-3", "92213000-7", "92214000-4", "92215000-1", "92216000-8", "92217000-5", "92220000-9", "92221000-6", "92222000-3", "92224000-7", "92225000-4", "92225100-7", "92226000-1", "92230000-2", "92231000-9", "92232000-6", "92300000-4", "92310000-7", "92311000-4", "92312000-1", "92312100-2", "92312110-5", "92312120-8", "92312130-1", "92312140-4", "92312200-3", "92312210-6", "92312211-3", "92312212-0", "92312213-7", "92312220-9", "92312230-2", "92312240-5", "92312250-8", "92312251-5", "92320000-0", "92330000-3", "92331000-0", "92331100-1", "92331200-2", "92331210-5", "92332000-7", "92340000-6", "92341000-3", "92342000-0", "92342100-1", "92342200-2", "92350000-9", "92351000-6", "92351100-7", "92351200-8", "92352000-3", "92352100-4", "92352200-5", "92360000-2", "92370000-5", "92400000-5", "92500000-6", "92510000-9", "92511000-6", "92512000-3", "92512100-4", "92520000-2", "92521000-9", "92521100-0", "92521200-1", "92521210-4", "92521220-7", "92522000-6", "92522100-7", "92522200-8", "92530000-5", "92531000-2", "92532000-9", "92533000-6", "92534000-3", "92600000-7", "92610000-0", "92620000-3", "92621000-0", "92622000-7", "92700000-8", "98000000-3", "98100000-4", "98110000-7", "98111000-4", "98112000-1", "98113000-8", "98113100-9", "98120000-0", "98130000-3", "98131000-0", "98132000-7", "98133000-4", "98133100-5", "98133110-8", "98200000-5", "98300000-6", "98310000-9", "98311000-6", "98311100-7", "98311200-8", "98312000-3", "98312100-4", "98313000-0", "98314000-7", "98315000-4", "98316000-1", "98320000-2", "98321000-9", "98321100-0", "98322000-6", "98322100-7", "98322110-0", "98322120-3", "98322130-6", "98322140-9", "98330000-5", "98331000-2", "98332000-9", "98333000-6", "98334000-3", "98336000-7", "98340000-8", "98341000-5", "98341100-6", "98341110-9", "98341120-2", "98341130-5", "98341140-8", "98342000-2", "98350000-1", "98351000-8", "98351100-9", "98351110-2", "98360000-4", "98361000-1", "98362000-8", "98362100-9", "98363000-5", "98370000-7", "98371000-4", "98371100-5", "98371110-8", "98371111-5", "98371120-1", "98371200-6", "98380000-0", "98390000-3", "98391000-0", "98392000-7", "98393000-4", "98394000-1", "98395000-8", "98396000-5", "98500000-8", "98510000-1", "98511000-8", "98512000-5", "98513000-2", "98513100-3", "98513200-4", "98513300-5", "98513310-8", "98514000-9", "98900000-2", "98910000-5"] diff --git a/docs/source/tutorial/create-auction-procuringEntity.http b/docs/source/tutorial/create-auction-procuringEntity.http new file mode 100644 index 0000000..ea13c65 --- /dev/null +++ b/docs/source/tutorial/create-auction-procuringEntity.http @@ -0,0 +1,154 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 2029 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 500 + }, + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "kind": "general", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + }, + "mode": "test", + "title_ru": "футляры к государственным наградам", + "auctionPeriod": { + "startDate": "2017-12-14T16:56:17.205813" + }, + "items": [ + { + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "description": "Земля для військовослужбовців", + "id": "aff7d0febd8847b78f31662488efd20b", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "title_en": "Cases with state awards", + "dgfID": "219560" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/057ecdd1ad8f45ea8151e731ac2b30f3 + +{ + "access": { + "token": "52d7fbc91420401d908289b3cbfe71e9" + }, + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000002", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:25.801167+02:00", + "endDate": "2017-12-14T16:55:24.860531+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-14T16:55:24.860531+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "kind": "general", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "title_en": "[TESTING] Cases with state awards", + "id": "057ecdd1ad8f45ea8151e731ac2b30f3", + "title": "[ТЕСТУВАННЯ] футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:25.805777+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:25.801167+02:00", + "endDate": "2017-12-14T16:55:24.860531+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-15T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:25.801167+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "unit": { + "code": "44617100-9", + "name": "item" + }, + "description": "Земля для військовослужбовців", + "id": "aff7d0febd8847b78f31662488efd20b", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "mode": "test", + "title_ru": "[ТЕСТИРОВАНИЕ] футляры к государственным наградам", + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/finauction-adding-vdr.http b/docs/source/tutorial/finauction-adding-vdr.http new file mode 100644 index 0000000..d38f424 --- /dev/null +++ b/docs/source/tutorial/finauction-adding-vdr.http @@ -0,0 +1,31 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents?acc_token=6c03609dd6844e42bc1318fddf20c937 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 127 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://virtial-data-room.com/id_of_room", + "title": "VDR for auction lot", + "documentType": "virtualDataRoom" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents/4e24994ddc1c4c72b24b992f8826acf4 + +{ + "data": { + "title": "VDR for auction lot", + "url": "http://virtial-data-room.com/id_of_room", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.313920+02:00", + "documentType": "virtualDataRoom", + "dateModified": "2017-11-30T16:56:24.313948+02:00", + "id": "4e24994ddc1c4c72b24b992f8826acf4" + } +} + diff --git a/docs/source/tutorial/finauction-documents-2.http b/docs/source/tutorial/finauction-documents-2.http new file mode 100644 index 0000000..71351d3 --- /dev/null +++ b/docs/source/tutorial/finauction-documents-2.http @@ -0,0 +1,35 @@ +GET /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "technical specification", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1b63ae48aa3e4caf99aac3455888c7d6?KeyID=c822be4a&Signature=Cqo%2Fl%2FHX9fy29aZ4TPnu9LB6ZtHdt6tquLKAJIGPLchoAf4OTMDnRAqLTeQK8rW9jgzFQ6I9HGfJtUP8i3gKDA%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.108881+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:24.108911+02:00", + "id": "74e4e4b7624d420b8448a6220e0a86cf" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b0a0c1a4b083475caaa4c8fb08d18781?KeyID=c822be4a&Signature=xnYvodjAvZu8pjdlyQ4kdlC62x%252BEi2JnnuWKvRdNbne9KWdXVWSlqM%252BeGrGuJ4%252BS2e9qmZRCg9vHJvc1iz%252BMAA%253D%253D", + "title": "AwardCriteria.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.174808+02:00", + "dateModified": "2017-11-30T16:56:24.174838+02:00", + "id": "55dc8e33c47948eab4e7b327bede3959" + } + ] +} + diff --git a/docs/source/tutorial/finauction-documents-3.http b/docs/source/tutorial/finauction-documents-3.http new file mode 100644 index 0000000..10cb314 --- /dev/null +++ b/docs/source/tutorial/finauction-documents-3.http @@ -0,0 +1,35 @@ +GET /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "description": "technical specification", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1b63ae48aa3e4caf99aac3455888c7d6?KeyID=c822be4a&Signature=Cqo%2Fl%2FHX9fy29aZ4TPnu9LB6ZtHdt6tquLKAJIGPLchoAf4OTMDnRAqLTeQK8rW9jgzFQ6I9HGfJtUP8i3gKDA%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.108881+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:24.108911+02:00", + "id": "74e4e4b7624d420b8448a6220e0a86cf" + }, + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/3efb323d6d6a42c9817ec011d6c8898f?KeyID=c822be4a&Signature=oMIup%252BjcxK%2FooCGXGpptyKCu1slmnk3T1I8XhOKPQXsKAD3R3zPyoDvYbF%252B47ZdbzNJ8m9v3TNQdsbseMlv7CA%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.174808+02:00", + "dateModified": "2017-11-30T16:56:24.243244+02:00", + "id": "55dc8e33c47948eab4e7b327bede3959" + } + ] +} + diff --git a/docs/source/tutorial/finauction-documents.http b/docs/source/tutorial/finauction-documents.http new file mode 100644 index 0000000..9113873 --- /dev/null +++ b/docs/source/tutorial/finauction-documents.http @@ -0,0 +1,24 @@ +GET /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents/74e4e4b7624d420b8448a6220e0a86cf HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "technical specification", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1b63ae48aa3e4caf99aac3455888c7d6?KeyID=c822be4a&Signature=Cqo%2Fl%2FHX9fy29aZ4TPnu9LB6ZtHdt6tquLKAJIGPLchoAf4OTMDnRAqLTeQK8rW9jgzFQ6I9HGfJtUP8i3gKDA%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.108881+02:00", + "previousVersions": [], + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:24.108911+02:00", + "id": "74e4e4b7624d420b8448a6220e0a86cf" + } +} + diff --git a/docs/source/tutorial/finauction-post-attempt-json-data.http b/docs/source/tutorial/finauction-post-attempt-json-data.http new file mode 100644 index 0000000..8df0cfa --- /dev/null +++ b/docs/source/tutorial/finauction-post-attempt-json-data.http @@ -0,0 +1,162 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1972 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfFinancialAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "dgfID": "219560", + "auctionPeriod": { + "startDate": "2017-12-14" + }, + "items": [ + { + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "quantity": 5, + "description": "Земля для військовослужбовців", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + } + } + ], + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28 + +{ + "access": { + "token": "6c03609dd6844e42bc1318fddf20c937" + }, + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:23.942831+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "73e1598288054eb98e8153ee9e69bb28", + "eligibilityCriteria_ru": "К участию допускаются только лицензированные финансовые учреждения.", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "eligibilityCriteria_en": "Only licensed financial institutions are eligible to participate.", + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:23.946137+02:00", + "status": "active.tendering", + "eligibilityCriteria": "До участі допускаються лише ліцензовані фінансові установи.", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:23.942831+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfFinancialAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:23.942831+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "e16351a78632484e8756b1dea38e6201", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/finauction-update-award-criteria.http b/docs/source/tutorial/finauction-update-award-criteria.http new file mode 100644 index 0000000..8f1f3ec --- /dev/null +++ b/docs/source/tutorial/finauction-update-award-criteria.http @@ -0,0 +1,32 @@ +PUT /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents/55dc8e33c47948eab4e7b327bede3959?acc_token=6c03609dd6844e42bc1318fddf20c937 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 340 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/3efb323d6d6a42c9817ec011d6c8898f?KeyID=c822be4a&Signature=ihcWFQ7J6n6ycnrnh0RJKYBGr3PXLL4%2Fu39OMCUhkdXcrv9CY%2FXcFty3b%2BqTiMV6ODEMR7zAyub4CwZXgyoYBA%3D%3D", + "title": "AwardCriteria-2.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/3efb323d6d6a42c9817ec011d6c8898f?KeyID=c822be4a&Signature=oMIup%252BjcxK%2FooCGXGpptyKCu1slmnk3T1I8XhOKPQXsKAD3R3zPyoDvYbF%252B47ZdbzNJ8m9v3TNQdsbseMlv7CA%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.174808+02:00", + "dateModified": "2017-11-30T16:56:24.243244+02:00", + "id": "55dc8e33c47948eab4e7b327bede3959" + } +} + diff --git a/docs/source/tutorial/finauction-upload-award-criteria.http b/docs/source/tutorial/finauction-upload-award-criteria.http new file mode 100644 index 0000000..f417008 --- /dev/null +++ b/docs/source/tutorial/finauction-upload-award-criteria.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents?acc_token=6c03609dd6844e42bc1318fddf20c937 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 338 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b0a0c1a4b083475caaa4c8fb08d18781?KeyID=c822be4a&Signature=eUjEvPipgCDUg2CRW0uqyy%2Br5C7MNpbTp26C83J4cy7H84gzepDYr%2BfNWkPzjpTqZfg%2BIfTNVj86hY07Z9mcBA%3D%3D", + "title": "AwardCriteria.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents/55dc8e33c47948eab4e7b327bede3959 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/b0a0c1a4b083475caaa4c8fb08d18781?KeyID=c822be4a&Signature=xnYvodjAvZu8pjdlyQ4kdlC62x%252BEi2JnnuWKvRdNbne9KWdXVWSlqM%252BeGrGuJ4%252BS2e9qmZRCg9vHJvc1iz%252BMAA%253D%253D", + "title": "AwardCriteria.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.174808+02:00", + "dateModified": "2017-11-30T16:56:24.174838+02:00", + "id": "55dc8e33c47948eab4e7b327bede3959" + } +} + diff --git a/docs/source/tutorial/finbidder-documents.http b/docs/source/tutorial/finbidder-documents.http new file mode 100644 index 0000000..b073d4e --- /dev/null +++ b/docs/source/tutorial/finbidder-documents.http @@ -0,0 +1,24 @@ +GET /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca/documents?acc_token=b6c5e3c4087848a08703ae24889033a7 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca/documents/523bf2858a644c37bb188b696ae1ee65?download=9d26f2842ae149228d379eb98961e054", + "title": "FinancialLicense.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.486255+02:00", + "documentType": "financialLicense", + "dateModified": "2017-11-30T16:56:24.486283+02:00", + "id": "523bf2858a644c37bb188b696ae1ee65" + } + ] +} + diff --git a/docs/source/tutorial/get-answer.http b/docs/source/tutorial/get-answer.http new file mode 100644 index 0000000..c43eae0 --- /dev/null +++ b/docs/source/tutorial/get-answer.http @@ -0,0 +1,19 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/questions/e966c8cdacc14655907b34713b141d18 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність", + "date": "2017-11-30T16:56:26.610507+02:00", + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"", + "id": "e966c8cdacc14655907b34713b141d18", + "questionOf": "tender" + } +} + diff --git a/docs/source/tutorial/get-awards.http b/docs/source/tutorial/get-awards.http new file mode 100644 index 0000000..fc4c2a5 --- /dev/null +++ b/docs/source/tutorial/get-awards.http @@ -0,0 +1,97 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "status": "pending.verification", + "paymentPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T17:16:29.509749+02:00" + }, + "verificationPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:59:30.218082+02:00" + }, + "signingPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T17:16:29.509749+02:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "complaintPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00" + }, + "bid_id": "0d76a3f619044106b9bcdc0e57e93dad", + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:27.695166+02:00", + "id": "add0cbb7aa114e7cb6f5e127071f8b53" + }, + { + "status": "pending.waiting", + "complaintPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "bid_id": "afaa508128da4829b9202fe300965bf4", + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:27.695166+02:00", + "id": "14f4c1774be847098f247565c4871574" + } + ] +} + diff --git a/docs/source/tutorial/initial-auction-listing.http b/docs/source/tutorial/initial-auction-listing.http new file mode 100644 index 0000000..65b7ba5 --- /dev/null +++ b/docs/source/tutorial/initial-auction-listing.http @@ -0,0 +1,22 @@ +GET /api/2.3/auctions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "next_page": { + "path": "/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.621767%2B02%3A00", + "uri": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions?offset=2017-11-30T16%3A56%3A25.621767%2B02%3A00", + "offset": "2017-11-30T16:56:25.621767+02:00" + }, + "data": [ + { + "id": "301d66e275cb4861ba502c1eaafa88ae", + "dateModified": "2017-11-30T16:56:25.621767+02:00" + } + ] +} + diff --git a/docs/source/tutorial/initial-finauction-listing.http b/docs/source/tutorial/initial-finauction-listing.http new file mode 100644 index 0000000..d703548 --- /dev/null +++ b/docs/source/tutorial/initial-finauction-listing.http @@ -0,0 +1,22 @@ +GET /api/2.3/auctions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "next_page": { + "path": "/api/2.3/auctions?offset=2017-11-30T16%3A56%3A23.946137%2B02%3A00", + "uri": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions?offset=2017-11-30T16%3A56%3A23.946137%2B02%3A00", + "offset": "2017-11-30T16:56:23.946137+02:00" + }, + "data": [ + { + "id": "73e1598288054eb98e8153ee9e69bb28", + "dateModified": "2017-11-30T16:56:23.946137+02:00" + } + ] +} + diff --git a/docs/source/tutorial/list-question.http b/docs/source/tutorial/list-question.http new file mode 100644 index 0000000..a43ac52 --- /dev/null +++ b/docs/source/tutorial/list-question.http @@ -0,0 +1,21 @@ +GET /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/questions HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Host: api-sandbox.ea.openprocurement.org + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": [ + { + "description": "Просимо додати таблицю потрібної калорійності харчування", + "title": "Калорійність", + "date": "2017-11-30T16:56:26.610507+02:00", + "answer": "Таблицю додано в файлі \"Kalorijnist.xslx\"", + "id": "e966c8cdacc14655907b34713b141d18", + "questionOf": "tender" + } + ] +} + diff --git a/docs/source/tutorial/out-of-rectification-period-editing-denied.http b/docs/source/tutorial/out-of-rectification-period-editing-denied.http new file mode 100644 index 0000000..c836775 --- /dev/null +++ b/docs/source/tutorial/out-of-rectification-period-editing-denied.http @@ -0,0 +1,87 @@ +PATCH /api/2.3/auctions/aad622eb435a443e8a7afd5432c5d4e6?acc_token=8f2c28a574a647ab8f3dfaeadbbbadb2 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 2076 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "procurementMethodDetails": "quick, accelerator=1440", + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "dgfID": "219560", + "auctionPeriod": { + "startDate": "2017-12-04" + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + }, + "contractPeriod": { + "startDate": "2017-11-22T15:29:31.486546", + "endDate": "2017-11-25T15:29:31.486546" + }, + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5.001 + } + ], + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + } +} + + +403 Forbidden +Content-Type: application/json; charset=UTF-8 + +{ + "status": "error", + "errors": [ + { + "description": "Auction can be edited only during the rectification period: from (2017-11-06T15:29:31.491067+02:00) to (2017-11-20T15:28:31.491067+02:00).", + "location": "body", + "name": "data" + } + ] +} + diff --git a/docs/source/tutorial/owner-auction-protocol.http b/docs/source/tutorial/owner-auction-protocol.http new file mode 100644 index 0000000..4c32f80 --- /dev/null +++ b/docs/source/tutorial/owner-auction-protocol.http @@ -0,0 +1,36 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 383 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/79f7d75e9ff34c1d94289241ebd04a46?KeyID=8473a74a&Signature=Dw9ofeROBRO2k0vLPta83X2j28ym58QAiJ%2BKEtgsCkgGnY7vD6%2BBo%2Bdk29rxKjuVbQ%2FCyfdPWZKW8wFk8qCfAg%3D%3D", + "title": "SignedAuctionProtocol.pdf", + "format": "application/pdf", + "hash": "md5:00000000000000000000000000000000", + "documentType": "auctionProtocol" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53/documents/edc7c486de494ac3bdcc0b456d006e4a + +{ + "data": { + "dateModified": "2017-11-30T16:56:28.217417+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/79f7d75e9ff34c1d94289241ebd04a46?KeyID=8473a74a&Signature=ZZf5dIDTAFetGGoNyGHK0TaTX%2FMo%2FTcKq%2FTatSSpuIZleTjJFvbciSiMq9MNq3mZGWRdK%2FYKfT0lkoOKYooXDA%253D%253D", + "author": "auction_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.217384+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "edc7c486de494ac3bdcc0b456d006e4a" + } +} + diff --git a/docs/source/tutorial/patch-cancellation.http b/docs/source/tutorial/patch-cancellation.http new file mode 100644 index 0000000..fe3d8be --- /dev/null +++ b/docs/source/tutorial/patch-cancellation.http @@ -0,0 +1,30 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e/documents/6aebbc98305a4847830bdc40863a4d6b?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 48 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "description": "Changed description" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "Changed description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/02dd9977d20e4b409d307bc67ee6ca36?KeyID=8473a74a&Signature=5WtHn%252BXf4U2eKnBY5mwdZNifHaf%2FMoApsRroJSOzQBI%252BdJ5ZwCkP%252BTZmjkZ%2FDOh1M4U5JY7u1MJE8%252Bp7YQOSBw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.945693+02:00", + "dateModified": "2017-11-30T16:56:29.945720+02:00", + "id": "6aebbc98305a4847830bdc40863a4d6b" + } +} + diff --git a/docs/source/tutorial/patch-items-value-periods.http b/docs/source/tutorial/patch-items-value-periods.http new file mode 100644 index 0000000..05a1093 --- /dev/null +++ b/docs/source/tutorial/patch-items-value-periods.http @@ -0,0 +1,101 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 75 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "tenderPeriod": { + "endDate": "2017-12-15T16:56:35.944933+02:00" + } + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "procurementMethod": "open", + "auctionID": "UA-PS-2017-11-30-000001", + "enquiryPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "submissionMethod": "electronicAuction", + "next_check": "2017-12-13T23:59:50+02:00", + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + }, + "owner": "broker", + "id": "301d66e275cb4861ba502c1eaafa88ae", + "title": "футляри до державних нагород", + "tenderAttempts": 1, + "procurementMethodDetails": "quick, accelerator=1440", + "dateModified": "2017-11-30T16:56:25.621767+02:00", + "status": "active.tendering", + "tenderPeriod": { + "startDate": "2017-11-30T16:56:25.617199+02:00", + "endDate": "2017-12-13T23:59:50+02:00" + }, + "auctionPeriod": { + "shouldStartAfter": "2017-12-14T00:00:00+02:00" + }, + "procurementMethodType": "dgfOtherAssets", + "dgfID": "219560", + "date": "2017-11-30T16:56:25.617199+02:00", + "minimalStep": { + "currency": "UAH", + "amount": 35.0, + "valueAddedTaxIncluded": true + }, + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "description": "Земельні ділянки", + "id": "66113000-5" + }, + "address": { + "postalCode": "79000", + "countryName": "Україна", + "streetAddress": "вул. Банкова 1", + "region": "м. Київ", + "locality": "м. Київ" + }, + "id": "6abd12c929084367ac08d9d9138ccab4", + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5 + } + ], + "value": { + "currency": "UAH", + "amount": 100.0, + "valueAddedTaxIncluded": true + }, + "awardCriteria": "highestCost" + } +} + diff --git a/docs/source/tutorial/prepare-cancellation.http b/docs/source/tutorial/prepare-cancellation.http new file mode 100644 index 0000000..c961846 --- /dev/null +++ b/docs/source/tutorial/prepare-cancellation.http @@ -0,0 +1,27 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 43 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "reason": "cancellation reason" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e + +{ + "data": { + "date": "2017-11-30T16:56:29.616244+02:00", + "status": "pending", + "reason": "cancellation reason", + "cancellationOf": "tender", + "id": "3fd26d96a4454abf9a875bef110dba4e" + } +} + diff --git a/docs/source/tutorial/register-2nd-bidder.http b/docs/source/tutorial/register-2nd-bidder.http new file mode 100644 index 0000000..f55b9c2 --- /dev/null +++ b/docs/source/tutorial/register-2nd-bidder.http @@ -0,0 +1,82 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 723 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "qualified": true, + "value": { + "amount": 501 + }, + "tenderers": [ + { + "contactPoint": { + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк", + "email": "aagt@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "countryName": "Україна", + "postalCode": "79013", + "region": "м. Львів", + "streetAddress": "вул. Островського, 34", + "locality": "м. Львів" + } + } + ] + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/0d76a3f619044106b9bcdc0e57e93dad + +{ + "access": { + "token": "73842c515600468a8829fea44817fce1" + }, + "data": { + "status": "active", + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:27.113380+02:00", + "qualified": true, + "tenderers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "owner": "broker", + "id": "0d76a3f619044106b9bcdc0e57e93dad" + } +} + diff --git a/docs/source/tutorial/register-2nd-finbidder.http b/docs/source/tutorial/register-2nd-finbidder.http new file mode 100644 index 0000000..e1f70dd --- /dev/null +++ b/docs/source/tutorial/register-2nd-finbidder.http @@ -0,0 +1,96 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1004 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "qualified": true, + "tenderers": [ + { + "additionalIdentifiers": [ + { + "scheme": "UA-FIN", + "id": "А01 457213" + } + ], + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + ], + "value": { + "currency": "UAH", + "amount": 479, + "valueAddedTaxIncluded": true + }, + "eligible": true + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/afc000ac87e642d8b70141957772cdb8 + +{ + "access": { + "token": "47bbd4a1e6f9460b94cea52301caca48" + }, + "data": { + "status": "active", + "eligible": true, + "value": { + "currency": "UAH", + "amount": 479.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:24.588843+02:00", + "qualified": true, + "tenderers": [ + { + "additionalIdentifiers": [ + { + "scheme": "UA-FIN", + "id": "А01 457213" + } + ], + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "owner": "broker", + "id": "afc000ac87e642d8b70141957772cdb8" + } +} + diff --git a/docs/source/tutorial/register-bidder.http b/docs/source/tutorial/register-bidder.http new file mode 100644 index 0000000..b3bd8dc --- /dev/null +++ b/docs/source/tutorial/register-bidder.http @@ -0,0 +1,83 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 776 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "draft", + "qualified": true, + "value": { + "amount": 500 + }, + "tenderers": [ + { + "contactPoint": { + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк", + "email": "soleksuk@gmail.com" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "countryName": "Україна", + "postalCode": "21100", + "region": "м. Вінниця", + "streetAddress": "вул. Островського, 33", + "locality": "м. Вінниця" + } + } + ] + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4 + +{ + "access": { + "token": "a94a2b6627aa46f3bbb83ff885e3beae" + }, + "data": { + "status": "draft", + "value": { + "currency": "UAH", + "amount": 500.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:26.821209+02:00", + "qualified": true, + "tenderers": [ + { + "contactPoint": { + "email": "soleksuk@gmail.com", + "telephone": "+380 (432) 21-69-30", + "name": "Сергій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137256", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Школяр»", + "address": { + "postalCode": "21100", + "countryName": "Україна", + "streetAddress": "вул. Островського, 33", + "region": "м. Вінниця", + "locality": "м. Вінниця" + } + } + ], + "owner": "broker", + "id": "afaa508128da4829b9202fe300965bf4" + } +} + diff --git a/docs/source/tutorial/register-finbidder.http b/docs/source/tutorial/register-finbidder.http new file mode 100644 index 0000000..d5a2999 --- /dev/null +++ b/docs/source/tutorial/register-finbidder.http @@ -0,0 +1,96 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 1004 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "qualified": true, + "tenderers": [ + { + "additionalIdentifiers": [ + { + "scheme": "UA-FIN", + "id": "А01 457213" + } + ], + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + ], + "value": { + "currency": "UAH", + "amount": 469, + "valueAddedTaxIncluded": true + }, + "eligible": true + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca + +{ + "access": { + "token": "b6c5e3c4087848a08703ae24889033a7" + }, + "data": { + "status": "active", + "eligible": true, + "value": { + "currency": "UAH", + "amount": 469.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:24.381299+02:00", + "qualified": true, + "tenderers": [ + { + "additionalIdentifiers": [ + { + "scheme": "UA-FIN", + "id": "А01 457213" + } + ], + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "postalCode": "01220", + "countryName": "Україна", + "streetAddress": "вул. Банкова, 11, корпус 1", + "region": "м. Київ", + "locality": "м. Київ" + } + } + ], + "owner": "broker", + "id": "c7a52fb296b143cc87728f74b2585fca" + } +} + diff --git a/docs/source/tutorial/tenderperiod-validation-error.http b/docs/source/tutorial/tenderperiod-validation-error.http new file mode 100644 index 0000000..9595c71 --- /dev/null +++ b/docs/source/tutorial/tenderperiod-validation-error.http @@ -0,0 +1,88 @@ +POST /api/2.3/auctions?opt_pretty=1 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 2037 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "футляри до державних нагород", + "minimalStep": { + "currency": "UAH", + "amount": 35 + }, + "auctionPeriod": { + "startDate": "2017-09-02T15:56:30.045984" + }, + "tenderAttempts": 1, + "procurementMethodType": "dgfOtherAssets", + "value": { + "currency": "UAH", + "amount": 100 + }, + "dgfID": "219560", + "items": [ + { + "description": "Земля для військовослужбовців", + "classification": { + "scheme": "CPV", + "id": "66113000-5", + "description": "Земельні ділянки" + }, + "address": { + "countryName": "Україна", + "postalCode": "79000", + "region": "м. Київ", + "streetAddress": "вул. Банкова 1", + "locality": "м. Київ" + }, + "contractPeriod": { + "startDate": "2017-08-30T15:56:30.043635", + "endDate": "2017-09-02T15:56:30.043635" + }, + "unit": { + "code": "44617100-9", + "name": "item" + }, + "quantity": 5.001 + } + ], + "procuringEntity": { + "contactPoint": { + "name": "Державне управління справами", + "telephone": "0440000000" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "name": "Державне управління справами", + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1", + "locality": "м. Київ" + } + } + } +} + + +422 Unprocessable Entity +Content-Type: application/json; charset=UTF-8 + +{ + "status": "error", + "errors": [ + { + "description": [ + "tenderPeriod should be greater than 6 days" + ], + "location": "body", + "name": "tenderPeriod" + } + ] +} + diff --git a/docs/source/tutorial/update-award-criteria.http b/docs/source/tutorial/update-award-criteria.http new file mode 100644 index 0000000..f95268b --- /dev/null +++ b/docs/source/tutorial/update-award-criteria.http @@ -0,0 +1,32 @@ +PUT /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/3385ba24fb704db79cb8a70561e023c7?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 336 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=zV0b0U6S2LivauIlHbmy3NjVsbCTyEtgWFhrVYM3rEVniUg%2FJnfwZc3BruHog0KupIa2qItySihDKH2sVU1UAQ%3D%3D", + "title": "AwardCriteria-2.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9840d23dc3194951a561e6b3d959fac0?KeyID=8473a74a&Signature=vJlSrjCYsuQhptjoPNewJOzwmvXFcLc5HA8pIMybY%252B0qd7VYuGlhFpTPnwpMtpFEnblx87Fz%252BXuJ9x%2FBELicCg%253D%253D", + "title": "AwardCriteria-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.221784+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + } +} + diff --git a/docs/source/tutorial/update-cancellation-doc.http b/docs/source/tutorial/update-cancellation-doc.http new file mode 100644 index 0000000..d16730c --- /dev/null +++ b/docs/source/tutorial/update-cancellation-doc.http @@ -0,0 +1,33 @@ +PUT /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e/documents/6aebbc98305a4847830bdc40863a4d6b?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 331 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1981cae19a6d4577bf343cf0b7d813f5?KeyID=8473a74a&Signature=8gW%2BOhgmZJCtbnvWqrJA%2Bigktxl1Ze93F9aM6jRFkTFNYgGjSTv7UcmiLAzKivOQlJDM0rAk5VD9ORurYDjDCw%3D%3D", + "title": "Notice-2.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "Changed description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1981cae19a6d4577bf343cf0b7d813f5?KeyID=8473a74a&Signature=6PDYxf6GgOgkJuoH%2FR4qtBFHx%2FEcXKpV9NJ0lWVPu7IBKLdQ8%252ByiK5kIQk5YZ9aebaDik0e4JNDdJihcZVA%252BBg%253D%253D", + "title": "Notice-2.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.945693+02:00", + "dateModified": "2017-11-30T16:56:30.284752+02:00", + "id": "6aebbc98305a4847830bdc40863a4d6b" + } +} + diff --git a/docs/source/tutorial/upload-asset-familiarization.http b/docs/source/tutorial/upload-asset-familiarization.http new file mode 100644 index 0000000..fab621c --- /dev/null +++ b/docs/source/tutorial/upload-asset-familiarization.http @@ -0,0 +1,32 @@ +POST /api/2.3/auctions/06a31c1ae5d048d0ad5723f2c81f2495/documents?acc_token=1e38e432232d499aadedfa06b7d96bae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 154 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "title": "Asset_Familiarization.pdf", + "accessDetails": "Familiar with asset: days, time, address", + "documentType": "x_dgfAssetFamiliarization" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/06a31c1ae5d048d0ad5723f2c81f2495/documents/2bcdc11607cf4c96a0bc617410ff866f + +{ + "data": { + "title": "Asset_Familiarization.pdf", + "format": "offline/on-site-examination", + "accessDetails": "Familiar with asset: days, time, address", + "documentOf": "tender", + "datePublished": "2016-12-02T18:19:09.742143+02:00", + "documentType": "x_dgfAssetFamiliarization", + "dateModified": "2016-12-02T18:19:09.742191+02:00", + "id": "2bcdc11607cf4c96a0bc617410ff866f" + } +} + diff --git a/docs/source/tutorial/upload-auction-notice.http b/docs/source/tutorial/upload-auction-notice.http new file mode 100644 index 0000000..494dc4d --- /dev/null +++ b/docs/source/tutorial/upload-auction-notice.http @@ -0,0 +1,37 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 415 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "title": "Notice.pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=P1G3pRNxZchhK%2FgkOzQoI4eQtwB%2BhjrtHZpWFS4DHIsNZke%2BhlU%2Fckb5vkmRwzqcg96vsSluTsCXIfg4TWd6Bg%3D%3D", + "format": "application/pdf", + "documentType": "technicalSpecifications" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/418d8f99150a4b92a57b81cc18cd968a + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "document description", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/323a56de45c243bb88a568c652d9ca2b?KeyID=8473a74a&Signature=u52VVOil6Bd6RED8Jt8wIJv2ioBCOV5meDxqcLgCksUxsJeTTj2aL5xHGYGjnsDBb0N6NohsEHBoxR5WaFE8Cw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.092186+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:26.092222+02:00", + "id": "418d8f99150a4b92a57b81cc18cd968a" + } +} + diff --git a/docs/source/tutorial/upload-award-criteria.http b/docs/source/tutorial/upload-award-criteria.http new file mode 100644 index 0000000..a1bcc63 --- /dev/null +++ b/docs/source/tutorial/upload-award-criteria.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 340 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/68fe48f4593a4de9844e6548344b2696?KeyID=8473a74a&Signature=20qbIlw9A9vFgmcjaagAfrYpHKp5oWHqcqZEBDuJIq%2FwysuHo4C%2BREnHEOneynezrY%2FoIQoJ8379xY%2BDJId4BQ%3D%3D", + "title": "AwardCriteria.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/3385ba24fb704db79cb8a70561e023c7 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/68fe48f4593a4de9844e6548344b2696?KeyID=8473a74a&Signature=QZwWxRCYJDGM8BwdJ%252Bh%2FZ7EfjK1tSuHstIWY7Phw8MUeywT2GsNNucpnf2UGZGud5EPLKF1xOz9hX%252BWHtaSeBw%253D%253D", + "title": "AwardCriteria.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.157156+02:00", + "dateModified": "2017-11-30T16:56:26.157192+02:00", + "id": "3385ba24fb704db79cb8a70561e023c7" + } +} + diff --git a/docs/source/tutorial/upload-bid-proposal.http b/docs/source/tutorial/upload-bid-proposal.http new file mode 100644 index 0000000..bae5573 --- /dev/null +++ b/docs/source/tutorial/upload-bid-proposal.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents?acc_token=a94a2b6627aa46f3bbb83ff885e3beae HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 329 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/4accad3bd17a4f0baa9f6a8ea96397f7?KeyID=8473a74a&Signature=F1ZZ8oz1qK%2B51JWibcyBu4pKvQcdApeIzqnBqPAbC9cdvKzLWXgVTNPak47HJv4BsbUhFSa9j9qb7pQ6mMOsBg%3D%3D", + "title": "Proposal.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents/3bd15f6db7764b7e9651fdf15dde6316 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/bids/afaa508128da4829b9202fe300965bf4/documents/3bd15f6db7764b7e9651fdf15dde6316?download=4accad3bd17a4f0baa9f6a8ea96397f7", + "title": "Proposal.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.994147+02:00", + "dateModified": "2017-11-30T16:56:26.994175+02:00", + "id": "3bd15f6db7764b7e9651fdf15dde6316" + } +} + diff --git a/docs/source/tutorial/upload-cancellation-doc.http b/docs/source/tutorial/upload-cancellation-doc.http new file mode 100644 index 0000000..79eef40 --- /dev/null +++ b/docs/source/tutorial/upload-cancellation-doc.http @@ -0,0 +1,33 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 333 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/02dd9977d20e4b409d307bc67ee6ca36?KeyID=8473a74a&Signature=WhL6NTgs5mjvzOHNCCeQke4w1%2F7zXZ7lFpc59uvGIzXOAJPb8fwjWqupDk86%2Frroe1%2B77jX624%2Bo6ZLSkbCADw%3D%3D", + "title": "Notice.pdf", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/cancellations/3fd26d96a4454abf9a875bef110dba4e/documents/6aebbc98305a4847830bdc40863a4d6b + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/02dd9977d20e4b409d307bc67ee6ca36?KeyID=8473a74a&Signature=5WtHn%252BXf4U2eKnBY5mwdZNifHaf%2FMoApsRroJSOzQBI%252BdJ5ZwCkP%252BTZmjkZ%2FDOh1M4U5JY7u1MJE8%252Bp7YQOSBw%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:29.945693+02:00", + "dateModified": "2017-11-30T16:56:29.945720+02:00", + "id": "6aebbc98305a4847830bdc40863a4d6b" + } +} + diff --git a/docs/source/tutorial/upload-finauction-notice.http b/docs/source/tutorial/upload-finauction-notice.http new file mode 100644 index 0000000..0d78aba --- /dev/null +++ b/docs/source/tutorial/upload-finauction-notice.http @@ -0,0 +1,37 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents?acc_token=6c03609dd6844e42bc1318fddf20c937 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 412 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "technical specification", + "title": "Notice.pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1b63ae48aa3e4caf99aac3455888c7d6?KeyID=c822be4a&Signature=QCihV3O02wIHwqfKrwHkYdZ4jtSlChjb8EKFrnRDwr6fv1qdAOmQ7Id6vM0vCWQaWvv4%2FPpEwTE4DYGWUECgAQ%3D%3D", + "format": "application/pdf", + "documentType": "technicalSpecifications" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/documents/74e4e4b7624d420b8448a6220e0a86cf + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "description": "technical specification", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/1b63ae48aa3e4caf99aac3455888c7d6?KeyID=c822be4a&Signature=Cqo%2Fl%2FHX9fy29aZ4TPnu9LB6ZtHdt6tquLKAJIGPLchoAf4OTMDnRAqLTeQK8rW9jgzFQ6I9HGfJtUP8i3gKDA%253D%253D", + "title": "Notice.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.108881+02:00", + "documentType": "technicalSpecifications", + "dateModified": "2017-11-30T16:56:24.108911+02:00", + "id": "74e4e4b7624d420b8448a6220e0a86cf" + } +} + diff --git a/docs/source/tutorial/upload-finbid-financial-license.http b/docs/source/tutorial/upload-finbid-financial-license.http new file mode 100644 index 0000000..c432e51 --- /dev/null +++ b/docs/source/tutorial/upload-finbid-financial-license.http @@ -0,0 +1,35 @@ +POST /api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca/documents?acc_token=b6c5e3c4087848a08703ae24889033a7 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 381 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/9d26f2842ae149228d379eb98961e054?KeyID=c822be4a&Signature=GihlzLpKCv%2Fv86BLw%2Fn8wAMDJhbuncQkvQpe68VIyD15Z0MfPipOfda9ENxJNDZ3ygf%2B%2F8%2Fv6AypQlORVmLoDw%3D%3D", + "title": "FinancialLicense.pdf", + "format": "application/pdf", + "hash": "md5:00000000000000000000000000000000", + "documentType": "financialLicense" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca/documents/523bf2858a644c37bb188b696ae1ee65 + +{ + "data": { + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/73e1598288054eb98e8153ee9e69bb28/bids/c7a52fb296b143cc87728f74b2585fca/documents/523bf2858a644c37bb188b696ae1ee65?download=9d26f2842ae149228d379eb98961e054", + "title": "FinancialLicense.pdf", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:24.486255+02:00", + "documentType": "financialLicense", + "dateModified": "2017-11-30T16:56:24.486283+02:00", + "id": "523bf2858a644c37bb188b696ae1ee65" + } +} + diff --git a/docs/source/tutorial/upload-first-auction-illustration.http b/docs/source/tutorial/upload-first-auction-illustration.http new file mode 100644 index 0000000..8fe6cb5 --- /dev/null +++ b/docs/source/tutorial/upload-first-auction-illustration.http @@ -0,0 +1,39 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 436 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "title": "first_illustration.jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=A72CeRi4%2B8fC9UG9C%2FuvfJdkbzFP52dV0xg%2B7gXZoHp3EF4HjQAR1xdz0W%2F%2BcV902JTBXbJG9ebWHwZiyU2HCg%3D%3D", + "format": "image/jpeg", + "documentType": "illustration" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/f143cdc5fef246f59d11cd3bc7c72d46 + +{ + "data": { + "index": 1, + "hash": "md5:00000000000000000000000000000000", + "description": "First illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2840dd02387746c8882c2087e55b9f14?KeyID=8473a74a&Signature=CTN%2FyvXW3%252Bz7lGcIGWXJGAYdUUudzcpWk1%2F9TldffuMmRChRSJJsi%2F%2FHBzjXb%252B0f4DuzUiUbq8bqD%2FP70jlFAQ%253D%253D", + "title": "first_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.293411+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.293438+02:00", + "id": "f143cdc5fef246f59d11cd3bc7c72d46" + } +} + diff --git a/docs/source/tutorial/upload-second-auction-illustration.http b/docs/source/tutorial/upload-second-auction-illustration.http new file mode 100644 index 0000000..7e3ea11 --- /dev/null +++ b/docs/source/tutorial/upload-second-auction-illustration.http @@ -0,0 +1,39 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 430 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Second illustration description", + "title": "second_illustration.jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bfd750de3e7b49b5a991b6cdaf2c208e?KeyID=8473a74a&Signature=vmvWJOCo0jvQ1wr8Czb2%2BrC8ntp51VS0BYxtlXrCiPyKuKv7d7XJoVeAMmw8bH9RE28w1cW8BECbEgScz5ISBQ%3D%3D", + "format": "image/jpeg", + "documentType": "illustration" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/eb64e2d0457e42c89aed5861301d3d06 + +{ + "data": { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Second illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/bfd750de3e7b49b5a991b6cdaf2c208e?KeyID=8473a74a&Signature=nXLYMy2OkK2aIJDwV6kn7z3BkQD4wMe1ccc9%252BSvKDcUemJGUcmxtcGPn57JUQ6AJznS4IfCvaHVyDo5Aez7pDA%253D%253D", + "title": "second_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.376954+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.376981+02:00", + "id": "eb64e2d0457e42c89aed5861301d3d06" + } +} + diff --git a/docs/source/tutorial/upload-third-auction-illustration.http b/docs/source/tutorial/upload-third-auction-illustration.http new file mode 100644 index 0000000..91b0304 --- /dev/null +++ b/docs/source/tutorial/upload-third-auction-illustration.http @@ -0,0 +1,39 @@ +POST /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 432 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Third illustration description", + "title": "third_illustration.jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2d40e8da608c4f10b9432671cf47c9aa?KeyID=8473a74a&Signature=BgTF%2BhgcDdTXB%2BMmv4Xfyl0PHorwUgDAKN7GVtlMm%2FoufbQVpM3pO11DN98KuWxwva2DIy73KKNE1hiIa53WBw%3D%3D", + "format": "image/jpeg", + "documentType": "illustration" + } +} + + +201 Created +Content-Type: application/json; charset=UTF-8 +Location: http://api-sandbox.ea.openprocurement.org/api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/documents/fdafece528e54fe5a7b38f025be993c3 + +{ + "data": { + "index": 2, + "hash": "md5:00000000000000000000000000000000", + "description": "Third illustration description", + "format": "image/jpeg", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/2d40e8da608c4f10b9432671cf47c9aa?KeyID=8473a74a&Signature=AGnUbHWEz4OOa7kxT1%2Fj4Ml7cNOw%252BcsUiDVX9HQhwqAdi4UGtaxWqeAZ2YhsI20lzMp67Fq%252BUo6jPmWdLdWuAQ%253D%253D", + "title": "third_illustration.jpeg", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:26.434267+02:00", + "documentType": "illustration", + "dateModified": "2017-11-30T16:56:26.434293+02:00", + "id": "fdafece528e54fe5a7b38f025be993c3" + } +} + diff --git a/docs/source/tutorial/verify-protocol.http b/docs/source/tutorial/verify-protocol.http new file mode 100644 index 0000000..6eaf33e --- /dev/null +++ b/docs/source/tutorial/verify-protocol.http @@ -0,0 +1,93 @@ +PATCH /api/2.3/auctions/301d66e275cb4861ba502c1eaafa88ae/awards/add0cbb7aa114e7cb6f5e127071f8b53?acc_token=ccf4d45ff9524ec9ae87f38c43d7b0a3 HTTP/1.0 +Authorization: Basic YnJva2VyOg== +Content-Length: 39 +Content-Type: application/json +Host: api-sandbox.ea.openprocurement.org + +{ + "data": { + "status": "pending.payment" + } +} + + +200 OK +Content-Type: application/json; charset=UTF-8 + +{ + "data": { + "status": "pending.payment", + "paymentPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T17:16:29.509749+02:00" + }, + "documents": [ + { + "dateModified": "2017-11-30T16:56:28.083997+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/326d29c8df4744149f6082d061e6492e?KeyID=8473a74a&Signature=W07o9qqLEOV3dvjZZVzBFeolqx4QEUoFCZPnHeu4xyBsP7NJma%252BZINjCbfVSmXeRHYiAnDikplownjV%2FJE%252B6BQ%253D%253D", + "author": "bid_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.083969+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "de5b4f4f5aa04ef6a16606d1152b061a" + }, + { + "dateModified": "2017-11-30T16:56:28.217417+02:00", + "hash": "md5:00000000000000000000000000000000", + "format": "application/pdf", + "url": "http://public.docs-sandbox.ea.openprocurement.org/get/79f7d75e9ff34c1d94289241ebd04a46?KeyID=8473a74a&Signature=ZZf5dIDTAFetGGoNyGHK0TaTX%2FMo%2FTcKq%2FTatSSpuIZleTjJFvbciSiMq9MNq3mZGWRdK%2FYKfT0lkoOKYooXDA%253D%253D", + "author": "auction_owner", + "documentOf": "tender", + "datePublished": "2017-11-30T16:56:28.217384+02:00", + "documentType": "auctionProtocol", + "title": "SignedAuctionProtocol.pdf", + "id": "edc7c486de494ac3bdcc0b456d006e4a" + } + ], + "verificationPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T16:56:28.375177+02:00" + }, + "complaintPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00" + }, + "suppliers": [ + { + "contactPoint": { + "email": "aagt@gmail.com", + "telephone": "+380 (322) 91-69-30", + "name": "Андрій Олексюк" + }, + "identifier": { + "scheme": "UA-EDR", + "id": "00137226", + "uri": "http://www.sc.gov.ua/" + }, + "name": "ДКП «Книга»", + "address": { + "postalCode": "79013", + "countryName": "Україна", + "streetAddress": "вул. Островського, 34", + "region": "м. Львів", + "locality": "м. Львів" + } + } + ], + "signingPeriod": { + "startDate": "2017-11-30T16:56:27.695166+02:00", + "endDate": "2017-11-30T17:16:29.509749+02:00" + }, + "bid_id": "0d76a3f619044106b9bcdc0e57e93dad", + "value": { + "currency": "UAH", + "amount": 501.0, + "valueAddedTaxIncluded": true + }, + "date": "2017-11-30T16:56:28.382166+02:00", + "id": "add0cbb7aa114e7cb6f5e127071f8b53" + } +} + diff --git a/docs/source/upload.rst b/docs/source/upload.rst new file mode 100644 index 0000000..5f76933 --- /dev/null +++ b/docs/source/upload.rst @@ -0,0 +1,28 @@ +.. _upload: + +Documents Uploading +=================== + +All of the document uploading API endpoints follow the same set of rules. + +Upload document with registration +--------------------------------- + +#. :ref:`Register document upload in document service `. + +#. Add document in API: + + .. include:: tutorial/upload-auction-notice.http + :code: + +#. :ref:`Upload document in document service `. + +Upload document without registration +------------------------------------ + +#. :ref:`Upload document without registration `. + +#. Add document in API: + + .. include:: tutorial/upload-auction-notice.http + :code: diff --git a/openprocurement/__init__.py b/openprocurement/__init__.py new file mode 100644 index 0000000..f48ad10 --- /dev/null +++ b/openprocurement/__init__.py @@ -0,0 +1,6 @@ +# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/openprocurement/auctions/__init__.py b/openprocurement/auctions/__init__.py new file mode 100644 index 0000000..f48ad10 --- /dev/null +++ b/openprocurement/auctions/__init__.py @@ -0,0 +1,6 @@ +# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/openprocurement/auctions/lease/__init__.py b/openprocurement/auctions/lease/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openprocurement/auctions/lease/adapters.py b/openprocurement/auctions/lease/adapters.py new file mode 100644 index 0000000..e0179d5 --- /dev/null +++ b/openprocurement/auctions/lease/adapters.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.adapters import AuctionConfigurator +from openprocurement.auctions.lease.models import ( + propertyLease +) +from openprocurement.auctions.core.plugins.awarding.v2_1.adapters import ( + AwardingV2_1ConfiguratorMixin +) + + +class AuctionRubbleOtherConfigurator(AuctionConfigurator, + AwardingV2_1ConfiguratorMixin): + name = 'Auction Rubble Configurator' + model = propertyLease + diff --git a/openprocurement/auctions/lease/cav_ps.json b/openprocurement/auctions/lease/cav_ps.json new file mode 100644 index 0000000..71a99fe --- /dev/null +++ b/openprocurement/auctions/lease/cav_ps.json @@ -0,0 +1 @@ +["07227000-6", "06121000-6", "06123000-0", "04120000-5", "08160000-5", "07223000-8", "06120000-9", "04111000-9", "07224000-5", "05111100-7", "04234000-7", "07124000-4", "06129000-2", "04151000-1", "04233000-0", "06127000-8", "04132000-2", "04213000-4", "05110200-1", "05110900-8", "07125000-1", "08110000-0", "04152000-8", "04112000-6", "07123000-7", "04232000-3", "07210000-4", "05110700-6", "06126000-1", "05110600-5", "07200000-1", "07000000-9", "04231000-6", "07220000-7", "04140000-1", "08100000-7", "04123000-6", "07100000-0", "04110000-2", "04114000-0", "05110500-4", "06100000-3", "04113000-3", "04200000-0", "08150000-2", "04223000-7", "06110000-6", "04211000-0", "08130000-6", "07110000-3", "04224000-4", "04131000-5", "04121000-2", "07222000-1", "04225000-1", "08120000-3", "04210000-3", "04142000-5", "06128000-5", "04221000-3", "05111200-8", "05110400-3", "04100000-9", "06112000-0", "06122000-3", "07226000-9", "08140000-9", "04212000-7", "04150000-4", "04220000-6", "05110100-0", "05000000-5", "07120000-6", "07127000-5", "04230000-9", "05100000-6", "05111300-9", "07121000-3", "07225000-2", "04000000-8", "06000000-2", "05111000-6", "04141000-8", "06125000-4", "07126000-8", "04122000-9", "06124000-7", "05110800-7", "04214000-1", "07122000-0", "04222000-0", "06111000-3", "05110000-9", "04130000-8", "07221000-4", "05110300-2"] \ No newline at end of file diff --git a/openprocurement/auctions/lease/constants.py b/openprocurement/auctions/lease/constants.py new file mode 100644 index 0000000..60e99ef --- /dev/null +++ b/openprocurement/auctions/lease/constants.py @@ -0,0 +1,37 @@ +from datetime import datetime, timedelta + +from openprocurement.auctions.core.constants import TZ, ORA_CODES, read_json + +#document types +DOCUMENT_TYPE_OFFLINE = ['x_dgfAssetFamiliarization'] +DOCUMENT_TYPE_URL_ONLY = ['virtualDataRoom'] + +#requiremnt periods +MINIMAL_EXPOSITION_PERIOD = timedelta(days=6) +MINIMAL_PERIOD_FROM_RECTIFICATION_END = timedelta(days=5) +VERIFY_AUCTION_PROTOCOL_TIME = timedelta(days=6) +AWARD_PAYMENT_TIME = timedelta(days=20) +CONTRACT_SIGNING_TIME = timedelta(days=20) + +#time constants +DGF_ID_REQUIRED_FROM = datetime(2017, 1, 1, tzinfo=TZ) +DGF_DECISION_REQUIRED_FROM = datetime(2017, 1, 1, tzinfo=TZ) +CLASSIFICATION_PRECISELY_FROM = datetime(2017, 7, 19, tzinfo=TZ) +MINIMAL_EXPOSITION_REQUIRED_FROM = datetime(2017, 11, 17, tzinfo=TZ) +DGF_ADDRESS_REQUIRED_FROM = datetime(2018, 2, 9, tzinfo=TZ) + +#codes +CAVPS_CODES = read_json('cav_ps.json') +CPVS_CODES = read_json('cpvs.json') + +ORA_CODES[0:0] = ["UA-IPN", "UA-FIN"] + +NUMBER_OF_BIDS_TO_BE_QUALIFIED = 2 + +#code units +CPV_NON_SPECIFIC_LOCATION_UNITS = ('45', '48', '50', '51', '55', '60', '63', '64', + '65', '66', '71', '72', '73', '75', '76', '77', + '79', '80', '85', '90', '92', '98') +CAV_NON_SPECIFIC_LOCATION_UNITS = ('07', '08') + +DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE = "propertyLease" diff --git a/openprocurement/auctions/lease/cpvs.json b/openprocurement/auctions/lease/cpvs.json new file mode 100644 index 0000000..775de7f --- /dev/null +++ b/openprocurement/auctions/lease/cpvs.json @@ -0,0 +1 @@ +["HA28-9", "UB03-0", "TA04-1", "BC32-7", "CA69-7", "AB32-5", "KA13-8", "CB15-6", "GC09-3", "AB31-2", "BC14-3", "RA11-9", "BA52-5", "IA23-5", "GA17-5", "TA39-6", "BC17-2", "BA51-2", "GC12-2", "GC10-6", "AB35-4", "EA10-2", "FG08-3", "BC35-6", "JA12-4", "BC36-9", "CB16-9", "GA05-9", "EA27-3", "DA12-7", "HA24-7", "MB01-5", "LA38-4", "GC02-2", "CA44-2", "QB18-0", "BA39-6", "UA01-3", "QB57-7", "LA35-5", "DA28-5", "CB19-8", "QA11-8", "MB02-8", "FD04-8", "CB38-5", "DA27-2", "AB36-7", "DA11-4", "TA06-7", "CB12-7", "LA31-3", "FD03-5", "IA06-4", "CB11-4", "EA20-2", "QB10-6", "GC11-9", "FB13-3", "QB54-8", "JA08-2", "FA01-6", "AB19-6", "BA36-7", "FA04-5", "BC13-0", "RA15-1", "AB14-1", "BA31-2", "AB17-0", "QA12-1", "EA23-1", "RC05-3", "RA16-4", "LA32-6", "BC10-1", "MB04-4", "QB50-6", "BC18-5", "PA01-7", "MA08-5", "AB13-8", "EA24-4", "FF02-4", "CA21-3", "GA12-0", "EA01-5", "AA11-1", "LA16-8", "BA19-6", "EA28-6", "TA11-2", "CB30-1", "IA05-1", "AA16-6", "TA22-5", "MA07-2", "LA10-0", "QA03-4", "KA09-6", "LA15-5", "DA40-1", "PB06-3", "BA14-1", "BA35-4", "CA03-9", "UA02-6", "MA03-0", "DA21-4", "JA21-1", "CA04-2", "LA53-9", "KA02-5", "IA28-0", "BA32-5", "CA07-1", "EA06-0", "DA18-5", "DA19-8", "CB37-2", "AA37-9", "FB11-7", "BA17-0", "RB18-1", "JA07-9", "CB43-0", "BA10-9", "PA03-3", "HA06-3", "PB05-0", "AA15-3", "EA05-7", "QB36-4", "RB10-7", "JA04-0", "HA09-2", "LA44-2", "BA13-8", "PB02-1", "LA11-3", "EA02-8", "IA38-0", "HA01-8", "LA13-9", "TA35-4", "QB15-1", "FF01-1", "MB03-1", "DA29-8", "DA10-1", "HA20-5", "FG24-1", "DA13-0", "FG23-8", "LA39-7", "IA33-5", "IA34-8", "QA10-5", "CA25-5", "HA27-6", "DA26-9", "FB07-5", "QB32-2", "EA21-5", "DA17-2", "HA29-2", "CA36-8", "DA25-6", "CA22-6", "KA05-4", "BA43-8", "CA08-4", "EA22-8", "AA38-2", "CA39-7", "AB18-3", "RB17-8", "FB12-0", "PA02-0", "QA13-4", "BA37-0", "IA16-4", "IA30-6", "JA01-1", "RB13-6", "IA11-9", "GA32-0", "QB07-7", "EA26-0", "IA37-7", "EA25-7", "BA15-4", "LA14-2", "CA58-4", "FG09-6", "EA29-9", "AA10-8", "LA17-1", "BA34-1", "FE03-6", "QB20-6", "FC02-1", "IA19-3", "HA04-7", "BA16-7", "CA29-7", "AB20-9", "EA08-6", "CA35-5", "CA26-8", "EA07-3", "CA06-8", "CA32-6", "CA05-5", "CA50-0", "BA33-8", "JA09-5", "EA04-4", "BA30-9", "TA26-7", "JA05-3", "HA22-1", "GC28-0", "AA33-7", "AA35-3", "HA07-6", "GA19-1", "BA12-5", "CB06-9", "AA19-5", "BA11-2", "BB07-1", "HA08-9", "AA30-8", "FG06-7", "IA39-3", "JA02-4", "IA15-1", "LA37-1", "AA14-0", "JA24-9", "AA17-9", "QB23-5", "HA03-4", "PB03-4", "EA03-1", "LA36-8", "GA11-7", "GC24-8", "GC23-5", "CA57-1", "TA46-7", "FG22-5", "FG20-9", "IA32-2", "FB04-6", "BB03-9", "CA37-1", "HA26-3", "RB03-6", "CA38-4", "CA23-9", "CA20-0", "CA54-2", "CA02-6", "CA53-9", "AA39-5", "JA13-7", "JA20-8", "AA36-6", "BB04-2", "JA23-7", "FB03-3", "GC27-7", "CA09-7", "RA01-9", "GC21-9", "IA31-9", "DA44-3", "BC11-4", "DA16-9", "CA31-3", "GA33-3", "BC45-6", "GC06-4", "RD11-2", "BC42-7", "QA02-1", "QB09-3", "FG25-4", "IA13-5", "BC25-6", "QB41-9", "GC15-1", "EA15-7", "IA10-6", "IA35-1", "AB04-1", "IA36-4", "TA45-4", "GC05-1", "AA12-4", "BC26-9", "FE01-0", "QB26-4", "QB24-8", "FE02-3", "CA30-0", "MA13-0", "CA33-9", "CA28-4", "IA18-0", "TA24-1", "CA27-1", "BC46-9", "CA51-3", "TA19-6", "FG05-4", "CA34-2", "KA11-2", "TA05-4", "CA24-2", "BC28-5", "RB06-5", "BC41-4", "GC01-9", "TA27-0", "TA02-5", "AA31-1", "BA40-9", "BA47-0", "AA32-4", "LA49-7", "CA65-5", "LA41-3", "BB01-3", "BC23-0", "CB08-5", "BC24-3", "AA18-2", "IA14-8", "FG01-2", "GA20-4", "FG02-5", "IA17-7", "GA01-7", "AB33-8", "QB21-9", "LA45-5", "GC25-1", "TA37-0", "CA59-7", "TA23-8", "AA13-7", "CA55-5", "TA08-3", "CA56-8", "BB02-6", "GA03-3", "QB01-9", "CB07-2", "AB23-8", "RA04-8", "BC06-9", "BC20-1", "CB33-0", "CA52-6", "RA03-5", "BC01-4", "QB05-1", "LA28-4", "QB49-3", "GC26-4", "BC02-7", "BC27-2", "AB27-0", "LA46-8", "GC29-3", "BB05-5", "BB06-8", "QB02-2", "IA02-2", "TA10-9", "QB40-6", "BA38-3", "TA09-6", "MF10-6", "GA07-5", "DA37-2", "BC44-3", "CB22-7", "TA07-0", "RD10-9", "GC07-7", "GA22-0", "CB04-3", "QB46-4", "GC04-8", "QB06-4", "UB02-7", "CB25-6", "DA30-1", "ME05-0", "KA06-7", "CB03-0", "TA47-0", "DA43-0", "GC03-5", "DA33-0", "LA24-2", "FG21-2", "LA23-9", "MA11-4", "CB26-9", "RB11-0", "TA41-2", "GC08-0", "FG04-1", "CB27-2", "TA48-3", "DA38-5", "BC48-5", "KA10-9", "AB09-6", "IA41-9", "QB53-5", "QB29-3", "TA29-6", "RA08-0", "FG07-0", "GA09-1", "TA03-8", "MA12-7", "GA04-6", "BC29-8", "RA07-7", "BC05-6", "QB45-1", "FB08-8", "QB51-9", "BC43-0", "TA25-4", "BC40-1", "LA20-0", "ME02-1", "CB47-2", "MA04-3", "BA46-7", "LA05-5", "BA44-1", "CB44-3", "QA01-8", "BA23-8", "FB10-4", "QA06-3", "BC22-7", "FG03-8", "LA40-0", "LA43-9", "KA14-1", "ME01-8", "SA03-6", "DA02-7", "DA34-3", "CB21-4", "TA21-2", "LA09-7", "SA04-9", "GC32-2", "CB40-1", "CB29-8", "QB25-1", "JA06-6", "EA19-9", "BA48-3", "GB01-8", "AB29-6", "BC21-4", "TA28-3", "EA11-5", "AB21-2", "AA46-6", "AB22-5", "QB03-5", "QA05-0", "BC03-0", "BA41-2", "QB48-0", "BA42-5", "LA47-1", "LA54-2", "LA48-4", "AA42-4", "EA12-8", "DA09-8", "AB26-7", "AA45-3", "JA18-2", "GC14-8", "AA06-6", "DA05-6", "AA01-1", "CB05-6", "TA40-9", "QB04-8", "LA25-5", "LA26-8", "BC08-5", "FG10-9", "GC17-7", "ME04-7", "DA01-4", "DA06-9", "DA32-7", "MA10-1", "CB09-8", "BA29-6", "DA31-4", "AB25-4", "AB28-3", "CB01-4", "LA22-6", "AA24-0", "CB02-7", "GA10-4", "EA16-0", "AA41-1", "JA14-0", "AB03-8", "RA09-3", "AB05-4", "TA43-8", "QB43-5", "RA06-4", "AB06-7", "GA08-8", "BC04-3", "DA39-8", "FB06-2", "HA30-5", "BA26-7", "AB08-3", "EA30-2", "JA17-9", "SA01-0", "AA02-4", "LA21-3", "BC07-2", "RA05-1", "QB47-7", "LA18-4", "QB44-8", "CB39-8", "AA28-2", "MA14-3", "SA02-3", "HA05-0", "MD04-6", "ME03-4", "GB03-4", "KA16-7", "BA08-3", "LA01-3", "KA15-4", "LA02-6", "DA14-3", "DA35-6", "IA20-6", "CB20-1", "QA07-6", "BA49-6", "DA03-0", "IA27-7", "HA02-1", "DA36-9", "CB41-4", "CA17-1", "CB23-0", "CA14-2", "BA25-4", "AB02-5", "CB28-5", "MD03-3", "RB08-1", "BA04-1", "GA21-7", "FB02-0", "RB04-9", "BA27-0", "HA19-2", "BA03-8", "EA13-1", "AA44-0", "HA16-3", "IA01-9", "CA18-4", "FB09-1", "LA27-1", "RB07-8", "QA08-9", "FB05-9", "EA09-9", "KA03-8", "FC01-8", "EA14-4", "GB04-7", "LA04-2", "AA43-7", "MD07-5", "IA24-8", "LA06-8", "DA08-5", "BA45-4", "HA15-0", "LA29-7", "DA07-2", "HA21-8", "AA07-9", "FG19-6", "AA05-3", "DA04-3", "IA09-3", "QB28-0", "DA22-7", "HA12-1", "CB46-9", "IA42-2", "CA13-9", "RB21-0", "AA40-8", "LA42-6", "CA43-9", "EA17-3", "CB45-6", "BA28-3", "HA11-8", "BC09-8", "EA18-6", "LA50-0", "CB34-3", "TA12-5", "JA19-5", "GA06-2", "JA16-6", "AB07-0", "AA20-8", "AA09-5", "AA26-6", "HA31-8", "JA15-3", "AA23-7", "UB05-6", "RB02-3", "BA20-9", "JA11-1", "QB30-6", "PB01-8", "AA03-7", "TA36-7", "FA02-9", "UB01-4", "HA25-0", "AA29-5", "CA48-4", "GA02-0", "BA06-7", "QB12-2", "GB02-1", "LA03-9", "CA01-3", "JA22-4", "RD01-2", "RC04-0", "RD09-6", "IA21-9", "BA05-4", "CA16-8", "MD02-0", "CA40-0", "CA15-5", "CA47-1", "RB14-9", "GA18-8", "AA25-3", "MD01-7", "RD03-8", "AA27-9", "RB09-4", "BA24-1", "CA62-6", "AA48-2", "HA17-6", "IA22-2", "LA33-9", "TA01-2", "RB05-2", "MF02-2", "BA01-2", "RD06-7", "GC33-5", "LA07-1", "TA44-1", "HA14-7", "BA02-5", "RB01-0", "CA61-3", "TA16-7", "QB16-4", "IA04-8", "MF05-1", "CA10-0", "IA07-7", "MF06-4", "GA16-2", "CA66-8", "RB20-7", "MD05-9", "AB24-1", "GC30-6", "BA09-6", "QB35-1", "QB37-7", "TA33-8", "CA12-6", "GC22-2", "IA40-6", "HA10-5", "BA07-0", "QB38-0", "RD05-4", "FG12-5", "AA08-2", "TA20-9", "BA22-5", "RC06-6", "GA13-3", "BC38-5", "CA11-3", "AA34-0", "HA23-4", "CA19-7", "RA02-2", "HA18-9", "IA26-4", "RD02-5", "GC34-8", "TA34-1", "TA15-4", "RC01-1", "PB04-7", "FG11-2", "BA53-8", "BA54-1", "AA22-4", "AA21-1", "RB19-4", "JA03-7", "UB08-5", "IA03-5", "GC19-3", "BC30-1", "UB07-2", "BC37-2", "FG16-7", "MD06-2", "UB04-3", "MF01-9", "QA09-2", "FG15-4", "FC03-4", "FG18-3", "QB31-9", "GC16-4", "IA25-1", "MF09-3", "TA30-9", "IA08-0", "AA04-0", "CA49-7", "QB13-5", "QB11-9", "CA45-5", "QB08-0", "CA46-8", "GA15-9", "CB14-3", "AB30-9", "CB13-0", "CB42-7", "BC33-0", "RB15-2", "SC01-2", "CA41-3", "BC16-9", "TA38-3", "BA50-9", "QB42-2", "RA10-6", "CA63-9", "UB06-9", "BC15-6", "BC34-3", "RA13-5", "AB34-1", "RB16-5", "LA08-4", "CA60-0", "SB02-3", "TA17-0", "TA18-3", "RC08-2", "MA09-8", "RD07-0", "QB56-4", "BC19-8", "LA34-2", "TA13-8", "DA42-7", "KA12-5", "CB17-2", "GC31-9", "MF04-8", "RC02-4", "MF07-7", "QB19-3", "MA01-4", "QB17-7", "CB18-5", "QB14-8", "CB10-1", "CA64-2", "QB33-5", "LA30-0", "RC07-9", "FD02-2", "CA67-1", "FD05-1", "MF03-5", "AB37-0", "IA29-3", "CA68-4", "LA51-3", "SB01-1", "QB39-3", "GC20-6", "RD04-1", "FA03-2", "FG13-8", "DA41-4", "CB32-7", "KA04-1", "AB16-7", "CB35-6", "QB55-1", "BC39-8", "RA14-8", "RA12-2", "HA13-4", "TA14-1", "RD08-3", "BC12-7", "CA42-6", "AB12-5", "QB52-2", "RC03-7", "CB24-3", "FD01-9", "QB34-8", "AB15-4", "FB01-7", "BA18-3", "QB27-7", "MA06-9", "QA04-7", "GC13-5", "GA14-6", "KA01-2", "LA12-6", "DA24-3", "FG14-1", "RB12-3", "BC31-4", "FG17-0", "CB31-4", "GC18-0", "KA07-0", "MA02-7", "LA55-5", "DA15-6", "MF08-0", "KA08-3", "TA42-5", "MA05-6", "DA23-0", "JA10-8", "TA32-5", "DA20-1", "CB36-9", "TA31-2", "LA52-6", "AB11-2", "LA19-7", "AA47-9"] \ No newline at end of file diff --git a/openprocurement/auctions/lease/includeme.py b/openprocurement/auctions/lease/includeme.py new file mode 100644 index 0000000..af80eac --- /dev/null +++ b/openprocurement/auctions/lease/includeme.py @@ -0,0 +1,53 @@ +import logging + +from pyramid.interfaces import IRequest + +from openprocurement.auctions.core.includeme import ( + IContentConfigurator, + IAwardingNextCheck +) +from openprocurement.auctions.core.plugins.awarding.v2_1.adapters import ( + AwardingNextCheckV2_1 +) + +from openprocurement.auctions.lease.adapters import ( + AuctionRubbleOtherConfigurator +) +from openprocurement.auctions.lease.constants import ( + DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE +) +from openprocurement.auctions.lease.models import ( + IRubbleAuction, + propertyLease +) + +LOGGER = logging.getLogger(__name__) + + +def includeme_lease(config, plugin_config=None): + procurement_method_types = plugin_config.get('aliases', []) + if plugin_config.get('use_default', False): + procurement_method_types.append( + DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE + ) + for procurementMethodType in procurement_method_types: + config.add_auction_procurementMethodType(propertyLease, + procurementMethodType) + + config.scan("openprocurement.auctions.lease.views.property") + + # Register adapters + config.registry.registerAdapter( + AuctionRubbleOtherConfigurator, + (IRubbleAuction, IRequest), + IContentConfigurator + ) + config.registry.registerAdapter( + AwardingNextCheckV2_1, + (IRubbleAuction,), + IAwardingNextCheck + ) + + LOGGER.info("Included openprocurement.auctions.lease.property plugin", + extra={'MESSAGE_ID': 'included_plugin'}) + diff --git a/openprocurement/auctions/lease/migration.py b/openprocurement/auctions/lease/migration.py new file mode 100644 index 0000000..0cd4fa8 --- /dev/null +++ b/openprocurement/auctions/lease/migration.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +import logging + +from openprocurement.auctions.core.plugins.awarding.v2_1.migration import ( + migrate_awarding_1_0_to_awarding_2_1 +) +from openprocurement.auctions.core.traversal import Root +from openprocurement.auctions.core.utils import ( + get_plugins, get_procurement_method_types, get_now, read_yaml +) + +LOGGER = logging.getLogger(__name__) +SCHEMA_VERSION = 1 +SCHEMA_DOC = 'openprocurement_auctions_dgf_schema' + + +def get_db_schema_version(db): + schema_doc = db.get(SCHEMA_DOC, {"_id": SCHEMA_DOC}) + return schema_doc.get("version", SCHEMA_VERSION - 1) + + +def set_db_schema_version(db, version): + schema_doc = db.get(SCHEMA_DOC, {"_id": SCHEMA_DOC}) + schema_doc["version"] = version + db.save(schema_doc) + + +def migrate_data(registry, destination=None): + plugins_config = read_yaml(registry.settings.get('plugins')) + existing_plugins = get_plugins(plugins_config) + if registry.settings.get('plugins') and not any(existing_plugins): + return + cur_version = get_db_schema_version(registry.db) + if cur_version == SCHEMA_VERSION: + return cur_version + for step in xrange(cur_version, destination or SCHEMA_VERSION): + LOGGER.info("Migrate openprocurement auction schema from {} to {}".format(step, step + 1), extra={'MESSAGE_ID': 'migrate_data'}) + migration_func = globals().get('from{}to{}'.format(step, step + 1)) + if migration_func: + migration_func(registry) + set_db_schema_version(registry.db, step + 1) + + +def from0to1(registry): + class Request(object): + def __init__(self, registry): + self.registry = registry + + results = registry.db.iterview('auctions/all', 2 ** 10, include_docs=True) + + request = Request(registry) + root = Root(request) + procurement_method_types = get_procurement_method_types( + registry, ['propertyLease', 'leaseFinancial'] + ) + docs = [] + for i in results: + auction = i.doc + migrate_awarding_1_0_to_awarding_2_1(auction, procurement_method_types) + model = registry.auction_procurementMethodTypes.get(auction['procurementMethodType']) + if model: + try: + auction = model(auction) + auction.__parent__ = root + auction = auction.to_primitive() + except: # pragma: no cover + LOGGER.error("Failed migration of auction {} to schema 1.".format(auction.id), extra={'MESSAGE_ID': 'migrate_data_failed', 'AUCTION_ID': auction.id}) + else: + auction['dateModified'] = get_now().isoformat() + docs.append(auction) + if len(docs) >= 2 ** 7: # pragma: no cover + registry.db.update(docs) + docs = [] + if docs: + registry.db.update(docs) \ No newline at end of file diff --git a/openprocurement/auctions/lease/models.py b/openprocurement/auctions/lease/models.py new file mode 100644 index 0000000..1d54750 --- /dev/null +++ b/openprocurement/auctions/lease/models.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +from datetime import datetime, timedelta, time + +from schematics.exceptions import ValidationError +from schematics.transforms import blacklist, whitelist +from schematics.types import StringType, IntType, BooleanType +from schematics.types.compound import ModelType +from schematics.types.serializable import serializable +from pyramid.security import Allow +from zope.interface import implementer + +from openprocurement.auctions.core.includeme import IAwardingNextCheck +from openprocurement.auctions.core.models import ( + get_auction, + Lot, + Period, + Cancellation as BaseCancellation, + Question as BaseQuestion, + flashProcuringEntity, + Feature, + validate_items_uniq, + validate_features_uniq, validate_lots_uniq, + schematics_embedded_role, IsoDateTimeType, + IAuction, + calc_auction_end_time, + edit_role, + Administrator_role, + dgfCDB2Document as Document, + dgfCDB2Item as Item, + dgfOrganization as Organization, + dgfCDB2Complaint as Complaint, + Identifier, + ListType +) +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.utils import ( + SANDBOX_MODE, TZ, calculate_business_date, get_request_from_root, get_now, + AUCTIONS_COMPLAINT_STAND_STILL_TIME as COMPLAINT_STAND_STILL_TIME +) + +from openprocurement.auctions.flash.models import ( + Auction as BaseAuction, Bid as BaseBid, +) + +from .constants import ( + DGF_ID_REQUIRED_FROM, + MINIMAL_EXPOSITION_PERIOD, + MINIMAL_EXPOSITION_REQUIRED_FROM, + MINIMAL_PERIOD_FROM_RECTIFICATION_END +) +from .utils import get_auction_creation_date, generate_rectificationPeriod + + +def bids_validation_wrapper(validation_func): + def validator(klass, data, value): + orig_data = data + while not isinstance(data['__parent__'], BaseAuction): + # in case this validation wrapper is used for subelement of bid (such as parameters) + # traverse back to the bid to get possibility to check status # troo-to-to =) + data = data['__parent__'] + if data['status'] in ('invalid', 'draft'): + # skip not valid bids + return + tender = data['__parent__'] + request = tender.__parent__.request + if request.method == "PATCH" and isinstance(tender, BaseAuction) and request.authenticated_role == "auction_owner": + # disable bids validation on tender PATCH requests as tender bids will be invalidated + return + return validation_func(klass, orig_data, value) + return validator + + +class ProcuringEntity(flashProcuringEntity): + identifier = ModelType(Identifier, required=True) + additionalIdentifiers = ListType(ModelType(Identifier)) + + +class Bid(BaseBid): + class Options: + roles = { + 'create': whitelist('value', 'tenderers', 'parameters', 'lotValues', 'status', 'qualified'), + } + + status = StringType(choices=['active', 'draft', 'invalid'], default='active') + tenderers = ListType(ModelType(Organization), required=True, min_size=1, max_size=1) + documents = ListType(ModelType(Document), 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 Question(BaseQuestion): + author = ModelType(Organization, required=True) + + +class Cancellation(BaseCancellation): + documents = ListType(ModelType(Document), default=list()) + + +def validate_not_available(items, *args): + if items: + raise ValidationError(u"Option not available in this procurementMethodType") + + +def rounding_shouldStartAfter(start_after, auction, use_from=datetime(2016, 6, 1, tzinfo=TZ)): + if (auction.enquiryPeriod and auction.enquiryPeriod.startDate or get_now()) > use_from and not (SANDBOX_MODE and auction.submissionMethodDetails and u'quick' in auction.submissionMethodDetails): + midnigth = datetime.combine(start_after.date(), time(0, tzinfo=start_after.tzinfo)) + if start_after >= midnigth: + start_after = midnigth + timedelta(1) + return start_after + + +class AuctionAuctionPeriod(Period): + """The auction period.""" + + @serializable(serialize_when_none=False) + def shouldStartAfter(self): + if self.endDate: + return + auction = self.__parent__ + if auction.lots or auction.status not in ['active.tendering', 'active.auction']: + return + if self.startDate and get_now() > calc_auction_end_time(auction.numberOfBids, self.startDate): + start_after = calc_auction_end_time(auction.numberOfBids, self.startDate) + elif auction.tenderPeriod and auction.tenderPeriod.endDate: + start_after = auction.tenderPeriod.endDate + else: + return + return rounding_shouldStartAfter(start_after, auction).isoformat() + + def validate_startDate(self, data, startDate): + auction = get_auction(data['__parent__']) + if not auction.revisions and not startDate: + raise ValidationError(u'This field is required.') + + +class RectificationPeriod(Period): + invalidationDate = IsoDateTimeType() + + +create_role = (blacklist( + 'owner_token', 'owner', '_attachments', 'revisions', 'date', 'dateModified', 'doc_id', 'auctionID', 'bids', + 'documents', 'awards', 'questions', 'complaints', 'auctionUrl', 'status', + 'enquiryPeriod', 'tenderPeriod', 'awardPeriod', 'procurementMethod', 'eligibilityCriteria', + 'eligibilityCriteria_en', 'eligibilityCriteria_ru', 'awardCriteria', 'submissionMethod', 'cancellations', + 'numberOfBidders', 'contracts') + schematics_embedded_role) +edit_role = (edit_role + blacklist('enquiryPeriod', 'tenderPeriod', 'auction_value', 'auction_minimalStep', 'auction_guarantee', 'eligibilityCriteria', 'eligibilityCriteria_en', 'eligibilityCriteria_ru', 'awardCriteriaDetails', 'awardCriteriaDetails_en', 'awardCriteriaDetails_ru', 'procurementMethodRationale', 'procurementMethodRationale_en', 'procurementMethodRationale_ru', 'submissionMethodDetails', 'submissionMethodDetails_en', 'submissionMethodDetails_ru', 'minNumberOfQualifiedBids')) +Administrator_role = (Administrator_role + whitelist('awards')) + + + +class IRubbleAuction(IAuction): + """Marker interface for Rubble auctions""" + + +@implementer(IRubbleAuction) +class Auction(BaseAuction): + """Data regarding auction process - publicly inviting prospective contractors to submit bids for evaluation and selecting a winner or winners.""" + class Options: + roles = { + 'create': create_role, + 'edit_active.tendering': (blacklist('enquiryPeriod', 'tenderPeriod', 'rectificationPeriod', 'auction_value', 'auction_minimalStep', 'auction_guarantee', 'eligibilityCriteria', 'eligibilityCriteria_en', 'eligibilityCriteria_ru', 'minNumberOfQualifiedBids') + edit_role), + 'Administrator': (whitelist('rectificationPeriod') + Administrator_role), + } + + _procedure_type = "propertyLease" + 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()) + complaints = ListType(ModelType(Complaint), default=list()) + contracts = ListType(ModelType(Contract), default=list()) + dgfID = StringType() + documents = ListType(ModelType(Document), 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. + tenderAttempts = IntType(choices=[1, 2, 3, 4]) + auctionPeriod = ModelType(AuctionAuctionPeriod, required=True, default={}) + procurementMethodType = StringType() + procuringEntity = ModelType(ProcuringEntity, required=True) + status = StringType(choices=['draft', 'active.tendering', 'active.auction', 'active.qualification', 'active.awarded', 'complete', 'cancelled', 'unsuccessful'], default='active.tendering') + questions = ListType(ModelType(Question), default=list()) + features = ListType(ModelType(Feature), validators=[validate_features_uniq, validate_not_available]) + lots = ListType(ModelType(Lot), default=list(), validators=[validate_lots_uniq, validate_not_available]) + items = ListType(ModelType(Item), required=True, min_size=1, validators=[validate_items_uniq]) + minNumberOfQualifiedBids = IntType(choices=[1, 2]) + + def __acl__(self): + return [ + (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_auction'), + (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_auction_award'), + (Allow, '{}_{}'.format(self.owner, self.owner_token), 'upload_auction_documents'), + ] + + def initialize(self): + if not self.enquiryPeriod: + self.enquiryPeriod = type(self).enquiryPeriod.model_class() + if not self.tenderPeriod: + self.tenderPeriod = type(self).tenderPeriod.model_class() + now = get_now() + start_date = TZ.localize(self.auctionPeriod.startDate.replace(tzinfo=None)) + self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now + pause_between_periods = start_date - (start_date.replace(hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1)) + end_date = calculate_business_date(start_date, -pause_between_periods, self) + self.enquiryPeriod.endDate = end_date + self.tenderPeriod.endDate = self.enquiryPeriod.endDate + if not self.rectificationPeriod: + self.rectificationPeriod = generate_rectificationPeriod(self) + self.rectificationPeriod.startDate = now + self.auctionPeriod.startDate = None + self.auctionPeriod.endDate = None + self.date = now + if self.lots: + for lot in self.lots: + lot.date = now + + def validate_tenderPeriod(self, data, period): + """Auction start date must be not closer than MINIMAL_EXPOSITION_PERIOD days and not a holiday""" + if not (period and period.startDate and period.endDate): + return + if get_auction_creation_date(data) < MINIMAL_EXPOSITION_REQUIRED_FROM: + return + if calculate_business_date(period.startDate, MINIMAL_EXPOSITION_PERIOD, data) > period.endDate: + raise ValidationError(u"tenderPeriod should be greater than 6 days") + + def validate_rectificationPeriod(self, data, period): + if not (period and period.startDate) or not period.endDate: + return + if period.endDate > TZ.localize(calculate_business_date(data['tenderPeriod']['endDate'], -MINIMAL_PERIOD_FROM_RECTIFICATION_END, data).replace(tzinfo=None)): + raise ValidationError(u"rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate") + + def validate_value(self, data, value): + if value.currency != u'UAH': + raise ValidationError(u"currency should be only UAH") + + def validate_dgfID(self, data, dgfID): + if not dgfID: + if get_auction_creation_date(data) > DGF_ID_REQUIRED_FROM: + raise ValidationError(u'This field is required.') + + @serializable(serialize_when_none=False) + def next_check(self): + now = get_now() + checks = [] + if self.status == 'active.tendering' and self.tenderPeriod and self.tenderPeriod.endDate: + checks.append(self.tenderPeriod.endDate.astimezone(TZ)) + elif not self.lots and self.status == 'active.auction' and self.auctionPeriod and self.auctionPeriod.startDate and not self.auctionPeriod.endDate: + if now < self.auctionPeriod.startDate: + checks.append(self.auctionPeriod.startDate.astimezone(TZ)) + elif now < calc_auction_end_time(self.numberOfBids, self.auctionPeriod.startDate).astimezone(TZ): + checks.append(calc_auction_end_time(self.numberOfBids, self.auctionPeriod.startDate).astimezone(TZ)) + elif self.lots and self.status == 'active.auction': + for lot in self.lots: + if lot.status != 'active' or not lot.auctionPeriod or not lot.auctionPeriod.startDate or lot.auctionPeriod.endDate: + continue + if now < lot.auctionPeriod.startDate: + checks.append(lot.auctionPeriod.startDate.astimezone(TZ)) + elif now < calc_auction_end_time(lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ): + checks.append(calc_auction_end_time(lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ)) + # Use next_check part from awarding + request = get_request_from_root(self) + if request is not None: + awarding_check = request.registry.getAdapter(self, IAwardingNextCheck).add_awarding_checks(self) + if awarding_check is not None: + checks.append(awarding_check) + if self.status.startswith('active'): + from openprocurement.auctions.core.utils import calculate_business_date + for complaint in self.complaints: + if complaint.status == 'claim' and complaint.dateSubmitted: + checks.append(calculate_business_date(complaint.dateSubmitted, COMPLAINT_STAND_STILL_TIME, self)) + elif complaint.status == 'answered' and complaint.dateAnswered: + checks.append(calculate_business_date(complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self)) + for award in self.awards: + for complaint in award.complaints: + if complaint.status == 'claim' and complaint.dateSubmitted: + checks.append(calculate_business_date(complaint.dateSubmitted, COMPLAINT_STAND_STILL_TIME, self)) + elif complaint.status == 'answered' and complaint.dateAnswered: + checks.append(calculate_business_date(complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self)) + return min(checks).isoformat() if checks else None + + +propertyLease = Auction diff --git a/openprocurement/auctions/lease/tests/__init__.py b/openprocurement/auctions/lease/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openprocurement/auctions/lease/tests/auction.py b/openprocurement/auctions/lease/tests/auction.py new file mode 100644 index 0000000..91f92b0 --- /dev/null +++ b/openprocurement/auctions/lease/tests/auction.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +import unittest +from copy import deepcopy + +from openprocurement.auctions.core.tests.auctions import ( + AuctionAuctionResourceTestMixin, + AuctionLotAuctionResourceTestMixin, + AuctionMultipleLotAuctionResourceTestMixin +) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.auction_blanks import ( + # AuctionSameValueAuctionResourceTest + post_auction_auction_not_changed, + post_auction_auction_reversed, + # AuctionFeaturesAuctionResourceTest + get_auction_features_auction +) + +from openprocurement.auctions.lease.constants import DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE +from openprocurement.auctions.lease.tests.base import ( + BaseAuctionWebTest, test_bids, test_lots, test_organization, test_features_auction_data, + test_financial_auction_data, test_financial_bids, test_financial_organization, +) +from openprocurement.auctions.lease.tests.blanks.auction_blanks import ( + # AuctionAuctionResourceTest + post_auction_auction, + # AuctionLotAuctionResourceTest + post_auction_auction_lot, + # AuctionMultipleLotAuctionResourceTest + post_auction_auction_2_lots, +) + + +class AuctionAuctionResourceTest(BaseAuctionWebTest, AuctionAuctionResourceTestMixin): + #initial_data = auction_data + initial_status = 'active.tendering' + initial_bids = test_bids + + test_post_auction_auction = snitch(post_auction_auction) + + +class AuctionSameValueAuctionResourceTest(BaseAuctionWebTest): + initial_status = 'active.auction' + initial_bids = [ + { + "tenderers": [ + test_organization + ], + "value": { + "amount": 469, + "currency": "UAH", + "valueAddedTaxIncluded": True + }, + 'qualified': True + } + for i in range(3) + ] + test_post_auction_auction_not_changed = snitch(post_auction_auction_not_changed) + test_post_auction_auction_reversed = snitch(post_auction_auction_reversed) + + +@unittest.skip("option not available") +class AuctionLotAuctionResourceTest(BaseAuctionWebTest, AuctionLotAuctionResourceTestMixin): + initial_lots = test_lots + + test_post_auction_auction_lots = snitch(post_auction_auction_lot) + + + +@unittest.skip("option not available") +class AuctionMultipleLotAuctionResourceTest(BaseAuctionWebTest, AuctionMultipleLotAuctionResourceTestMixin): + initial_lots = 2 * test_lots + test_post_auction_auction_2_lots = snitch(post_auction_auction_2_lots) + + +@unittest.skip("option not available") +class AuctionFeaturesAuctionResourceTest(BaseAuctionWebTest): + initial_data = test_features_auction_data + initial_status = 'active.auction' + initial_bids = [ + { + "parameters": [ + { + "code": i["code"], + "value": 0.1, + } + for i in test_features_auction_data['features'] + ], + "tenderers": [ + test_organization + ], + "value": { + "amount": 469, + "currency": "UAH", + "valueAddedTaxIncluded": True + }, + 'qualified': True + }, + { + "parameters": [ + { + "code": i["code"], + "value": 0.15, + } + for i in test_features_auction_data['features'] + ], + "tenderers": [ + test_organization + ], + "value": { + "amount": 479, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + + test_get_auction_features_auction = snitch(get_auction_features_auction) + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionAuctionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionSameValueAuctionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionFeaturesAuctionResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/auth.ini b/openprocurement/auctions/lease/tests/auth.ini new file mode 100644 index 0000000..4d241d1 --- /dev/null +++ b/openprocurement/auctions/lease/tests/auth.ini @@ -0,0 +1,27 @@ +[auction] +auction = auction + +[chronograph] +chronograph = chronograph + +[Administrator] +administrator = administrator + +[tests] +chrisr = chrisr + +[brokers] +broker = broker +broker05 = broker05 +broker1 = broker1,1 +broker2 = broker2,2 +broker3 = broker3,3 +broker4 = broker4,4 +broker1t = broker1t,1t +broker2t = broker2t,2t + +[reviewers] +reviewer = reviewer + +[admins] +test = token \ No newline at end of file diff --git a/openprocurement/auctions/lease/tests/award.py b/openprocurement/auctions/lease/tests/award.py new file mode 100644 index 0000000..9ba58e9 --- /dev/null +++ b/openprocurement/auctions/lease/tests/award.py @@ -0,0 +1,308 @@ +# -*- coding: utf-8 -*- +import unittest +from copy import deepcopy + + +from openprocurement.auctions.lease.tests.base import ( + BaseAuctionWebTest, test_lots, test_organization, + test_bids as base_bids, + test_financial_auction_data, + test_financial_organization, +) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.plugins.awarding.v2_1.tests.blanks.award_blanks import ( + # CreateAuctionAwardTest + create_auction_award_invalid, + create_auction_award, + # AuctionAwardProcessTest + invalid_patch_auction_award, + patch_auction_award, + patch_auction_award_admin, + complate_auction_with_second_award1, + complate_auction_with_second_award2, + complate_auction_with_second_award3, + successful_second_auction_award, + unsuccessful_auction1, + unsuccessful_auction2, + unsuccessful_auction3, + unsuccessful_auction4, + unsuccessful_auction5, + get_auction_awards, + patch_auction_award_Administrator_change, + # AuctionLotAwardResourceTest + create_auction_award_lot, + patch_auction_award_lot, + patch_auction_award_unsuccessful_lot, + # Auction2LotAwardResourceTest + create_auction_award_2_lots, + patch_auction_award_2_lots, + # AuctionAwardComplaintResourceTest + create_auction_award_complaint_invalid, + create_auction_award_complaint, + patch_auction_award_complaint, + review_auction_award_complaint, + get_auction_award_complaint, + get_auction_award_complaints, + # AuctionLotAwardComplaintResourceTest + create_auction_award_complaint_lot_complaint, + patch_auction_award_complaint_lot_complaint, + get_auction_award_complaint_lot_complaint, + get_auction_award_complaints_lot_complaint, + # Auction2LotAwardComplaintResourceTest + create_auction_award_complaint_2_lot_complaint, + patch_auction_award_complaint_2_lot_complaint, + # AuctionAwardComplaintDocumentResourceTest + not_found_award_complaint_document, + create_auction_award_complaint_document, + put_auction_award_complaint_document, + patch_auction_award_complaint_document, + # Auction2LotAwardComplaintDocumentResourceTest + create_auction_award_complaint_document_2_lots, + put_auction_award_complaint_document_2_lots, + patch_auction_award_complaint_document_2_lots, + # AuctionAwardDocumentResourceTest + not_found_award_document, + create_auction_award_document, + put_auction_award_document, + patch_auction_award_document, + # Auction2LotAwardDocumentResourceTest + create_auction_award_document_2_lots, + put_auction_award_document_2_lots, + patch_auction_award_document_2_lots, +) +bid = { + "tenderers": [ + test_organization + ], + "value": { + "amount": 459, + "currency": "UAH", + "valueAddedTaxIncluded": True + }, + "qualified": True + } +test_bids = deepcopy(base_bids) +test_bids.append(bid) + +test_financial_bids = [] +for i in test_bids: + bid = deepcopy(i) + bid.update({'eligible': True}) + bid['tenderers'] = [test_financial_organization] + test_financial_bids.append(bid) + + +class CreateAuctionAwardTest(BaseAuctionWebTest): + #initial_data = auction_data + initial_status = 'active.qualification' + initial_bids = test_bids + docservice = True + + test_create_auction_award_invalid = snitch(create_auction_award_invalid) + test_create_auction_award = snitch(create_auction_award) + + + +class AuctionAwardProcessTest(BaseAuctionWebTest): + #initial_data = auction_data + initial_status = 'active.auction' + initial_bids = test_bids + docservice = True + + test_invalid_patch_auction_award = snitch(invalid_patch_auction_award) + test_patch_auction_award = snitch(patch_auction_award) + test_patch_auction_award_admin = snitch(patch_auction_award_admin) + test_complate_auction_with_second_award1 = snitch(complate_auction_with_second_award1) + test_complate_auction_with_second_award2 = snitch(complate_auction_with_second_award2) + test_complate_auction_with_second_award3 = snitch(complate_auction_with_second_award3) + test_successful_second_auction_award = snitch(successful_second_auction_award) + test_unsuccessful_auction1 = snitch(unsuccessful_auction1) + test_unsuccessful_auction2 = snitch(unsuccessful_auction2) + test_unsuccessful_auction3 = snitch(unsuccessful_auction3) + test_unsuccessful_auction4 = snitch(unsuccessful_auction4) + test_unsuccessful_auction5 = snitch(unsuccessful_auction5) + test_get_auction_awards = snitch(get_auction_awards) + test_patch_auction_award_Administrator_change = snitch(patch_auction_award_Administrator_change) + + def setUp(self): + super(AuctionAwardProcessTest, self).setUp() + self.post_auction_results() + + +@unittest.skip("option not available") +class AuctionLotAwardResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_lots = test_lots + initial_bids = test_bids + + test_create_auction_award_lot = snitch(create_auction_award_lot) + test_patch_auction_award_lot = snitch(patch_auction_award_lot) + test_patch_auction_award_unsuccessful_lot = snitch(patch_auction_award_unsuccessful_lot) + + +@unittest.skip("option not available") +class Auction2LotAwardResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_lots = 2 * test_lots + initial_bids = test_bids + + test_create_auction_award_2_lots = snitch(create_auction_award_2_lots) + test_patch_auction_award_2_lots = snitch(patch_auction_award_2_lots) + + +@unittest.skip("option not available") +class AuctionAwardComplaintResourceTest(BaseAuctionWebTest): + #initial_data = auction_data + initial_status = 'active.qualification' + initial_bids = test_bids + + test_create_auction_award_complaint_invalid = snitch(create_auction_award_complaint_invalid) + test_create_auction_award_complaint = snitch(create_auction_award_complaint) + test_patch_auction_award_complaint = snitch(patch_auction_award_complaint) + test_review_auction_award_complaint = snitch(review_auction_award_complaint) + test_get_auction_award_complaint = snitch(get_auction_award_complaint) + test_get_auction_award_complaints = snitch(get_auction_award_complaints) + + def setUp(self): + super(AuctionAwardComplaintResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': self.initial_bids[0]['id']}}) + award = response.json['data'] + self.award_id = award['id'] + + +@unittest.skip("option not available") +class AuctionLotAwardComplaintResourceTest(BaseAuctionWebTest): + #initial_data = auction_data + initial_status = 'active.qualification' + initial_lots = test_lots + initial_bids = test_bids + + test_create_auction_award_complaint_lot_complaint = snitch(create_auction_award_complaint_lot_complaint) + test_patch_auction_award_complaint_lot_complaint = snitch(patch_auction_award_complaint_lot_complaint) + test_get_auction_award_complaint_lot_complaint = snitch(get_auction_award_complaint_lot_complaint) + test_get_auction_award_complaints_lot_complaint = snitch(get_auction_award_complaints_lot_complaint) + + def setUp(self): + super(AuctionLotAwardComplaintResourceTest, self).setUp() + # Create award + bid = self.initial_bids[0] + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': bid['id'], 'lotID': bid['lotValues'][0]['relatedLot']}}) + award = response.json['data'] + self.award_id = award['id'] + + +@unittest.skip("option not available") +class Auction2LotAwardComplaintResourceTest(BaseAuctionWebTest): + initial_lots = 2 * test_lots + + test_create_auction_award_complaint_2_lot_complaint = snitch(create_auction_award_complaint_2_lot_complaint) + test_patch_auction_award_complaint_2_lot_complaint = snitch(patch_auction_award_complaint_2_lot_complaint) + test_get_auction_award_complaint_lot_complaint = snitch(get_auction_award_complaint_lot_complaint) + test_get_auction_award_complaints_lot_complaint = snitch(get_auction_award_complaints_lot_complaint) + + + +@unittest.skip("option not available") +class AuctionAwardComplaintDocumentResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + + test_not_found_award_complaint_document = snitch(not_found_award_complaint_document) + test_create_auction_award_complaint_document = snitch(create_auction_award_complaint_document) + test_put_auction_award_complaint_document = snitch(put_auction_award_complaint_document) + test_patch_auction_award_complaint_document = snitch(patch_auction_award_complaint_document) + + + def setUp(self): + super(AuctionAwardComplaintDocumentResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': self.initial_bids[0]['id']}}) + award = response.json['data'] + self.award_id = award['id'] + # Create complaint for award + response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( + self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) + complaint = response.json['data'] + self.complaint_id = complaint['id'] + self.complaint_owner_token = response.json['access']['token'] + + +@unittest.skip("option not available") +class Auction2LotAwardComplaintDocumentResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + initial_lots = 2 * test_lots + + test_create_auction_award_complaint_document_2_lots = snitch(create_auction_award_complaint_document_2_lots) + test_put_auction_award_complaint_document_2_lots = snitch(put_auction_award_complaint_document_2_lots) + test_patch_auction_award_complaint_document_2_lots = snitch(patch_auction_award_complaint_document_2_lots) + + def setUp(self): + super(Auction2LotAwardComplaintDocumentResourceTest, self).setUp() + # Create award + bid = self.initial_bids[0] + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': bid['id'], 'lotID': bid['lotValues'][0]['relatedLot']}}) + award = response.json['data'] + self.award_id = award['id'] + # Create complaint for award + response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( + self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) + complaint = response.json['data'] + self.complaint_id = complaint['id'] + self.complaint_owner_token = response.json['access']['token'] + + +class AuctionAwardDocumentResourceTest(BaseAuctionWebTest): + initial_status = 'active.auction' + initial_bids = test_bids + + test_not_found_award_document = snitch(not_found_award_document) + test_create_auction_award_document = snitch(create_auction_award_document) + test_put_auction_award_document = snitch(put_auction_award_document) + test_patch_auction_award_document = snitch(patch_auction_award_document) + + def setUp(self): + super(AuctionAwardDocumentResourceTest, self).setUp() + self.post_auction_results() + + +@unittest.skip("option not available") +class Auction2LotAwardDocumentResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + initial_lots = 2 * test_lots + + test_create_auction_award_document_2_lots = snitch(create_auction_award_document_2_lots) + test_put_auction_award_document_2_lots = snitch(put_auction_award_document_2_lots) + test_patch_auction_award_document_2_lots = snitch(patch_auction_award_document_2_lots) + + def setUp(self): + super(Auction2LotAwardDocumentResourceTest, self).setUp() + # Create award + bid = self.initial_bids[0] + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': bid['id'], 'lotID': bid['lotValues'][0]['relatedLot']}}) + award = response.json['data'] + self.award_id = award['id'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(Auction2LotAwardComplaintDocumentResourceTest)) + suite.addTest(unittest.makeSuite(Auction2LotAwardComplaintResourceTest)) + suite.addTest(unittest.makeSuite(Auction2LotAwardDocumentResourceTest)) + suite.addTest(unittest.makeSuite(Auction2LotAwardResourceTest)) + suite.addTest(unittest.makeSuite(AuctionAwardComplaintDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionAwardComplaintResourceTest)) + suite.addTest(unittest.makeSuite(AuctionAwardDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotAwardResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/base.py b/openprocurement/auctions/lease/tests/base.py new file mode 100644 index 0000000..467a068 --- /dev/null +++ b/openprocurement/auctions/lease/tests/base.py @@ -0,0 +1,510 @@ +# -*- coding: utf-8 -*- +import os +from base64 import b64encode +from copy import deepcopy +from datetime import datetime, timedelta +from urllib import urlencode +from uuid import uuid4 + +from openprocurement.auctions.core.tests.base import ( + BaseWebTest as CoreBaseWebTest, + BaseAuctionWebTest as CoreBaseAuctionWebTest +) +from openprocurement.auctions.core.utils import ( + apply_data_patch, get_now, SANDBOX_MODE +) + +from openprocurement.auctions.lease.constants import ( + DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE +) + +DEFAULT_ACCELERATION = 1440 + + +now = datetime.now() +test_organization = { + "name": u"Державне управління справами", + "identifier": { + "scheme": u"UA-EDR", + "id": u"00037256", + "uri": u"http://www.dus.gov.ua/" + }, + "address": { + "countryName": u"Україна", + "postalCode": u"01220", + "region": u"м. Київ", + "locality": u"м. Київ", + "streetAddress": u"вул. Банкова, 11, корпус 1" + }, + "contactPoint": { + "name": u"Державне управління справами", + "telephone": u"0440000000" + } +} +test_procuringEntity = test_organization.copy() +test_auction_data = { + "title": u"футляри до державних нагород", + "dgfID": u"219560", + "tenderAttempts": 1, + "procuringEntity": test_procuringEntity, + "value": { + "amount": 100, + "currency": u"UAH" + }, + "minimalStep": { + "amount": 35, + "currency": u"UAH" + }, + "items": [ + { + "description": u"Земля для військовослужбовців", + "classification": { + "scheme": u"CPV", + "id": u"66113000-5", + "description": u"Земельні ділянки" + }, + "unit": { + "name": u"item", + "code": u"44617100-9" + }, + "quantity": 5.001, + "contractPeriod": { + "startDate": (now + timedelta(days=2)).isoformat(), + "endDate": (now + timedelta(days=5)).isoformat() + }, + "address": { + "countryName": u"Україна", + "postalCode": "79000", + "region": u"м. Київ", + "locality": u"м. Київ", + "streetAddress": u"вул. Банкова 1" + } + } + ], + "auctionPeriod": { + "startDate": (now.date() + timedelta(days=14)).isoformat() + }, + "procurementMethodType": DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE, +} +if SANDBOX_MODE: + test_auction_data['procurementMethodDetails'] = 'quick, accelerator={}'.format(DEFAULT_ACCELERATION) +test_auction_maximum_data = deepcopy(test_auction_data) +test_auction_maximum_data.update({ + "title_en" : u"Cases with state awards", + "title_ru" : u"футляры к государственным наградам", + "description" : u"футляри до державних нагород", + "description_en" : u"Cases with state awards", + "description_ru" : u"футляры к государственным наградам" +}) +test_auction_maximum_data["items"][0].update({ + "description_en" : u"Cases with state awards", + "description_ru" : u"футляры к государственным наградам" +}) +test_features_auction_data = test_auction_data.copy() +test_features_item = test_features_auction_data['items'][0].copy() +test_features_item['id'] = "1" +test_features_auction_data['items'] = [test_features_item] +test_features_auction_data["features"] = [ + { + "code": "OCDS-123454-AIR-INTAKE", + "featureOf": "item", + "relatedItem": "1", + "title": u"Потужність всмоктування", + "title_en": "Air Intake", + "description": u"Ефективна потужність всмоктування пилососа, в ватах (аероватах)", + "enum": [ + { + "value": 0.1, + "title": u"До 1000 Вт" + }, + { + "value": 0.15, + "title": u"Більше 1000 Вт" + } + ] + }, + { + "code": "OCDS-123454-YEARS", + "featureOf": "tenderer", + "title": u"Років на ринку", + "title_en": "Years trading", + "description": u"Кількість років, які організація учасник працює на ринку", + "enum": [ + { + "value": 0.05, + "title": u"До 3 років" + }, + { + "value": 0.1, + "title": u"Більше 3 років, менше 5 років" + }, + { + "value": 0.15, + "title": u"Більше 5 років" + } + ] + } +] +base_test_bids = [ + { + "tenderers": [ + test_organization + ], + "value": { + "amount": 469, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + }, + { + "tenderers": [ + test_organization + ], + "value": { + "amount": 479, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } +] + +test_bids = [] +for i in base_test_bids: + i = deepcopy(i) + i.update({'qualified': True}) + test_bids.append(i) + +test_lots = [ + { + 'title': 'lot title', + 'description': 'lot description', + 'value': test_auction_data['value'], + 'minimalStep': test_auction_data['minimalStep'], + } +] +test_features = [ + { + "code": "code_item", + "featureOf": "item", + "relatedItem": "1", + "title": u"item feature", + "enum": [ + { + "value": 0.01, + "title": u"good" + }, + { + "value": 0.02, + "title": u"best" + } + ] + }, + { + "code": "code_tenderer", + "featureOf": "tenderer", + "title": u"tenderer feature", + "enum": [ + { + "value": 0.01, + "title": u"good" + }, + { + "value": 0.02, + "title": u"best" + } + ] + } +] + +test_financial_auction_data = deepcopy(test_auction_data) +test_financial_auction_data["procurementMethodType"] = DEFAULT_PROCUREMENT_METHOD_TYPE_LEASE + +test_financial_organization = deepcopy(test_organization) +test_financial_organization['additionalIdentifiers'] = [{ + "scheme": u"UA-FIN", + "id": u"А01 457213" +}] + +test_financial_bids = [] +for i in test_bids: + bid = deepcopy(i) + bid.update({'eligible': True}) + bid['tenderers'] = [test_financial_organization] + test_financial_bids.append(bid) + + +class BaseWebTest(CoreBaseWebTest): + + """Base Web Test to test openprocurement.auctions.lease. + + It setups the database before each test and delete it after. + """ + + relative_to = os.path.dirname(__file__) + + +class BaseAuctionWebTest(CoreBaseAuctionWebTest): + relative_to = os.path.dirname(__file__) + initial_data = test_auction_data + initial_organization = test_organization + + def go_to_rectificationPeriod_end(self): + now = get_now() + self.set_status('active.tendering', { + "rectificationPeriod": { + "startDate": (now - timedelta(days=14)).isoformat(), + "endDate": (now - (timedelta(minutes=6) if SANDBOX_MODE else timedelta(days=6))).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=14)).isoformat(), + "endDate": (now + (timedelta(minutes=1) if SANDBOX_MODE else timedelta(days=1))).isoformat() + }, + "enquiryPeriod": { + "startDate": (now - timedelta(days=14)).isoformat(), + "endDate": (now + (timedelta(minutes=1) if SANDBOX_MODE else timedelta(days=1))).isoformat() + }, + "auctionPeriod": { + "startDate": (now + timedelta(days=1)).isoformat() + } + }) + + def set_status(self, status, extra=None): + data = {'status': status} + if status == 'active.tendering': + data.update({ + "enquiryPeriod": { + "startDate": (now).isoformat(), + "endDate": (now + timedelta(days=7)).isoformat() + }, + "rectificationPeriod": { + "startDate": (now).isoformat(), + "endDate": (now + timedelta(days=1)).isoformat() + }, + "tenderPeriod": { + "startDate": (now).isoformat(), + "endDate": (now + timedelta(days=7)).isoformat() + } + }) + elif status == 'active.auction': + data.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=7)).isoformat(), + "endDate": (now).isoformat() + }, + "rectificationPeriod": { + "startDate": (now - timedelta(days=7)).isoformat(), + "endDate": (now - timedelta(days=6)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=7)).isoformat(), + "endDate": (now).isoformat() + }, + "auctionPeriod": { + "startDate": (now).isoformat() + } + }) + if self.initial_lots: + data.update({ + 'lots': [ + { + "auctionPeriod": { + "startDate": (now).isoformat() + } + } + for i in self.initial_lots + ] + }) + elif status == 'active.qualification': + data.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "rectificationPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=6)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat() + } + }) + if self.initial_lots: + data.update({ + 'lots': [ + { + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + } + } + for i in self.initial_lots + ] + }) + elif status == 'active.awarded': + data.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "rectificationPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=6)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + if self.initial_lots: + data.update({ + 'lots': [ + { + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + } + } + for i in self.initial_lots + ] + }) + elif status == 'complete': + data.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=18)).isoformat(), + "endDate": (now - timedelta(days=11)).isoformat() + }, + "rectificationPeriod": { + "startDate": (now - timedelta(days=18)).isoformat(), + "endDate": (now - timedelta(days=17)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=18)).isoformat(), + "endDate": (now - timedelta(days=11)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=11)).isoformat(), + "endDate": (now - timedelta(days=10)).isoformat() + }, + "awardPeriod": { + "startDate": (now - timedelta(days=10)).isoformat(), + "endDate": (now - timedelta(days=10)).isoformat() + } + }) + if self.initial_lots: + data.update({ + 'lots': [ + { + "auctionPeriod": { + "startDate": (now - timedelta(days=11)).isoformat(), + "endDate": (now - timedelta(days=10)).isoformat() + } + } + for i in self.initial_lots + ] + }) + if extra: + data.update(extra) + auction = self.db.get(self.auction_id) + auction.update(apply_data_patch(auction, data)) + self.db.save(auction) + authorization = self.app.authorization + self.app.authorization = ('Basic', ('chronograph', '')) + #response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.app.authorization = authorization + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + return response + + def upload_auction_protocol(self, award): + award_id = award['id'] + response = self.app.post_json('/auctions/{}/awards/{}/documents?acc_token={}'.format(self.auction_id, award_id, self.auction_token), + {'data': { + 'title': 'auction_protocol.pdf', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + "description": "auction protocol", + "documentType": 'auctionProtocol', + + }}) + + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual('auction_protocol.pdf', response.json["data"]["title"]) + self.assertEqual('auctionProtocol', response.json["data"]["documentType"]) + self.assertEqual('auction_owner', response.json["data"]["author"]) + + def post_auction_results(self): + authorization = self.app.authorization + self.app.authorization = ('Basic', ('auction', '')) + now = get_now() + auction_result = { + 'bids': [ + { + "id": b['id'], + "date": (now - timedelta(seconds=i)).isoformat(), + "value": b['value'] + } + for i, b in enumerate(self.initial_bids) + ] + } + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': auction_result}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertEqual('active.qualification', auction["status"]) + self.first_award = auction['awards'][0] + self.second_award = auction['awards'][1] + self.first_award_id = self.first_award['id'] + self.second_award_id = self.second_award['id'] + self.app.authorization = authorization + + def generate_docservice_url(self): + uuid = uuid4().hex + key = self.app.app.registry.docservice_key + keyid = key.hex_vk()[:8] + signature = b64encode(key.signature("{}\0{}".format(uuid, '0' * 32))) + query = {'Signature': signature, 'KeyID': keyid} + return "http://localhost/get/{}?{}".format(uuid, urlencode(query)) + + def patch_award(self, award_id, status, bid_token=None): + if bid_token: + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(self.auction_id, award_id, bid_token), {"data": {"status": status}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + return response + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award_id), {"data": {"status": status}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + return response + + def forbidden_patch_award(self, award_id, before_status, status): + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award_id), {"data": {"status": status}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't switch award ({}) status to ({}) status".format(before_status, status)) + + +class BaseFinancialAuctionWebTest(BaseAuctionWebTest): + relative_to = os.path.dirname(__file__) + initial_data = test_financial_auction_data + initial_organization = test_financial_organization diff --git a/openprocurement/auctions/lease/tests/bidder.py b/openprocurement/auctions/lease/tests/bidder.py new file mode 100644 index 0000000..cf3aeac --- /dev/null +++ b/openprocurement/auctions/lease/tests/bidder.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +import unittest +from copy import deepcopy + +from openprocurement.auctions.lease.tests.base import ( + BaseAuctionWebTest, + test_auction_data, + test_features_auction_data, + test_financial_organization, + test_financial_auction_data, + test_bids, + test_financial_bids, + test_organization +) + +from openprocurement.auctions.lease.tests.blanks.bidder_blanks import ( + # AuctionBidderResourceTest + create_auction_bidder_invalid, + patch_auction_bidder, + get_auction_bidder, + delete_auction_bidder, + get_auction_auctioners, + bid_Administrator_change, + # AuctionBidInvalidationAuctionResourceTest + post_auction_all_invalid_bids, + post_auction_one_invalid_bid, + post_auction_one_valid_bid, + # AuctionBidderProcessTest + reactivate_invalidated_bids, + # AuctionBidderFeaturesResourceTest + features_bidder, + # AuctionBidderDocumentResourceTest + create_auction_bidder_document_nopending +) +from openprocurement.auctions.core.tests.blanks.bidder_blanks import ( + # AuctionBidderResourceTest + create_auction_bidder, + # AuctionBidderFeaturesResourceTest + features_bidder_invalid +) +from openprocurement.auctions.core.tests.bidder import ( + AuctionBidderDocumentResourceTestMixin, + AuctionBidderDocumentWithDSResourceTestMixin +) +from openprocurement.auctions.core.tests.base import snitch + + +class AuctionBidderResourceTest(BaseAuctionWebTest): + initial_status = 'active.tendering' + test_financial_organization = test_financial_organization + + test_create_auction_bidded = snitch(create_auction_bidder) + test_create_auction_bidder_invalid = snitch(create_auction_bidder_invalid) + test_patch_auction_bidder = snitch(patch_auction_bidder) + test_get_auction_bidder = snitch(get_auction_bidder) + test_delete_auction_bidder = snitch(delete_auction_bidder) + test_get_auction_auctioners = snitch(get_auction_auctioners) + test_bid_Administrator_change = snitch(bid_Administrator_change) + + +class AuctionBidInvalidationAuctionResourceTest(BaseAuctionWebTest): + initial_data = test_auction_data + initial_status = 'active.auction' + initial_bids = [ + { + "tenderers": [ + test_organization + ], + "value": { + "amount": (initial_data['value']['amount'] + initial_data['minimalStep']['amount']/2), + "currency": "UAH", + "valueAddedTaxIncluded": True + }, + 'qualified': True + } + for i in range(3) + ] + test_post_auction_all_invalid_bids = snitch(post_auction_all_invalid_bids) + test_post_auction_one_invalid_bid = snitch(post_auction_one_invalid_bid) + test_post_auction_one_valid_bid = snitch(post_auction_one_valid_bid) + + +class AuctionBidderProcessTest(BaseAuctionWebTest): + initial_data = test_auction_data + initial_bids = test_bids + + test_reactivate_invalidated_bids = snitch(reactivate_invalidated_bids) + + +@unittest.skip("option not available") +class AuctionBidderFeaturesResourceTest(BaseAuctionWebTest): + initial_data = test_features_auction_data + initial_status = 'active.tendering' + + test_features_bidder = snitch(features_bidder) + test_features_bidder_invalid = snitch(features_bidder_invalid) + + +class AuctionBidderDocumentResourceTest(BaseAuctionWebTest, AuctionBidderDocumentResourceTestMixin): + initial_status = 'active.tendering' + test_create_auction_bidder_document_nopending = snitch(create_auction_bidder_document_nopending) + + def setUp(self): + super(AuctionBidderDocumentResourceTest, self).setUp() + # Create bid + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + bid = response.json['data'] + self.bid_id = bid['id'] + self.bid_token = response.json['access']['token'] + + +class AuctionBidderDocumentWithDSResourceTest(BaseAuctionWebTest, + AuctionBidderDocumentResourceTestMixin, + AuctionBidderDocumentWithDSResourceTestMixin): + initial_status = 'active.tendering' + docservice = True + test_create_auction_bidder_document_nopending = snitch(create_auction_bidder_document_nopending) + + def setUp(self): + super(AuctionBidderDocumentWithDSResourceTest, self).setUp() + # Create bid + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + bid = response.json['data'] + self.bid_id = bid['id'] + self.bid_token = response.json['access']['token'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionBidderDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionBidderDocumentWithDSResourceTest)) + suite.addTest(unittest.makeSuite(AuctionBidderFeaturesResourceTest)) + suite.addTest(unittest.makeSuite(AuctionBidderProcessTest)) + suite.addTest(unittest.makeSuite(AuctionBidderResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/blanks/__init__.py b/openprocurement/auctions/lease/tests/blanks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openprocurement/auctions/lease/tests/blanks/auction_blanks.py b/openprocurement/auctions/lease/tests/blanks/auction_blanks.py new file mode 100644 index 0000000..78a4a31 --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/auction_blanks.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- + +def post_auction_auction(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertNotEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertEqual(auction["bids"][0]['value']['amount'], patch_data["bids"][1]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], patch_data["bids"][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Can't report auction results in current (active.qualification) auction status") + + +def post_auction_auction_lot(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + 'lotValues': [ + { + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + 'lotValues': [ + { + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + for lot in self.initial_lots: + response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") + + +def post_auction_auction_2_lots(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + 'lotValues': [ + { + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + 'lotValues': [ + { + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], [{"lotValues": ["Number of lots of auction results did not match the number of auction lots"]}]) + + for bid in patch_data['bids']: + bid['lotValues'] = [bid['lotValues'][0].copy() for i in self.initial_lots] + + patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][0]['relatedLot'] + + response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], [{u'lotValues': [{u'relatedLot': [u'relatedLot should be one of lots of bid']}]}]) + + patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][1]['relatedLot'] + + for lot in self.initial_lots: + response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") + + +def get_auction_auction_features(self): + response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertNotEqual(auction, self.initial_data) + self.assertIn('dateModified', auction) + self.assertIn('minimalStep', auction) + self.assertNotIn("procuringEntity", auction) + self.assertNotIn("tenderers", auction["bids"][0]) + self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertIn('features', auction) + self.assertIn('parameters', auction["bids"][0]) diff --git a/openprocurement/auctions/lease/tests/blanks/bidder_blanks.py b/openprocurement/auctions/lease/tests/blanks/bidder_blanks.py new file mode 100644 index 0000000..b9fc41d --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/bidder_blanks.py @@ -0,0 +1,675 @@ +# -*- coding: utf-8 -*- +from copy import deepcopy + +from openprocurement.auctions.core.tests.base import JSON_RENDERER_ERROR + +from openprocurement.auctions.lease.tests.base import test_financial_organization + + +# AuctionBidderResourceTest + +def create_auction_bidder_invalid(self): + response = self.app.post_json('/auctions/some_id/bids', { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + request_path = '/auctions/{}/bids'.format(self.auction_id) + response = self.app.post(request_path, 'data', status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': + u"Content-Type header should be one of ['application/json']", u'location': u'header', + u'name': u'Content-Type'} + ]) + + response = self.app.post( + request_path, 'data', content_type='application/json', status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + JSON_RENDERER_ERROR + ]) + + response = self.app.post_json(request_path, 'data', status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json( + request_path, {'not_data': {}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': { + 'invalid_field': 'invalid_value'}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Rogue field', u'location': + u'body', u'name': u'invalid_field'} + ]) + + response = self.app.post_json(request_path, { + 'data': {'tenderers': [{'identifier': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'identifier': [ + u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', + u'name': u'tenderers'} + ]) + + response = self.app.post_json(request_path, { + 'data': {'tenderers': [{'identifier': {}}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, + response.json['errors']) + if self.initial_organization == test_financial_organization: + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, + response.json['errors']) + self.assertIn({u'description': [ + {u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, + u'name': [u'This field is required.'], u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + else: + self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], + u'id': [u'This field is required.']}, + u'name': [u'This field is required.'], + u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + + response = self.app.post_json(request_path, {'data': {'tenderers': [{ + 'name': 'name', 'identifier': {'uri': 'invalid_value'}}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, + response.json['errors']) + if self.initial_organization == test_financial_organization: + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, + response.json['errors']) + self.assertIn({u'description': [ + {u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], + u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}], + u'location': u'body', u'name': u'tenderers'}, response.json['errors']) + else: + self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], + u'id': [u'This field is required.'], + u'uri': [u'Not a well formed URL.']}, + u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, + {'data': {'tenderers': [self.initial_organization], 'qualified': True}}, + status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, + response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, + 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, + 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [ + u'valueAddedTaxIncluded of bid should be identical to valueAddedTaxIncluded of value of auction'], + u'location': u'body', u'name': u'value'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, + 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, + 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn( + {u'description': [u'currency of bid should be identical to currency of value of auction'], u'location': u'body', + u'name': u'value'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True, + 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + if self.initial_organization == test_financial_organization: + self.assertIn( + {u'description': u"invalid literal for int() with base 10: 'additionalIdentifiers'", u'location': u'body', + u'name': u'data'}, response.json['errors']) + else: + self.assertIn({u'description': u"invalid literal for int() with base 10: 'contactPoint'", u'location': u'body', + u'name': u'data'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, + status=422) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, + status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'qualified'}, + response.json['errors']) + + +def patch_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active", "value": {"amount": 60}}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'tenderers': [{"name": u"Державне управління управлінням справами"}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['date'], bidder['date']) + self.assertNotEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 500}, 'tenderers': [self.initial_organization]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['date'], bidder['date']) + self.assertEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["value"]["amount"], 400) + self.assertNotEqual(response.json['data']['date'], bidder['date']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "active") + self.assertNotEqual(response.json['data']['date'], bidder['date']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "draft"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can\'t update bid to (draft) status") + + response = self.app.patch_json('/auctions/{}/bids/some_id'.format(self.auction_id), {"data": {"value": {"amount": 400}}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.patch_json('/auctions/some_id/bids/some_id', {"data": {"value": {"amount": 400}}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + self.set_status('complete') + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["value"]["amount"], 400) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update bid in current (complete) auction status") + + +def get_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + bid_token = response.json['access']['token'] + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't view bid in current (active.tendering) auction status") + + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bidder['id'], bid_token)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'], bidder) + + self.set_status('active.qualification') + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + bidder_data = response.json['data'] + #self.assertIn(u'participationUrl', bidder_data) + #bidder_data.pop(u'participationUrl') + self.assertEqual(bidder_data, bidder) + + response = self.app.get('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.get('/auctions/some_id/bids/some_id', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't delete bid in current (active.qualification) auction status") + + +def delete_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'], bidder) + + revisions = self.db.get(self.auction_id).get('revisions') + self.assertTrue(any([i for i in revisions[-2][u'changes'] if i['op'] == u'remove' and i['path'] == u'/bids'])) + self.assertTrue(any([i for i in revisions[-1][u'changes'] if i['op'] == u'add' and i['path'] == u'/bids'])) + + response = self.app.delete('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.delete('/auctions/some_id/bids/some_id', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + +def get_auction_auctioners(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + response = self.app.get('/auctions/{}/bids'.format(self.auction_id), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't view bids in current (active.tendering) auction status") + + self.set_status('active.qualification') + + response = self.app.get('/auctions/{}/bids'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][0], bidder) + + response = self.app.get('/auctions/some_id/bids', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + +def bid_Administrator_change(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": { + 'tenderers': [{"identifier": {"id": "00000000"}}], + "value": {"amount": 400} + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']["value"]["amount"], 400) + self.assertEqual(response.json['data']["tenderers"][0]["identifier"]["id"], "00000000") + + +# AuctionBidInvalidationAuctionResourceTest + + +def post_auction_all_invalid_bids(self): + self.app.authorization = ('Basic', ('auction', '')) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': self.initial_bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], self.initial_bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + self.assertLess(auction["bids"][0]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + self.assertEqual(auction["bids"][0]['status'], 'invalid') + self.assertEqual(auction["bids"][1]['status'], 'invalid') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + self.assertEqual('unsuccessful', auction["status"]) + + +def post_auction_one_invalid_bid(self): + self.app.authorization = ('Basic', ('auction', '')) + + bids = deepcopy(self.initial_bids) + bids[0]['value']['amount'] = bids[0]['value']['amount'] * 3 + bids[1]['value']['amount'] = bids[1]['value']['amount'] * 2 + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + + self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) + self.assertGreater(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + + self.assertEqual(auction["bids"][0]['status'], 'active') + self.assertEqual(auction["bids"][1]['status'], 'active') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + + self.assertEqual('active.qualification', auction["status"]) + + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + +def post_auction_one_valid_bid(self): + self.app.authorization = ('Basic', ('auction', '')) + + bids = deepcopy(self.initial_bids) + bids[0]['value']['amount'] = bids[0]['value']['amount'] * 2 + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + + self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + + self.assertEqual(auction["bids"][0]['status'], 'active') + self.assertEqual(auction["bids"][1]['status'], 'invalid') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + + self.assertEqual('active.qualification', auction["status"]) + + for i, status in enumerate(['pending.verification', 'unsuccessful']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + +# AuctionBidderProcessTest + + +def reactivate_invalidated_bids(self): + + bid1_id = self.initial_bids[0]['id'] + bid2_id = self.initial_bids[1]['id'] + bid1_token = self.initial_bids_tokens[self.initial_bids[0]['id']] + bid2_token = self.initial_bids_tokens[self.initial_bids[1]['id']] + + # patch + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), {'data': {'value': {'amount': 540}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token)) + self.assertEqual(response.json['data']["status"], "invalid") + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token)) + self.assertEqual(response.json['data']["status"], "invalid") + + # reactivate bids invalid bid value.amount + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {'data': {"status": "active"}}, status=422) + self.assertEqual(response.json['errors'], [ + {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {'data': {"status": "active"}}, status=422) + self.assertEqual(response.json['errors'], [ + {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + + # set bid value.amount above auction value.amount + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {"data": {"value": {"amount": 800}}}) + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {"data": {"value": {"amount": 900}}}) + + # reactivate bids + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {'data': {"status": "active"}}) + self.assertEqual(response.json['data']["status"], "active") + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {'data': {"status": "active"}}) + self.assertEqual(response.json['data']["status"], "active") + +# AuctionBidderFeaturesResourceTest + + +def features_bidder(self): + test_features_bids = [ + { + "parameters": [ + { + "code": i["code"], + "value": 0.1, + } + for i in self.initial_data['features'] + ], + "status": "active", + "tenderers": [ + self.initial_organization + ], + "value": { + "amount": 469, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + }, + { + "parameters": [ + { + "code": i["code"], + "value": 0.15, + } + for i in self.initial_data['features'] + ], + "tenderers": [ + self.initial_organization + ], + "status": "draft", + "value": { + "amount": 479, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + for i in test_features_bids: + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': i}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bid = response.json['data'] + bid.pop(u'date') + bid.pop(u'id') + self.assertEqual(bid, i) + +# AuctionBidderDocumentResourceTest + + +def create_auction_bidder_document_nopending(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + bid = response.json['data'] + bid_id = bid['id'] + + response = self.app.post('/auctions/{}/bids/{}/documents'.format( + self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + + self.set_status('active.qualification') + + response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format( + self.auction_id, bid_id, doc_id), {"data": {"description": "document description"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") + + response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( + self.auction_id, bid_id, doc_id), 'content3', content_type='application/msword', status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") + + response = self.app.post('/auctions/{}/bids/{}/documents'.format( + self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document because award of bid is not in pending state") diff --git a/openprocurement/auctions/lease/tests/blanks/chronograph_blanks.py b/openprocurement/auctions/lease/tests/blanks/chronograph_blanks.py new file mode 100644 index 0000000..04db354 --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/chronograph_blanks.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +from datetime import datetime, timedelta + +from openprocurement.auctions.core.utils import get_now + + +# AuctionSwitchQualificationResourceTest + + +def switch_to_qualification1(self): + response = self.set_status('active.auction', {'status': self.initial_status}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "unsuccessful") + self.assertNotIn("awards", response.json['data']) + + +def switch_to_qualification(self): + auction = self.db.get(self.auction_id) + auction['minNumberOfQualifiedBids'] = 1 + self.db.save(auction) + response = self.set_status('active.auction', {'status': self.initial_status}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "active.qualification") + self.assertEqual(len(response.json['data']["awards"]), 1) + + +# AuctionAuctionPeriodResourceTest + + +def set_auction_period(self): + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], 'active.tendering') + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertIn('auctionPeriod', item) + self.assertIn('shouldStartAfter', item['auctionPeriod']) + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('T00:00:00+', item['auctionPeriod']['shouldStartAfter']) + self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(item['auctionPeriod']['startDate'], '9999-01-01T00:00:00+00:00') + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": None}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": None}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertNotIn('startDate', item['auctionPeriod']) + +def reset_auction_period(self): + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], 'active.tendering') + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertIn('auctionPeriod', item) + self.assertIn('shouldStartAfter', item['auctionPeriod']) + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + + self.set_status('active.auction', {'status': 'active.tendering'}) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) + + now = get_now().isoformat() + auction = self.db.get(self.auction_id) + if self.initial_lots: + auction['lots'][0]['auctionPeriod']['startDate'] = now + else: + auction['auctionPeriod']['startDate'] = now + self.db.save(auction) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertGreater(response.json['data']['next_check'], item['auctionPeriod']['startDate']) + self.assertEqual(response.json['data']['next_check'], self.db.get(self.auction_id)['next_check']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertNotIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertGreater(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + auction = self.db.get(self.auction_id) + self.assertGreater(auction['next_check'], response.json['data']['tenderPeriod']['endDate']) + auction['tenderPeriod']['endDate'] = auction['tenderPeriod']['startDate'] + auction['tenderPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() + auction['enquiryPeriod']['startDate'] = auction['tenderPeriod']['startDate'] + auction['enquiryPeriod']['endDate'] = auction['tenderPeriod']['endDate'] + auction['rectificationPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() + auction['rectificationPeriod']['endDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=5)).isoformat() + if self.initial_lots: + auction['lots'][0]['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] + else: + auction['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] + self.db.save(auction) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertNotIn('next_check', response.json['data']) + self.assertNotIn('next_check', self.db.get(self.auction_id)) + shouldStartAfter = item['auctionPeriod']['shouldStartAfter'] + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertEqual(item['auctionPeriod']['shouldStartAfter'], shouldStartAfter) + self.assertNotIn('next_check', response.json['data']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) diff --git a/openprocurement/auctions/lease/tests/blanks/document_blanks.py b/openprocurement/auctions/lease/tests/blanks/document_blanks.py new file mode 100644 index 0000000..22c64d9 --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/document_blanks.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- + +def create_auction_document(self): + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json, {"data": []}) + + response = self.app.post('/auctions/{}/documents'.format( + self.auction_id), upload_files=[('file', u'укр.doc', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + if self.docservice: + self.assertIn('Signature=', response.json["data"]["url"]) + self.assertIn('KeyID=', response.json["data"]["url"]) + self.assertNotIn('Expires=', response.json["data"]["url"]) + key = response.json["data"]["url"].split('/')[-1].split('?')[0] + auction = self.db.get(self.auction_id) + self.assertIn(key, auction['documents'][-1]["url"]) + self.assertIn('Signature=', auction['documents'][-1]["url"]) + self.assertIn('KeyID=', auction['documents'][-1]["url"]) + self.assertNotIn('Expires=', auction['documents'][-1]["url"]) + else: + key = response.json["data"]["url"].split('?')[-1].split('=')[-1] + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"][0]["id"]) + self.assertEqual(u'укр.doc', response.json["data"][0]["title"]) + + response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( + self.auction_id, doc_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': u'url', u'name': u'download'} + ]) + + if self.docservice: + response = self.app.get('/auctions/{}/documents/{}?download={}'.format( + self.auction_id, doc_id, key)) + self.assertEqual(response.status, '302 Moved Temporarily') + self.assertIn('http://localhost/get/', response.location) + self.assertIn('Signature=', response.location) + self.assertIn('KeyID=', response.location) + self.assertNotIn('Expires=', response.location) + else: + response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( + self.auction_id, doc_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': u'url', u'name': u'download'} + ]) + + response = self.app.get('/auctions/{}/documents/{}?download={}'.format( + self.auction_id, doc_id, key)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/msword') + self.assertEqual(response.content_length, 7) + self.assertEqual(response.body, 'content') + + response = self.app.get('/auctions/{}/documents/{}'.format( + self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + + response = self.app.post('/auctions/{}/documents?acc_token=acc_token'.format( + self.auction_id), upload_files=[('file', u'укр.doc'.encode("ascii", "xmlcharrefreplace"), 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertNotIn('acc_token', response.headers['Location']) + + self.set_status('active.auction') + + response = self.app.post('/auctions/{}/documents'.format( + self.auction_id), upload_files=[('file', u'укр.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") + + +def put_auction_offline_document(self): + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + dateModified = response.json["data"]['dateModified'] + datePublished = response.json["data"]['datePublished'] + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Новий порядок ознайомлення', + 'documentType': 'x_dgfAssetFamiliarization', + }}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': [u'This field is required.'], u'location': u'body', u'name': u'accessDetails'} + ]) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Новий порядок ознайомлення', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', + 'hash': 'md5:' + '0' * 32, + }}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [{'description': [u'This field is not required.'], u'location': u'body', u'name': u'hash'}]) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #2', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + auction = self.db.get(self.auction_id) + self.assertEqual(u'Порядок ознайомлення з майном #2', auction['documents'][-1]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', auction['documents'][-1]["accessDetails"]) + self.assertEqual('offline/on-site-examination', auction['documents'][-1]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', auction['documents'][-1]["documentType"]) + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"][-1]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"][-1]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"][-1]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"][-1]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"][-1]["documentType"]) + + response = self.app.get('/auctions/{}/documents/{}'.format(self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) + dateModified2 = response.json["data"]['dateModified'] + self.assertTrue(dateModified < dateModified2) + self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) + self.assertEqual(response.json["data"]['datePublished'], datePublished) + + response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(dateModified, response.json["data"][0]['dateModified']) + self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) + + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #3', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + dateModified = response.json["data"]['dateModified'] + self.assertIn(doc_id, response.headers['Location']) + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) + self.assertEqual(dateModified, response.json["data"][1]['dateModified']) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #4', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #4', response.json["data"]["title"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + auction = self.db.get(self.auction_id) + self.assertEqual(u'Порядок ознайомлення з майном #4', auction['documents'][-1]["title"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + self.set_status('active.auction') + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #5', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") \ No newline at end of file diff --git a/openprocurement/auctions/lease/tests/blanks/lot_blanks.py b/openprocurement/auctions/lease/tests/blanks/lot_blanks.py new file mode 100644 index 0000000..c1c63ee --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/lot_blanks.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +def patch_auction_currency(self): + # create lot + response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + lot = response.json['data'] + self.assertEqual(lot['value']['currency'], "UAH") + + # update auction currency without mimimalStep currency change + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"value": {"currency": "GBP"}}}, + status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'currency should be identical to currency of value of auction'], + u'location': u'body', u'name': u'minimalStep'}, + {u"description": [u"currency should be only UAH"], + u"location": u"body", u"name": u"value"} + ]) diff --git a/openprocurement/auctions/lease/tests/blanks/migration_blanks.py b/openprocurement/auctions/lease/tests/blanks/migration_blanks.py new file mode 100644 index 0000000..16f3a52 --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/migration_blanks.py @@ -0,0 +1,1175 @@ +# -*- coding: utf-8 -*- +from copy import deepcopy +from datetime import timedelta +from uuid import uuid4 + +from openprocurement.auctions.core.utils import get_now + +from openprocurement.auctions.lease.migration import migrate_data +# MigrateTestFrom1To2Bids + +def migrate_one_pending(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['status'], 'active.qualification') + + 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']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), + {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + 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']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][1]['status'], u'pending.verification') + + +def migrate_one_active(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') + self.assertEqual(auction['status'], 'active.awarded') + + 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']['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + active_award = response.json['data'][0] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), + {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + 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']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][1]['status'], u'pending.verification') + + +def migrate_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + pending_award['bid_id'] = auction['bids'][0]['id'] + auction['awards'] = [unsuccessful_award, pending_award] + auction.update(auction) + + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertEqual(auction['status'], 'active.qualification') + + +def migrate_unsuccessful_active(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + active_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [unsuccessful_award, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') + self.assertEqual(auction['status'], 'active.awarded') + +# MigrateTestFrom1To2WithTwoBids + + +def migrate_pending_to_unsuccesful(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + 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']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + 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']['status'], u'unsuccessful') + + +def migrate_pending_to_complete(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + 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']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'pending.payment') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + + +def migrate_active_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + 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']['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + active_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + 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']['status'], u'unsuccessful') + + +def migrate_active_to_complete(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract_id), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + + +def migrate_cancelled_pending_to_complete(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + cancelled_award = deepcopy(pending_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + cancelled_award['complaintPeriod']['endDate'] = get_now().isoformat() + auction['awards'] = [cancelled_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + self.assertEqual(auction['awards'][2]['status'], 'pending.waiting') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 3) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'pending.payment') + self.assertEqual(response.json['data'][2]['status'], u'pending.waiting') + pending_award = response.json['data'][1] + waiting_award = response.json['data'][2] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'pending.payment') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + + +def migrate_unsuccessful_pending_to_complete(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + pending_award['bid_id'] = auction['bids'][1]['id'] + auction['awards'] = [unsuccessful_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][1]['status'], u'pending.payment') + pending_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + +def migrate_unsuccessful_active_to_complete(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][0]['id'], + 'suppliers': auction['bids'][0]['tenderers'], + 'value': auction['bids'][0]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + active_award['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=9)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][1]['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + +def migrate_cancelled_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + pending_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][2]) + self.assertIn('paymentPeriod', auction['awards'][2]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 3) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'pending.payment') + pending_award = response.json['data'][2] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'complete') + +def migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + cancelled_award2 = deepcopy(cancelled_award) + cancelled_award2['bid_id'] = pending_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 4) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'cancelled') + self.assertEqual(auction['awards'][3]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][3]) + self.assertIn('paymentPeriod', auction['awards'][3]) + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + 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']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']['awards']), 4) + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 4) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'cancelled') + self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') + +def migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + cancelled_award2 = deepcopy(cancelled_award) + cancelled_award2['bid_id'] = active_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 4) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'cancelled') + self.assertEqual(auction['awards'][3]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][3]) + self.assertIn('paymentPeriod', auction['awards'][3]) + self.assertIn('signingPeriod', auction['awards'][3]) + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']['awards']), 4) + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 4) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'cancelled') + self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') + +def migrate_awards_number(self): + auction = self.db.get(self.auction_id) + award_1 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "active", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + award_2 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + award_3 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award_1, award_2, award_3] + auction.update(auction) + awards_num = len(auction['awards']) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + migrated_awards_num = len(auction['awards']) + self.assertEqual(awards_num, migrated_awards_num) + +# MigrateTestFrom1To2WithThreeBids + +def migrate_unsuccessful_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + unsuccessful_award2 = deepcopy(unsuccessful_award) + unsuccessful_award['bid_id'] = auction['bids'][2]['id'] + unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, unsuccessful_award2, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'pending.payment') + +def migrate_unsuccessful_unsuccessful_active(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][0]['id'], + 'suppliers': auction['bids'][0]['tenderers'], + 'value': auction['bids'][0]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + unsuccessful_award2 = deepcopy(unsuccessful_award) + unsuccessful_award['bid_id'] = auction['bids'][2]['id'] + unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, unsuccessful_award2, active_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') diff --git a/openprocurement/auctions/lease/tests/blanks/tender_blanks.py b/openprocurement/auctions/lease/tests/blanks/tender_blanks.py new file mode 100644 index 0000000..1adc928 --- /dev/null +++ b/openprocurement/auctions/lease/tests/blanks/tender_blanks.py @@ -0,0 +1,1323 @@ +# -*- coding: utf-8 -*- +import unittest + +from copy import deepcopy +from datetime import timedelta, time +from iso8601 import parse_date + +from openprocurement.auctions.core.constants import ( + DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, + DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM +) +from openprocurement.auctions.core.tests.base import JSON_RENDERER_ERROR +from openprocurement.auctions.core.utils import get_now, SANDBOX_MODE, TZ + +from openprocurement.auctions.lease.constants import ( + MINIMAL_PERIOD_FROM_RECTIFICATION_END +) +from openprocurement.auctions.lease.models import ( + DGF_ID_REQUIRED_FROM +) +from openprocurement.auctions.lease.tests.base import ( + DEFAULT_ACCELERATION +) + +# AuctionTest + + +def create_role(self): + fields = set([ + 'awardCriteriaDetails', 'awardCriteriaDetails_en', 'awardCriteriaDetails_ru', + 'description', 'description_en', 'description_ru', 'dgfID', 'tenderAttempts', + 'features', 'guarantee', 'hasEnquiries', 'items', 'lots', 'minimalStep', 'mode', + 'procurementMethodRationale', 'procurementMethodRationale_en', 'procurementMethodRationale_ru', + 'procurementMethodType', 'procuringEntity', 'minNumberOfQualifiedBids', + 'submissionMethodDetails', 'submissionMethodDetails_en', 'submissionMethodDetails_ru', + 'title', 'title_en', 'title_ru', 'value', 'auctionPeriod', 'rectificationPeriod' + ]) + if SANDBOX_MODE: + fields.add('procurementMethodDetails') + self.assertEqual(set(self.auction._fields) - self.auction._options.roles['create'].fields, fields) + + +def edit_role(self): + fields = set([ + 'description', 'description_en', 'description_ru', + 'features', 'hasEnquiries', 'items', 'procuringEntity', + 'value', 'minimalStep', 'guarantee', 'tenderAttempts', 'title_en', 'dgfID', 'title_ru', + 'title' + ]) + if SANDBOX_MODE: + fields.add('procurementMethodDetails') + self.assertEqual(set(self.auction._fields) - self.auction._options.roles['edit_active.tendering'].fields, fields) + + +# AuctionResourceTest + + +def create_auction_validation_accelerated(self): + request_path = '/auctions' + now = get_now() + data = self.initial_data.copy() + auction_data = deepcopy(self.initial_data) + if SANDBOX_MODE: + startDate = (now + timedelta(days=8, hours=4) / DEFAULT_ACCELERATION).isoformat() + else: + startDate = (now + timedelta(days=8, hours=4)).isoformat() + auction_data['auctionPeriod'] = {'startDate': startDate} + response = self.app.post_json(request_path, {'data': auction_data}, status=201) + auction = response.json['data'] + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + tender_period_startDate = parse_date(auction['tenderPeriod']['startDate'], None) + if not tender_period_startDate.tzinfo: + tender_period_startDate = TZ.localize(tender_period_startDate) + tender_period_endDate = parse_date(auction['tenderPeriod']['endDate'], None) + if not tender_period_endDate.tzinfo: + tender_period_endDate = TZ.localize(tender_period_endDate) + if SANDBOX_MODE: + self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4) / DEFAULT_ACCELERATION) + else: + self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4)) + +def create_auction_invalid(self): + request_path = '/auctions' + response = self.app.post(request_path, 'data', status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': + u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} + ]) + + response = self.app.post( + request_path, 'data', content_type='application/json', status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + JSON_RENDERER_ERROR + ]) + + response = self.app.post_json(request_path, 'data', status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'not_data': {}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': []}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': {'procurementMethodType': 'invalid_value'}}, status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'procurementMethodType is not implemented', u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': {'invalid_field': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Rogue field', u'location': + u'body', u'name': u'invalid_field'} + ]) + + response = self.app.post_json(request_path, {'data': {'value': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [ + u'Please use a mapping for this field or Value instance instead of unicode.'], u'location': u'body', u'name': u'value'} + ]) + + response = self.app.post_json(request_path, {'data': {'procurementMethod': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u"Value must be one of ['open', 'selective', 'limited']."], u'location': u'body', u'name': u'procurementMethod'}, response.json['errors']) + #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'tenderPeriod'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'minimalStep'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) + #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'enquiryPeriod'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) + + response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': 'invalid_value'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'endDate': [u"Could not parse invalid_value. Should be ISO8601."]}, u'location': u'body', u'name': u'enquiryPeriod'} + ]) + + response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': '9999-12-31T23:59:59.999999'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'endDate': [u'date value out of range']}, u'location': u'body', u'name': u'enquiryPeriod'} + ]) + + self.initial_data['tenderPeriod'] = self.initial_data.pop('auctionPeriod') + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['auctionPeriod'] = self.initial_data.pop('tenderPeriod') + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'startDate': [u'This field is required.']}, u'location': u'body', u'name': u'auctionPeriod'} + ]) + + self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2014-10-01T00:00:00'} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data.pop('tenderPeriod') + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'startDate': [u'period should begin before its end']}, u'location': u'body', u'name': u'tenderPeriod'} + ]) + + #data = self.initial_data['tenderPeriod'] + #self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2015-10-01T00:00:00'} + #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + #self.initial_data['tenderPeriod'] = data + #self.assertEqual(response.status, '422 Unprocessable Entity') + #self.assertEqual(response.content_type, 'application/json') + #self.assertEqual(response.json['status'], 'error') + #self.assertEqual(response.json['errors'], [ + #{u'description': [u'period should begin after enquiryPeriod'], u'location': u'body', u'name': u'tenderPeriod'} + #]) + + now = get_now() + #self.initial_data['awardPeriod'] = {'startDate': now.isoformat(), 'endDate': now.isoformat()} + #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + #del self.initial_data['awardPeriod'] + #self.assertEqual(response.status, '422 Unprocessable Entity') + #self.assertEqual(response.content_type, 'application/json') + #self.assertEqual(response.json['status'], 'error') + #self.assertEqual(response.json['errors'], [ + #{u'description': [u'period should begin after tenderPeriod'], u'location': u'body', u'name': u'awardPeriod'} + #]) + + data = self.initial_data['auctionPeriod'] + self.initial_data['auctionPeriod'] = {'startDate': (now + timedelta(days=15)).isoformat(), 'endDate': (now + timedelta(days=15)).isoformat()} + self.initial_data['awardPeriod'] = {'startDate': (now + timedelta(days=14)).isoformat(), 'endDate': (now + timedelta(days=14)).isoformat()} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['auctionPeriod'] = data + del self.initial_data['awardPeriod'] + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'period should begin after auctionPeriod'], u'location': u'body', u'name': u'awardPeriod'} + ]) + + auction_data = deepcopy(self.initial_data) + if SANDBOX_MODE: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5) / DEFAULT_ACCELERATION).isoformat()} + else: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5)).isoformat()} + response = self.app.post_json(request_path, {'data': auction_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}, + {u'description': [u'tenderPeriod should be greater than 6 days'], u'location': u'body', u'name': u'tenderPeriod'} + ]) + + if SANDBOX_MODE: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10) / DEFAULT_ACCELERATION).isoformat()} + auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9) / DEFAULT_ACCELERATION).isoformat()} + else: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10)).isoformat()} + auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9)).isoformat()} + response = self.app.post_json(request_path, {'data': auction_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [{u'description': [u'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '1000.0'} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'value should be less than value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '100.0', 'valueAddedTaxIncluded': False} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'valueAddedTaxIncluded should be identical to valueAddedTaxIncluded of value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '100.0', 'currency': "USD"} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'currency should be identical to currency of value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + auction_data = deepcopy(self.initial_data) + auction_data['value'] = {'amount': '100.0', 'currency': "USD"} + auction_data['minimalStep'] = {'amount': '5.0', 'currency': "USD"} + response = self.app.post_json(request_path, {'data': auction_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': [u'currency should be only UAH'], u'location': u'body', u'name': u'value'} + ]) + + data = self.initial_data["procuringEntity"]["contactPoint"]["telephone"] + del self.initial_data["procuringEntity"]["contactPoint"]["telephone"] + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data["procuringEntity"]["contactPoint"]["telephone"] = data + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'contactPoint': {u'email': [u'telephone or email should be present']}}, u'location': u'body', u'name': u'procuringEntity'} + ]) + + +@unittest.skipIf(get_now() < DGF_ID_REQUIRED_FROM, "Can`t create auction without dgfID only from {}".format(DGF_ID_REQUIRED_FROM)) +def required_dgf_id(self): + data = self.initial_data.copy() + del data['dgfID'] + response = self.app.post_json('/auctions', {'data': data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [{"location": "body", "name": "dgfID", "description": ["This field is required."]}]) + + data['dgfID'] = self.initial_data['dgfID'] + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('dgfID', auction) + self.assertEqual(data['dgfID'], auction['dgfID']) + + +@unittest.skipIf(get_now() < DGF_ADDRESS_REQUIRED_FROM, "Can`t create auction without item.address only from {}".format(DGF_ADDRESS_REQUIRED_FROM)) +def required_dgf_item_address(self): + auction_data = deepcopy(self.initial_data) + del auction_data['items'][0]['address'] + + address = { + "countryName": u"Україна", + "postalCode": "79000", + "region": u"м. Київ", + "locality": u"м. Київ", + "streetAddress": u"вул. Банкова 1" + } + + # CAV-PS specific location code test (address is required) + auction_data['items'][0]['classification'] = { + "scheme": u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + del auction_data['items'][0]['address'] + + # CPV specific location code test (address is required) + auction_data['items'][0]['classification'] = { + "scheme": u"CPV", + "id": u"34965000-9", + "description": u"Всебічно направлений далекомірний радіомаяк" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + del auction_data['items'][0]["address"] + + # CAV-PS/CPV non specific location code test (address is not required) + auction_data['items'][0]['classification'] = { + "scheme": u"CPV", + "id": u"90470000-2", + "description": u"Послуги з чищення каналізаційних колекторів" + } + item = deepcopy(auction_data['items'][0]) + item['classification'] = { + "scheme": u"CAV-PS", + "id": u"07227000-6", + "description": u"Застава - Інше" + } + auction_data['items'].append(item) + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + +def create_auction_auctionPeriod(self): + data = self.initial_data.copy() + #tenderPeriod = data.pop('tenderPeriod') + #data['auctionPeriod'] = {'startDate': tenderPeriod['endDate']} + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('tenderPeriod', auction) + self.assertIn('auctionPeriod', auction) + self.assertNotIn('startDate', auction['auctionPeriod']) + self.assertEqual(parse_date(data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) + if SANDBOX_MODE: + auction_startDate = parse_date(data['auctionPeriod']['startDate'], None) + if not auction_startDate.tzinfo: + auction_startDate = TZ.localize(auction_startDate) + tender_endDate = parse_date(auction['tenderPeriod']['endDate'], None) + if not tender_endDate.tzinfo: + tender_endDate = TZ.localize(tender_endDate) + self.assertLessEqual((auction_startDate - tender_endDate).total_seconds(), 70) + else: + self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).date(), parse_date(data['auctionPeriod']['startDate'], TZ).date() - timedelta(days=1)) + self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).time(), time(20, 0)) + + +def create_auction_rectificationPeriod_generated(self): + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('tenderPeriod', auction) + self.assertIn('enquiryPeriod', auction) + self.assertIn('rectificationPeriod', auction) + self.assertIn('auctionPeriod', auction) + self.assertNotIn('startDate', auction['auctionPeriod']) + self.assertEqual(parse_date(self.initial_data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) + timedelta_during_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate']) + if not SANDBOX_MODE: + self.assertEqual(timedelta_during_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) + else: + self.assertEqual(timedelta_during_periods_ends, (MINIMAL_PERIOD_FROM_RECTIFICATION_END / DEFAULT_ACCELERATION)) + + +def create_auction_rectificationPeriod_set(self): + now = get_now() + auction_data = deepcopy(self.initial_data) + auction_data['rectificationPeriod'] = {'endDate' : (get_now() + timedelta(days=2)).isoformat()} + auction_data['auctionPeriod'] = {'startDate' : (get_now() + timedelta(days=10)).isoformat()} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + self.assertIn('rectificationPeriod', auction) + timedelta_during_set_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction_data['rectificationPeriod']['endDate']) + self.assertGreaterEqual(timedelta_during_set_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) + self.assertEqual(timedelta_during_set_periods_ends, parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate'])) + + +def create_auction_generated(self): + data = self.initial_data.copy() + #del data['awardPeriod'] + data.update({'id': 'hash', 'doc_id': 'hash2', 'auctionID': 'hash3'}) + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + if 'procurementMethodDetails' in auction: + auction.pop('procurementMethodDetails') + self.assertEqual(set(auction), set([ + u'procurementMethodType', u'id', u'date', u'dateModified', u'auctionID', u'status', u'enquiryPeriod', + u'tenderPeriod', u'minimalStep', u'items', u'value', u'procuringEntity', u'next_check', u'dgfID', + u'procurementMethod', u'awardCriteria', u'submissionMethod', u'title', u'owner', u'auctionPeriod', + u'tenderAttempts', u'rectificationPeriod' + ])) + self.assertNotEqual(data['id'], auction['id']) + self.assertNotEqual(data['doc_id'], auction['id']) + self.assertNotEqual(data['auctionID'], auction['auctionID']) + + +def create_auction(self): + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + response = self.app.post_json('/auctions', {"data": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertEqual(set(auction) - set(self.initial_data), set([ + u'id', u'dateModified', u'auctionID', u'date', u'status', u'procurementMethod', u'rectificationPeriod', + u'awardCriteria', u'submissionMethod', u'next_check', u'owner', u'enquiryPeriod', u'tenderPeriod', + ])) + self.assertIn(auction['id'], response.headers['Location']) + + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(set(response.json['data']), set(auction)) + self.assertEqual(response.json['data'], auction) + + response = self.app.post_json('/auctions?opt_jsonp=callback', {"data": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/javascript') + self.assertIn('callback({"', response.body) + + response = self.app.post_json('/auctions?opt_pretty=1', {"data": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('{\n "', response.body) + + response = self.app.post_json('/auctions', {"data": self.initial_data, "options": {"pretty": True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('{\n "', response.body) + + auction_data = deepcopy(self.initial_data) + auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertIn('guarantee', data) + self.assertEqual(data['guarantee']['amount'], 100500) + self.assertEqual(data['guarantee']['currency'], "USD") + + +def additionalClassifications(self): + auction_data = deepcopy(self.initial_data) + # CAV-PS classification test + auction_data['items'][0]['classification'] = { + "scheme" : u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertEqual(data['items'][0]['classification']['scheme'], 'CAV-PS') + self.assertEqual(data['items'][0]['classification']['id'], '04210000-3') + + # CAV-PS and CPV classification in different items + auction_data = deepcopy(self.initial_data) + item = deepcopy(auction_data['items'][0]) + item['classification'] = { + "scheme" : u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + auction_data['items'].append(item) + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertEqual(data['items'][1]['classification']['scheme'], 'CAV-PS') + self.assertEqual(data['items'][1]['classification']['id'], '04210000-3') + self.assertEqual(data['items'][0]['classification']['scheme'], 'CPV') + self.assertEqual(data['items'][0]['classification']['id'], '66113000-5') + + # Additional Classification + + auction_data['items'][0]['additionalClassifications'] = [{ + "scheme" : u"CPVS", + "id": u"PA01-7", + "description": u"Найм" + }] + response = self.app.post_json('/auctions', {'data': auction_data}, status=201) + data = response.json['data'] + self.assertEqual(data['items'][0]['additionalClassifications'][0]['scheme'], 'CPVS') + self.assertEqual(data['items'][0]['additionalClassifications'][0]['id'], 'PA01-7') + + # CAV-PS classification fail test + auction_data['items'][0]['classification'] = { + "scheme" : u"CAV-PS", + "id": u"07227000-3", # last number is wrong + "description": u"Застава - Інше" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertTrue(response.json['errors'][0]['description'][0]['classification']) + + # Bad classification + auction_data['items'][0]['classification'] = { + "scheme" : u"CAE", # wrong scheme + "id": u"07227000-6", + "description": u"Застава - Інше" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'scheme': [u"Value must be one of [u'CPV', u'CAV-PS']."]}}], u'location': u'body', u'name': u'items'}]) + + # Additional Classification wrong id + auction_data['items'][0]['additionalClassifications'] = [{ + "scheme" : u"CPVS", + "id": u"PA01-2", # Wrong ID + "description": u"Найм" + }] + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertRegexpMatches(response.json['errors'][0]['description'][0]['additionalClassifications'][0]['id'][0], "Value must be one of*") + + +@unittest.skipIf(get_now() < CLASSIFICATION_PRECISELY_FROM, "Can`t setup precisely classification from {}".format(CLASSIFICATION_PRECISELY_FROM)) +def cavps_cpvs_classifications(self): + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + "scheme": u"CPV", + "id": u"19212310-1", + "description": u"Нерухоме майно" + }}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + "scheme": u"CPV", + "id": u"03100000-2", + "description": u"Нерухоме майно" + }}]}}, status=422) + self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'id': [u'At least CPV classification class (XXXX0000-Y) should be specified more precisely']}}], u'location': u'body', u'name': u'items'}]) + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + +def patch_auction(self): + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + owner_token = response.json['access']['token'] + dateModified = auction.pop('dateModified') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'status': 'cancelled'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['status'], 'cancelled') + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'cancelled'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['status'], 'cancelled') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'procuringEntity': {'kind': 'defense'}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotIn('kind', response.json['data']['procuringEntity']) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertNotIn('startDate', response.json['data']['tenderPeriod']) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'tenderPeriod': {'startDate': auction['enquiryPeriod']['endDate']}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertIn('startDate', response.json['data']['tenderPeriod']) + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'procurementMethodRationale': 'Open'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction = response.json['data'] + new_dateModified = new_auction.pop('dateModified') + new_auction['rectificationPeriod'].pop('invalidationDate') + self.assertEqual(auction, new_auction) + self.assertNotEqual(dateModified, new_dateModified) + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'dateModified': new_dateModified}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction2 = response.json['data'] + new_dateModified2 = new_auction2.pop('dateModified') + new_auction2['rectificationPeriod'].pop('invalidationDate') + self.assertEqual(new_auction, new_auction2) + self.assertEqual(new_dateModified, new_dateModified2) + + revisions = self.db.get(auction['id']).get('revisions') + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'items': [self.initial_data['items'][0]]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'items': [{}, self.initial_data['items'][0]]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #item0 = response.json['data']['items'][0] + #item1 = response.json['data']['items'][1] + #self.assertNotEqual(item0.pop('id'), item1.pop('id')) + #self.assertEqual(item0, item1) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'items': [{}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertEqual(len(response.json['data']['items']), 1) + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + #"scheme": u"CAV", + #"id": u"04000000-8", + #"description": u"Нерухоме майно" + #}}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'enquiryPeriod': {'endDate': new_dateModified2}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction = response.json['data'] + self.assertIn('startDate', new_auction['enquiryPeriod']) + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12, "valueAddedTaxIncluded": True}}}, status=422) + #self.assertEqual(response.status, '422 Unprocessable Entity') + #self.assertEqual(response.json['errors'][0], {u'description': {u'valueAddedTaxIncluded': u'Rogue field'}, u'location': u'body', u'name': u'guarantee'}) + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertIn('guarantee', response.json['data']) + #self.assertEqual(response.json['data']['guarantee']['amount'], 12) + #self.assertEqual(response.json['data']['guarantee']['currency'], 'UAH') + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"currency": "USD"}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.json['data']['guarantee']['currency'], 'USD') + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}) + #self.assertEqual(response.status, '200 OK') + + #response = self.app.get('/auctions/{}'.format(auction['id'])) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertIn('auctionUrl', response.json['data']) + + # Check availability of value, minimalStep, guarantee + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertIn('value', response.json['data']) + self.assertIn('guarantee', response.json['data']) + self.assertIn('minimalStep', response.json['data']) + + value = response.json['data']['value'] + + # 422 very low amount + response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) + self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) + + auction_data = self.db.get(auction['id']) + auction_data['status'] = 'complete' + self.db.save(auction_data) + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update auction in current (complete) status") + + +def patch_auction_rectificationPeriod_invalidationDate(self): + + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) + auction = response.json['data'] + owner_token = response.json['access']['token'] + + # patch one of main auction field by auction owner + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) + + +def patch_old_auction_rectificationPeriod_invalidationDate(self): + + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['auctionPeriod']['startDate'] = (get_now().date() + timedelta(days=8)).isoformat() + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) + auction = response.json['data'] + owner_token = response.json['access']['token'] + + db_auction = self.db.get(auction['id']) + del db_auction['rectificationPeriod'] + self.db.save(db_auction) + + # patch one of main auction field by auction owner + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) + + +def auction_Administrator_change(self): + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.post_json('/auctions/{}/questions'.format(auction['id']), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + question = response.json['data'] + + authorization = self.app.authorization + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test', 'procuringEntity': {"identifier": {"id": "00000000"}}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['mode'], u'test') + self.assertEqual(response.json['data']["procuringEntity"]["identifier"]["id"], "00000000") + + response = self.app.patch_json('/auctions/{}/questions/{}'.format(auction['id'], question['id']), {"data": {"answer": "answer"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {"location": "url", "name": "role", "description": "Forbidden"} + ]) + self.app.authorization = authorization + + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.post_json('/auctions/{}/cancellations'.format(auction['id']), {'data': {'reason': 'cancellation reason', 'status': 'active'}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['mode'], u'test') + + self.app.authorization = authorization + auction_data = deepcopy(self.initial_data) + auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + self.app.authorization = ('Basic', ('administrator', '')) + + # Check availability of value, minimalStep, guarantee + + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertIn('value', response.json['data']) + self.assertIn('guarantee', response.json['data']) + self.assertIn('minimalStep', response.json['data']) + + # 422 very low amount + response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) + self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) + + +# AuctionFieldsEditingTest + + +def patch_auction_denied(self): + + # patch auction during rectificationPeriod + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, + status=200) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['value']['amount'], 80) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'minimalStep': {'amount': 20}}}, status=200) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['minimalStep']['amount'], 20) + + self.go_to_rectificationPeriod_end() + + # patch auction after the rectificationPeriod.endDate + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, + status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertIn(u'Auction can be edited only during the rectification period', + response.json['errors'][0][u'description']) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'minimalStep': {'amount': 20}}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertIn(u'Auction can be edited only during the rectification period', + response.json['errors'][0][u'description']) + +def patch_auction_during_rectification_period(self): + auction_data = deepcopy(self.initial_maximum_data) + classification_data_edited = { + "scheme": "CAV-PS", + "description": "Edited field", + "id": "06125000-4" + } + unit_data_edited = { + "code": "44617100-0", + "name": "edited item" + } + address_data_edited = auction_data["procuringEntity"]["address"] + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + for param in ['title', 'title_en', 'title_ru']: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {param: auction[param] + u' EDITED'}}, status=200) + self.assertNotEqual(response.json['data'][param], auction[param]) + self.assertEqual(response.json['data'][param], auction[param] + u' EDITED') + + for param in ['description', 'description_en', 'description_ru']: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{param: auction[param] + u' EDITED'}]}}, status=200) + self.assertNotEqual(response.json['data']['items'][0][param], auction['items'][0][param]) + self.assertEqual(response.json['data']['items'][0][param], auction[param] + u' EDITED') + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"address": address_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['address'], auction['items'][0]['address']) + self.assertEqual(response.json['data']['items'][0]['address'], address_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"classification": classification_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['classification'], auction['items'][0]['classification']) + self.assertEqual(response.json['data']['items'][0]['classification'], classification_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"unit": unit_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['unit'], auction['items'][0]['unit']) + self.assertEqual(response.json['data']['items'][0]['unit'], unit_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"quantity": auction['items'][0]['quantity'] + 1}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity']) + self.assertEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity'] + 1) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'tenderAttempts': auction['tenderAttempts'] + 1}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts']) + self.assertEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts'] + 1) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'dgfID': auction['dgfID'] + u'EDITED'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['dgfID'], auction['dgfID']) + self.assertEqual(response.json['data']['dgfID'], auction['dgfID'] + u'EDITED') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), { + 'data': {'value': {'valueAddedTaxIncluded': False, 'amount': auction['value']['amount']}, + 'minimalStep': {'valueAddedTaxIncluded': False}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['value']['valueAddedTaxIncluded'], False) + self.assertEqual(response.json['data']['minimalStep']['valueAddedTaxIncluded'], False) + + +def invalidate_bids_auction_unsuccessful(self): + + # patch auction already created + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), + {'data': {'value': {'amount': 80}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + # switch to active.auction + + response = self.set_status('active.auction', {'status': self.initial_status}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "unsuccessful") + self.assertNotIn("awards", response.json['data']) + self.assertNotIn("bids", response.json['data']) + + +# AuctionProcessTest + + +def one_valid_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + + data = deepcopy(self.initial_data) + data['minNumberOfQualifiedBids'] = 1 + + response = self.app.post_json('/auctions', + {"data": data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + response = self.set_status('active.tendering', {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}) + self.assertIn("auctionPeriod", response.json['data']) + # create bid + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + # switch to active.qualification + self.set_status('active.auction', {'status': 'active.tendering'}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) + self.assertNotIn('auctionPeriod', response.json['data']) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending.verification award + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_date = [i['date'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual('auction_protocol.pdf', response.json["data"]["title"]) + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + + # set award as pending.payment + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) + self.assertNotEqual(response.json['data']['date'], award_date) + # set award as active + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) + # get contract id + response = self.app.get('/auctions/{}'.format(auction_id)) + contract_id = response.json['data']['contracts'][-1]['id'] + # after stand slill period + self.app.authorization = ('Basic', ('chronograph', '')) + self.set_status('complete', {'status': 'active.awarded'}) + # time travel + auction = self.db.get(auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + # sign contract + self.app.authorization = ('Basic', ('broker', '')) + self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) + # check status + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'complete') + +def one_invalid_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + data = deepcopy(self.initial_data) + data['minNumberOfQualifiedBids'] = 1 + + response = self.app.post_json('/auctions', + {"data": data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + self.set_status('active.tendering') + # create bid + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + # switch to active.qualification + self.set_status('active.auction', {"auctionPeriod": {"startDate": None}, 'status': 'active.tendering'}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + # set award as unsuccessful + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), + {"data": {"status": "unsuccessful"}}) + + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'unsuccessful') + + +def first_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + response = self.app.post_json('/auctions', + {"data": self.initial_data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + self.set_status('active.tendering') + # create bid + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + bid_id = response.json['data']['id'] + bid_token = response.json['access']['token'] + bids_tokens = {bid_id: bid_token} + # create second bid + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + bids_tokens[response.json['data']['id']] = response.json['access']['token'] + # switch to active.auction + self.set_status('active.auction') + + # get auction info + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.get('/auctions/{}/auction'.format(auction_id)) + auction_bids_data = response.json['data']['bids'] + # posting auction urls + response = self.app.patch_json('/auctions/{}/auction'.format(auction_id), + { + 'data': { + 'auctionUrl': 'https://auction.auction.url', + 'bids': [ + { + 'id': i['id'], + 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) + } + for i in auction_bids_data + ] + } + }) + # view bid participationUrl + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(auction_id, bid_id, bid_token)) + self.assertEqual(response.json['data']['participationUrl'], 'https://auction.auction.url/for_bid/{}'.format(bid_id)) + + # posting auction results + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(auction_id), + {'data': {'bids': auction_bids_data}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending.verification award + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id = award['id'] + # Upload auction protocol + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + # set award as unsuccessful + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), + {"data": {"status": "unsuccessful"}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award2 = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award2_id = award2['id'] + self.assertNotEqual(award_id, award2_id) + # create first award complaint + # self.app.authorization = ('Basic', ('broker', '')) + # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), + # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) + # complaint_id = response.json['data']['id'] + # complaint_owner_token = response.json['access']['token'] + # # create first award complaint #2 + # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), + # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) + # # answering claim + # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, owner_token), {"data": { + # "status": "answered", + # "resolutionType": "resolved", + # "resolution": "resolution text " * 2 + # }}) + # # satisfying resolution + # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, complaint_owner_token), {"data": { + # "satisfied": True, + # "status": "resolved" + # }}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id = award['id'] + # Upload auction protocol + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + # set award as "pending.payment + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) + # set award as active + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) + # get contract id + response = self.app.get('/auctions/{}'.format(auction_id)) + contract_id = response.json['data']['contracts'][-1]['id'] + # create auction contract document for test + response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=201) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + # after stand slill period + self.app.authorization = ('Basic', ('chronograph', '')) + self.set_status('complete', {'status': 'active.awarded'}) + # time travel + auction = self.db.get(auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + # sign contract + self.app.authorization = ('Basic', ('broker', '')) + self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) + # check status + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'complete') + + response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") + + response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), {"data": {"description": "document description"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") + + response = self.app.put('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") diff --git a/openprocurement/auctions/lease/tests/cancellation.py b/openprocurement/auctions/lease/tests/cancellation.py new file mode 100644 index 0000000..693415a --- /dev/null +++ b/openprocurement/auctions/lease/tests/cancellation.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.lease.tests.base import BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, test_financial_bids +from openprocurement.auctions.core.tests.cancellation import ( + AuctionCancellationResourceTestMixin, + AuctionLotCancellationResourceTestMixin, + AuctionLotsCancellationResourceTestMixin, + AuctionCancellationDocumentResourceTestMixin +) + + +class AuctionCancellationResourceTest(BaseAuctionWebTest, AuctionCancellationResourceTestMixin): + initial_status = 'active.tendering' + initial_bids = test_bids + + +@unittest.skip("option not available") +class AuctionLotCancellationResourceTest(BaseAuctionWebTest, AuctionLotCancellationResourceTestMixin): + initial_status = 'active.tendering' + initial_lots = test_lots + initial_bids = test_bids + + +@unittest.skip("option not available") +class AuctionLotsCancellationResourceTest(BaseAuctionWebTest, AuctionLotsCancellationResourceTestMixin): + initial_status = 'active.tendering' + initial_lots = 2 * test_lots + initial_bids = test_bids + + +class AuctionCancellationDocumentResourceTest(BaseAuctionWebTest, AuctionCancellationDocumentResourceTestMixin): + + def setUp(self): + super(AuctionCancellationDocumentResourceTest, self).setUp() + # Create cancellation + response = self.app.post_json('/auctions/{}/cancellations'.format( + self.auction_id), {'data': {'reason': 'cancellation reason'}}) + cancellation = response.json['data'] + self.cancellation_id = cancellation['id'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionCancellationDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotsCancellationResourceTest)) + suite.addTest(unittest.makeSuite(AuctionCancellationResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/chronograph.py b/openprocurement/auctions/lease/tests/chronograph.py new file mode 100644 index 0000000..da1033f --- /dev/null +++ b/openprocurement/auctions/lease/tests/chronograph.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.chronograph_blanks import ( + # AuctionSwitchAuctionResourceTest + switch_to_auction, + # AuctionSwitchUnsuccessfulResourceTest + switch_to_unsuccessful, + # AuctionComplaintSwitchResourceTest + switch_to_pending, + switch_to_complaint, + # AuctionAwardComplaintSwitchResourceTest + switch_to_pending_award, + switch_to_complaint_award, +) +from openprocurement.auctions.lease.tests.base import ( + BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, + test_financial_organization, test_financial_bids, +) +from openprocurement.auctions.lease.tests.blanks.chronograph_blanks import ( + # AuctionSwitchQualificationResourceTest + switch_to_qualification, + switch_to_qualification1, + # AuctionAuctionPeriodResourceTest + set_auction_period, + reset_auction_period +) + + +class AuctionSwitchQualificationResourceTest(BaseAuctionWebTest): + initial_bids = test_bids[:1] + test_switch_to_qualification1 = snitch(switch_to_qualification1) + test_switch_to_qualification = snitch(switch_to_qualification) + + +class AuctionSwitchAuctionResourceTest(BaseAuctionWebTest): + initial_bids = test_bids + + test_switch_to_auction = snitch(switch_to_auction) + + +class AuctionSwitchUnsuccessfulResourceTest(BaseAuctionWebTest): + + test_switch_to_unsuccessful = snitch(switch_to_unsuccessful) + + +@unittest.skip("option not available") +class AuctionLotSwitchQualificationResourceTest(AuctionSwitchQualificationResourceTest): + initial_lots = test_lots + + +@unittest.skip("option not available") +class AuctionLotSwitchAuctionResourceTest(AuctionSwitchAuctionResourceTest): + initial_lots = test_lots + + +@unittest.skip("option not available") +class AuctionLotSwitchUnsuccessfulResourceTest(AuctionSwitchUnsuccessfulResourceTest): + initial_lots = test_lots + + +class AuctionAuctionPeriodResourceTest(BaseAuctionWebTest): + initial_bids = test_bids + + test_set_auction_period = snitch(set_auction_period) + test_reset_auction_period = snitch(reset_auction_period) + + +class AuctionComplaintSwitchResourceTest(BaseAuctionWebTest): + + test_switch_to_pending = snitch(switch_to_pending) + test_switch_to_complaint = snitch(switch_to_complaint) + + +@unittest.skip("option not available") +class AuctionLotComplaintSwitchResourceTest(AuctionComplaintSwitchResourceTest): + initial_lots = test_lots + + +@unittest.skip("option not available") +class AuctionAwardComplaintSwitchResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + + test_switch_to_pending_award = snitch(switch_to_pending_award) + test_switch_to_complaint_award = snitch(switch_to_complaint_award) + + def setUp(self): + super(AuctionAwardComplaintSwitchResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format( + self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': self.initial_bids[0]['id']}}) + award = response.json['data'] + self.award_id = award['id'] + + +@unittest.skip("option not available") +class AuctionLotAwardComplaintSwitchResourceTest(AuctionAwardComplaintSwitchResourceTest): + initial_lots = test_lots + + def setUp(self): + super(AuctionAwardComplaintSwitchResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format(self.auction_id), {'data': { + 'suppliers': [self.initial_organization], + 'status': 'pending', + 'bid_id': self.initial_bids[0]['id'], + 'lotID': self.initial_bids[0]['lotValues'][0]['relatedLot'] + }}) + award = response.json['data'] + self.award_id = award['id'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionAwardComplaintSwitchResourceTest)) + suite.addTest(unittest.makeSuite(AuctionComplaintSwitchResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotAwardComplaintSwitchResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotComplaintSwitchResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotSwitchAuctionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotSwitchQualificationResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotSwitchUnsuccessfulResourceTest)) + suite.addTest(unittest.makeSuite(AuctionSwitchAuctionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionSwitchQualificationResourceTest)) + suite.addTest(unittest.makeSuite(AuctionSwitchUnsuccessfulResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/complaint.py b/openprocurement/auctions/lease/tests/complaint.py new file mode 100644 index 0000000..d06f112 --- /dev/null +++ b/openprocurement/auctions/lease/tests/complaint.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.core.tests.complaint import ( + AuctionComplaintResourceTestMixin, + InsiderAuctionComplaintDocumentResourceTestMixin +) +from openprocurement.auctions.core.tests.blanks.complaint_blanks import ( + # AuctionLotAwardComplaintResourceTest + create_auction_complaint_lot +) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.lease.tests.base import ( + BaseAuctionWebTest, test_auction_data, test_lots, + test_financial_auction_data, test_financial_organization +) + + + +class AuctionComplaintResourceTest(BaseAuctionWebTest, AuctionComplaintResourceTestMixin): + pass + + + +@unittest.skip("option not available") +class AuctionLotAwardComplaintResourceTest(BaseAuctionWebTest): + initial_lots = test_lots + + test_create_auction_complaint_lot = snitch(create_auction_complaint_lot) + + +class AuctionComplaintDocumentResourceTest(BaseAuctionWebTest, InsiderAuctionComplaintDocumentResourceTestMixin): + + def setUp(self): + super(AuctionComplaintDocumentResourceTest, self).setUp() + # Create complaint + response = self.app.post_json('/auctions/{}/complaints'.format( + self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) + complaint = response.json['data'] + self.complaint_id = complaint['id'] + self.complaint_owner_token = response.json['access']['token'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionComplaintDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionComplaintResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/contract.py b/openprocurement/auctions/lease/tests/contract.py new file mode 100644 index 0000000..70fe25f --- /dev/null +++ b/openprocurement/auctions/lease/tests/contract.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +import unittest +from datetime import timedelta + +from openprocurement.auctions.core.tests.contract import ( + AuctionContractDocumentResourceTestMixin, + Auction2LotContractDocumentResourceTestMixin +) + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.plugins.contracting.v2_1.tests.blanks.contract_blanks import ( + # AuctionContractResourceTest + create_auction_contract_invalid, + create_auction_contract, + create_auction_contract_in_complete_status, + patch_auction_contract, + get_auction_contract, + get_auction_contracts, + # Auction2LotContractResourceTest + patch_auction_contract_2_lots + +) +from openprocurement.auctions.core.utils import get_now +from openprocurement.auctions.lease.tests.base import BaseAuctionWebTest, test_auction_data, test_bids, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization + + +class AuctionContractResourceTest(BaseAuctionWebTest): + #initial_data = auction_data + initial_status = 'active.auction' + initial_bids = test_bids + + test_create_auction_contract_invalid = snitch(create_auction_contract_invalid) + test_create_auction_contract = snitch(create_auction_contract) + test_create_auction_contract_in_complete_status = snitch(create_auction_contract_in_complete_status) + test_patch_auction_contract = snitch(patch_auction_contract) + test_get_auction_contract = snitch(get_auction_contract) + test_get_auction_contracts = snitch(get_auction_contracts) + + + def setUp(self): + super(AuctionContractResourceTest, self).setUp() + # Create award + authorization = self.app.authorization + self.app.authorization = ('Basic', ('auction', '')) + now = get_now() + auction_result = { + 'bids': [ + { + "id": b['id'], + "date": (now - timedelta(seconds=i)).isoformat(), + "value": b['value'] + } + for i, b in enumerate(self.initial_bids) + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': auction_result}) + self.assertEqual(response.status, '200 OK') + auction = response.json['data'] + self.app.authorization = authorization + self.award = auction['awards'][0] + self.award_id = self.award['id'] + self.award_value = self.award['value'] + self.award_suppliers = self.award['suppliers'] + + self.set_status('active.qualification') + + self.app.authorization = ('Basic', ('token', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, self.award_id, self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "pending.payment"}}) + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) + + + +@unittest.skip("option not available") +class Auction2LotContractResourceTest(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + initial_lots = 2 * test_lots + test_patch_auction_contract = snitch(patch_auction_contract_2_lots) + + + def setUp(self): + super(Auction2LotContractResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format(self.auction_id), {'data': { + 'suppliers': [self.initial_organization], + 'status': 'pending', + 'bid_id': self.initial_bids[0]['id'], + 'lotID': self.initial_lots[0]['id'] + }}) + award = response.json['data'] + self.award_id = award['id'] + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) + + +class AuctionContractDocumentResourceTest(BaseAuctionWebTest, AuctionContractDocumentResourceTestMixin): + #initial_data = auction_data + initial_status = 'active.auction' + initial_bids = test_bids + + def setUp(self): + super(AuctionContractDocumentResourceTest, self).setUp() + # Create award + authorization = self.app.authorization + self.app.authorization = ('Basic', ('auction', '')) + now = get_now() + auction_result = { + 'bids': [ + { + "id": b['id'], + "date": (now - timedelta(seconds=i)).isoformat(), + "value": b['value'] + } + for i, b in enumerate(self.initial_bids) + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': auction_result}) + self.assertEqual(response.status, '200 OK') + auction = response.json['data'] + self.app.authorization = authorization + self.award = auction['awards'][0] + self.award_id = self.award['id'] + self.award_value = self.award['value'] + self.award_suppliers = self.award['suppliers'] + + self.set_status('active.qualification') + + self.app.authorization = ('Basic', ('token', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, self.award_id, self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "pending.payment"}}) + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) + # Create contract for award + response = self.app.post_json('/auctions/{}/contracts'.format(self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) + contract = response.json['data'] + self.contract_id = contract['id'] + + + +@unittest.skip("option not available") +class Auction2LotContractDocumentResourceTest(BaseAuctionWebTest, Auction2LotContractDocumentResourceTestMixin): + initial_status = 'active.qualification' + initial_bids = test_bids + initial_lots = 2 * test_lots + + def setUp(self): + super(Auction2LotContractDocumentResourceTest, self).setUp() + # Create award + response = self.app.post_json('/auctions/{}/awards'.format(self.auction_id), {'data': { + 'suppliers': [self.initial_organization], + 'status': 'pending', + 'bid_id': self.initial_bids[0]['id'], + 'lotID': self.initial_lots[0]['id'] + }}) + award = response.json['data'] + self.award_id = award['id'] + self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) + # Create contract for award + response = self.app.post_json('/auctions/{}/contracts'.format(self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) + contract = response.json['data'] + self.contract_id = contract['id'] + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionContractResourceTest)) + suite.addTest(unittest.makeSuite(AuctionContractDocumentResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/document.py b/openprocurement/auctions/lease/tests/document.py new file mode 100644 index 0000000..c54f87a --- /dev/null +++ b/openprocurement/auctions/lease/tests/document.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.document_blanks import ( + # AuctionDocumentResourceTest + not_found, + put_auction_document, + patch_auction_document, + # AuctionDocumentWithDSResourceTest + create_auction_document_json_invalid, + create_auction_document_json, + put_auction_document_json, + create_auction_offline_document, + # FinancialAuctionDocumentWithDSResourceTest + create_auction_document_vdr, + put_auction_document_vdr +) + +from openprocurement.auctions.lease.tests.base import BaseAuctionWebTest, test_financial_auction_data, test_bids, test_financial_bids +from openprocurement.auctions.lease.tests.blanks.document_blanks import ( + create_auction_document, + put_auction_offline_document +) + +class AuctionDocumentResourceTestMixin(object): + test_not_found = snitch(not_found) + test_create_auction_document = snitch(create_auction_document) + test_put_auction_document = snitch(put_auction_document) + test_patch_auction_document = snitch(patch_auction_document) + + +class AuctionDocumentResourceTest(BaseAuctionWebTest, AuctionDocumentResourceTestMixin): + docservice = False + + +class AuctionDocumentWithDSResourceTest(BaseAuctionWebTest, AuctionDocumentResourceTestMixin): + docservice = True + initial_bids = test_bids + test_create_auction_document_json_invalid = snitch(create_auction_document_json_invalid) + test_create_auction_document_json = snitch(create_auction_document_json) + test_put_auction_document_json = snitch(put_auction_document_json) + test_create_auction_offline_document = snitch(create_auction_offline_document) + test_put_auction_offline_document = snitch(put_auction_offline_document) + + def check_bids_invalidated_and_activate(self): + for bid in self.initial_bids: + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid['id'], self.initial_bids_tokens[bid['id']])) + self.assertEqual(response.json['data']["status"], "invalid") + response = self.app.patch_json( + '/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid['id'], self.initial_bids_tokens[bid['id']]), + {'data': {"status": "active"}}) + self.assertEqual(response.json['data']["status"], "active") + + def check_bids_are_active(self): + for bid in self.initial_bids: + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid['id'], self.initial_bids_tokens[bid['id']])) + self.assertEqual(response.json['data']["status"], "active") + + def test_create_document_during_and_after_rectificationPeriod(self): + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json, {"data": []}) + + # test document POST + + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'укр.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"][0]["id"]) + self.assertEqual(u'укр.doc', response.json["data"][0]["title"]) + + self.check_bids_invalidated_and_activate() + + # test document PATCH + + response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { + "description": "document description", + "documentType": 'auctionNotice' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertIn("documentType", response.json["data"]) + self.assertEqual(response.json["data"]["documentType"], 'auctionNotice') + + self.check_bids_invalidated_and_activate() + + # test document PUT + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'name.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(u'name.doc', response.json["data"]["title"]) + + self.check_bids_invalidated_and_activate() + + self.go_to_rectificationPeriod_end() + + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'укр.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.json['errors'], [ + {u'description': u'Document can be added only during the rectificationPeriod period.', u'location': + u'body', u'name': u'data'} + ]) + + self.check_bids_are_active() + + response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { + "description": "document description", + "documentType": 'auctionNotice' + }}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.json['errors'], [ + {u'description': u'Document can be updated only during the rectificationPeriod period.', u'location': + u'body', u'name': u'data'} + ]) + + self.check_bids_are_active() + + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'укр.doc', + 'url': self.generate_docservice_url(), + 'hash': 'md5:' + '0' * 32, + 'format': 'application/msword', + }}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.json['errors'], [ + {u'description': u'Document can be added only during the rectificationPeriod period.', u'location': + u'body', u'name': u'data'} + ]) + + self.check_bids_are_active() + + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionDocumentResourceTest)) + suite.addTest(unittest.makeSuite(AuctionDocumentWithDSResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/lot.py b/openprocurement/auctions/lease/tests/lot.py new file mode 100644 index 0000000..faf97a0 --- /dev/null +++ b/openprocurement/auctions/lease/tests/lot.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.core.tests.lot import ( + AuctionLotResourceTestMixin, + AuctionLotProcessTestMixin +) +from openprocurement.auctions.core.tests.blanks.lot_blanks import ( + # AuctionLotFeatureResourceTest + auction_value, + auction_features_invalid, + # AuctionLotBidderResourceTest + create_auction_bidder_invalid, + patch_auction_bidder, + # AuctionLotFeatureBidderResourceTest + create_auction_bidder_invalid_feature, + create_auction_bidder_feature +) +from openprocurement.auctions.core.tests.base import snitch + +from openprocurement.auctions.lease.tests.base import BaseWebTest, BaseAuctionWebTest, test_auction_data, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization +from openprocurement.auctions.lease.tests.blanks.lot_blanks import ( + patch_auction_currency +) + +@unittest.skip("option not available") +class AuctionLotResourceTest(BaseAuctionWebTest, AuctionLotResourceTestMixin): + test_auction_data = test_auction_data + test_lots = test_lots + test_patch_auction_currency = snitch(patch_auction_currency) + + +@unittest.skip("option not available") +class AuctionLotFeatureResourceTest(BaseAuctionWebTest): + test_auction_data = test_auction_data + initial_lots = 2 * test_lots + + test_auction_value = snitch(auction_value) + test_auction_features_invalid = snitch(auction_features_invalid) + + +@unittest.skip("option not available") +class AuctionLotBidderResourceTest(BaseAuctionWebTest): + initial_status = 'active.tendering' + initial_lots = test_lots + + create_auction_bidder_invalid = snitch(create_auction_bidder_invalid) + patch_auction_bidder = snitch(patch_auction_bidder) + + +@unittest.skip("option not available") +class AuctionLotFeatureBidderResourceTest(BaseAuctionWebTest): + initial_lots = test_lots + test_create_auction_bidder_invalid_feature = snitch(create_auction_bidder_invalid_feature) + test_create_auction_bidder_feature = snitch(create_auction_bidder_feature) + + def setUp(self): + super(AuctionLotFeatureBidderResourceTest, self).setUp() + self.lot_id = self.initial_lots[0]['id'] + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": { + "items": [ + { + 'relatedLot': self.lot_id, + 'id': '1' + } + ], + "features": [ + { + "code": "code_item", + "featureOf": "item", + "relatedItem": "1", + "title": u"item feature", + "enum": [ + { + "value": 0.01, + "title": u"good" + }, + { + "value": 0.02, + "title": u"best" + } + ] + }, + { + "code": "code_lot", + "featureOf": "lot", + "relatedItem": self.lot_id, + "title": u"lot feature", + "enum": [ + { + "value": 0.01, + "title": u"good" + }, + { + "value": 0.02, + "title": u"best" + } + ] + }, + { + "code": "code_tenderer", + "featureOf": "tenderer", + "title": u"tenderer feature", + "enum": [ + { + "value": 0.01, + "title": u"good" + }, + { + "value": 0.02, + "title": u"best" + } + ] + } + ] + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['items'][0]['relatedLot'], self.lot_id) + self.set_status('active.tendering') + + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionLotResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotBidderResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotFeatureBidderResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotProcessTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/main.py b/openprocurement/auctions/lease/tests/main.py new file mode 100644 index 0000000..0863847 --- /dev/null +++ b/openprocurement/auctions/lease/tests/main.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +import unittest + +from openprocurement.auctions.lease.tests import auction, award, bidder, document, tender, question, complaint + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(auction.suite()) + suite.addTest(award.suite()) + suite.addTest(bidder.suite()) + suite.addTest(complaint.suite()) + suite.addTest(document.suite()) + suite.addTest(migration.suite()) + suite.addTest(question.suite()) + suite.addTest(tender.suite()) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/migration.py b/openprocurement/auctions/lease/tests/migration.py new file mode 100644 index 0000000..6974051 --- /dev/null +++ b/openprocurement/auctions/lease/tests/migration.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +import unittest + +from uuid import uuid4 +from copy import deepcopy + +from openprocurement.auctions.core.tests.base import snitch + +from openprocurement.auctions.lease.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION +from openprocurement.auctions.lease.tests.base import BaseWebTest, BaseAuctionWebTest, test_bids +from openprocurement.auctions.lease.tests.blanks.migration_blanks import ( + # MigrateTestFrom1To2Bids + migrate_one_pending, + migrate_one_active, + migrate_unsuccessful_active, + migrate_unsuccessful_pending, + # MigrateTestFrom1To2WithTwoBids + migrate_pending_to_unsuccesful, + migrate_pending_to_complete, + migrate_active_to_unsuccessful, + migrate_active_to_complete, + migrate_cancelled_pending_to_complete, + migrate_unsuccessful_pending_to_complete, + migrate_unsuccessful_active_to_complete, + migrate_cancelled_unsuccessful_pending, + migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful, + migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful, + migrate_awards_number, + # MigrateTestFrom1To2WithThreeBids + migrate_unsuccessful_unsuccessful_pending, + migrate_unsuccessful_unsuccessful_active +) + + +class MigrateTest(BaseWebTest): + + def setUp(self): + super(MigrateTest, self).setUp() + migrate_data(self.app.app.registry) + + def test_migrate(self): + self.assertEqual(get_db_schema_version(self.db), SCHEMA_VERSION) + migrate_data(self.app.app.registry, 1) + self.assertEqual(get_db_schema_version(self.db), SCHEMA_VERSION) + + +class MigrateTestFrom1To2Bids(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + test_migrate_one_pending = snitch(migrate_one_pending) + test_migrate_one_active = snitch(migrate_one_active) + test_migrate_unsuccessful_active = snitch(migrate_unsuccessful_active) + test_migrate_unsuccessful_pending = snitch(migrate_unsuccessful_pending) + + def setUp(self): + super(MigrateTestFrom1To2Bids, self).setUp() + migrate_data(self.app.app.registry) + set_db_schema_version(self.db, 0) + auction = self.db.get(self.auction_id) + auction['bids'][0]['value']['amount'] = auction['value']['amount'] + self.db.save(auction) + + +class MigrateTestFrom1To2WithTwoBids(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + + test_migrate_pending_to_unsuccesful = snitch(migrate_pending_to_unsuccesful) + test_migrate_pending_to_complete = snitch(migrate_pending_to_complete) + test_migrate_active_to_unsuccessful= snitch(migrate_active_to_unsuccessful) + test_migrate_active_to_complete = snitch(migrate_active_to_complete) + test_migrate_cancelled_pending_to_complete = snitch(migrate_cancelled_pending_to_complete) + test_migrate_unsuccessful_pending_to_complete = snitch(migrate_unsuccessful_pending_to_complete) + test_migrate_unsuccessful_active_to_complete = snitch(migrate_unsuccessful_active_to_complete) + test_migrate_cancelled_unsuccessful_pending = snitch(migrate_cancelled_unsuccessful_pending) + test_migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful = snitch(migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful) + test_migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful = snitch(migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful) + test_migrate_awards_number = snitch(migrate_awards_number) + + def setUp(self): + super(MigrateTestFrom1To2WithTwoBids, self).setUp() + migrate_data(self.app.app.registry) + set_db_schema_version(self.db, 0) + + +class MigrateTestFrom1To2WithThreeBids(BaseAuctionWebTest): + initial_status = 'active.qualification' + initial_bids = test_bids + test_migrate_unsuccessful_unsuccessful_pending = snitch(migrate_unsuccessful_unsuccessful_pending) + test_migrate_unsuccessful_unsuccessful_active = snitch(migrate_unsuccessful_unsuccessful_active) + + def setUp(self): + super(MigrateTestFrom1To2WithThreeBids, self).setUp() + migrate_data(self.app.app.registry) + set_db_schema_version(self.db, 0) + auction = self.db.get(self.auction_id) + auction['bids'].append(deepcopy(auction['bids'][0])) + auction['bids'][-1]['id'] = uuid4().hex + self.db.save(auction) + + +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)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') \ No newline at end of file diff --git a/openprocurement/auctions/lease/tests/plugins.yaml b/openprocurement/auctions/lease/tests/plugins.yaml new file mode 100644 index 0000000..bd08bb2 --- /dev/null +++ b/openprocurement/auctions/lease/tests/plugins.yaml @@ -0,0 +1,7 @@ +--- +auctions.core: + plugins: + auctions.lease: + aliases: [] + use_default: true + migration: false diff --git a/openprocurement/auctions/lease/tests/question.py b/openprocurement/auctions/lease/tests/question.py new file mode 100644 index 0000000..576d3e0 --- /dev/null +++ b/openprocurement/auctions/lease/tests/question.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +import unittest + +from openprocurement.auctions.core.tests.question import ( + AuctionQuestionResourceTestMixin +) +from openprocurement.auctions.core.tests.blanks.question_blanks import ( + create_auction_question_lot, + patch_auction_question_lot +) +from openprocurement.auctions.core.tests.base import snitch + +from openprocurement.auctions.lease.tests.base import BaseAuctionWebTest, test_lots, test_financial_auction_data, test_financial_organization + + +class AuctionQuestionResourceTest(BaseAuctionWebTest, AuctionQuestionResourceTestMixin): + pass + + +@unittest.skip("option not available") +class AuctionLotQuestionResourceTest(BaseAuctionWebTest): + initial_lots = 2 * test_lots + create_auction_question_lot = snitch(create_auction_question_lot) + patch_auction_question_lot = snitch(patch_auction_question_lot) + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionQuestionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionLotQuestionResourceTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/tender.py b/openprocurement/auctions/lease/tests/tender.py new file mode 100644 index 0000000..0282348 --- /dev/null +++ b/openprocurement/auctions/lease/tests/tender.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +import re +import unittest +# from calendar import monthrange +# from copy import deepcopy +# from datetime import datetime, timedelta, time, date +# from uuid import uuid4 +# from iso8601 import parse_date +# import pytz + +from openprocurement.auctions.lease.models import propertyLease +from openprocurement.auctions.lease.tests.base import test_auction_maximum_data, test_auction_data, test_financial_auction_data, test_organization, test_financial_organization, BaseWebTest, BaseAuctionWebTest, DEFAULT_ACCELERATION, test_bids, test_financial_bids + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.tender_blanks import ( + simple_add_auction +) +from openprocurement.auctions.core.tests.blanks.tender_blanks import ( + # AuctionResourceTest + auction_features_invalid, + auction_features, + patch_tender_jsonpatch, + dateModified_auction, + guarantee, + empty_listing, + listing, + listing_changes, + listing_draft, + create_auction_draft, + get_auction, + auction_not_found, + invalid_auction_conditions +) +from openprocurement.auctions.lease.tests.blanks.tender_blanks import ( + # AuctionTest + create_role, + edit_role, + # AuctionResourceTest + create_auction_validation_accelerated, + create_auction_invalid, + required_dgf_id, + required_dgf_item_address, + create_auction_auctionPeriod, + create_auction_rectificationPeriod_generated, + create_auction_rectificationPeriod_set, + create_auction_generated, + create_auction, + additionalClassifications, + cavps_cpvs_classifications, + patch_auction, + patch_auction_rectificationPeriod_invalidationDate, + patch_old_auction_rectificationPeriod_invalidationDate, + auction_Administrator_change, + # AuctionFieldsEditingTest + patch_auction_denied, + patch_auction_during_rectification_period, + invalidate_bids_auction_unsuccessful, + # AuctionProcessTest + one_valid_bid_auction, + one_invalid_bid_auction, + first_bid_auction, +) + + +class AuctionTest(BaseWebTest): + auction = propertyLease + initial_data = test_auction_data + test_simple_add_auction = snitch(simple_add_auction) + test_create_role = snitch(create_role) + test_edit_role = snitch(edit_role) + + +class AuctionResourceTest(BaseWebTest): + initial_data = test_auction_data + initial_organization = test_organization + initial_status = 'active.tendering' + + test_empty_listing = snitch(empty_listing) + test_listing = snitch(listing) + test_listing_changes = snitch(listing_changes) + test_listing_draft = snitch(listing_draft) + test_create_auction_draft = snitch(create_auction_draft) + test_get_auction = snitch(get_auction) + test_auction_not_found = snitch(auction_not_found) + test_create_auction_validation_accelerated = snitch(create_auction_validation_accelerated) + test_create_auction_invalid = snitch(create_auction_invalid) + test_required_dgf_id = snitch(required_dgf_id) + test_required_dgf_item_address = snitch(required_dgf_item_address) + test_create_auction_auctionPeriod = snitch(create_auction_auctionPeriod) + test_create_auction_rectificationPeriod_generated = snitch(create_auction_rectificationPeriod_generated) + test_create_auction_rectificationPeriod_set = snitch(create_auction_rectificationPeriod_set) + test_create_auction_generated = snitch(create_auction_generated) + test_create_auction = snitch(create_auction) + test_additionalClassifications = snitch(additionalClassifications) + test_cavps_cpvs_classifications = snitch(cavps_cpvs_classifications) + test_auction_features_invalid = snitch(unittest.skip("option not available")(auction_features_invalid)) + test_auction_features = snitch(unittest.skip("option not available")(auction_features)) + test_patch_tender_jsonpatch = snitch(patch_tender_jsonpatch) + test_patch_auction = snitch(patch_auction) + test_patch_auction_rectificationPeriod_invalidationDate = snitch(patch_auction_rectificationPeriod_invalidationDate) + test_patch_old_auction_rectificationPeriod_invalidationDate = snitch(patch_old_auction_rectificationPeriod_invalidationDate) + test_dateModified_auction = snitch(dateModified_auction) + test_guarantee = snitch(guarantee) + test_auction_Administrator_change = snitch(auction_Administrator_change) + + +class AuctionFieldsEditingTest(BaseAuctionWebTest): + initial_data = test_auction_data + initial_maximum_data = test_auction_maximum_data + initial_organization = test_organization + initial_bids = test_bids + patch_auction_denied = snitch(patch_auction_denied) + patch_auction_during_rectification_period = snitch(patch_auction_during_rectification_period) + invalidate_bids_auction_unsuccessful = snitch(invalidate_bids_auction_unsuccessful) + + +class AuctionProcessTest(BaseAuctionWebTest): + test_invalid_auction_conditions = snitch(unittest.skip("option not available")(invalid_auction_conditions)) + test_one_valid_bid_auction = snitch(one_valid_bid_auction) + test_one_invalid_bid_auction = snitch(one_invalid_bid_auction) + test_first_bid_auction = snitch(first_bid_auction) + + + #setUp = BaseWebTest.setUp + def setUp(self): + super(AuctionProcessTest.__bases__[0], self).setUp() + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(AuctionProcessTest)) + suite.addTest(unittest.makeSuite(AuctionResourceTest)) + suite.addTest(unittest.makeSuite(AuctionFieldsEditingTest)) + suite.addTest(unittest.makeSuite(AuctionTest)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/openprocurement/auctions/lease/tests/tests.ini b/openprocurement/auctions/lease/tests/tests.ini new file mode 100644 index 0000000..594798a --- /dev/null +++ b/openprocurement/auctions/lease/tests/tests.ini @@ -0,0 +1,52 @@ +[app:main] +use = egg:openprocurement.api + +couchdb.db_name = flash_tests +couchdb.url = http://op:op@localhost:5984/ + +auth.file = %(here)s/auth.ini + +pyramid.reload_templates = true +pyramid.debug_authorization = true +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = true +pyramid.default_locale_name = en +plugins = %(here)s/plugins.yaml + +[server:main] +use = egg:chaussette +host = 0.0.0.0 +port = 6543 +backend = gevent + +# Begin logging configuration + +[loggers] +keys = root, openprocurement + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_openprocurement] +level = DEBUG +handlers = +qualname = openprocurement + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/openprocurement/auctions/lease/utils.py b/openprocurement/auctions/lease/utils.py new file mode 100644 index 0000000..ad91af1 --- /dev/null +++ b/openprocurement/auctions/lease/utils.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +from logging import getLogger + +from pkg_resources import get_distribution + +from openprocurement.auctions.core.utils import ( + check_complaint_status, check_auction_status, remove_draft_bids, + upload_file as base_upload_file, get_file as base_get_file, + API_DOCUMENT_BLACKLISTED_FIELDS as DOCUMENT_BLACKLISTED_FIELDS, + context_unpack, calculate_business_date, get_now, TZ +) + +from .constants import ( + DOCUMENT_TYPE_URL_ONLY, + DOCUMENT_TYPE_OFFLINE, + MINIMAL_PERIOD_FROM_RECTIFICATION_END +) + + +PKG = get_distribution(__package__) +LOGGER = getLogger(PKG.project_name) + + +def upload_file(request, blacklisted_fields=DOCUMENT_BLACKLISTED_FIELDS): + first_document = request.validated['documents'][0] if 'documents' in request.validated and request.validated['documents'] else None + if 'data' in request.validated and request.validated['data']: + document = request.validated['document'] + if document.documentType in (DOCUMENT_TYPE_URL_ONLY + DOCUMENT_TYPE_OFFLINE): + if first_document: + for attr_name in type(first_document)._fields: + if attr_name not in blacklisted_fields: + setattr(document, attr_name, getattr(first_document, attr_name)) + if document.documentType in DOCUMENT_TYPE_OFFLINE: + document.format = 'offline/on-site-examination' + return document + return base_upload_file(request, blacklisted_fields) + + +def get_file(request): + document = request.validated['document'] + if document.documentType == 'virtualDataRoom': + request.response.status = '302 Moved Temporarily' + request.response.location = document.url + return document.url + return base_get_file(request) + + +def check_bids(request): + auction = request.validated['auction'] + if auction.auctionPeriod: + if auction.numberOfBids < (auction.minNumberOfQualifiedBids or 2): + auction.auctionPeriod.startDate = None + auction.status = 'unsuccessful' + elif auction.numberOfBids == 1: + auction.auctionPeriod.startDate = None + request.content_configurator.start_awarding() + + +def check_auction_protocol(award): + if award.documents: + for document in award.documents: + if document['documentType'] == 'auctionProtocol' and document['author'] == 'auction_owner': + return True + return False + + +def check_status(request): + auction = request.validated['auction'] + now = get_now() + for complaint in auction.complaints: + check_complaint_status(request, complaint, now) + for award in auction.awards: + for complaint in award.complaints: + check_complaint_status(request, complaint, now) + if not auction.lots and auction.status == 'active.tendering' and auction.tenderPeriod.endDate <= now: + LOGGER.info('Switched auction {} to {}'.format(auction['id'], 'active.auction'), + extra=context_unpack(request, {'MESSAGE_ID': 'switched_auction_active.auction'})) + auction.status = 'active.auction' + remove_draft_bids(request) + remove_invalid_bids(request) + check_bids(request) + return + elif auction.lots and auction.status == 'active.tendering' and auction.tenderPeriod.endDate <= now: + LOGGER.info('Switched auction {} to {}'.format(auction['id'], 'active.auction'), + extra=context_unpack(request, {'MESSAGE_ID': 'switched_auction_active.auction'})) + auction.status = 'active.auction' + remove_draft_bids(request) + remove_invalid_bids(request) + check_bids(request) + [setattr(i.auctionPeriod, 'startDate', None) for i in auction.lots if i.numberOfBids < 2 and i.auctionPeriod] + return + elif not auction.lots and auction.status == 'active.awarded': + standStillEnds = [ + a.complaintPeriod.endDate.astimezone(TZ) + for a in auction.awards + if a.complaintPeriod.endDate + ] + if not standStillEnds: + return + standStillEnd = max(standStillEnds) + if standStillEnd <= now: + check_auction_status(request) + elif auction.lots and auction.status in ['active.qualification', 'active.awarded']: + if any([i['status'] in auction.block_complaint_status and i.relatedLot is None for i in auction.complaints]): + return + for lot in auction.lots: + if lot['status'] != 'active': + continue + lot_awards = [i for i in auction.awards if i.lotID == lot.id] + standStillEnds = [ + a.complaintPeriod.endDate.astimezone(TZ) + for a in lot_awards + if a.complaintPeriod.endDate + ] + if not standStillEnds: + continue + standStillEnd = max(standStillEnds) + if standStillEnd <= now: + check_auction_status(request) + return + + +def calculate_enddate(auction, period, duration): + period.endDate = calculate_business_date(period.startDate, duration, auction, True) + round_to_18_hour_delta = period.endDate.replace(hour=18, minute=0, second=0) - period.endDate + period.endDate = calculate_business_date(period.endDate, round_to_18_hour_delta, auction, False) + + +def invalidate_bids_under_threshold(auction): + """Invalidate bids that lower value.amount + minimalStep.amount""" + value_threshold = round(auction['value']['amount'] + + auction['minimalStep']['amount'], 2) + for bid in auction['bids']: + if bid['value']['amount'] < value_threshold: + bid['status'] = 'invalid' + + +def get_auction_creation_date(data): + auction_creation_date = (data.get('revisions')[0].date if data.get('revisions') else get_now()) + return auction_creation_date + + +def remove_invalid_bids(request): + auction = request.validated['auction'] + if [bid for bid in auction.bids if getattr(bid, "status", "active") == "invalid"]: + LOGGER.info('Remove invalid bids', + extra=context_unpack(request, {'MESSAGE_ID': 'remove_invalid_bids'})) + auction.bids = [bid for bid in auction.bids if getattr(bid, "status", "active") != "invalid"] + + +def invalidate_bids_data(auction): + for bid in auction.bids: + setattr(bid, "status", "invalid") + auction.rectificationPeriod.invalidationDate = get_now() + + +def generate_rectificationPeriod(auction): + now = get_now() + if not auction.rectificationPeriod: + period = type(auction).rectificationPeriod.model_class() + period.startDate = period.startDate or now + if not period.endDate: + calculated_endDate = calculate_business_date(auction.tenderPeriod.endDate, -MINIMAL_PERIOD_FROM_RECTIFICATION_END, auction) + period.endDate = calculated_endDate if calculated_endDate > now else now + period.invalidationDate = None + return period diff --git a/openprocurement/auctions/lease/validation.py b/openprocurement/auctions/lease/validation.py new file mode 100644 index 0000000..9ddb17a --- /dev/null +++ b/openprocurement/auctions/lease/validation.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import error_handler, get_now, TZ + +from openprocurement.auctions.lease.utils import generate_rectificationPeriod + + +def validate_rectification_period_editing(request, **kwargs): + if request.context.status == 'active.tendering' and request.authenticated_role not in ['chronograph', 'Administrator']: + auction = request.validated['auction'] + rectificationPeriod = auction.rectificationPeriod or generate_rectificationPeriod(auction) + if rectificationPeriod.endDate.astimezone(TZ) < get_now(): + request.errors.add('body', 'data', 'Auction can be edited only during the rectification period: from ({}) to ({}).'.format(rectificationPeriod.startDate.isoformat(), rectificationPeriod.endDate.isoformat())) + request.errors.status = 403 + raise error_handler(request) diff --git a/openprocurement/auctions/lease/views/__init__.py b/openprocurement/auctions/lease/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openprocurement/auctions/lease/views/property/__init__.py b/openprocurement/auctions/lease/views/property/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openprocurement/auctions/lease/views/property/auction.py b/openprocurement/auctions/lease/views/property/auction.py new file mode 100644 index 0000000..e94280c --- /dev/null +++ b/openprocurement/auctions/lease/views/property/auction.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + json_view, + context_unpack, + APIResource, + save_auction, + apply_patch, + opresource, + cleanup_bids_for_cancelled_lots +) +from openprocurement.auctions.core.validation import ( + validate_auction_auction_data, +) + +from openprocurement.auctions.lease.utils import ( + invalidate_bids_under_threshold +) + + +@opresource(name='propertyLease:Auction Auction', + collection_path='/auctions/{auction_id}/auction', + path='/auctions/{auction_id}/auction/{auction_lot_id}', + auctionsprocurementMethodType="propertyLease", + description="auction auction data") +class AuctionAuctionResource(APIResource): + + @json_view(permission='auction') + def collection_get(self): + """Get auction info. + + Get auction auction info + ----------------------- + + Example request to get auction auction information: + + .. sourcecode:: http + + GET /auctions/4879d3f8ee2443169b5fbbc9f89fa607/auction HTTP/1.1 + Host: example.com + Accept: application/json + + This is what one should expect in response: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "dateModified": "2014-10-27T08:06:58.158Z", + "bids": [ + { + "value": { + "amount": 500, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + }, + { + "value": { + "amount": 485, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + ], + "minimalStep":{ + "amount": 35, + "currency": "UAH" + }, + "tenderPeriod":{ + "startDate": "2014-11-04T08:00:00" + } + } + } + + """ + if self.request.validated['auction_status'] != 'active.auction': + self.request.errors.add('body', 'data', 'Can\'t get auction info in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + return {'data': self.request.validated['auction'].serialize("auction_view")} + + @json_view(content_type="application/json", permission='auction', validators=(validate_auction_auction_data)) + def collection_patch(self): + """Set urls for access to auction. + """ + if apply_patch(self.request, src=self.request.validated['auction_src']): + self.LOGGER.info('Updated auction urls', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_auction_patch'})) + return {'data': self.request.validated['auction'].serialize("auction_view")} + + @json_view(content_type="application/json", permission='auction', validators=(validate_auction_auction_data)) + def collection_post(self): + """Report auction results. + + Report auction results + ---------------------- + + Example request to report auction results: + + .. sourcecode:: http + + POST /auctions/4879d3f8ee2443169b5fbbc9f89fa607/auction HTTP/1.1 + Host: example.com + Accept: application/json + + { + "data": { + "dateModified": "2014-10-27T08:06:58.158Z", + "bids": [ + { + "value": { + "amount": 400, + "currency": "UAH" + } + }, + { + "value": { + "amount": 385, + "currency": "UAH" + } + } + ] + } + } + + This is what one should expect in response: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "dateModified": "2014-10-27T08:06:58.158Z", + "bids": [ + { + "value": { + "amount": 400, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + }, + { + "value": { + "amount": 385, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + ], + "minimalStep":{ + "amount": 35, + "currency": "UAH" + }, + "tenderPeriod":{ + "startDate": "2014-11-04T08:00:00" + } + } + } + + """ + apply_patch(self.request, save=False, src=self.request.validated['auction_src']) + auction = self.request.validated['auction'] + invalidate_bids_under_threshold(auction) + if any([i.status == 'active' for i in auction.bids]): + self.request.content_configurator.start_awarding() + else: + auction.status = 'unsuccessful' + if save_auction(self.request): + self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_auction_post'})) + return {'data': self.request.validated['auction'].serialize(self.request.validated['auction'].status)} + + @json_view(content_type="application/json", permission='auction', validators=(validate_auction_auction_data)) + def patch(self): + """Set urls for access to auction for lot. + """ + if apply_patch(self.request, src=self.request.validated['auction_src']): + self.LOGGER.info('Updated auction urls', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_auction_patch'})) + return {'data': self.request.validated['auction'].serialize("auction_view")} + + @json_view(content_type="application/json", permission='auction', validators=(validate_auction_auction_data)) + def post(self): + """Report auction results for lot. + """ + apply_patch(self.request, save=False, src=self.request.validated['auction_src']) + auction = self.request.validated['auction'] + if all([i.auctionPeriod and i.auctionPeriod.endDate for i in auction.lots if i.numberOfBids > 1 and i.status == 'active']): + cleanup_bids_for_cancelled_lots(auction) + invalidate_bids_under_threshold(auction) + if any([i.status == 'active' for i in auction.bids]): + self.request.content_configurator.start_awarding() + else: + auction.status = 'unsuccessful' + if save_auction(self.request): + self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_auction_post'})) + return {'data': self.request.validated['auction'].serialize(self.request.validated['auction'].status)} diff --git a/openprocurement/auctions/lease/views/property/bid.py b/openprocurement/auctions/lease/views/property/bid.py new file mode 100644 index 0000000..fc46376 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/bid.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + get_now, + json_view, + context_unpack, + APIResource, + set_ownership, + save_auction, + apply_patch, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_bid_data, + validate_patch_bid_data, +) + + +@opresource(name='propertyLease:Auction Bids', + collection_path='/auctions/{auction_id}/bids', + path='/auctions/{auction_id}/bids/{bid_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction bids") +class AuctionBidResource(APIResource): + + @json_view(content_type="application/json", permission='create_bid', validators=(validate_bid_data,)) + def collection_post(self): + """Registration of new bid proposal + + Creating new Bid proposal + ------------------------- + + Example request to create bid proposal: + + .. sourcecode:: http + + POST /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids HTTP/1.1 + Host: example.com + Accept: application/json + + { + "data": { + "tenderers": [ + { + "id": { + "name": "Державне управління справами", + "scheme": "https://ns.openprocurement.org/ua/edrpou", + "uid": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "locality": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1" + } + } + ], + "value": { + "amount": 489, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + } + + This is what one should expect in response: + + .. sourcecode:: http + + HTTP/1.1 201 Created + Content-Type: application/json + + { + "data": { + "id": "4879d3f8ee2443169b5fbbc9f89fa607", + "status": "registration", + "date": "2014-10-28T11:44:17.947Z", + "tenderers": [ + { + "id": { + "name": "Державне управління справами", + "scheme": "https://ns.openprocurement.org/ua/edrpou", + "uid": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "locality": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1" + } + } + ], + "value": { + "amount": 489, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + } + + """ + # See https://github.com/open-contracting/standard/issues/78#issuecomment-59830415 + # for more info upon schema + auction = self.request.validated['auction'] + if self.request.validated['auction_status'] != 'active.tendering': + self.request.errors.add('body', 'data', 'Can\'t add bid in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if auction.tenderPeriod.startDate and get_now() < auction.tenderPeriod.startDate or get_now() > auction.tenderPeriod.endDate: + self.request.errors.add('body', 'data', 'Bid can be added only during the tendering period: from ({}) to ({}).'.format(auction.tenderPeriod.startDate and auction.tenderPeriod.startDate.isoformat(), auction.tenderPeriod.endDate.isoformat())) + self.request.errors.status = 403 + return + bid = self.request.validated['bid'] + set_ownership(bid, self.request) + auction.bids.append(bid) + auction.modified = False + if save_auction(self.request): + self.LOGGER.info('Created auction bid {}'.format(bid.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_create'}, {'bid_id': bid.id})) + self.request.response.status = 201 + route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, bid_id=bid.id, _query={}) + return { + 'data': bid.serialize('view'), + 'access': { + 'token': bid.owner_token + } + } + + @json_view(permission='view_auction') + def collection_get(self): + """Bids Listing + + Get Bids List + ------------- + + Example request to get bids list: + + .. sourcecode:: http + + GET /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids HTTP/1.1 + Host: example.com + Accept: application/json + + This is what one should expect in response: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": [ + { + "value": { + "amount": 489, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + ] + } + + """ + auction = self.request.validated['auction'] + if self.request.validated['auction_status'] in ['active.tendering', 'active.auction']: + self.request.errors.add('body', 'data', 'Can\'t view bids in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + return {'data': [i.serialize(self.request.validated['auction_status']) for i in auction.bids]} + + @json_view(permission='view_auction') + def get(self): + """Retrieving the proposal + + Example request for retrieving the proposal: + + .. sourcecode:: http + + GET /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 + Host: example.com + Accept: application/json + + And here is the response to be expected: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Type: application/json + + { + "data": { + "value": { + "amount": 600, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + } + + """ + if self.request.authenticated_role == 'bid_owner': + return {'data': self.request.context.serialize('view')} + if self.request.validated['auction_status'] in ['active.tendering', 'active.auction']: + self.request.errors.add('body', 'data', 'Can\'t view bid in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + return {'data': self.request.context.serialize(self.request.validated['auction_status'])} + + @json_view(content_type="application/json", permission='edit_bid', validators=(validate_patch_bid_data,)) + def patch(self): + """Update of proposal + + Example request to change bid proposal: + + .. sourcecode:: http + + PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 + Host: example.com + Accept: application/json + + { + "data": { + "value": { + "amount": 600 + } + } + } + + And here is the response to be expected: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Type: application/json + + { + "data": { + "value": { + "amount": 600, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + } + + """ + + if self.request.authenticated_role != 'Administrator' and self.request.validated['auction_status'] != 'active.tendering': + self.request.errors.add('body', 'data', 'Can\'t update bid in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + auction = self.request.validated['auction'] + if self.request.authenticated_role != 'Administrator' and (auction.tenderPeriod.startDate and get_now() < auction.tenderPeriod.startDate or get_now() > auction.tenderPeriod.endDate): + self.request.errors.add('body', 'data', 'Bid can be updated only during the tendering period: from ({}) to ({}).'.format(auction.tenderPeriod.startDate and auction.tenderPeriod.startDate.isoformat(), auction.tenderPeriod.endDate.isoformat())) + self.request.errors.status = 403 + return + if self.request.authenticated_role != 'Administrator': + bid_status_to = self.request.validated['data'].get("status") + if bid_status_to != self.request.context.status and bid_status_to != "active": + self.request.errors.add('body', 'bid', 'Can\'t update bid to ({}) status'.format(bid_status_to)) + self.request.errors.status = 403 + return + value = self.request.validated['data'].get("value") and self.request.validated['data']["value"].get("amount") + if value and value != self.request.context.get("value", {}).get("amount"): + self.request.validated['data']['date'] = get_now().isoformat() + if self.request.context.lotValues: + lotValues = dict([(i.relatedLot, i.value.amount) for i in self.request.context.lotValues]) + for lotvalue in self.request.validated['data'].get("lotValues", []): + if lotvalue['relatedLot'] in lotValues and lotvalue.get("value", {}).get("amount") != lotValues[lotvalue['relatedLot']]: + lotvalue['date'] = get_now().isoformat() + self.request.validated['auction'].modified = False + if apply_patch(self.request, src=self.request.context.serialize()): + self.LOGGER.info('Updated auction bid {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_patch'})) + return {'data': self.request.context.serialize("view")} + + @json_view(permission='edit_bid') + def delete(self): + """Cancelling the proposal + + Example request for cancelling the proposal: + + .. sourcecode:: http + + DELETE /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 + Host: example.com + Accept: application/json + + And here is the response to be expected: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Type: application/json + + { + "data": { + "value": { + "amount": 489, + "currency": "UAH", + "valueAddedTaxIncluded": true + } + } + } + + """ + bid = self.request.context + if self.request.validated['auction_status'] != 'active.tendering': + self.request.errors.add('body', 'data', 'Can\'t delete bid in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + auction = self.request.validated['auction'] + if auction.tenderPeriod.startDate and get_now() < auction.tenderPeriod.startDate or get_now() > auction.tenderPeriod.endDate: + self.request.errors.add('body', 'data', 'Bid can be deleted only during the tendering period: from ({}) to ({}).'.format(auction.tenderPeriod.startDate and auction.tenderPeriod.startDate.isoformat(), auction.tenderPeriod.endDate.isoformat())) + self.request.errors.status = 403 + return + res = bid.serialize("view") + self.request.validated['auction'].bids.remove(bid) + self.request.validated['auction'].modified = False + if save_auction(self.request): + self.LOGGER.info('Deleted auction bid {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_delete'})) + return {'data': res} diff --git a/openprocurement/auctions/lease/views/property/bid_document.py b/openprocurement/auctions/lease/views/property/bid_document.py new file mode 100644 index 0000000..e277742 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/bid_document.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + get_now, + get_file, + upload_file, + update_file_content_type, + json_view, + context_unpack, + APIResource, + save_auction, + apply_patch, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_file_update, + validate_file_upload, + validate_patch_document_data, +) + + +@opresource(name='propertyLease:Auction Bid Documents', + collection_path='/auctions/{auction_id}/bids/{bid_id}/documents', + path='/auctions/{auction_id}/bids/{bid_id}/documents/{document_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction bidder documents") +class AuctionBidDocumentResource(APIResource): + + def validate_bid_document(self, operation): + auction = self.request.validated['auction'] + if auction.status not in ['active.tendering', 'active.qualification']: + self.request.errors.add('body', 'data', 'Can\'t {} document in current ({}) auction status'.format(operation, auction.status)) + self.request.errors.status = 403 + return + if auction.status == 'active.tendering' and not (auction.tenderPeriod.startDate < get_now() < auction.tenderPeriod.endDate): + self.request.errors.add('body', 'data', 'Document can be {} only during the tendering period: from ({}) to ({}).'.format('added' if operation == 'add' else 'updated', auction.tenderPeriod.startDate.isoformat(), auction.tenderPeriod.endDate.isoformat())) + self.request.errors.status = 403 + return + if auction.status == 'active.qualification' and not [i for i in auction.awards if 'pending' in i.status and i.bid_id == self.request.validated['bid_id']]: + self.request.errors.add('body', 'data', 'Can\'t {} document because award of bid is not in pending state'.format(operation)) + self.request.errors.status = 403 + return + return True + + @json_view(permission='view_auction') + def collection_get(self): + """Auction Bid Documents List""" + if self.request.validated['auction_status'] in ['active.tendering', 'active.auction'] and self.request.authenticated_role != 'bid_owner': + self.request.errors.add('body', 'data', 'Can\'t view bid documents in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if self.request.params.get('all', ''): + collection_data = [i.serialize("view") for i in self.context.documents] + else: + collection_data = sorted(dict([ + (i.id, i.serialize("view")) + for i in self.context.documents + ]).values(), key=lambda i: i['dateModified']) + return {'data': collection_data} + + @json_view(validators=(validate_file_upload,), permission='edit_bid') + def collection_post(self): + """Auction Bid Document Upload + """ + if not self.validate_bid_document('add'): + return + document = upload_file(self.request) + self.context.documents.append(document) + if self.request.validated['auction_status'] == 'active.tendering': + self.request.validated['auction'].modified = False + if save_auction(self.request): + self.LOGGER.info('Created auction bid document {}'.format(document.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_create'}, {'document_id': document.id})) + self.request.response.status = 201 + document_route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) + return {'data': document.serialize("view")} + + @json_view(permission='view_auction') + def get(self): + """Auction Bid Document Read""" + if self.request.validated['auction_status'] in ['active.tendering', 'active.auction'] and self.request.authenticated_role != 'bid_owner': + self.request.errors.add('body', 'data', 'Can\'t view bid document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if self.request.params.get('download'): + return get_file(self.request) + document = self.request.validated['document'] + document_data = document.serialize("view") + document_data['previousVersions'] = [ + i.serialize("view") + for i in self.request.validated['documents'] + if i.url != document.url + ] + return {'data': document_data} + + @json_view(validators=(validate_file_update,), permission='edit_bid') + def put(self): + """Auction Bid Document Update""" + if not self.validate_bid_document('update'): + return + document = upload_file(self.request) + self.request.validated['bid'].documents.append(document) + if self.request.validated['auction_status'] == 'active.tendering': + self.request.validated['auction'].modified = False + if save_auction(self.request): + self.LOGGER.info('Updated auction bid document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_put'})) + return {'data': document.serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_bid') + def patch(self): + """Auction Bid Document Update""" + if not self.validate_bid_document('update'): + return + if self.request.validated['auction_status'] == 'active.tendering': + self.request.validated['auction'].modified = False + if apply_patch(self.request, src=self.request.context.serialize()): + update_file_content_type(self.request) + self.LOGGER.info('Updated auction bid document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_patch'})) + return {'data': self.request.context.serialize("view")} diff --git a/openprocurement/auctions/lease/views/property/cancellation.py b/openprocurement/auctions/lease/views/property/cancellation.py new file mode 100644 index 0000000..b65072f --- /dev/null +++ b/openprocurement/auctions/lease/views/property/cancellation.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + json_view, + context_unpack, + APIResource, + get_now, + apply_patch, + save_auction, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_cancellation_data, + validate_patch_cancellation_data, +) + + +@opresource(name='propertyLease:Auction Cancellations', + collection_path='/auctions/{auction_id}/cancellations', + path='/auctions/{auction_id}/cancellations/{cancellation_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction cancellations") +class AuctionCancellationResource(APIResource): + + def cancel_auction(self): + auction = self.request.validated['auction'] + if auction.status in ['active.tendering', 'active.auction']: + auction.bids = [] + auction.status = 'cancelled' + + def cancel_lot(self, cancellation=None): + + if not cancellation: + cancellation = self.context + auction = self.request.validated['auction'] + [setattr(i, 'status', 'cancelled') for i in auction.lots if i.id == cancellation.relatedLot] + statuses = set([lot.status for lot in auction.lots]) + if statuses == set(['cancelled']): + self.cancel_auction() + elif not statuses.difference(set(['unsuccessful', 'cancelled'])): + auction.status = 'unsuccessful' + elif not statuses.difference(set(['complete', 'unsuccessful', 'cancelled'])): + auction.status = 'complete' + if auction.status == 'active.auction' and all([ + i.auctionPeriod and i.auctionPeriod.endDate + for i in self.request.validated['auction'].lots + if i.numberOfBids > 1 and i.status == 'active' + ]): + self.request.content_configurator.start_awarding() + + @json_view(content_type="application/json", validators=(validate_cancellation_data,), permission='edit_auction') + def collection_post(self): + """Post a cancellation + """ + auction = self.request.validated['auction'] + if auction.status in ['complete', 'cancelled', 'unsuccessful']: + self.request.errors.add('body', 'data', 'Can\'t add cancellation in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + cancellation = self.request.validated['cancellation'] + cancellation.date = get_now() + if any([i.status != 'active' for i in auction.lots if i.id == cancellation.relatedLot]): + self.request.errors.add('body', 'data', 'Can add cancellation only in active lot status') + self.request.errors.status = 403 + return + if cancellation.relatedLot and cancellation.status == 'active': + self.cancel_lot(cancellation) + elif cancellation.status == 'active': + self.cancel_auction() + auction.cancellations.append(cancellation) + if save_auction(self.request): + self.LOGGER.info('Created auction cancellation {}'.format(cancellation.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_create'}, {'cancellation_id': cancellation.id})) + self.request.response.status = 201 + route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, cancellation_id=cancellation.id, _query={}) + return {'data': cancellation.serialize("view")} + + @json_view(permission='view_auction') + def collection_get(self): + """List cancellations + """ + return {'data': [i.serialize("view") for i in self.request.validated['auction'].cancellations]} + + @json_view(permission='view_auction') + def get(self): + """Retrieving the cancellation + """ + return {'data': self.request.validated['cancellation'].serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_cancellation_data,), permission='edit_auction') + def patch(self): + """Post a cancellation resolution + """ + auction = self.request.validated['auction'] + if auction.status in ['complete', 'cancelled', 'unsuccessful']: + self.request.errors.add('body', 'data', 'Can\'t update cancellation in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + if any([i.status != 'active' for i in auction.lots if i.id == self.request.context.relatedLot]): + self.request.errors.add('body', 'data', 'Can update cancellation only in active lot status') + self.request.errors.status = 403 + return + apply_patch(self.request, save=False, src=self.request.context.serialize()) + if self.request.context.relatedLot and self.request.context.status == 'active': + self.cancel_lot() + elif self.request.context.status == 'active': + self.cancel_auction() + if save_auction(self.request): + self.LOGGER.info('Updated auction cancellation {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_patch'})) + return {'data': self.request.context.serialize("view")} diff --git a/openprocurement/auctions/lease/views/property/cancellation_document.py b/openprocurement/auctions/lease/views/property/cancellation_document.py new file mode 100644 index 0000000..4094ed7 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/cancellation_document.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + get_file, + upload_file, + update_file_content_type, + json_view, + context_unpack, + APIResource, + save_auction, + apply_patch, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_file_update, + validate_file_upload, + validate_patch_document_data, +) + + +@opresource(name='propertyLease:Auction Cancellation Documents', + collection_path='/auctions/{auction_id}/cancellations/{cancellation_id}/documents', + path='/auctions/{auction_id}/cancellations/{cancellation_id}/documents/{document_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction cancellation documents") +class AuctionCancellationDocumentResource(APIResource): + + @json_view(permission='view_auction') + def collection_get(self): + """Auction Cancellation Documents List""" + if self.request.params.get('all', ''): + collection_data = [i.serialize("view") for i in self.context.documents] + else: + collection_data = sorted(dict([ + (i.id, i.serialize("view")) + for i in self.context.documents + ]).values(), key=lambda i: i['dateModified']) + return {'data': collection_data} + + @json_view(validators=(validate_file_upload,), permission='edit_auction') + def collection_post(self): + """Auction Cancellation Document Upload + """ + if self.request.validated['auction_status'] in ['complete', 'cancelled', 'unsuccessful']: + self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + document = upload_file(self.request) + self.context.documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Created auction cancellation document {}'.format(document.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_document_create'}, {'document_id': document.id})) + self.request.response.status = 201 + document_route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) + return {'data': document.serialize("view")} + + @json_view(permission='view_auction') + def get(self): + """Auction Cancellation Document Read""" + if self.request.params.get('download'): + return get_file(self.request) + document = self.request.validated['document'] + document_data = document.serialize("view") + document_data['previousVersions'] = [ + i.serialize("view") + for i in self.request.validated['documents'] + if i.url != document.url + ] + return {'data': document_data} + + @json_view(validators=(validate_file_update,), permission='edit_auction') + def put(self): + """Auction Cancellation Document Update""" + if self.request.validated['auction_status'] in ['complete', 'cancelled', 'unsuccessful']: + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + document = upload_file(self.request) + self.request.validated['cancellation'].documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Updated auction cancellation document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_document_put'})) + return {'data': document.serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_auction') + def patch(self): + """Auction Cancellation Document Update""" + if self.request.validated['auction_status'] in ['complete', 'cancelled', 'unsuccessful']: + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if apply_patch(self.request, src=self.request.context.serialize()): + update_file_content_type(self.request) + self.LOGGER.info('Updated auction cancellation document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_document_patch'})) + return {'data': self.request.context.serialize("view")} diff --git a/openprocurement/auctions/lease/views/property/complaint.py b/openprocurement/auctions/lease/views/property/complaint.py new file mode 100644 index 0000000..39354c0 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/complaint.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + context_unpack, + json_view, + set_ownership, + APIResource, + get_now, + apply_patch, + check_auction_status, + opresource, + save_auction, +) +from openprocurement.auctions.core.validation import ( + validate_complaint_data, + validate_patch_complaint_data, +) + + +@opresource(name='propertyLease:Auction Complaints', + collection_path='/auctions/{auction_id}/complaints', + path='/auctions/{auction_id}/complaints/{complaint_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction complaints") +class AuctionComplaintResource(APIResource): + + @json_view(content_type="application/json", validators=(validate_complaint_data,), permission='nobody') + def collection_post(self): + """Post a complaint + """ + auction = self.context + if auction.status not in ['active.tendering']: + self.request.errors.add('body', 'data', 'Can\'t add complaint in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + complaint = self.request.validated['complaint'] + complaint.date = get_now() + if complaint.status == 'claim': + complaint.dateSubmitted = get_now() + else: + complaint.status = 'draft' + complaint.complaintID = '{}.{}{}'.format(auction.auctionID, self.server_id, sum([len(i.complaints) for i in auction.awards], len(auction.complaints)) + 1) + set_ownership(complaint, self.request) + auction.complaints.append(complaint) + if save_auction(self.request): + self.LOGGER.info('Created auction complaint {}'.format(complaint.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_create'}, {'complaint_id': complaint.id})) + self.request.response.status = 201 + route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, complaint_id=complaint.id, _query={}) + return { + 'data': complaint.serialize(auction.status), + 'access': { + 'token': complaint.owner_token + } + } + + @json_view(permission='view_auction') + def collection_get(self): + """List complaints + """ + return {'data': [i.serialize("view") for i in self.context.complaints]} + + @json_view(permission='view_auction') + def get(self): + """Retrieving the complaint + """ + return {'data': self.context.serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_complaint_data,), permission='edit_complaint') + def patch(self): + """Post a complaint resolution + """ + auction = self.request.validated['auction'] + if auction.status not in ['active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: + self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + if self.context.status not in ['draft', 'claim', 'answered', 'pending']: + self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) status'.format(self.context.status)) + self.request.errors.status = 403 + return + data = self.request.validated['data'] + # complaint_owner + if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered', 'pending'] and data.get('status', self.context.status) == 'cancelled': + apply_patch(self.request, save=False, src=self.context.serialize()) + self.context.dateCanceled = get_now() + elif self.request.authenticated_role == 'complaint_owner' and auction.status in ['active.tendering'] and self.context.status == 'draft' and data.get('status', self.context.status) == self.context.status: + apply_patch(self.request, save=False, src=self.context.serialize()) + elif self.request.authenticated_role == 'complaint_owner' and auction.status in ['active.tendering'] and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim': + apply_patch(self.request, save=False, src=self.context.serialize()) + self.context.dateSubmitted = get_now() + elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('status', self.context.status) == self.context.status: + apply_patch(self.request, save=False, src=self.context.serialize()) + elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is True and data.get('status', self.context.status) == 'resolved': + apply_patch(self.request, save=False, src=self.context.serialize()) + elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is False and data.get('status', self.context.status) == 'pending': + apply_patch(self.request, save=False, src=self.context.serialize()) + self.context.type = 'complaint' + self.context.dateEscalated = get_now() + elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status: + apply_patch(self.request, save=False, src=self.context.serialize()) + elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('resolution', self.context.resolution) and data.get('resolutionType', self.context.resolutionType) and data.get('status', self.context.status) == 'answered': + if len(data.get('resolution', self.context.resolution)) < 20: + self.request.errors.add('body', 'data', 'Can\'t update complaint: resolution too short') + self.request.errors.status = 403 + return + apply_patch(self.request, save=False, src=self.context.serialize()) + self.context.dateAnswered = get_now() + elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending': + apply_patch(self.request, save=False, src=self.context.serialize()) + # reviewers + elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == self.context.status: + apply_patch(self.request, save=False, src=self.context.serialize()) + elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) in ['resolved', 'invalid', 'declined']: + apply_patch(self.request, save=False, src=self.context.serialize()) + self.context.dateDecision = get_now() + else: + self.request.errors.add('body', 'data', 'Can\'t update complaint') + self.request.errors.status = 403 + return + if self.context.tendererAction and not self.context.tendererActionDate: + self.context.tendererActionDate = get_now() + if self.context.status not in ['draft', 'claim', 'answered', 'pending'] and auction.status in ['active.qualification', 'active.awarded']: + check_auction_status(self.request) + if save_auction(self.request): + self.LOGGER.info('Updated auction complaint {}'.format(self.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_patch'})) + return {'data': self.context.serialize("view")} diff --git a/openprocurement/auctions/lease/views/property/complaint_document.py b/openprocurement/auctions/lease/views/property/complaint_document.py new file mode 100644 index 0000000..2330121 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/complaint_document.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.constants import STATUS4ROLE +from openprocurement.auctions.core.utils import ( + save_auction, + apply_patch, + opresource, + get_file, + upload_file, + update_file_content_type, + json_view, + context_unpack, + APIResource, +) +from openprocurement.auctions.core.validation import ( + validate_file_update, + validate_file_upload, + validate_patch_document_data, +) + + +@opresource(name='propertyLease:Auction Complaint Documents', + collection_path='/auctions/{auction_id}/complaints/{complaint_id}/documents', + path='/auctions/{auction_id}/complaints/{complaint_id}/documents/{document_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction complaint documents") +class AuctionComplaintDocumentResource(APIResource): + + @json_view(permission='view_auction') + def collection_get(self): + """Auction Complaint Documents List""" + if self.request.params.get('all', ''): + collection_data = [i.serialize("view") for i in self.context.documents] + else: + collection_data = sorted(dict([ + (i.id, i.serialize("view")) + for i in self.context.documents + ]).values(), key=lambda i: i['dateModified']) + return {'data': collection_data} + + @json_view(validators=(validate_file_upload,), permission='edit_complaint') + def collection_post(self): + """Auction Complaint Document Upload + """ + if self.request.validated['auction_status'] not in ['active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: + self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if self.context.status not in STATUS4ROLE.get(self.request.authenticated_role, []): + self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) complaint status'.format(self.context.status)) + self.request.errors.status = 403 + return + document = upload_file(self.request) + document.author = self.request.authenticated_role + self.context.documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Created auction complaint document {}'.format(document.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_document_create'}, {'document_id': document.id})) + self.request.response.status = 201 + document_route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) + return {'data': document.serialize("view")} + + @json_view(permission='view_auction') + def get(self): + """Auction Complaint Document Read""" + if self.request.params.get('download'): + return get_file(self.request) + document = self.request.validated['document'] + document_data = document.serialize("view") + document_data['previousVersions'] = [ + i.serialize("view") + for i in self.request.validated['documents'] + if i.url != document.url + ] + return {'data': document_data} + + @json_view(validators=(validate_file_update,), permission='edit_complaint') + def put(self): + """Auction Complaint Document Update""" + if self.request.authenticated_role != self.context.author: + self.request.errors.add('url', 'role', 'Can update document only author') + self.request.errors.status = 403 + return + if self.request.validated['auction_status'] not in ['active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if self.request.validated['complaint'].status not in STATUS4ROLE.get(self.request.authenticated_role, []): + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) complaint status'.format(self.request.validated['complaint'].status)) + self.request.errors.status = 403 + return + document = upload_file(self.request) + document.author = self.request.authenticated_role + self.request.validated['complaint'].documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Updated auction complaint document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_document_put'})) + return {'data': document.serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_complaint') + def patch(self): + """Auction Complaint Document Update""" + if self.request.authenticated_role != self.context.author: + self.request.errors.add('url', 'role', 'Can update document only author') + self.request.errors.status = 403 + return + if self.request.validated['auction_status'] not in ['active.tendering', 'active.auction', 'active.qualification', 'active.awarded']: + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if self.request.validated['complaint'].status not in STATUS4ROLE.get(self.request.authenticated_role, []): + self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) complaint status'.format(self.request.validated['complaint'].status)) + self.request.errors.status = 403 + return + if apply_patch(self.request, src=self.request.context.serialize()): + update_file_content_type(self.request) + self.LOGGER.info('Updated auction complaint document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_document_patch'})) + return {'data': self.request.context.serialize("view")} diff --git a/openprocurement/auctions/lease/views/property/lot.py b/openprocurement/auctions/lease/views/property/lot.py new file mode 100644 index 0000000..6092089 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/lot.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + json_view, + context_unpack, + APIResource, + get_now, + apply_patch, + save_auction, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_lot_data, + validate_patch_lot_data, +) + + +@opresource(name='propertyLease:Auction Lots', + collection_path='/auctions/{auction_id}/lots', + path='/auctions/{auction_id}/lots/{lot_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction lots") +class AuctionLotResource(APIResource): + + @json_view(content_type="application/json", validators=(validate_lot_data,), permission='edit_auction') + def collection_post(self): + """Add a lot + """ + auction = self.request.validated['auction'] + if auction.status not in ['active.tendering']: + self.request.errors.add('body', 'data', 'Can\'t add lot in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + lot = self.request.validated['lot'] + lot.date = get_now() + auction.lots.append(lot) + if save_auction(self.request): + self.LOGGER.info('Created auction lot {}'.format(lot.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_create'}, {'lot_id': lot.id})) + self.request.response.status = 201 + route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, lot_id=lot.id, _query={}) + return {'data': lot.serialize("view")} + + @json_view(permission='view_auction') + def collection_get(self): + """Lots Listing + """ + return {'data': [i.serialize("view") for i in self.request.validated['auction'].lots]} + + @json_view(permission='view_auction') + def get(self): + """Retrieving the lot + """ + return {'data': self.request.context.serialize("view")} + + @json_view(content_type="application/json", validators=(validate_patch_lot_data,), permission='edit_auction') + def patch(self): + """Update of lot + """ + auction = self.request.validated['auction'] + if auction.status not in ['active.tendering']: + self.request.errors.add('body', 'data', 'Can\'t update lot in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + if apply_patch(self.request, src=self.request.context.serialize()): + self.LOGGER.info('Updated auction lot {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_patch'})) + return {'data': self.request.context.serialize("view")} + + @json_view(permission='edit_auction') + def delete(self): + """Lot deleting + """ + auction = self.request.validated['auction'] + if auction.status not in ['active.tendering']: + self.request.errors.add('body', 'data', 'Can\'t delete lot in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + lot = self.request.context + res = lot.serialize("view") + auction.lots.remove(lot) + if save_auction(self.request): + self.LOGGER.info('Deleted auction lot {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_delete'})) + return {'data': res} diff --git a/openprocurement/auctions/lease/views/property/question.py b/openprocurement/auctions/lease/views/property/question.py new file mode 100644 index 0000000..760652f --- /dev/null +++ b/openprocurement/auctions/lease/views/property/question.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + json_view, + context_unpack, + APIResource, + get_now, + apply_patch, + save_auction, + opresource, +) +from openprocurement.auctions.core.validation import ( + validate_question_data, + validate_patch_question_data, +) + + +@opresource(name='propertyLease:Auction Questions', + collection_path='/auctions/{auction_id}/questions', + path='/auctions/{auction_id}/questions/{question_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction questions") +class AuctionQuestionResource(APIResource): + + @json_view(content_type="application/json", validators=(validate_question_data,), permission='create_question') + def collection_post(self): + """Post a question + """ + auction = self.request.validated['auction'] + if auction.status != 'active.tendering' or get_now() < auction.enquiryPeriod.startDate or get_now() > auction.enquiryPeriod.endDate: + self.request.errors.add('body', 'data', 'Can add question only in enquiryPeriod') + self.request.errors.status = 403 + return + question = self.request.validated['question'] + if any([i.status != 'active' for i in auction.lots if i.id == question.relatedItem]): + self.request.errors.add('body', 'data', 'Can add question only in active lot status') + self.request.errors.status = 403 + return + auction.questions.append(question) + if save_auction(self.request): + self.LOGGER.info('Created auction question {}'.format(question.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_question_create'}, {'question_id': question.id})) + self.request.response.status = 201 + route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, question_id=question.id, _query={}) + return {'data': question.serialize("view")} + + @json_view(permission='view_auction') + def collection_get(self): + """List questions + """ + return {'data': [i.serialize(self.request.validated['auction'].status) for i in self.request.validated['auction'].questions]} + + @json_view(permission='view_auction') + def get(self): + """Retrieving the question + """ + return {'data': self.request.validated['question'].serialize(self.request.validated['auction'].status)} + + @json_view(content_type="application/json", permission='edit_auction', validators=(validate_patch_question_data,)) + def patch(self): + """Post an Answer + """ + auction = self.request.validated['auction'] + if auction.status != 'active.tendering': + self.request.errors.add('body', 'data', 'Can\'t update question in current ({}) auction status'.format(auction.status)) + self.request.errors.status = 403 + return + if any([i.status != 'active' for i in auction.lots if i.id == self.request.context.relatedItem]): + self.request.errors.add('body', 'data', 'Can update question only in active lot status') + self.request.errors.status = 403 + return + if apply_patch(self.request, src=self.request.context.serialize()): + self.LOGGER.info('Updated auction question {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_question_patch'})) + return {'data': self.request.context.serialize(auction.status)} diff --git a/openprocurement/auctions/lease/views/property/tender.py b/openprocurement/auctions/lease/views/property/tender.py new file mode 100644 index 0000000..82d0ad5 --- /dev/null +++ b/openprocurement/auctions/lease/views/property/tender.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + context_unpack, + json_view, + APIResource, + apply_patch, + opresource, + save_auction, +) +from openprocurement.auctions.core.validation import ( + validate_patch_auction_data, +) + +from openprocurement.auctions.lease.utils import ( + check_status, + invalidate_bids_data, + generate_rectificationPeriod +) +from openprocurement.auctions.lease.validation import ( + validate_rectification_period_editing, +) + + +@opresource(name='propertyLease:Auction', + path='/auctions/{auction_id}', + auctionsprocurementMethodType="propertyLease", + description="Open Contracting compatible data exchange format. See http://ocds.open-contracting.org/standard/r/master/#auction for more info") +class AuctionResource(APIResource): + + @json_view(permission='view_auction') + def get(self): + """Auction Read + + Get Auction + ---------- + + Example request to get auction: + + .. sourcecode:: http + + GET /auctions/64e93250be76435397e8c992ed4214d1 HTTP/1.1 + Host: example.com + Accept: application/json + + This is what one should expect in response: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "data": { + "id": "64e93250be76435397e8c992ed4214d1", + "auctionID": "UA-64e93250be76435397e8c992ed4214d1", + "dateModified": "2014-10-27T08:06:58.158Z", + "procuringEntity": { + "id": { + "name": "Державне управління справами", + "scheme": "https://ns.openprocurement.org/ua/edrpou", + "uid": "00037256", + "uri": "http://www.dus.gov.ua/" + }, + "address": { + "countryName": "Україна", + "postalCode": "01220", + "region": "м. Київ", + "locality": "м. Київ", + "streetAddress": "вул. Банкова, 11, корпус 1" + } + }, + "value": { + "amount": 500, + "currency": "UAH", + "valueAddedTaxIncluded": true + }, + "itemsToBeProcured": [ + { + "description": "футляри до державних нагород", + "primaryClassification": { + "scheme": "CAV", + "id": "44617100-9", + "description": "Cartons" + }, + "additionalClassification": [ + { + "scheme": "ДКПП", + "id": "17.21.1", + "description": "папір і картон гофровані, паперова й картонна тара" + } + ], + "unitOfMeasure": "item", + "quantity": 5 + } + ], + "enquiryPeriod": { + "endDate": "2014-10-31T00:00:00" + }, + "tenderPeriod": { + "startDate": "2014-11-03T00:00:00", + "endDate": "2014-11-06T10:00:00" + }, + "awardPeriod": { + "endDate": "2014-11-13T00:00:00" + }, + "contractPeriod": { + "endDate": "2014-11-20T00:00:00" + }, + "minimalStep": { + "amount": 35, + "currency": "UAH" + } + } + } + + """ + if self.request.authenticated_role == 'chronograph': + auction_data = self.context.serialize('chronograph_view') + else: + auction_data = self.context.serialize(self.context.status) + return {'data': auction_data} + + #@json_view(content_type="application/json", validators=(validate_auction_data, ), permission='edit_auction') + #def put(self): + #"""Auction Edit (full)""" + #auction = self.request.validated['auction'] + #if auction.status in ['complete', 'unsuccessful', 'cancelled']: + #self.request.errors.add('body', 'data', 'Can\'t update auction in current ({}) status'.format(auction.status)) + #self.request.errors.status = 403 + #return + #apply_patch(self.request, src=self.request.validated['auction_src']) + #return {'data': auction.serialize(auction.status)} + + @json_view(content_type="application/json", validators=(validate_patch_auction_data, validate_rectification_period_editing), permission='edit_auction') + def patch(self): + """Auction Edit (partial) + + For example here is how procuring entity can change number of items to be procured and total Value of a auction: + + .. sourcecode:: http + + PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607 HTTP/1.1 + Host: example.com + Accept: application/json + + { + "data": { + "value": { + "amount": 600 + }, + "itemsToBeProcured": [ + { + "quantity": 6 + } + ] + } + } + + And here is the response to be expected: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Type: application/json + + { + "data": { + "id": "4879d3f8ee2443169b5fbbc9f89fa607", + "auctionID": "UA-64e93250be76435397e8c992ed4214d1", + "dateModified": "2014-10-27T08:12:34.956Z", + "value": { + "amount": 600 + }, + "itemsToBeProcured": [ + { + "quantity": 6 + } + ] + } + } + + """ + auction = self.context + if self.request.authenticated_role != 'Administrator' and auction.status in ['complete', 'unsuccessful', 'cancelled']: + self.request.errors.add('body', 'data', 'Can\'t update auction in current ({}) status'.format(auction.status)) + self.request.errors.status = 403 + return + if self.request.authenticated_role == 'chronograph': + apply_patch(self.request, save=False, src=self.request.validated['auction_src']) + check_status(self.request) + save_auction(self.request) + else: + apply_patch(self.request, save=False, src=self.request.validated['auction_src']) + if auction.status == 'active.tendering' and self.request.authenticated_role == 'auction_owner': + if not auction.rectificationPeriod: + auction.rectificationPeriod = generate_rectificationPeriod(auction) + invalidate_bids_data(auction) + save_auction(self.request) + self.LOGGER.info('Updated auction {}'.format(auction.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_patch'})) + return {'data': auction.serialize(auction.status)} diff --git a/openprocurement/auctions/lease/views/property/tender_document.py b/openprocurement/auctions/lease/views/property/tender_document.py new file mode 100644 index 0000000..044399f --- /dev/null +++ b/openprocurement/auctions/lease/views/property/tender_document.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.utils import ( + json_view, + context_unpack, + APIResource, + save_auction, + apply_patch, + opresource, + get_now, +) +from openprocurement.auctions.core.validation import ( + validate_file_update, + validate_file_upload, + validate_patch_document_data, +) + +from openprocurement.auctions.lease.utils import ( + upload_file, get_file, invalidate_bids_data, generate_rectificationPeriod +) + + +@opresource(name='propertyLease:Auction Documents', + collection_path='/auctions/{auction_id}/documents', + path='/auctions/{auction_id}/documents/{document_id}', + auctionsprocurementMethodType="propertyLease", + description="Auction related binary files (PDFs, etc.)") +class AuctionDocumentResource(APIResource): + + def validate_document_editing_period(self, operation): + auction_not_in_editable_state = (self.request.authenticated_role != 'auction' and self.request.validated['auction_status'] != 'active.tendering' or \ + self.request.authenticated_role == 'auction' and self.request.validated['auction_status'] not in ['active.auction', 'active.qualification']) + + auction = self.request.validated['auction'] + if auction_not_in_editable_state: + self.request.errors.add('body', 'data', 'Can\'t {} document in current ({}) auction status'.format('add' if operation == 'add' else 'update', self.request.validated['auction_status'])) + self.request.errors.status = 403 + return + if auction.rectificationPeriod.endDate < get_now() and self.request.authenticated_role != 'auction': + self.request.errors.add('body', 'data', 'Document can be {} only during the rectificationPeriod period.'.format('added' if operation == 'add' else 'updated')) + self.request.errors.status = 403 + return + return True + + @json_view(permission='view_auction') + def collection_get(self): + """Auction Documents List""" + if self.request.params.get('all', ''): + collection_data = [i.serialize("view") for i in self.context.documents] + else: + collection_data = sorted(dict([ + (i.id, i.serialize("view")) + for i in self.context.documents + ]).values(), key=lambda i: i['dateModified']) + return {'data': collection_data} + + @json_view(permission='upload_auction_documents', validators=(validate_file_upload,)) + def collection_post(self): + """Auction Document Upload""" + if not self.validate_document_editing_period('add'): + return + document = upload_file(self.request) + if self.request.authenticated_role != "auction": + if not self.request.auction.rectificationPeriod: + self.request.auction.rectificationPeriod = generate_rectificationPeriod(self.request.auction) + invalidate_bids_data(self.request.auction) + self.context.documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Created auction document {}'.format(document.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_document_create'}, {'document_id': document.id})) + self.request.response.status = 201 + document_route = self.request.matched_route.name.replace("collection_", "") + self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) + return {'data': document.serialize("view")} + + @json_view(permission='view_auction') + def get(self): + """Auction Document Read""" + document = self.request.validated['document'] + offline = bool(document.get('documentType') == 'x_dgfAssetFamiliarization') + if self.request.params.get('download') and not offline: + return get_file(self.request) + document_data = document.serialize("view") + document_data['previousVersions'] = [ + i.serialize("view") + for i in self.request.validated['documents'] + if i.url != document.url or + (offline and i.dateModified != document.dateModified) + ] + return {'data': document_data} + + @json_view(permission='upload_auction_documents', validators=(validate_file_update,)) + def put(self): + """Auction Document Update""" + if not self.validate_document_editing_period('update'): + return + document = upload_file(self.request) + if self.request.authenticated_role != "auction": + if not self.request.auction.rectificationPeriod: + self.request.auction.rectificationPeriod = generate_rectificationPeriod(self.request.auction) + invalidate_bids_data(self.request.auction) + self.request.validated['auction'].documents.append(document) + if save_auction(self.request): + self.LOGGER.info('Updated auction document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_document_put'})) + return {'data': document.serialize("view")} + + @json_view(content_type="application/json", permission='upload_auction_documents', validators=(validate_patch_document_data,)) + def patch(self): + """Auction Document Update""" + if not self.validate_document_editing_period('update'): + return + apply_patch(self.request, save=False, src=self.request.context.serialize()) + if self.request.authenticated_role != "auction": + if not self.request.auction.rectificationPeriod: + self.request.auction.rectificationPeriod = generate_rectificationPeriod(self.request.auction) + invalidate_bids_data(self.request.auction) + if save_auction(self.request): + self.LOGGER.info('Updated auction document {}'.format(self.request.context.id), + extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_document_patch'})) + return {'data': self.request.context.serialize("view")} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..559b98d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,53 @@ +CouchDB==1.0 +Jinja2==2.7.3 +LEPL==5.1.3 +MarkupSafe==0.23 +PasteDeploy==1.5.2 +PyYAML==3.11 +Pygments==2.0.2 +Sphinx==1.3.1 +WebOb==1.4.1 +WebTest==2.0.18 +beautifulsoup4==4.3.2 +boto==2.31.1 +chaussette==1.2 +cornice==1.0.0 +couchdb-schematics==1.1.1 +coverage==3.7.1 +docutils==0.12 +gevent==1.1rc5 +greenlet==0.4.9 +iso8601==0.1.10 +jsonpointer==1.9 +mock==1.0.1 +nose==1.3.4 +pbkdf2==1.3 +py==1.4.26 +pycrypto==2.6.1 +pyramid-exclog==0.7 +pyramid==1.5.7 +pytest==2.6.4 +python-coveralls==2.5.0 +pytz==2014.10 +repoze.lru==0.6 +requests==2.7.0 +schematics==1.1.0 +setuptools==7.0 +sh==1.11 +simplejson==3.6.5 +six==1.9.0 +sphinxcontrib-httpdomain==1.4.0 +translationstring==1.3 +tzlocal==1.1.2 +venusian==1.0 +waitress==0.8.9 +zope.deprecation==4.1.1 +zope.interface==4.1.1 +git+https://github.com/openprocurement/barbecue.git +git+https://github.com/openprocurement/python-json-patch.git +git+https://github.com/openprocurement/rfc6266.git +-e git+https://github.com/openprocurement/openprocurement.api.git@master#egg=openprocurement.api +-e git+https://github.com/openprocurement/openprocurement.auctions.core.git@master#egg=openprocurement.auctions.core +-e git+https://github.com/openprocurement/openprocurement.auctions.flash.git@master#egg=openprocurement.auctions.flash +-e git+https://github.com/openprocurement/schematics-flexible.git@master#egg=schematics-flexible +-e git+https://github.com/openprocurement/openprocurement.schemas.dgf.git@master#egg=openprocurement.schemas.dgf \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..89df4f6 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[nosetests] +all-modules=1 +cover-erase = 1 +cover-html=1 +cover-package=openprocurement.auctions.lease +logging-level=INFO +with-coverage=1 +with-doctest=1 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..efff412 --- /dev/null +++ b/setup.py @@ -0,0 +1,51 @@ +from setuptools import setup, find_packages +import os + +version = '1.1.1-sale' + +entry_points = { + 'openprocurement.auctions.core.plugins': [ + 'auctions.lease = openprocurement.auctions.lease.includeme:includeme_lease' + ], + 'openprocurement.api.migrations': [ + 'auctions = openprocurement.auctions.lease.migration:migrate_data' + ], + 'openprocurement.tests': [ + 'auctions.lease = openprocurement.auctions.lease.tests.main:suite' + ] +} + +requires = [ + 'setuptools', + 'openprocurement.api', + 'openprocurement.auctions.core', + 'openprocurement.auctions.flash', +] + +docs_requires = requires + [ + 'sphinxcontrib-httpdomain', +] + +setup(name='openprocurement.auctions.lease', + version=version, + description="", + long_description=open("README.rst").read() + "\n" + + open(os.path.join("docs", "HISTORY.txt")).read(), + # Get more strings from + # http://pypi.python.org/pypi?:action=list_classifiers + classifiers=[ + "Programming Language :: Python", + ], + keywords='', + author='Quintagroup, Ltd.', + author_email='info@quintagroup.com', + license='Apache License 2.0', + url='https://github.com/raccoongang/openprocurement.auctions.lease', + packages=find_packages(exclude=['ez_setup']), + namespace_packages=['openprocurement', 'openprocurement.auctions'], + include_package_data=True, + zip_safe=False, + extras_require={'docs': docs_requires}, + install_requires=requires, + entry_points=entry_points, + ) diff --git a/versions.cfg b/versions.cfg new file mode 100644 index 0000000..28c691f --- /dev/null +++ b/versions.cfg @@ -0,0 +1,124 @@ +[versions] +openprocurement.api = 2.3.17 +barbecue = 0.1.dev6 +Jinja2 = 2.7.3 +MarkupSafe = 0.23 +PasteDeploy = 1.5.2 +Pygments = 2.0.2 +Sphinx = 1.3.1 +WebOb = 1.7 +WebTest = 2.0.20 +docutils = 0.12 +jsonpointer = 1.9 +nose = 1.3.7 +py = 1.4.26 +pyramid = 1.9 +python-coveralls = 2.5.0 +repoze.lru = 0.6 +translationstring = 1.3 +venusian = 1.0 +waitress = 0.8.9 +zc.recipe.egg = 2.0.3 +zope.deprecation = 4.1.1 +zope.interface = 4.1.1 +# Required by: +# couchdb-schematics==1.1.1 +CouchDB = 1.0 + +# Required by: +# rfc6266==0.0.6 +LEPL = 5.1.3 + +# Required by: +# python-coveralls==2.5.0 +PyYAML = 3.11 + +# Required by: +# WebTest==2.0.18 +beautifulsoup4 = 4.3.2 + +# Required by: +# openprocurement.api==0.8.1 +boto = 2.31.1 + +# Required by: +# openprocurement.api==0.8.1 +chaussette = 1.2 + +# Required by: +# openprocurement.api==0.8.1 +cornice = 3.1.0 + +# Required by: +# openprocurement.api==0.8.1 +couchdb-schematics = 1.1.1 + +# Required by: +# openprocurement.api==0.8.1 +gevent = 1.1.1 + +# Required by: +# gevent==1.0.1 +greenlet = 0.4.9 + +# Required by: +# openprocurement.api==0.8.1 +iso8601 = 0.1.11 + +# Required by: +# openprocurement.api==0.8.1 +jsonpatch = 1.9op1 + +# Required by: +# openprocurement.api==0.8.1 +pbkdf2 = 1.3 + +# Required by: +# openprocurement.api==0.8.1 +pyramid-exclog = 0.7 + +# Required by: +# couchdb-schematics==1.1.1 +pytest = 2.6.4 + +# Required by: +# tzlocal==1.1.2 +pytz = 2014.10 + +# Required by: +# python-coveralls==2.5.0 +requests = 2.10.0 + +# Required by: +# openprocurement.api==0.8.1 +rfc6266 = 0.0.6 + +# Required by: +# couchdb-schematics==1.1.1 +schematics = 1.1.1 + +# Required by: +# python-coveralls==2.5.0 +sh = 1.11 + +# Required by: +# cornice==1.0.0 +simplejson = 3.6.5 + +# Required by: +# WebTest==2.0.18 +# python-coveralls==2.5.0 +# sphinxcontrib-httpdomain==1.3.0 +six = 1.9.0 + +# Required by: +# openprocurement.api==0.8.1 +sphinxcontrib-httpdomain = 1.4.0 + +# Required by: +# openprocurement.api==0.8.1 +tzlocal = 1.1.2 + +# Required by: +# setuptools==0.7 +zc.buildout = 2.2.5