From 39bbfb745ad0567db8cee25fbb831bb4adb42266 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Mon, 22 Oct 2018 16:16:58 -0400 Subject: [PATCH] Fix task order creation --- atst/domain/requests/requests.py | 12 +++--- atst/domain/task_orders.py | 11 +++++- .../routes/requests/financial_verification.py | 38 ++++++++++++++----- atst/utils/__init__.py | 22 ++++++++++- tests/domain/test_task_orders.py | 10 ----- tests/routes/test_financial_verification.py | 17 +++++++++ 6 files changed, 81 insertions(+), 29 deletions(-) diff --git a/atst/domain/requests/requests.py b/atst/domain/requests/requests.py index 028739c9..1f8adf12 100644 --- a/atst/domain/requests/requests.py +++ b/atst/domain/requests/requests.py @@ -5,17 +5,12 @@ from atst.models.request_revision import RequestRevision from atst.models.request_status_event import RequestStatusEvent, RequestStatus from atst.models.request_review import RequestReview from atst.models.request_internal_comment import RequestInternalComment -from atst.utils import deep_merge +from atst.utils import deep_merge, pick from .query import RequestsQuery from .authorization import RequestsAuthorization -def pick(keys, d): - _keys = set(keys) - return {k: v for (k, v) in d.items() if k in _keys} - - def create_revision_from_request_body(body): body = {k: v for p in body.values() for k, v in p.items()} DATES = ["start_date", "date_latest_training"] @@ -79,7 +74,10 @@ class Requests(object): @classmethod def update(cls, request_id, request_delta): request = RequestsQuery.get_with_lock(request_id) + return Requests._update(request, request_delta) + @classmethod + def _update(cls, request, request_delta): new_body = deep_merge(request_delta, request.body) revision = create_revision_from_request_body(new_body) request.revisions.append(revision) @@ -183,7 +181,7 @@ class Requests(object): if task_order: request.task_order = task_order - request = Requests.update(request.id, {"financial_verification": delta}) + request = Requests._update(request, {"financial_verification": delta}) return request diff --git a/atst/domain/task_orders.py b/atst/domain/task_orders.py index c01a38f9..539c4682 100644 --- a/atst/domain/task_orders.py +++ b/atst/domain/task_orders.py @@ -5,6 +5,7 @@ from atst.database import db from atst.models.task_order import TaskOrder, Source, FundingType from atst.models.attachment import Attachment from .exceptions import NotFoundError +from atst.utils import drop, update_obj class TaskOrders(object): @@ -38,7 +39,8 @@ class TaskOrders(object): @classmethod def create(cls, **kwargs): - task_order = TaskOrder(**kwargs) + to_data = drop(["source"], kwargs) + task_order = TaskOrder(source=Source.MANUAL, **to_data) db.session.add(task_order) db.session.commit() @@ -75,3 +77,10 @@ class TaskOrders(object): return TaskOrders.create( **data, number=number, pdf=attachment, source=Source.MANUAL ) + + @classmethod + def update(cls, task_order, dct): + updated = update_obj(task_order, dct) + db.session.add(updated) + db.session.commit() + return updated diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index bc052c4d..63064a53 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -13,7 +13,7 @@ from atst.domain.requests.financial_verification import ( ) from atst.models.attachment import Attachment from atst.domain.task_orders import TaskOrders -from atst.utils import getattr_path +from atst.utils import getattr_path, update_obj def fv_extended(_http_request): @@ -73,15 +73,33 @@ class FinancialVerificationBase(object): def _try_create_task_order(self, form, attachment): form_data = form.data - task_order_number = form_data.get("task_order_number") - if task_order_number: - task_order_data = { - k: v for (k, v) in form_data.items() if k in TaskOrders.TASK_ORDER_DATA - } - return TaskOrders.get_or_create( - task_order_number, attachment=attachment, data=task_order_data - ) - return None + task_order_number = form_data.pop("task_order_number") + if task_order_number is None: + return None + + task_order_data = { + k: v for (k, v) in form_data.items() if k in TaskOrders.TASK_ORDER_DATA + } + task_order_data["number"] = task_order_number + funding_type = getattr_path(form_data, "funding_type.data") + task_order_data["funding_type"] = funding_type if funding_type != "" else None + + if attachment: + task_order_data["pdf"] = attachment + + try: + task_order = TaskOrders.get(task_order_number) + task_order = TaskOrders.update(task_order, task_order_data) + return task_order + except NotFoundError: + pass + + try: + return TaskOrders._get_from_eda(task_order_number) + except NotFoundError: + pass + + return TaskOrders.create(**task_order_data) def _apply_pe_number_error(self, field): suggestion = self.pe_validator.suggest_pe_id(field.data) diff --git a/atst/utils/__init__.py b/atst/utils/__init__.py index 51eb9b01..d5c846e3 100644 --- a/atst/utils/__init__.py +++ b/atst/utils/__init__.py @@ -26,10 +26,30 @@ def deep_merge(source, destination: dict): def getattr_path(obj, path, default=None): _obj = obj for item in path.split("."): - _obj = getattr(_obj, item, default) + if isinstance(_obj, dict): + _obj = _obj.get(item) + else: + _obj = getattr(_obj, item, default) return _obj +def update_obj(obj, dct): + for k, v in dct.items(): + if hasattr(obj, k) and v is not None: + setattr(obj, k, v) + return obj + + def camel_to_snake(camel_cased): s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", camel_cased) return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower() + + +def drop(keys, dct): + _keys = set(keys) + return {k: v for k, v in dct.items() if k not in _keys} + + +def pick(keys, dct): + _keys = set(keys) + return {k: v for (k, v) in dct.items() if k in _keys} diff --git a/tests/domain/test_task_orders.py b/tests/domain/test_task_orders.py index cc83d284..ebdbf4d3 100644 --- a/tests/domain/test_task_orders.py +++ b/tests/domain/test_task_orders.py @@ -15,16 +15,6 @@ def test_can_get_task_order(): assert to.id == to.id -def test_can_get_task_order_from_eda(monkeypatch): - monkeypatch.setattr( - "atst.domain.task_orders.TaskOrders._client", lambda: MockEDAClient() - ) - to = TaskOrders.get(MockEDAClient.MOCK_CONTRACT_NUMBER) - - assert to.number == MockEDAClient.MOCK_CONTRACT_NUMBER - assert to.source == TaskOrderSource.EDA - - def test_nonexistent_task_order_raises_without_client(): with pytest.raises(NotFoundError): TaskOrders.get("some fake number") diff --git a/tests/routes/test_financial_verification.py b/tests/routes/test_financial_verification.py index 5a492eed..0b2c10c4 100644 --- a/tests/routes/test_financial_verification.py +++ b/tests/routes/test_financial_verification.py @@ -226,6 +226,23 @@ def test_can_save_draft_with_just_pdf(extended_financial_verification_data): assert form.task_order +def test_task_order_info_present_in_extended_form( + fv_data, extended_financial_verification_data +): + request = RequestFactory.create() + user = UserFactory.create() + data = { + "clin_0001": extended_financial_verification_data["clin_0001"], + "task_order_number": fv_data["task_order_number"], + } + SaveFinancialVerificationDraft( + TrueValidator, TrueValidator, user, request, data, is_extended=True + ).execute() + + form = GetFinancialVerificationForm(user, request, is_extended=True).execute() + assert form.clin_0001.data + + def test_update_fv_route(client, user_session, fv_data): user = UserFactory.create() request = RequestFactory.create(creator=user)