Refactor Portfolio to_dictionary method
In refactoring this method, refactor some other areas: - add a property to generate a dict needed for the "initial clin" - add new relationship field to get all CLINs associated with a portfolio - add a property to either get or generate a portfolio's domain name - least importantly, sort imports - On the CLIN model, add a property to get a JEDI clin type's number, i.e. JEDI_CLIN_3 -> 3. This should be the "initial_clin_type".
This commit is contained in:
parent
d46ed2b5b4
commit
dba63cdd15
@ -333,7 +333,7 @@ def create_billing_instruction(self):
|
||||
initial_clin_amount=clin.obligated_amount,
|
||||
initial_clin_start_date=str(clin.start_date),
|
||||
initial_clin_end_date=str(clin.end_date),
|
||||
initial_clin_type=clin.number,
|
||||
initial_clin_type=clin.jedi_clin_number,
|
||||
initial_task_order_id=str(clin.task_order_id),
|
||||
)
|
||||
|
||||
|
@ -65,6 +65,10 @@ class CLIN(Base, mixins.TimestampsMixin):
|
||||
]
|
||||
)
|
||||
|
||||
@property
|
||||
def jedi_clin_number(self):
|
||||
return self.jedi_clin_type.value[-1]
|
||||
|
||||
def to_dictionary(self):
|
||||
data = {
|
||||
c.name: getattr(self, c.name)
|
||||
|
@ -1,23 +1,23 @@
|
||||
import re
|
||||
from string import ascii_lowercase, digits
|
||||
from random import choices
|
||||
from itertools import chain
|
||||
from random import choices
|
||||
from string import ascii_lowercase, digits
|
||||
from typing import Dict
|
||||
|
||||
from sqlalchemy import Column, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.types import ARRAY
|
||||
|
||||
from atst.models.base import Base
|
||||
import atst.models.types as types
|
||||
import atst.models.mixins as mixins
|
||||
from atst.models.task_order import TaskOrder
|
||||
from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus
|
||||
from atst.domain.permission_sets import PermissionSets
|
||||
from atst.utils import first_or_none
|
||||
from atst.database import db
|
||||
|
||||
from sqlalchemy_json import NestedMutableJson
|
||||
|
||||
from atst.database import db
|
||||
import atst.models.mixins as mixins
|
||||
import atst.models.types as types
|
||||
from atst.domain.permission_sets import PermissionSets
|
||||
from atst.models.base import Base
|
||||
from atst.models.portfolio_role import PortfolioRole
|
||||
from atst.models.portfolio_role import Status as PortfolioRoleStatus
|
||||
from atst.utils import first_or_none
|
||||
|
||||
|
||||
class Portfolio(
|
||||
Base, mixins.TimestampsMixin, mixins.AuditableMixin, mixins.DeletableMixin
|
||||
@ -54,6 +54,7 @@ class Portfolio(
|
||||
roles = relationship("PortfolioRole")
|
||||
|
||||
task_orders = relationship("TaskOrder")
|
||||
clins = relationship("CLIN", secondary="task_orders")
|
||||
|
||||
@property
|
||||
def owner_role(self):
|
||||
@ -82,13 +83,27 @@ class Portfolio(
|
||||
return len(self.task_orders)
|
||||
|
||||
@property
|
||||
def active_clins(self):
|
||||
return [
|
||||
clin
|
||||
for task_order in self.task_orders
|
||||
for clin in task_order.clins
|
||||
if clin.is_active
|
||||
]
|
||||
def initial_clin_dict(self) -> Dict:
|
||||
initial_clin = min(
|
||||
(
|
||||
clin
|
||||
for clin in self.clins
|
||||
if (clin.is_active and clin.task_order.is_signed)
|
||||
),
|
||||
key=lambda clin: clin.start_date,
|
||||
default=None,
|
||||
)
|
||||
if initial_clin:
|
||||
return {
|
||||
"initial_task_order_id": initial_clin.task_order.number,
|
||||
"initial_clin_number": initial_clin.number,
|
||||
"initial_clin_type": initial_clin.jedi_clin_number,
|
||||
"initial_clin_amount": initial_clin.obligated_amount,
|
||||
"initial_clin_start_date": initial_clin.start_date.strftime("%Y/%m/%d"),
|
||||
"initial_clin_end_date": initial_clin.end_date.strftime("%Y/%m/%d"),
|
||||
}
|
||||
else:
|
||||
return {}
|
||||
|
||||
@property
|
||||
def active_task_orders(self):
|
||||
@ -170,25 +185,33 @@ class Portfolio(
|
||||
def portfolio_id(self):
|
||||
return self.id
|
||||
|
||||
@property
|
||||
def domain_name(self):
|
||||
"""
|
||||
CSP domain name associated with portfolio.
|
||||
If a domain name is not set, generate one.
|
||||
"""
|
||||
domain_name = re.sub("[^0-9a-zA-Z]+", "", self.name).lower() + "".join(
|
||||
choices(ascii_lowercase + digits, k=4)
|
||||
)
|
||||
if self.csp_data:
|
||||
return self.csp_data.get("domain_name", domain_name)
|
||||
else:
|
||||
return domain_name
|
||||
|
||||
@property
|
||||
def application_id(self):
|
||||
return None
|
||||
|
||||
def to_dictionary(self):
|
||||
ppoc = self.owner
|
||||
user_id = f"{ppoc.first_name[0]}{ppoc.last_name}".lower()
|
||||
|
||||
domain_name = re.sub("[^0-9a-zA-Z]+", "", self.name).lower() + "".join(
|
||||
choices(ascii_lowercase + digits, k=4)
|
||||
)
|
||||
portfolio_data = {
|
||||
"user_id": user_id,
|
||||
return {
|
||||
"user_id": f"{self.owner.first_name[0]}{self.owner.last_name}".lower(),
|
||||
"password": "",
|
||||
"domain_name": domain_name,
|
||||
"first_name": ppoc.first_name,
|
||||
"last_name": ppoc.last_name,
|
||||
"domain_name": self.domain_name,
|
||||
"first_name": self.owner.first_name,
|
||||
"last_name": self.owner.last_name,
|
||||
"country_code": "US",
|
||||
"password_recovery_email_address": ppoc.email,
|
||||
"password_recovery_email_address": self.owner.email,
|
||||
"address": { # TODO: TBD if we're sourcing this from data or config
|
||||
"company_name": "",
|
||||
"address_line_1": "",
|
||||
@ -198,27 +221,9 @@ class Portfolio(
|
||||
"postal_code": "",
|
||||
},
|
||||
"billing_profile_display_name": "ATAT Billing Profile",
|
||||
**self.initial_clin_dict,
|
||||
}
|
||||
|
||||
try:
|
||||
initial_task_order: TaskOrder = self.task_orders[0]
|
||||
initial_clin = initial_task_order.clins[0]
|
||||
portfolio_data.update(
|
||||
{
|
||||
"initial_clin_amount": initial_clin.obligated_amount,
|
||||
"initial_clin_start_date": initial_clin.start_date.strftime(
|
||||
"%Y/%m/%d"
|
||||
),
|
||||
"initial_clin_end_date": initial_clin.end_date.strftime("%Y/%m/%d"),
|
||||
"initial_clin_type": initial_clin.number,
|
||||
"initial_task_order_id": initial_task_order.number,
|
||||
}
|
||||
)
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
return portfolio_data
|
||||
|
||||
def __repr__(self):
|
||||
return "<Portfolio(name='{}', user_count='{}', id='{}')>".format(
|
||||
self.name, self.user_count, self.id
|
||||
|
Loading…
x
Reference in New Issue
Block a user