Add properties to portfolio model
1. Funding duration Returns a tuple of the earliest period of performance start date and latest period of performance end date for all active task order in a portfolio. 2. Days to funding expiration Returns the numbei of days between today and the lastest period performance end date of all active task orders 3. Active task orders Returns a list of a portfolio's active task orders a
This commit is contained in:
parent
4f2a75b64f
commit
7a0dc4d264
@ -74,6 +74,49 @@ class Portfolio(
|
|||||||
if clin.is_active
|
if clin.is_active
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def active_task_orders(self):
|
||||||
|
return [task_order for task_order in self.task_orders if task_order.is_active]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def funding_duration(self):
|
||||||
|
"""
|
||||||
|
Return the earliest period of performance start date and latest period
|
||||||
|
of performance end date for all active task orders in a portfolio.
|
||||||
|
@return: (datetime.date or None, datetime.date or None)
|
||||||
|
"""
|
||||||
|
start_dates = (
|
||||||
|
task_order.start_date
|
||||||
|
for task_order in self.task_orders
|
||||||
|
if task_order.is_active
|
||||||
|
)
|
||||||
|
|
||||||
|
end_dates = (
|
||||||
|
task_order.end_date
|
||||||
|
for task_order in self.task_orders
|
||||||
|
if task_order.is_active
|
||||||
|
)
|
||||||
|
|
||||||
|
earliest_pop_start_date = min(start_dates, default=None)
|
||||||
|
latest_pop_end_date = max(end_dates, default=None)
|
||||||
|
|
||||||
|
return (earliest_pop_start_date, latest_pop_end_date)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def days_to_funding_expiration(self):
|
||||||
|
"""
|
||||||
|
Returns the number of days between today and the lastest period performance
|
||||||
|
end date of all active Task Orders
|
||||||
|
"""
|
||||||
|
return max(
|
||||||
|
(
|
||||||
|
task_order.days_to_expiration
|
||||||
|
for task_order in self.task_orders
|
||||||
|
if task_order.is_active
|
||||||
|
),
|
||||||
|
default=None,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def members(self):
|
def members(self):
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
from tests.factories import ApplicationFactory, PortfolioFactory
|
from tests.factories import (
|
||||||
|
ApplicationFactory,
|
||||||
|
PortfolioFactory,
|
||||||
|
TaskOrderFactory,
|
||||||
|
CLINFactory,
|
||||||
|
random_future_date,
|
||||||
|
random_past_date,
|
||||||
|
)
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def test_portfolio_applications_excludes_deleted():
|
def test_portfolio_applications_excludes_deleted():
|
||||||
@ -7,3 +15,73 @@ def test_portfolio_applications_excludes_deleted():
|
|||||||
ApplicationFactory.create(portfolio=portfolio, deleted=True)
|
ApplicationFactory.create(portfolio=portfolio, deleted=True)
|
||||||
assert len(portfolio.applications) == 1
|
assert len(portfolio.applications) == 1
|
||||||
assert portfolio.applications[0].id == app.id
|
assert portfolio.applications[0].id == app.id
|
||||||
|
|
||||||
|
|
||||||
|
def test_funding_duration(session):
|
||||||
|
# portfolio with active task orders
|
||||||
|
portfolio = PortfolioFactory()
|
||||||
|
|
||||||
|
funding_start_date = random_past_date()
|
||||||
|
funding_end_date = random_future_date(year_min=2)
|
||||||
|
|
||||||
|
TaskOrderFactory.create(
|
||||||
|
signed_at=random_past_date(),
|
||||||
|
portfolio=portfolio,
|
||||||
|
create_clins=[
|
||||||
|
{
|
||||||
|
"start_date": funding_start_date,
|
||||||
|
"end_date": random_future_date(year_max=1),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
TaskOrderFactory.create(
|
||||||
|
portfolio=portfolio,
|
||||||
|
signed_at=random_past_date(),
|
||||||
|
create_clins=[
|
||||||
|
{"start_date": datetime.datetime.now(), "end_date": funding_end_date,}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert portfolio.funding_duration == (funding_start_date, funding_end_date)
|
||||||
|
|
||||||
|
# empty portfolio
|
||||||
|
empty_portfolio = PortfolioFactory()
|
||||||
|
assert empty_portfolio.funding_duration == (None, None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_days_remaining(session):
|
||||||
|
# portfolio with task orders
|
||||||
|
funding_end_date = random_future_date(year_min=2)
|
||||||
|
portfolio = PortfolioFactory()
|
||||||
|
TaskOrderFactory.create(
|
||||||
|
portfolio=portfolio,
|
||||||
|
signed_at=random_past_date(),
|
||||||
|
create_clins=[{"end_date": funding_end_date}],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
portfolio.days_to_funding_expiration
|
||||||
|
== (funding_end_date - datetime.date.today()).days
|
||||||
|
)
|
||||||
|
|
||||||
|
# empty portfolio
|
||||||
|
empty_portfolio = PortfolioFactory()
|
||||||
|
assert empty_portfolio.days_to_funding_expiration == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_active_task_orders(session):
|
||||||
|
portfolio = PortfolioFactory()
|
||||||
|
TaskOrderFactory.create(
|
||||||
|
portfolio=portfolio,
|
||||||
|
signed_at=random_past_date(),
|
||||||
|
create_clins=[
|
||||||
|
{
|
||||||
|
"start_date": datetime.date(2019, 1, 1),
|
||||||
|
"end_date": datetime.date(2019, 10, 31),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
TaskOrderFactory.create(
|
||||||
|
portfolio=portfolio, signed_at=random_past_date(), clins=[CLINFactory.create()]
|
||||||
|
)
|
||||||
|
assert len(portfolio.active_task_orders) == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user