commit
15cc01ed39
@ -0,0 +1,28 @@
|
|||||||
|
"""add jedi clin type to clin table
|
||||||
|
|
||||||
|
Revision ID: c19d6129cca1
|
||||||
|
Revises: 988f8b23fbf6
|
||||||
|
Create Date: 2019-06-04 11:30:25.283028
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'c19d6129cca1'
|
||||||
|
down_revision = '988f8b23fbf6'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('clins', sa.Column('jedi_clin_type', sa.Enum('JEDI_CLIN_1', 'JEDI_CLIN_2', 'JEDI_CLIN_3', 'JEDI_CLIN_4', name='jediclintype', native_enum=False), nullable=False))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('clins', 'jedi_clin_type')
|
||||||
|
# ### end Alembic commands ###
|
@ -6,7 +6,8 @@ from sqlalchemy.ext.hybrid import hybrid_property
|
|||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from werkzeug.datastructures import FileStorage
|
from werkzeug.datastructures import FileStorage
|
||||||
|
|
||||||
from atst.models import Attachment, Base, types, mixins
|
from atst.models import Attachment, Base, mixins, types
|
||||||
|
from atst.models.clin import JEDICLINType
|
||||||
|
|
||||||
|
|
||||||
class Status(Enum):
|
class Status(Enum):
|
||||||
@ -33,6 +34,8 @@ class TaskOrder(Base, mixins.TimestampsMixin):
|
|||||||
signer_dod_id = Column(String)
|
signer_dod_id = Column(String)
|
||||||
signed_at = Column(DateTime)
|
signed_at = Column(DateTime)
|
||||||
|
|
||||||
|
clins = relationship("CLIN")
|
||||||
|
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
def pdf(self):
|
def pdf(self):
|
||||||
return self._pdf
|
return self._pdf
|
||||||
@ -83,9 +86,26 @@ class TaskOrder(Base, mixins.TimestampsMixin):
|
|||||||
return (self.end_date - date.today()).days
|
return (self.end_date - date.today()).days
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
def total_obligated_funds(self):
|
||||||
|
total = 0
|
||||||
|
for clin in self.clins:
|
||||||
|
if clin.jedi_clin_type in [
|
||||||
|
JEDICLINType.JEDI_CLIN_1,
|
||||||
|
JEDICLINType.JEDI_CLIN_3,
|
||||||
|
]:
|
||||||
|
total += clin.obligated_amount
|
||||||
|
return total
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_contract_amount(self):
|
||||||
|
total = 0
|
||||||
|
for clin in self.clins:
|
||||||
|
total += clin.obligated_amount
|
||||||
|
return total
|
||||||
|
|
||||||
|
@property
|
||||||
|
# TODO delete when we delete task_order_review flow
|
||||||
def budget(self):
|
def budget(self):
|
||||||
# TODO: fix task order -- reimplement using CLINs
|
|
||||||
# Faked for display purposes
|
|
||||||
return 100000
|
return 100000
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
margin-top: $gap * 2;
|
margin-top: $gap * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.to-sidebar {
|
.totals-box {
|
||||||
padding: $gap * 4;
|
padding: $gap * 4;
|
||||||
padding-top: $gap * 2;
|
padding-top: $gap * 2;
|
||||||
flex-grow: unset;
|
flex-grow: unset;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
{% macro TOSidebar() -%}
|
{% macro TotalsBox(task_order) -%}
|
||||||
|
|
||||||
<div class="col to-sidebar">
|
<div class="col totals-box">
|
||||||
<div class="h4">Total obligated funds</div>
|
<div class="h4">Total obligated funds</div>
|
||||||
<div class="h3">$500,000</div>
|
<div class="h3">{{ task_order.total_obligated_funds | dollars }}</div>
|
||||||
<div>This is the funding allocated to cloud services. It may be 100% or a portion of the total task order budget.</div>
|
<div>This is the funding allocated to cloud services. It may be 100% or a portion of the total task order budget.</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div class="h4">Total contract amount</div>
|
<div class="h4">Total contract amount</div>
|
||||||
<div class="h3">$800,000</div>
|
<div class="h3">{{ task_order.total_contract_amount | dollars }}</div>
|
||||||
<div>This is the value of all funds obligated for this contract, including -- but not limited to -- funds obligated for the cloud.</div>
|
<div>This is the value of all funds obligated for this contract, including -- but not limited to -- funds obligated for the cloud.</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
@ -1,7 +1,7 @@
|
|||||||
{% extends 'portfolios/base.html' %}
|
{% extends 'portfolios/base.html' %}
|
||||||
|
|
||||||
{% from "components/icon.html" import Icon %}
|
{% from "components/icon.html" import Icon %}
|
||||||
{% from "components/to_sidebar.html" import TOSidebar %}
|
{% from "components/totals_box.html" import TotalsBox %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@
|
|||||||
<div class="h4">{{ Icon('ok',classes="icon-validation") }}document</div>
|
<div class="h4">{{ Icon('ok',classes="icon-validation") }}document</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ TOSidebar() }}
|
{{ TotalsBox(task_order=task_order) }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -269,6 +269,18 @@ class TaskOrderFactory(Base):
|
|||||||
number = factory.LazyFunction(random_task_order_number)
|
number = factory.LazyFunction(random_task_order_number)
|
||||||
|
|
||||||
|
|
||||||
|
class CLINFactory(Base):
|
||||||
|
class Meta:
|
||||||
|
model = CLIN
|
||||||
|
|
||||||
|
task_order = factory.SubFactory(TaskOrderFactory)
|
||||||
|
number = factory.LazyFunction(random_task_order_number)
|
||||||
|
start_date = datetime.date.today()
|
||||||
|
end_date = factory.LazyFunction(random_future_date)
|
||||||
|
obligated_amount = random.randint(100, 999999)
|
||||||
|
jedi_clin_type = random.choice([e.value for e in clin.JEDICLINType])
|
||||||
|
|
||||||
|
|
||||||
class NotificationRecipientFactory(Base):
|
class NotificationRecipientFactory(Base):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NotificationRecipient
|
model = NotificationRecipient
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
from werkzeug.datastructures import FileStorage
|
from werkzeug.datastructures import FileStorage
|
||||||
import pytest, datetime
|
import pytest, datetime
|
||||||
|
|
||||||
from atst.models.attachment import Attachment
|
from atst.models import *
|
||||||
|
from atst.models.clin import JEDICLINType
|
||||||
from atst.models.task_order import TaskOrder, Status
|
from atst.models.task_order import TaskOrder, Status
|
||||||
|
|
||||||
from tests.factories import random_future_date, random_past_date
|
from tests.factories import (
|
||||||
|
CLINFactory,
|
||||||
|
random_future_date,
|
||||||
|
random_past_date,
|
||||||
|
TaskOrderFactory,
|
||||||
|
)
|
||||||
from tests.mocks import PDF_FILENAME
|
from tests.mocks import PDF_FILENAME
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +36,33 @@ class TestTaskOrderStatus:
|
|||||||
assert to.status == Status.EXPIRED
|
assert to.status == Status.EXPIRED
|
||||||
|
|
||||||
|
|
||||||
|
class TestBudget:
|
||||||
|
def test_total_contract_amount(self):
|
||||||
|
to = TaskOrder()
|
||||||
|
assert to.total_contract_amount == 0
|
||||||
|
|
||||||
|
clin1 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_1)
|
||||||
|
clin2 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_2)
|
||||||
|
clin3 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_3)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
to.total_contract_amount
|
||||||
|
== clin1.obligated_amount + clin2.obligated_amount + clin3.obligated_amount
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_total_obligated_funds(self):
|
||||||
|
to = TaskOrder()
|
||||||
|
clin4 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_4)
|
||||||
|
assert to.total_obligated_funds == 0
|
||||||
|
|
||||||
|
clin1 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_1)
|
||||||
|
clin2 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_2)
|
||||||
|
clin3 = CLINFactory(task_order=to, jedi_clin_type=JEDICLINType.JEDI_CLIN_3)
|
||||||
|
assert (
|
||||||
|
to.total_obligated_funds == clin1.obligated_amount + clin3.obligated_amount
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestPDF:
|
class TestPDF:
|
||||||
def test_setting_pdf_with_attachment(self):
|
def test_setting_pdf_with_attachment(self):
|
||||||
to = TaskOrder()
|
to = TaskOrder()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user