Commit b4196659fa389a14422e5660b5fe1f7f3369b04a
Committed by
GitHub
Merge pull request #167 from ProzorroUKR/plan_status/breakdown
Plan status/breakdown
Showing
16 changed files
with
258 additions
and
24 deletions
... | ... | @@ -11,7 +11,7 @@ ${ERROR_PLAN_MESSAGE}= Calling method 'get_plan' failed: ResourceGone: {"status |
11 | 11 | |
12 | 12 | *** Keywords *** |
13 | 13 | Можливість оголосити тендер |
14 | - ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact.yaml | |
14 | + ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact_plan.yaml | |
15 | 15 | ${ARTIFACT}= load_data_from ${file_path} |
16 | 16 | Log ${ARTIFACT.tender_uaid} |
17 | 17 | ${NUMBER_OF_LOTS}= Convert To Integer ${NUMBER_OF_LOTS} |
... | ... | @@ -242,6 +242,7 @@ ${ERROR_PLAN_MESSAGE}= Calling method 'get_plan' failed: ResourceGone: {"status |
242 | 242 | |
243 | 243 | Можливість створити план закупівлі |
244 | 244 | ${NUMBER_OF_ITEMS}= Convert To Integer ${NUMBER_OF_ITEMS} |
245 | + ${NUMBER_OF_BREAKDOWN}= Convert To Integer ${NUMBER_OF_BREAKDOWN} | |
245 | 246 | ${tender_parameters}= Create Dictionary |
246 | 247 | ... mode=${MODE} |
247 | 248 | ... number_of_items=${NUMBER_OF_ITEMS} |
... | ... | @@ -250,6 +251,7 @@ ${ERROR_PLAN_MESSAGE}= Calling method 'get_plan' failed: ResourceGone: {"status |
250 | 251 | ... moz_integration=${${MOZ_INTEGRATION}} |
251 | 252 | ... road_index=${${ROAD_INDEX}} |
252 | 253 | ... gmdn_index=${${GMDN_INDEX}} |
254 | + ... number_of_breakdown=${NUMBER_OF_BREAKDOWN} | |
253 | 255 | ${DIALOGUE_TYPE}= Get Variable Value ${DIALOGUE_TYPE} |
254 | 256 | Run keyword if '${DIALOGUE_TYPE}' != '${None}' Set to dictionary ${tender_parameters} dialogue_type=${DIALOGUE_TYPE} |
255 | 257 | ${tender_data}= Підготувати дані для створення плану ${tender_parameters} |
... | ... | @@ -378,6 +380,7 @@ ${ERROR_PLAN_MESSAGE}= Calling method 'get_plan' failed: ResourceGone: {"status |
378 | 380 | Перевірити неможливість зміни поля ${field_name} тендера на значення ${field_value} для користувача ${username} |
379 | 381 | Require Failure ${username} Внести зміни в тендер ${TENDER['TENDER_UAID']} ${field_name} ${field_value} |
380 | 382 | |
383 | + | |
381 | 384 | Можливість змінити поле ${field_name} плану на ${field_value} |
382 | 385 | Run As ${tender_owner} Внести зміни в план ${TENDER['TENDER_UAID']} ${field_name} ${field_value} |
383 | 386 | |
... | ... | @@ -1708,3 +1711,28 @@ ${ERROR_PLAN_MESSAGE}= Calling method 'get_plan' failed: ResourceGone: {"status |
1708 | 1711 | ${document}= openprocurement_client.Отримати останній документ кваліфікації з типом registerExtract ${username} ${tender_uaid} ${award_id} |
1709 | 1712 | Порівняти об'єкти ${document['title']} edr_identification.yaml |
1710 | 1713 | |
1714 | +############################################################################################## | |
1715 | +# PLAN | |
1716 | +############################################################################################## | |
1717 | + | |
1718 | +Можливість скасувати план | |
1719 | + ${cancellation_data}= Підготувати дані про скасування плану | |
1720 | + Run As ${tender_owner} | |
1721 | + ... Скасувати план | |
1722 | + ... ${TENDER['TENDER_UAID']} | |
1723 | + ... ${cancellation_data} | |
1724 | + Set To Dictionary ${USERS.users['${tender_owner}']} plan_cancellation_data=${cancellation_data} | |
1725 | + | |
1726 | + | |
1727 | +Можливість перевірити статус плану після публікації тендера | |
1728 | + ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact_plan.yaml | |
1729 | + ${ARTIFACT}= load_data_from ${file_path} | |
1730 | + Log ${ARTIFACT.tender_uaid} | |
1731 | + Звірити статус плану ${tender_owner} ${ARTIFACT.tender_uaid} complete | |
1732 | + | |
1733 | + | |
1734 | +Можливість змінити на ${percent} відсотки бюджет плану | |
1735 | + ${percent}= Convert To Number ${percent} | |
1736 | + ${divider}= Convert To Number 0.01 | |
1737 | + ${value}= mult_and_round ${USERS.users['${tender_owner}'].tender_data.data.budget.amount} ${percent} ${divider} precision=${2} | |
1738 | + Можливість змінити поле budget.amount плану на ${value} | |
\ No newline at end of file | ... | ... |
... | ... | @@ -190,7 +190,7 @@ Library openprocurement_client.utils |
190 | 190 | |
191 | 191 | Створити тендер |
192 | 192 | [Arguments] ${username} ${tender_data} |
193 | - ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact.yaml | |
193 | + ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact_plan.yaml | |
194 | 194 | ${ARTIFACT}= load_data_from ${file_path} |
195 | 195 | Log ${ARTIFACT.tender_owner_access_token} |
196 | 196 | Log ${ARTIFACT.tender_id} |
... | ... | @@ -1681,6 +1681,36 @@ Library openprocurement_client.utils |
1681 | 1681 | ${filename}= download_file_from_url ${document.url} ${OUTPUT_DIR}${/}${document.title} |
1682 | 1682 | [return] ${filename} |
1683 | 1683 | |
1684 | + | |
1685 | +Скасувати план | |
1686 | + [Arguments] ${username} ${tender_uaid} ${cancellation_reason} | |
1687 | + ${tender}= openprocurement_client.Пошук плану по ідентифікатору ${username} ${tender_uaid} | |
1688 | + ${data}= Create dictionary cancellation=${cancellation_reason} | |
1689 | + ${cancellation_data}= Create dictionary data=${data} | |
1690 | + ${cancellation_data}= munch_dict arg=${cancellation_data} | |
1691 | + ${cancel_reply}= Call Method ${USERS.users['${username}'].plan_client} patch_plan | |
1692 | + ... ${tender.data.id} | |
1693 | + ... ${cancellation_data} | |
1694 | + ... access_token=${tender.access.token} | |
1695 | + ${cancellation_id}= Set variable ${cancel_reply.data.id} | |
1696 | + openprocurement_client.Підтвердити скасування плану ${username} ${tender_uaid} ${cancellation_id} | |
1697 | + | |
1698 | + | |
1699 | +Підтвердити скасування плану | |
1700 | + [Documentation] | |
1701 | + ... [Arguments] Username, tender uaid | |
1702 | + ... Find plan using uaid, get cancellation test_confirmation data and call patch_plan | |
1703 | + ... [Return] Nothing | |
1704 | + [Arguments] ${username} ${tender_uaid} ${cancellation_id} | |
1705 | + ${tender}= openprocurement_client.Пошук плану по ідентифікатору ${username} ${tender_uaid} | |
1706 | + ${data}= test_confirm_plan_cancel_data | |
1707 | + Log ${data} | |
1708 | + ${reply}= Call Method ${USERS.users['${username}'].plan_client} patch_plan | |
1709 | + ... ${tender.data.id} | |
1710 | + ... ${data} | |
1711 | + ... access_token=${tender.access.token} | |
1712 | + Log ${reply} | |
1713 | + | |
1684 | 1714 | ############################################################################## |
1685 | 1715 | # OpenUA procedure |
1686 | 1716 | ############################################################################## | ... | ... |
... | ... | @@ -65,7 +65,7 @@ Quinta: |
65 | 65 | openeu: |
66 | 66 | tender: [1, 35] |
67 | 67 | openua_defense: |
68 | - tender: [0, 30] | |
68 | + tender: [0, 20] | |
69 | 69 | open_competitive_dialogue: |
70 | 70 | accelerator: 1440 |
71 | 71 | tender: [0, 30] |
... | ... | @@ -90,14 +90,27 @@ Quinta: |
90 | 90 | Etender: |
91 | 91 | intervals: |
92 | 92 | default: |
93 | - enquiry: [0, 5] | |
93 | + enquiry: [0, 7] | |
94 | + tender: [0, 7] | |
95 | + belowThreshold: | |
96 | + enquiry: [0, 20] | |
97 | + tender: [0, 20] | |
98 | + accelerator: 1440 | |
99 | + openua: | |
100 | + tender: [1, 17] | |
101 | + openeu: | |
102 | + tender: [1, 35] | |
103 | + openua_defense: | |
104 | + tender: [0, 38] | |
105 | + open_competitive_dialogue: | |
106 | + tender: [0, 35] | |
94 | 107 | keywords_file: etender |
95 | 108 | roles: |
96 | 109 | provider: Etender_Provider1 |
97 | 110 | provider1: Etender_Provider2 |
98 | 111 | tender_owner: Etender_Owner |
99 | 112 | viewer: Etender_Viewer |
100 | - timeout_on_wait: 60 | |
113 | + timeout_on_wait: 30 | |
101 | 114 | DZO: |
102 | 115 | intervals: |
103 | 116 | default: | ... | ... |
... | ... | @@ -74,31 +74,31 @@ users: |
74 | 74 | size: [1400, 900] |
75 | 75 | Etender_Owner: |
76 | 76 | broker: Etender |
77 | - homepage: "http://bid.uat.e-tender.biz/#/" | |
78 | - login: Misha2 | |
79 | - password: Password1 | |
77 | + homepage: "https://qa-prozorro.e-tender.ua/#/" | |
78 | + login: auto_owner | |
79 | + password: Qq123456 | |
80 | 80 | browser: chrome |
81 | 81 | position: [0, 0] |
82 | 82 | size: [1366, 800] |
83 | 83 | Etender_Provider1: |
84 | 84 | broker: Etender |
85 | - homepage: "http://bid.uat.e-tender.biz/#/" | |
86 | - login: st_org | |
87 | - password: 12345678 | |
85 | + homepage: "https://qa-prozorro.e-tender.ua/#/" | |
86 | + login: auto_provider1 | |
87 | + password: Qq123456 | |
88 | 88 | browser: chrome |
89 | 89 | position: [0, 0] |
90 | 90 | size: [1366, 800] |
91 | 91 | Etender_Provider2: |
92 | 92 | broker: Etender |
93 | - homepage: "http://bid.uat.e-tender.biz/#/" | |
94 | - login: provider2 | |
95 | - password: Qa123456 | |
93 | + homepage: "https://qa-prozorro.e-tender.ua/#/" | |
94 | + login: auto_provider2 | |
95 | + password: Qq123456 | |
96 | 96 | browser: chrome |
97 | 97 | position: [0, 0] |
98 | 98 | size: [1366, 800] |
99 | 99 | Etender_Viewer: |
100 | 100 | broker: Etender |
101 | - homepage: "http://bid.uat.e-tender.biz/#/" | |
101 | + homepage: "https://qa-prozorro.e-tender.ua/#/" | |
102 | 102 | browser: chrome |
103 | 103 | position: [0, 0] |
104 | 104 | size: [1366, 800] | ... | ... |
... | ... | @@ -298,6 +298,7 @@ def test_tender_data_planning(params): |
298 | 298 | "currency": "UAH", |
299 | 299 | "amount": round(random.uniform(3000, 99999999999.99), 2), |
300 | 300 | "id": str(fake.random_int(min=1, max=99999999999)) + "-" + str(fake.random_int(min=1, max=9)), |
301 | + "breakdown": [] | |
301 | 302 | }, |
302 | 303 | "procuringEntity": { |
303 | 304 | "identifier": { |
... | ... | @@ -349,6 +350,12 @@ def test_tender_data_planning(params): |
349 | 350 | data["tender"]["procurementMethod"] = "open" |
350 | 351 | if params['mode'] in mode_limited: |
351 | 352 | data["tender"]["procurementMethod"] = "limited" |
353 | + if params.get('number_of_breakdown'): | |
354 | + value_data = breakdown_value_generation(params['number_of_breakdown'], data['budget']['amount']) | |
355 | + for value in value_data: | |
356 | + breakdown_element = test_breakdown_data() | |
357 | + breakdown_element['value']['amount'] = value | |
358 | + data['budget']['breakdown'].append(breakdown_element) | |
352 | 359 | return munchify(data) |
353 | 360 | |
354 | 361 | |
... | ... | @@ -784,7 +791,6 @@ def test_modification_data(item_id, field_name, field_value): |
784 | 791 | return munchify({'data':data}) |
785 | 792 | |
786 | 793 | |
787 | - | |
788 | 794 | def get_hash(file_contents): |
789 | 795 | return ("md5:"+hashlib.md5(file_contents).hexdigest()) |
790 | 796 | |
... | ... | @@ -970,3 +976,39 @@ def invalid_buyers_data(): |
970 | 976 | "name": "Київський Тестовий Ліцей" |
971 | 977 | } |
972 | 978 | return munchify(buyers) |
979 | + | |
980 | + | |
981 | +def test_plan_cancel_data(): | |
982 | + plan_cancel = { | |
983 | + "cancellation": { | |
984 | + "reason": "Підстава для скасування", | |
985 | + "reason_en": "Reason of the cancellation" | |
986 | + } | |
987 | + } | |
988 | + return munchify(plan_cancel) | |
989 | + | |
990 | + | |
991 | +def test_confirm_plan_cancel_data(): | |
992 | + return munchify({ | |
993 | + "data": { | |
994 | + "cancellation": { | |
995 | + "status": "active" | |
996 | + } | |
997 | + } | |
998 | + }) | |
999 | + | |
1000 | + | |
1001 | +def test_breakdown_data(): | |
1002 | + return munchify({ | |
1003 | + "title": random.choice(["state", "local"]), | |
1004 | + "description": fake.description(), | |
1005 | + "value": { | |
1006 | + "currency": "UAH" | |
1007 | + } | |
1008 | + }) | |
1009 | + | |
1010 | + | |
1011 | +def breakdown_value_generation(number_of_breakdown, plan_value): | |
1012 | + value_data = [round(random.uniform(1, plan_value / number_of_breakdown), 2) for _ in range(number_of_breakdown - 1)] | |
1013 | + value_data.append(plan_value - sum(value_data)) | |
1014 | + return value_data | ... | ... |
... | ... | @@ -28,6 +28,11 @@ Test Suite Teardown |
28 | 28 | Run Keyword And Ignore Error Створити артефакт |
29 | 29 | |
30 | 30 | |
31 | +Test Suite Teardown Plan | |
32 | + Close all browsers | |
33 | + Run Keyword And Ignore Error Створити артефакт план | |
34 | + | |
35 | + | |
31 | 36 | Set Suite Variable With Default Value |
32 | 37 | [Arguments] ${suite_var} ${def_value} |
33 | 38 | ${tmp}= Get Variable Value ${${suite_var}} ${def_value} |
... | ... | @@ -188,6 +193,23 @@ Get Broker Property By Username |
188 | 193 | log_object_data ${artifact} file_name=artifact update=${True} artifact=${True} |
189 | 194 | |
190 | 195 | |
196 | +Створити артефакт план | |
197 | + ${artifact}= Create Dictionary | |
198 | + ... api_version=${API_VERSION} | |
199 | + ... tender_uaid=${TENDER['TENDER_UAID']} | |
200 | + ... last_modification_date=${TENDER['LAST_MODIFICATION_DATE']} | |
201 | + ... mode=${MODE} | |
202 | + Run Keyword And Ignore Error Set To Dictionary ${artifact} | |
203 | + ... tender_owner=${USERS.users['${tender_owner}'].broker} | |
204 | + ... access_token=${USERS.users['${tender_owner}'].access_token} | |
205 | + ... tender_id=${USERS.users['${tender_owner}'].tender_data.data.id} | |
206 | + ... tender_owner_access_token=${USERS.users['${tender_owner}'].access_token} | |
207 | + Run Keyword And Ignore Error Set To Dictionary ${artifact} | |
208 | + ... tender_file_properties=${USERS.users['${tender_owner}'].tender_document.file_properties} | |
209 | + Log ${artifact} | |
210 | + log_object_data ${artifact} file_name=artifact_plan update=${True} artifact=${True} | |
211 | + | |
212 | + | |
191 | 213 | Завантажити дані про тендер |
192 | 214 | ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact.yaml |
193 | 215 | ${ARTIFACT}= load_data_from ${file_path} |
... | ... | @@ -336,6 +358,19 @@ Get Broker Property By Username |
336 | 358 | ... document=${document} |
337 | 359 | ... description=${new_description} |
338 | 360 | ${cancellation_data}= munchify ${cancellation_data} |
361 | + Log ${cancellation_data} | |
362 | + [Return] ${cancellation_data} | |
363 | + | |
364 | + | |
365 | +Підготувати дані про скасування плану | |
366 | + ${cancellation_reason}= create_fake_sentence | |
367 | + ${cancellation_reason_en}= create_fake_sentence | |
368 | + ${cancellation_data}= Create Dictionary | |
369 | + ... reason=${cancellation_reason} | |
370 | + ... reason_en=${cancellation_reason_en} | |
371 | + ${cancellation_data}= munchify ${cancellation_data} | |
372 | + #${cancellation_data}= test_plan_cancel_data | |
373 | + Log ${cancellation_data} | |
339 | 374 | [Return] ${cancellation_data} |
340 | 375 | |
341 | 376 | |
... | ... | @@ -951,6 +986,12 @@ Require Failure |
951 | 986 | [Arguments] ${username} ${tender_uaid} ${left} |
952 | 987 | ${right}= Run as ${username} Отримати інформацію із тендера ${tender_uaid} status |
953 | 988 | Порівняти об'єкти ${left} ${right} |
989 | + Порівняти об'єкти ${left} ${right} | |
990 | + | |
991 | + | |
992 | +Звірити статус плану | |
993 | + [Arguments] ${username} ${tender_uaid} ${left} | |
994 | + ${right}= Run as ${username} Отримати інформацію із плану ${tender_uaid} status | |
954 | 995 | |
955 | 996 | |
956 | 997 | Звірити статус об'єкта моніторингу | ... | ... |
... | ... | @@ -263,6 +263,15 @@ ${PLAN_TENDER} ${True} |
263 | 263 | Run Keyword And Expect Error * Можливість оголосити тендер з використанням валідації план-тендер ${4} |
264 | 264 | |
265 | 265 | |
266 | +Перевірити статус плану - завершено | |
267 | + [Tags] ${USERS.users['${tender_owner}'].broker}: Відображення основних даних плану | |
268 | + ... tender_owner | |
269 | + ... ${USERS.users['${tender_owner}'].broker} | |
270 | + ... plan_status_complete_view | |
271 | + ... critical | |
272 | + Можливість перевірити статус плану після публікації тендера | |
273 | + | |
274 | + | |
266 | 275 | Можливість знайти тендер по ідентифікатору |
267 | 276 | [Tags] ${USERS.users['${viewer}'].broker}: Пошук тендера |
268 | 277 | ... viewer tender_owner provider provider1 | ... | ... |
1 | 1 | *** Settings *** |
2 | 2 | Resource base_keywords.robot |
3 | 3 | Suite Setup Test Suite Setup |
4 | -Suite Teardown Test Suite Teardown | |
4 | +Suite Teardown Test Suite Teardown Plan | |
5 | 5 | |
6 | 6 | *** Variables *** |
7 | 7 | ${RESOURCE} plans |
... | ... | @@ -14,6 +14,7 @@ ${ITEM_MEAT} ${False} |
14 | 14 | ${MOZ_INTEGRATION} ${False} |
15 | 15 | ${ROAD_INDEX} ${False} |
16 | 16 | ${GMDN_INDEX} ${False} |
17 | +${NUMBER_OF_BREAKDOWN} ${2} | |
17 | 18 | |
18 | 19 | *** Test Cases *** |
19 | 20 | Неможливість створити план закупівлі з двома buyers |
... | ... | @@ -55,6 +56,16 @@ ${GMDN_INDEX} ${False} |
55 | 56 | Можливість знайти план по ідентифікатору |
56 | 57 | |
57 | 58 | |
59 | +Відображення статусу плану - заплановано | |
60 | + [Tags] ${USERS.users['${tender_owner}'].broker}: Відображення основних даних плану | |
61 | + ... tender_owner | |
62 | + ... ${USERS.users['${tender_owner}'].broker} | |
63 | + ... status_sheduled_view | |
64 | + ... critical | |
65 | + [Setup] Дочекатись синхронізації з майданчиком ${tender_owner} | |
66 | + Звірити статус плану ${tender_owner} ${TENDER['TENDER_UAID']} scheduled | |
67 | + | |
68 | + | |
58 | 69 | Відображення типу запланованого тендера |
59 | 70 | [Tags] ${USERS.users['${viewer}'].broker}: Відображення основних даних плану |
60 | 71 | ... viewer |
... | ... | @@ -265,8 +276,7 @@ ${GMDN_INDEX} ${False} |
265 | 276 | ... critical |
266 | 277 | [Setup] Дочекатись синхронізації з майданчиком ${tender_owner} |
267 | 278 | [Teardown] Оновити LAST_MODIFICATION_DATE |
268 | - ${new_amount}= create_fake_value_amount | |
269 | - Можливість змінити поле budget.amount плану на ${new_amount} | |
279 | + Можливість змінити на 150 відсотки бюджет плану | |
270 | 280 | |
271 | 281 | |
272 | 282 | Можливість змінити кінцеву дату доставки |
... | ... | @@ -337,3 +347,22 @@ ${GMDN_INDEX} ${False} |
337 | 347 | [Teardown] Оновити LAST_MODIFICATION_DATE |
338 | 348 | ${new_period}= create_fake_period days=${1460} |
339 | 349 | Можливість змінити поле budget.period плану на ${new_period} |
350 | + | |
351 | + | |
352 | +Можливість скасувати план | |
353 | + [Tags] ${USERS.users['${tender_owner}'].broker}: Скасування плану | |
354 | + ... tender_owner | |
355 | + ... ${USERS.users['${tender_owner}'].broker} | |
356 | + ... plan_cancellation | |
357 | + [Teardown] Оновити LAST_MODIFICATION_DATE | |
358 | + Можливість скасувати план | |
359 | + | |
360 | + | |
361 | +Відображення статусу плану - скасовано | |
362 | + [Tags] ${USERS.users['${tender_owner}'].broker}: Відображення основних даних плану | |
363 | + ... tender_owner | |
364 | + ... ${USERS.users['${tender_owner}'].broker} | |
365 | + ... status_cancelled_view | |
366 | + ... critical | |
367 | + [Setup] Дочекатись синхронізації з майданчиком ${tender_owner} | |
368 | + Звірити статус плану ${tender_owner} ${TENDER['TENDER_UAID']} cancelled | |
\ No newline at end of file | ... | ... |
... | ... | @@ -78,7 +78,9 @@ from .initial_data import ( |
78 | 78 | invalid_INN_data, |
79 | 79 | invalid_cost_data, |
80 | 80 | invalid_gmdn_data, |
81 | - invalid_buyers_data | |
81 | + invalid_buyers_data, | |
82 | + test_plan_cancel_data, | |
83 | + test_confirm_plan_cancel_data | |
82 | 84 | ) |
83 | 85 | from barbecue import chef |
84 | 86 | from restkit import request | ... | ... |
1 | +-v MODE:negotiation | |
2 | + | |
3 | +-v NUMBER_OF_ITEMS:2 | |
4 | +-v NUMBER_OF_LOTS:0 | |
5 | + | |
6 | +-i create_tender | |
7 | +-i add_tender_doc | |
8 | +-i add_award | |
9 | +-i find_tender | |
10 | +-i tender_view_milestone | |
11 | +-i tender_view | |
12 | +-i add_tender_doc | |
13 | +-i award_view | |
14 | +-i add_contract | |
15 | +-i modify_contract_amount_net | |
16 | +-i modify_contract_value | |
17 | + | ... | ... |
1 | +-v MODE:negotiation | |
2 | + | |
3 | +-v NUMBER_OF_ITEMS:2 | |
4 | +-v NUMBER_OF_LOTS:0 | |
5 | + | |
6 | +-i create_tender | |
7 | +-i add_tender_doc | |
8 | +-i add_award | |
9 | +-i find_tender | |
10 | +-i tender_view_title | |
11 | +-i tender_view | |
12 | +-i tender_view_description | |
13 | +-i tender_view_cause_description | |
14 | +-i tender_view_cause | |
15 | +-i tender_view_milestone | |
16 | +-i tender_view_contactPoint_url | |
17 | +-i tender_view_unit_code | |
18 | +-i tender_view_delivery_address | |
19 | +-i add_tender_doc | |
20 | +-i award_view | |
21 | +-i add_contract | |
22 | +-i modify_contract_amount_net | |
23 | +-i modify_contract_value | |
24 | + | ... | ... |
Please
register
or
login
to post a comment