Merge pull request #387 from dod-ccpo/save-finver-draft
Save Financial Verification Draft
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
from sqlalchemy import Column, String
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from flask import current_app as app
|
||||
|
||||
from atst.models import Base, types, mixins
|
||||
from atst.database import db
|
||||
from atst.uploader import UploadError
|
||||
from atst.domain.exceptions import NotFoundError
|
||||
|
||||
|
||||
class AttachmentError(Exception):
|
||||
@@ -16,20 +19,56 @@ class Attachment(Base, mixins.TimestampsMixin):
|
||||
id = types.Id()
|
||||
filename = Column(String, nullable=False)
|
||||
object_name = Column(String, unique=True, nullable=False)
|
||||
resource = Column(String)
|
||||
resource_id = Column(UUID(as_uuid=True), index=True)
|
||||
|
||||
@classmethod
|
||||
def attach(cls, fyle):
|
||||
def attach(cls, fyle, resource=None, resource_id=None):
|
||||
try:
|
||||
filename, object_name = app.uploader.upload(fyle)
|
||||
except UploadError as e:
|
||||
raise AttachmentError("Could not add attachment. " + str(e))
|
||||
|
||||
attachment = Attachment(filename=filename, object_name=object_name)
|
||||
attachment = Attachment(
|
||||
filename=filename,
|
||||
object_name=object_name,
|
||||
resource=resource,
|
||||
resource_id=resource_id,
|
||||
)
|
||||
|
||||
db.session.add(attachment)
|
||||
db.session.commit()
|
||||
|
||||
return attachment
|
||||
|
||||
@classmethod
|
||||
def get(cls, id_):
|
||||
try:
|
||||
return db.session.query(Attachment).filter_by(id=id_).one()
|
||||
except NoResultFound:
|
||||
raise NotFoundError("attachment")
|
||||
|
||||
@classmethod
|
||||
def get_for_resource(cls, resource, resource_id):
|
||||
try:
|
||||
return (
|
||||
db.session.query(Attachment)
|
||||
.filter_by(resource=resource, resource_id=resource_id)
|
||||
.one()
|
||||
)
|
||||
except NoResultFound:
|
||||
raise NotFoundError("attachment")
|
||||
|
||||
@classmethod
|
||||
def delete_for_resource(cls, resource, resource_id):
|
||||
try:
|
||||
return (
|
||||
db.session.query(Attachment)
|
||||
.filter_by(resource=resource, resource_id=resource_id)
|
||||
.delete()
|
||||
)
|
||||
except NoResultFound:
|
||||
raise NotFoundError("attachment")
|
||||
|
||||
def __repr__(self):
|
||||
return "<Attachment(name='{}', id='{}')>".format(self.filename, self.id)
|
||||
|
@@ -1,26 +1,14 @@
|
||||
from sqlalchemy import event
|
||||
from flask import g
|
||||
import re
|
||||
|
||||
from atst.models.audit_event import AuditEvent
|
||||
from atst.utils import camel_to_snake, getattr_path
|
||||
|
||||
ACTION_CREATE = "create"
|
||||
ACTION_UPDATE = "update"
|
||||
ACTION_DELETE = "delete"
|
||||
|
||||
|
||||
def getattr_path(obj, path, default=None):
|
||||
_obj = obj
|
||||
for item in path.split("."):
|
||||
_obj = getattr(_obj, item, default)
|
||||
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()
|
||||
|
||||
|
||||
class AuditableMixin(object):
|
||||
@staticmethod
|
||||
def create_audit_event(connection, resource, action):
|
||||
|
@@ -6,6 +6,7 @@ from atst.models import Base, types, mixins
|
||||
from atst.models.request_status_event import RequestStatus
|
||||
from atst.utils import first_or_none
|
||||
from atst.models.request_revision import RequestRevision
|
||||
from atst.models.task_order import Source as TaskOrderSource
|
||||
|
||||
|
||||
def map_properties_to_dict(properties, instance):
|
||||
@@ -135,7 +136,7 @@ class Request(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
|
||||
|
||||
@property
|
||||
def financial_verification(self):
|
||||
return self.body.get("financial_verification")
|
||||
return self.body.get("financial_verification", {})
|
||||
|
||||
@property
|
||||
def is_financially_verified(self):
|
||||
@@ -224,6 +225,18 @@ class Request(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
|
||||
def contracting_officer_email(self):
|
||||
return self.latest_revision.email_co
|
||||
|
||||
@property
|
||||
def pe_number(self):
|
||||
return self.body.get("financial_verification", {}).get("pe_id")
|
||||
|
||||
@property
|
||||
def has_manual_task_order(self):
|
||||
return (
|
||||
self.task_order.source == TaskOrderSource.MANUAL
|
||||
if self.task_order is not None
|
||||
else None
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Request(status='{}', name='{}', creator='{}', is_approved='{}', time_created='{}', id='{}')>".format(
|
||||
self.status_displayname,
|
||||
|
Reference in New Issue
Block a user