diff --git a/docs/source/locale/uk/LC_MESSAGES/tendering/pricequotation/tutorial.po b/docs/source/locale/uk/LC_MESSAGES/tendering/pricequotation/tutorial.po index 094419eb48..5f547786cd 100644 --- a/docs/source/locale/uk/LC_MESSAGES/tendering/pricequotation/tutorial.po +++ b/docs/source/locale/uk/LC_MESSAGES/tendering/pricequotation/tutorial.po @@ -7,14 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: openprocurement.api 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-26 16:27+0300\n" -"PO-Revision-Date: 2020-06-03 12:39+0200\n" +"POT-Creation-Date: 2020-09-14 17:34+0300\n" +"PO-Revision-Date: 2020-09-14 17:38+0200\n" "Last-Translator: Oleh Helesh \n" +"Language: en_US\n" "Language-Team: English \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 1.3\n" +"Generated-By: Babel 2.8.0\n" +"X-Generator: Lokalize 2.0\n" msgid "Tutorial" msgstr "Туторіал" @@ -46,16 +49,40 @@ msgstr "Створення закупівлі" msgid "Let's provide the data attribute in the submitted body :" msgstr "Введемо data атрибут у поданому тілі:" -msgid "Success! Now we can see that new object was 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 tender: its internal `id` (that matches the `Location` segment), its official `tenderID` and `dateModified` datestamp stating the moment in time when tender was last modified. Note that tender is created with `draft` status." -msgstr "Успіх! Тепер ми бачимо, що новий об’єкт було створено. Код відповіді `201` та заголовок відповіді `Location` вказує місцерозташування створеного об’єкта. Тіло відповіді показує інформацію про створену закупівлю, її внутрішнє `id` (яке співпадає з сегментом `Location`), її офіційне `tenderID` та `dateModified` дату, що показує час, коли закупівля востаннє модифікувалась. Зверніть увагу, що закупівля створюється зі статусом `draft`." +msgid "" +"Success! Now we can see that new object was 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 tender: its" +" internal `id` (that matches the `Location` segment), its official `tenderID`" +" and `dateModified` datestamp stating the moment in time when tender was last" +" modified. Note that tender is created with `draft` status." +msgstr "" +"Успіх! Тепер ми бачимо, що новий об’єкт було створено. Код відповіді `201` та" +" заголовок відповіді `Location` вказує місцерозташування створеного об’єкта." +" Тіло відповіді показує інформацію про створену закупівлю, її внутрішнє `id`" +" (яке співпадає з сегментом `Location`), її офіційне `tenderID` та" +" `dateModified` дату, що показує час, коли закупівля востаннє модифікувалась." +" Зверніть увагу, що закупівля створюється зі статусом `draft`." -msgid "**! Note:** User receives `access`: `token`: ``\"151a30932ee245e989771be867bc8235\"`` with which operations as a `Procuring Entity` role are accessible." -msgstr "**! Примітка:** Користувач отримує `access`: `token`: ``\"151a30932ee245e989771be867bc8235\"`` з яким доступні операції ролі Замовника." +msgid "" +"**! Note:** User receives `access`: `token`:" +" ``\"151a30932ee245e989771be867bc8235\"`` with which operations as a" +" `Procuring Entity` role are accessible." +msgstr "" +"**! Примітка:** Користувач отримує `access`: `token`:" +" ``\"151a30932ee245e989771be867bc8235\"`` з яким доступні операції ролі" +" Замовника." -msgid "Price Quotation procedure has ``procurementMethodType``: ``priceQuotation`` and ``procurementMethod``: ``selective``." -msgstr "Процедура Запиту цінових пропозицій має ``procurementMethodType``: ``priceQuotation`` та ``procurementMethod``: ``selective``." +msgid "" +"Price Quotation procedure has ``procurementMethodType``: ``priceQuotation``" +" and ``procurementMethod``: ``selective``." +msgstr "" +"Процедура Запиту цінових пропозицій має ``procurementMethodType``:" +" ``priceQuotation`` та ``procurementMethod``: ``selective``." -msgid "Let's access the URL of the created object (the `Location` header of the response):" +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 tender." @@ -64,11 +91,21 @@ msgstr "Ми бачимо ту ж відповідь, що і після ств msgid "Modifying tender" msgstr "Модифікація закупівлі" -msgid "Procuring Entity can modify tender before publishing. Let's update tender by supplementing it with all other essential properties:" -msgstr "Замовник може відредагувати закупівлю перед публікацією. Давайте оновимо закупівлю, доповнюючи її усіма іншими необхідними властивостями:" +msgid "" +"Procuring Entity can modify tender before publishing. Let's update tender by" +" supplementing it with all other essential properties:" +msgstr "" +"Замовник може відредагувати закупівлю перед публікацією. Давайте оновимо" +" закупівлю, доповнюючи її усіма іншими необхідними властивостями:" -msgid "We see the added properties have merged with existing tender data. Additionally, the `dateModified` property was updated to reflect the last modification datestamp." -msgstr "Ми бачимо, що додаткові властивості об’єднані з існуючими даними закупівлі. Додатково оновлена властивість `dateModified`, щоб відображати останню дату модифікації." +msgid "" +"We see the added properties have merged with existing tender data." +" Additionally, the `dateModified` property was updated to reflect the last" +" modification datestamp." +msgstr "" +"Ми бачимо, що додаткові властивості об’єднані з існуючими даними закупівлі." +" Додатково оновлена властивість `dateModified`, щоб відображати останню дату" +" модифікації." msgid "Checking the listing again reflects the new modification date:" msgstr "Ще одна перевірка списку відображає нову дату модифікації:" @@ -76,15 +113,32 @@ msgstr "Ще одна перевірка списку відображає но msgid "Publishing tender" msgstr "Публікація закупівлі" -msgid "After creation Procuring Entity publishes procedure by changing status to `draft.publishing` where **priceQuotationBot** robot runs validation of the procedure and supplement procedure with additional data taken from ProZorro e-Catalogues database including `shortListedFirms`." -msgstr "Після створення Замовник публікує процедуру, змінивши статус на `draft.publishing`, де робот **priceQuotationBot** запускає перевірку процедури та доповнює процедуру додатковими даними, отриманими з бази даних електронних каталогів ProZorro, включаючи `shortListedFirms`." +msgid "" +"After creation Procuring Entity publishes procedure by changing status to" +" `draft.publishing` where **priceQuotationBot** robot runs validation of the" +" procedure and supplement procedure with additional data taken from ProZorro" +" e-Catalogues database including `shortListedFirms`." +msgstr "" +"Після створення Замовник публікує процедуру, змінивши статус на" +" `draft.publishing`, де робот **priceQuotationBot** запускає перевірку" +" процедури та доповнює процедуру додатковими даними, отриманими з бази даних" +" електронних каталогів ProZorro, включаючи `shortListedFirms`." -msgid "After successful validation priceQuotationBot transmit procedure to status: `active.tendering`" -msgstr "Після успішної валідації priceQuotationBot переводить процедуру в статус: `active.tendering`" +msgid "" +"After successful validation priceQuotationBot transmit procedure to status:" +" `active.tendering`" +msgstr "" +"Після успішної валідації priceQuotationBot переводить процедуру в статус:" +" `active.tendering`" #, fuzzy -msgid "In case if procedure do not pass validation due to invalid options, it will be switched to status: `draft.unsuccessful` by the **priceQuotationBot**." -msgstr "У разі, якщо процедура не пройде перевірку через недійсні параметри, вона буде переведена в статус: `draft.unsuccessful` за допомогою priceQuotationBot." +msgid "" +"In case if procedure do not pass validation due to invalid options, it will" +" be switched to status: `draft.unsuccessful` by the **priceQuotationBot**." +msgstr "" +"У разі, якщо процедура не пройде перевірку через недійсні параметри, вона" +" буде переведена в статус: `draft.unsuccessful` за допомогою" +" priceQuotationBot." msgid "Bid submission" msgstr "Подача пропозицій" @@ -96,10 +150,17 @@ msgid "Tender status ``active.tendering`` allows registration of bids." msgstr "Статус закупівлі ``active.tendering`` дозволяє подання пропозицій." msgid "Bidder can register a bid with ``draft`` status:" -msgstr "Учасник може зареєструвати пропозицію зі статусом ``draft`` (чернетка):" +msgstr "" +"Учасник може зареєструвати пропозицію зі статусом ``draft`` (чернетка):" -msgid "**! Note:** User receives `access`: `token`: ``\"00e173e5f31f4decbb811cc01e10c1bf\"`` with which operations as a `Supplier` role are accessible." -msgstr "**! Примітка:** Користувач отримує `access`: `token`: ``\"151a30932ee245e989771be867bc8235\"`` з яким доступні операції ролі Постачальника." +msgid "" +"**! Note:** User receives `access`: `token`:" +" ``\"00e173e5f31f4decbb811cc01e10c1bf\"`` with which operations as a" +" `Supplier` role are accessible." +msgstr "" +"**! Примітка:** Користувач отримує `access`: `token`:" +" ``\"151a30932ee245e989771be867bc8235\"`` з яким доступні операції ролі" +" Постачальника." msgid "And activate a bid:" msgstr "Та активувати пропозицію:" @@ -122,35 +183,77 @@ msgstr "Можна перевірити завантажені документ msgid "Awarding process" msgstr "Процес визначення переможця" -msgid "After the tender period end date, system automatically creates `award` in `pending` status for the bid with the most economically advantageous price." -msgstr "Після закінчення тендерного періоду, система автоматично створює ``award`` у статусі ``pending`` для пропозиції з найбільш економічно вигідною ціною." +msgid "" +"After the tender period end date, system automatically creates `award` in" +" `pending` status for the bid with the most economically advantageous price." +msgstr "" +"Після закінчення тендерного періоду, система автоматично створює ``award`` у" +" статусі ``pending`` для пропозиції з найбільш економічно вигідною ціною." -msgid "The Supplier-winner can accept `award` by transferring it to status: `active`. The system is waiting for acceptance from the supplier-winner within `two working days`." -msgstr "Постачальник-переможець може підтвердити `award` змінивши його статус на `active`. Система очікуватиме підтвердження від постачальника-переможця в межах `двох робочих днів`." +msgid "" +"The Supplier-winner can accept `award` by transferring it to status:" +" `active`. The system is waiting for acceptance from the supplier-winner" +" within `two working days`." +msgstr "" +"Постачальник-переможець може підтвердити `award` змінивши його статус на" +" `active`. Система очікуватиме підтвердження від постачальника-переможця в" +" межах `двох робочих днів`." -msgid "Procuring Entity can cancel `award` after acceptance by changing `award` status to `cancelled` in case if supplier-winner declines to sign contract." -msgstr "Замовник може відмінити `award` після підтвердження змінивши його статус на `cancelled` у випадку якщо постачальник-переможець відмовляється підписувати контракт." +msgid "" +"Procuring Entity can cancel `award` after acceptance by changing `award`" +" status to `cancelled` in case if supplier-winner declines to sign contract." +msgstr "" +"Замовник може відмінити `award` після підтвердження змінивши його статус на" +" `cancelled` у випадку якщо постачальник-переможець відмовляється підписувати" +" контракт." -msgid "After canceling `award` system creates `second` `award` for the same bid in status: `pending` with access for Procuring Entity only. By the decision of Procuring Entity `second` `award` can be either changed for `active` or to `unsuccessful` with ability to upload supplementary documents." -msgstr "Після відміни `award`, система створює `другий` `award` для цієї пропозиції у статусі `pending` з доступом лише Замовника. За рішенням Замовника `другий` `award` може бути змінений на `active` або `unsuccessful` з можливістю завантажити супровідну документацію." +msgid "" +"After canceling `award` system creates `second` `award` for the same bid in" +" status: `pending` with access for Procuring Entity only. Procuring Entity" +" can change `second` `award` status to `unsuccessful` with ability to upload" +" supplementary documents." +msgstr "" +"Після відміни `award`, система створює `другий` `award` для цієї пропозиції у" +" статусі `pending` з доступом лише Замовника. Замовник може перевести" +" `другий` `авард` у статус `unsuccessful` з можливістю завантажувати" +" супровідну документацію." -msgid "The Supplier-winner can decline `award` by transferring it to status: `unsuccessful`." -msgstr "Постачальник-переможець може відмовитись від `award` змінивши його статус на `unsuccessful`." +msgid "" +"The Supplier-winner can decline `award` by transferring it to status:" +" `unsuccessful`." +msgstr "" +"Постачальник-переможець може відмовитись від `award` змінивши його статус на " +" `unsuccessful`." -msgid "`Award` will be granted to the next bid with most economically advantageous price, for the following cases:" -msgstr "`Award` буде наданий до наступної пропозиції з найбільш економічно вигідною ціною, у наступних випадках:" +msgid "" +"`Award` will be granted to the next bid with most economically advantageous" +" price, for the following cases:" +msgstr "" +"`Award` буде наданий до наступної пропозиції з найбільш економічно вигідною" +" ціною, у наступних випадках:" msgid "Supplier-winner didn't accept `award` within two working days." -msgstr "Постачальник-переможець не підтвердив `award` в межах двох робочих днів. " +msgstr "" +"Постачальник-переможець не підтвердив `award` в межах двох робочих днів. " msgid "Supplier-winner declined `award`." msgstr "Постачальник-переможець відмовився від `award`." -msgid "Supplier-winner refused to sign contract and `award` was canceled by Procuring Entity." -msgstr "Постачальник-переможець відмовився підписувати контракт і `award` був скасований Замовником." +msgid "" +"Supplier-winner refused to sign contract and `award` was canceled by" +" Procuring Entity." +msgstr "" +"Постачальник-переможець відмовився підписувати контракт і `award` був" +" скасований Замовником." -msgid "**Note !** In the case of `award` being transferred to `unsuccessful` status for the last bid, procedure will inherit termination status: **`unsuccessful`**." -msgstr "**! Примітка:** У випадку переходу `award` останньої пропозиції у статус `unsuccessful` процедура набуде кінцевий статус: **`unsuccessful`**." +msgid "" +"**Note !** In the case of `award` being transferred to `unsuccessful` status" +" for the last bid or if cancelled by Procuring Entity procedure will inherit" +" termination status: **`unsuccessful`**." +msgstr "" +"**! Примітка:** У випадку переходу `award` останньої пропозиції у статус" +" `unsuccessful` або якщо `award` був скаcовний Замовником процедура набуде" +" кінцевий статус: **`unsuccessful`**." msgid "Setting contract" msgstr "Налаштування угоди" @@ -158,11 +261,19 @@ msgstr "Налаштування угоди" msgid "Setting contract value" msgstr "Встановлення вартості угоди" -msgid "By default contract value is set based on the award, but there is a possibility to set custom contract value." -msgstr "За замовчуванням вартість угоди встановлюється на основі рішення про визначення переможця, але є можливість змінити це значення. " +msgid "" +"By default contract value is set based on the award, but there is a" +" possibility to set custom contract value." +msgstr "" +"За замовчуванням вартість угоди встановлюється на основі рішення про" +" визначення переможця, але є можливість змінити це значення. " -msgid "If you want to **lower contract value**, you can insert new one into the `amount` field." -msgstr "Якщо ви хочете **знизити вартість угоди**, ви можете встановити нове значення для поля `amount`." +msgid "" +"If you want to **lower contract value**, you can insert new one into the" +" `amount` field." +msgstr "" +"Якщо ви хочете **знизити вартість угоди**, ви можете встановити нове значення" +" для поля `amount`." msgid "`200 OK` response was returned. The value was modified successfully." msgstr "Було повернуто код відповіді `200 OK`. Значення змінено успішно." @@ -170,29 +281,46 @@ msgstr "Було повернуто код відповіді `200 OK`. Знач msgid "Setting contract signature date" msgstr "Встановлення дати підписання угоди" -msgid "There is a possibility to set custom contract signature date. You can insert appropriate date into the `dateSigned` field." -msgstr "Є можливість встановити дату підписання угоди. Для цього вставте відповідну дату в поле `dateSigned`." +msgid "" +"There is a possibility to set custom contract signature date. You can insert" +" appropriate date into the `dateSigned` field." +msgstr "" +"Є можливість встановити дату підписання угоди. Для цього вставте відповідну" +" дату в поле `dateSigned`." -msgid "If this date is not set, it will be auto-generated on the date of contract registration." -msgstr "Якщо ви не встановите дату підписання, то вона буде згенерована автоматично під час реєстрації угоди." +msgid "" +"If this date is not set, it will be auto-generated on the date of contract" +" registration." +msgstr "" +"Якщо ви не встановите дату підписання, то вона буде згенерована автоматично" +" під час реєстрації угоди." msgid "Setting contract validity period" msgstr "Встановлення терміну дії угоди" -msgid "Setting contract validity period is optional, but if it is needed, you can set appropriate `startDate` and `endDate`." -msgstr "Встановлення терміну дії угоди необов’язкове, але, якщо є необхідність, ви можете встановити відповідну дату початку `startDate` та кінця `endDate` терміну дії." +msgid "" +"Setting contract validity period is optional, but if it is needed, you can" +" set appropriate `startDate` and `endDate`." +msgstr "" +"Встановлення терміну дії угоди необов’язкове, але, якщо є необхідність, ви" +" можете встановити відповідну дату початку `startDate` та кінця `endDate`" +" терміну дії." msgid "Uploading contract documentation" msgstr "Завантаження документації по угоді" msgid "You can upload contract documents for the Price Quotation procedure." -msgstr "Ви можете завантажити документи угоди для процедури Запиту цінових пропозицій." +msgstr "" +"Ви можете завантажити документи угоди для процедури Запиту цінових пропозицій." msgid "Let's upload contract document:" msgstr "Завантажимо документ угоди:" -msgid "`201 Created` response code and `Location` header confirm that this document was added." -msgstr "`201` Використаємо URL створеного об’єкта (заголовок відповіді `Location`)." +msgid "" +"`201 Created` response code and `Location` header confirm that this document" +" was added." +msgstr "" +"`201` Використаємо URL створеного об’єкта (заголовок відповіді `Location`)." msgid "Let's view the uploaded contract document:" msgstr "Подивимось на список документів пов’язаних з угодою:" @@ -200,8 +328,12 @@ msgstr "Подивимось на список документів пов’я msgid "Cancelling tender" msgstr "Відміна закупівлі" -msgid "Tender creator can cancel tender anytime (except when tender in terminal status e.g. `draft.unsuccessful`, `unsuccessful`, `cancelled`, `complete`)." -msgstr "Замовник може скасувати закупівлю у будь-який момент (крім закупівель у кінцевому стані, наприклад, `unsuccessful`, `cancelled`, `complete`)." +msgid "" +"Tender creator can cancel tender anytime (except when tender in terminal" +" status e.g. `draft.unsuccessful`, `unsuccessful`, `cancelled`, `complete`)." +msgstr "" +"Замовник може скасувати закупівлю у будь-який момент (крім закупівель у" +" кінцевому стані, наприклад, `unsuccessful`, `cancelled`, `complete`)." msgid "The following steps should be applied:" msgstr "Для цього потрібно виконати наступні кроки:" @@ -215,26 +347,45 @@ msgstr "Наповніть його протоколом про причини msgid "Cancel the tender with the prepared reasons." msgstr "Скасуйте закупівлю через подані причини." -msgid "Only the request that has been activated (3rd step above) has power to cancel tender. I.e. you have to not only prepare cancellation request but to activate it as well." -msgstr "Запит на скасування, який не пройшов активації (3-й крок), не матиме сили, тобто, для скасування закупівлі буде обов’язковим не тільки створити заявку, але і активувати її." +msgid "" +"Only the request that has been activated (3rd step above) has power to cancel" +" tender. I.e. you have to not only prepare cancellation request but to" +" activate it as well." +msgstr "" +"Запит на скасування, який не пройшов активації (3-й крок), не матиме сили," +" тобто, для скасування закупівлі буде обов’язковим не тільки створити заявку," +" але і активувати її." -msgid "For cancelled cancellation you need to update cancellation status to `unsuccessful` from `draft` or `pending`." -msgstr "Для відміни скасування закупівлі, вам потрібно оновити статус скасування до `unsuccessful` з `draft` чи `pending`" +msgid "" +"For cancelled cancellation you need to update cancellation status to" +" `unsuccessful` from `draft` or `pending`." +msgstr "" +"Для відміни скасування закупівлі, вам потрібно оновити статус скасування до" +" `unsuccessful` з `draft` чи `pending`" msgid "See :ref:`cancellation` data structure for details." -msgstr "Дивіться структуру запиту :ref:`cancellation` для більш детальної інформації." +msgstr "" +"Дивіться структуру запиту :ref:`cancellation` для більш детальної інформації." msgid "Preparing the cancellation request" msgstr "Формування запиту на скасування" -msgid "You should pass `reason` and `reasonType`, `status` defaults to `draft`." -msgstr "Ви повинні передати змінні `reason` та `reasonType`, `status` у стані `draft`." +msgid "" +"You should pass `reason` and `reasonType`, `status` defaults to `draft`." +msgstr "" +"Ви повинні передати змінні `reason` та `reasonType`, `status` у стані `draft`." -msgid "There are four possible types of cancellation reason - tender was `noDemand`, `unFixable`, `forceMajeure` and `expensesCut`." -msgstr "При скасуванні, замовник має визначити один з чотирьох типів reasonType: `noDemand`, `unFixable`, `forceMajeure` aбо `expensesCut`." +msgid "" +"There are four possible types of cancellation reason - tender was `noDemand`," +" `unFixable`, `forceMajeure` and `expensesCut`." +msgstr "" +"При скасуванні, замовник має визначити один з чотирьох типів reasonType:" +" `noDemand`, `unFixable`, `forceMajeure` aбо `expensesCut`." msgid "`id` is autogenerated and passed in the `Location` header of response." -msgstr "`id` генерується автоматично і повертається у додатковому заголовку відповіді `Location`:" +msgstr "" +"`id` генерується автоматично і повертається у додатковому заголовку відповіді" +" `Location`:" msgid "You can change ``reasonType`` value to any of the above." msgstr "Ви можете виправити тип на будь-який що вказаний вище." @@ -242,8 +393,10 @@ msgstr "Ви можете виправити тип на будь-який що msgid "Filling cancellation with protocol and supplementary documentation" msgstr "Наповнення протоколом та іншою супровідною документацією" -msgid "This step is required. Without documents you can't update tender status." -msgstr "Цей крок обов'язковий. Без документів ви не можете оновити статус закупівлі." +msgid "" +"This step is required. Without documents you can't update tender status." +msgstr "" +"Цей крок обов'язковий. Без документів ви не можете оновити статус закупівлі." msgid "Upload the file contents" msgstr "Завантажити вміст файлу" diff --git a/docs/source/tendering/pricequotation/tutorial.rst b/docs/source/tendering/pricequotation/tutorial.rst index aee18138b6..9da463445f 100644 --- a/docs/source/tendering/pricequotation/tutorial.rst +++ b/docs/source/tendering/pricequotation/tutorial.rst @@ -156,7 +156,7 @@ Procuring Entity can cancel `award` after acceptance by changing `award` status :code: After canceling `award` system creates `second` `award` for the same bid in status: `pending` with access for Procuring Entity only. -By the decision of Procuring Entity `second` `award` can be either changed for `active` or to `unsuccessful` with ability to upload supplementary documents. +Procuring Entity can change `second` `award` status to `unsuccessful` with ability to upload supplementary documents. The Supplier-winner can decline `award` by transferring it to status: `unsuccessful`. @@ -167,9 +167,8 @@ The Supplier-winner can decline `award` by transferring it to status: `unsuccess 1. Supplier-winner didn't accept `award` within two working days. 2. Supplier-winner declined `award`. - 3. Supplier-winner refused to sign contract and `award` was canceled by Procuring Entity. -**Note !** In the case of `award` being transferred to `unsuccessful` status for the last bid, procedure will inherit termination status: **`unsuccessful`**. +**Note !** In the case of `award` being transferred to `unsuccessful` status for the last bid or if cancelled by Procuring Entity procedure will inherit termination status: **`unsuccessful`**. .. index:: Setting Contract diff --git a/docs/tests/test_pricequotation.py b/docs/tests/test_pricequotation.py index 4bbd3aa81e..a248699a69 100644 --- a/docs/tests/test_pricequotation.py +++ b/docs/tests/test_pricequotation.py @@ -283,21 +283,6 @@ def test_docs_tutorial(self): {"data": {"status": "active"}}) self.assertEqual(response.status, '200 OK') - with open(TARGET_DIR + 'award-cancelled.http', 'w') as self.app.file_obj: - response = self.app.patch_json( - '/tenders/{}/awards/{}?acc_token={}'.format(self.tender_id, award_id, owner_token), - {"data": {"status": "cancelled"}}) - self.assertEqual(response.status, '200 OK') - - response = self.app.get('/tenders/{}/awards'.format(self.tender_id)) - award = [i for i in response.json['data'] if i['status'] == 'pending'][0] - award_id = award['id'] - - response = self.app.patch_json( - '/tenders/{}/awards/{}?acc_token={}'.format(self.tender_id, award_id, owner_token), - {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - with open(TARGET_DIR + 'contract-listing.http', 'w') as self.app.file_obj: response = self.app.get('/tenders/{}/contracts'.format(self.tender_id)) self.assertEqual(response.status, '200 OK') diff --git a/src/openprocurement/tender/pricequotation/models/tender.py b/src/openprocurement/tender/pricequotation/models/tender.py index 96c87ac019..1c80afaeef 100644 --- a/src/openprocurement/tender/pricequotation/models/tender.py +++ b/src/openprocurement/tender/pricequotation/models/tender.py @@ -250,7 +250,7 @@ class Options: shortlistedFirms = ListType(ModelType(ShortlistedFirm), default=list()) criteria = ListType(ModelType(Criterion), default=list()) noticePublicationDate = IsoDateTimeType() - unsuccessfulReason = StringType() + unsuccessfulReason = ListType(StringType) procuring_entity_kinds = PQ_KINDS diff --git a/src/openprocurement/tender/pricequotation/tests/award.py b/src/openprocurement/tender/pricequotation/tests/award.py index e9fd031a17..0354e9d0a0 100644 --- a/src/openprocurement/tender/pricequotation/tests/award.py +++ b/src/openprocurement/tender/pricequotation/tests/award.py @@ -16,7 +16,8 @@ check_tender_award_disqualification, create_tender_award, patch_tender_award, - tender_award_transitions + tender_award_transitions, + check_tender_award_cancellation ) from openprocurement.tender.belowthreshold.tests.award import ( TenderAwardDocumentResourceTestMixin, @@ -49,6 +50,7 @@ class TenderAwardResourceTest(TenderContentWebTest, TenderAwardResourceTestMixin test_tender_award_transitions = snitch(tender_award_transitions) test_check_tender_award = snitch(check_tender_award) test_check_tender_award_disqualification = snitch(check_tender_award_disqualification) + test_check_tender_award_cancellation = snitch(check_tender_award_cancellation) class TenderAwardResourceScaleTest(TenderContentWebTest): diff --git a/src/openprocurement/tender/pricequotation/tests/award_blanks.py b/src/openprocurement/tender/pricequotation/tests/award_blanks.py index d0bb195cca..9b8bf0b590 100644 --- a/src/openprocurement/tender/pricequotation/tests/award_blanks.py +++ b/src/openprocurement/tender/pricequotation/tests/award_blanks.py @@ -184,23 +184,29 @@ def create_tender_award(self): self.assertEqual(response.json["data"][-1], award) award_request_path = "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award["id"], self.tender_token) - response = self.app.patch_json(award_request_path, {"data": {"status": "active"}}) - self.assertEqual(response.status, "200 OK") + + response = self.app.patch_json(award_request_path, {"data": {"status": "active"}}, status=403) + self.assertEqual(response.status, "403 Forbidden") self.assertEqual(response.content_type, "application/json") - self.assertEqual(response.json["data"]["status"], u"active") + self.assertEqual(response.json['status'], "error") + self.assertEqual( + response.json['errors'], + [{ + u'description': u"Can't change award status to active from pending", + u'location': u'body', + u'name': u'data' + }] + ) - response = self.app.get("/tenders/{}".format(self.tender_id)) + response = self.app.patch_json(award_request_path, {"data": {"status": "unsuccessful"}}) self.assertEqual(response.status, "200 OK") self.assertEqual(response.content_type, "application/json") - self.assertEqual(response.json["data"]["status"], u"active.awarded") + self.assertEqual(response.json["data"]["status"], "unsuccessful") - award_request_path = "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award["id"], self.tender_token) - response = self.app.patch_json(award_request_path, {"data": {"status": "cancelled"}}) + response = self.app.get("/tenders/{}".format(self.tender_id)) self.assertEqual(response.status, "200 OK") self.assertEqual(response.content_type, "application/json") - self.assertEqual(response.json["data"]["status"], u"cancelled") - self.assertIn("Location", response.headers) - + self.assertEqual(response.json["data"]["status"], u"unsuccessful") def patch_tender_award(self): @@ -528,3 +534,65 @@ def check_tender_award_disqualification(self): response.json["data"]["suppliers"][0]["identifier"]["id"], sorted_bids[1]["tenderers"][0]["identifier"]["id"] ) self.assertEqual(response.json["data"]["bid_id"], sorted_bids[1]["id"]) + + +def check_tender_award_cancellation(self): + # get bids + response = self.app.get("/tenders/{}/bids".format(self.tender_id)) + bids = response.json["data"] + bid_token = self.initial_bids_tokens[0] + tender_token = self.db.get(self.tender_id)['owner_token'] + sorted_bids = sorted(bids, key=lambda bid: bid["value"]['amount']) + + # get awards + response = self.app.get("/tenders/{}/awards".format(self.tender_id)) + # get pending award + award = [i for i in response.json["data"] if i["status"] == "pending"][0] + award_id = award['id'] + response = self.app.patch_json( + "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award_id, bid_token), + {"data": {"status": "active"}}, + ) + self.assertEqual(response.status, "200 OK") + self.assertEqual(response.content_type, "application/json") + self.assertEqual(response.json['data']['status'], "active") + + response = self.app.patch_json( + "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award_id, tender_token), + {"data": {"status": "cancelled"}}, + ) + + self.assertEqual(response.status, "200 OK") + self.assertEqual(response.content_type, "application/json") + self.assertEqual(response.json['data']['status'], "cancelled") + old_award = response.json['data'] + + response = self.app.get("/tenders/{}/awards".format(self.tender_id)) + + award = [i for i in response.json["data"] if i["status"] == "pending"][-1] + award_id = award['id'] + self.assertEqual(old_award['bid_id'], award['bid_id']) + + response = self.app.patch_json( + "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award_id, bid_token), + {"data": {"status": "active"}}, + status=403 + ) + self.assertEqual(response.status, "403 Forbidden") + self.assertEqual(response.content_type, "application/json") + self.assertEqual(response.json['status'], "error") + + for status in ('active', 'cancelled'): + response = self.app.patch_json( + "/tenders/{}/awards/{}?acc_token={}".format(self.tender_id, award_id, tender_token), + {"data": {"status": status}}, + status=403 + ) + self.assertEqual(response.status, "403 Forbidden") + self.assertEqual(response.content_type, "application/json") + self.assertEqual(response.json['status'], "error") + self.assertEqual(response.json['errors'], [{ + u'description': u"Can't change award status to {} from pending".format(status), + u'location': u'body', + u'name': u'data' + }]) diff --git a/src/openprocurement/tender/pricequotation/tests/data.py b/src/openprocurement/tender/pricequotation/tests/data.py index 0b72166b08..d48c462f7e 100644 --- a/src/openprocurement/tender/pricequotation/tests/data.py +++ b/src/openprocurement/tender/pricequotation/tests/data.py @@ -367,8 +367,8 @@ { "dataType": "integer", "id": "655360-0004-001-01", - "minValue": 250, - "title": u"Яскравість дисплея", + "maxValue": 250, + "title": "Яскравість дисплея", "unit": { "code": "A24", "name": u"кд/м²" diff --git a/src/openprocurement/tender/pricequotation/tests/tender_blanks.py b/src/openprocurement/tender/pricequotation/tests/tender_blanks.py index 5d1ebb2416..43e2109403 100644 --- a/src/openprocurement/tender/pricequotation/tests/tender_blanks.py +++ b/src/openprocurement/tender/pricequotation/tests/tender_blanks.py @@ -657,7 +657,7 @@ def create_tender_draft(self): ) response = self.app.patch_json( "/tenders/{}?acc_token={}".format(tender["id"], token), - {"data": {"status": self.primary_tender_status, "unsuccessfulReason": "some value from buyer"}} + {"data": {"status": self.primary_tender_status, "unsuccessfulReason": ["some value from buyer"]}} ) self.assertEqual(response.status, "200 OK") self.assertEqual(response.content_type, "application/json") @@ -1354,14 +1354,14 @@ def patch_tender_by_pq_bot(self): with change_auth(self.app, ("Basic", ("pricequotation", ""))) as app: self.app.patch_json( "/tenders/{}".format(tender_id), - {"data": {"status": "draft.unsuccessful", "unsuccessfulReason": "Profile not found in catalogue"}} + {"data": {"status": "draft.unsuccessful", "unsuccessfulReason": ["Profile not found in catalogue"]}} ) response = self.app.get("/tenders/{}".format(tender_id)) self.assertEqual(response.status, "200 OK") tender = response.json["data"] self.assertEqual(tender["status"], "draft.unsuccessful") - self.assertEqual(tender["unsuccessfulReason"], "Profile not found in catalogue") + self.assertEqual(tender["unsuccessfulReason"], ["Profile not found in catalogue"]) self.assertNotIn("classification", tender["items"][0]) self.assertNotIn("unit", tender["items"][0]) self.assertNotIn("shortlistedFirms", tender) diff --git a/src/openprocurement/tender/pricequotation/validation.py b/src/openprocurement/tender/pricequotation/validation.py index 1d79a21386..74552b3bf0 100644 --- a/src/openprocurement/tender/pricequotation/validation.py +++ b/src/openprocurement/tender/pricequotation/validation.py @@ -169,7 +169,7 @@ def matches(criteria, response): ) ) if not min_value and max_value: - if value < min_value: + if value > datatype.to_native(max_value): raise ValidationError( u'Value {} is higher then required {} in reqirement {}'.format( value, diff --git a/src/openprocurement/tender/pricequotation/views/award.py b/src/openprocurement/tender/pricequotation/views/award.py index 73fc18613e..7671fe5469 100644 --- a/src/openprocurement/tender/pricequotation/views/award.py +++ b/src/openprocurement/tender/pricequotation/views/award.py @@ -69,10 +69,19 @@ def collection_post(self): def patch(self): tender = self.request.validated["tender"] award = self.request.context + is_awarded = [ + a for a in tender.awards + if a.bid_id == award.bid_id and a.id != award.id + ] award_status = award.status apply_patch(self.request, save=False, src=self.request.context.serialize()) now = get_now() + if is_awarded and award.status != 'unsuccessful': + raise_operation_error( + self.request, + "Can't change award status to {} from {}".format(award.status, award_status) + ) if award_status == "pending" and award.status == "active": add_contract(self.request, award, now) @@ -83,22 +92,10 @@ def patch(self): i.status = "cancelled" add_next_award(self.request) elif award_status == "pending" and award.status == "unsuccessful": - add_next_award(self.request) - elif ( - award_status == "unsuccessful" - and award.status == "cancelled" - ): - if tender.status == "active.awarded": - tender.status = "active.qualification" - tender.awardPeriod.endDate = None - cancelled_awards = [] - for i in tender.awards[tender.awards.index(award):]: - i.status = "cancelled" - cancelled_awards.append(i.id) - for i in tender.contracts: - if i.awardID in cancelled_awards: - i.status = "cancelled" - add_next_award(self.request) + if is_awarded: + tender.status = 'unsuccessful' + else: + add_next_award(self.request) elif self.request.authenticated_role != "Administrator" and not ( award_status == "pending" and award.status == "pending" ):