Merge pull request #387 from dod-ccpo/save-finver-draft

Save Financial Verification Draft
This commit is contained in:
richard-dds
2018-10-29 10:26:30 -04:00
committed by GitHub
19 changed files with 1104 additions and 629 deletions

View File

@@ -0,0 +1,74 @@
import re
from atst.domain.task_orders import TaskOrders
from atst.domain.pe_numbers import PENumbers
from atst.domain.exceptions import NotFoundError
class PENumberValidator(object):
PE_REGEX = re.compile(
r"""
(0?\d) # program identifier
(0?\d) # category
(\d) # activity
(\d+) # sponsor element
(.+) # service
""",
re.X,
)
def validate(self, request, field):
if field.errors:
return False
if self._same_as_previous(request, field.data):
return True
try:
PENumbers.get(field.data)
except NotFoundError:
self._apply_error(field)
return False
return True
def suggest_pe_id(self, pe_id):
suggestion = pe_id
match = self.PE_REGEX.match(pe_id)
if match:
(program, category, activity, sponsor, service) = match.groups()
if len(program) < 2:
program = "0" + program
if len(category) < 2:
category = "0" + category
suggestion = "".join((program, category, activity, sponsor, service))
if suggestion != pe_id:
return suggestion
return None
def _same_as_previous(self, request, pe_id):
return request.pe_number == pe_id
def _apply_error(self, field):
suggestion = self.suggest_pe_id(field.data)
error_str = (
"We couldn't find that PE number. {}"
"If you have double checked it you can submit anyway. "
"Your request will need to go through a manual review."
).format('Did you mean "{}"? '.format(suggestion) if suggestion else "")
field.errors += (error_str,)
class TaskOrderNumberValidator(object):
def validate(self, field):
try:
TaskOrders.get(field.data)
except NotFoundError:
self._apply_error(field)
return False
return True
def _apply_error(self, field):
field.errors += ("Task Order number not found",)

View File

@@ -1,7 +1,5 @@
from werkzeug.datastructures import FileStorage
import dateutil
from atst.domain.task_orders import TaskOrders
from atst.domain.workspaces import Workspaces
from atst.models.request_revision import RequestRevision
from atst.models.request_status_event import RequestStatusEvent, RequestStatus
@@ -76,14 +74,15 @@ 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)
request = RequestsQuery.add_and_commit(request)
return request
return RequestsQuery.add_and_commit(request)
@classmethod
def approve_and_create_workspace(cls, request):
@@ -156,35 +155,12 @@ class Requests(object):
return Requests.status_count(RequestStatus.APPROVED)
@classmethod
def update_financial_verification(cls, request_id, financial_data):
def update_financial_verification(cls, request_id, financial_data, task_order=None):
request = RequestsQuery.get_with_lock(request_id)
request_data = financial_data.copy()
task_order_data = {
k: request_data.pop(k)
for (k, v) in financial_data.items()
if k in TaskOrders.TASK_ORDER_DATA
}
if task_order_data:
task_order_number = request_data.pop("task_order_number")
else:
task_order_number = request_data.get("task_order_number")
if "task_order" in request_data and isinstance(
request_data["task_order"], FileStorage
):
task_order_data["pdf"] = request_data.pop("task_order")
task_order = TaskOrders.get_or_create_task_order(
task_order_number, task_order_data
)
if task_order:
request.task_order = task_order
request = Requests.update(request.id, {"financial_verification": request_data})
request = Requests._update(request, {"financial_verification": financial_data})
return request
@classmethod

View File

@@ -2,9 +2,9 @@ from sqlalchemy.orm.exc import NoResultFound
from flask import current_app as app
from atst.database import db
from atst.models.task_order import TaskOrder, Source
from atst.models.attachment import Attachment
from atst.models.task_order import TaskOrder, Source, FundingType
from .exceptions import NotFoundError
from atst.utils import update_obj
class TaskOrders(object):
@@ -18,25 +18,28 @@ class TaskOrders(object):
)
except NoResultFound:
if TaskOrders._client():
task_order = TaskOrders._get_from_eda(order_number)
task_order = TaskOrders.get_from_eda(order_number)
else:
raise NotFoundError("task_order")
return task_order
@classmethod
def _get_from_eda(cls, order_number):
def get_from_eda(cls, order_number):
to_data = TaskOrders._client().get_contract(order_number, status="y")
if to_data:
# TODO: we need to determine exactly what we're getting and storing from the EDA client
return TaskOrders.create(source=Source.EDA, **to_data)
return TaskOrders.create(
source=Source.EDA, funding_type=FundingType.PROC, **to_data
)
else:
raise NotFoundError("task_order")
@classmethod
def create(cls, **kwargs):
task_order = TaskOrder(**kwargs)
def create(cls, source=Source.MANUAL, **kwargs):
to_data = {k: v for k, v in kwargs.items() if v not in ["", None]}
task_order = TaskOrder(source=source, **to_data)
db.session.add(task_order)
db.session.commit()
@@ -48,18 +51,8 @@ class TaskOrders(object):
return app.eda_client
@classmethod
def get_or_create_task_order(cls, number, task_order_data=None):
try:
return TaskOrders.get(number)
except NotFoundError:
if task_order_data:
pdf_file = task_order_data.pop("pdf")
# should catch the error here
attachment = Attachment.attach(pdf_file)
return TaskOrders.create(
**task_order_data,
number=number,
source=Source.MANUAL,
pdf=attachment,
)
def update(cls, task_order, dct):
updated = update_obj(task_order, dct, ignore_vals=lambda v: v in ["", None])
db.session.add(updated)
db.session.commit()
return updated