Create celery task for create_billing_instruction

This commit is contained in:
leigh-mil 2020-02-12 11:20:21 -05:00
parent aa2d353260
commit 6ef3265cb5
4 changed files with 99 additions and 2 deletions

View File

@ -220,6 +220,14 @@ class BillingInstructionCSPPayload(BaseCSPPayload):
billing_account_name: str billing_account_name: str
billing_profile_name: str billing_profile_name: str
class Config:
fields = {
"initial_clin_amount": "obligated_amount",
"initial_clin_start_date": "start_date",
"initial_clin_end_date": "end_date",
"initial_clin_type": "number",
}
class BillingInstructionCSPResult(AliasModel): class BillingInstructionCSPResult(AliasModel):
reported_clin_name: str reported_clin_name: str

View File

@ -10,6 +10,7 @@ from atst.domain.csp.cloud import CloudProviderInterface
from atst.domain.csp.cloud.exceptions import GeneralCSPException from atst.domain.csp.cloud.exceptions import GeneralCSPException
from atst.domain.csp.cloud.models import ( from atst.domain.csp.cloud.models import (
ApplicationCSPPayload, ApplicationCSPPayload,
BillingInstructionCSPPayload,
EnvironmentCSPPayload, EnvironmentCSPPayload,
UserCSPPayload, UserCSPPayload,
UserRoleCSPPayload, UserRoleCSPPayload,
@ -317,3 +318,31 @@ def send_task_order_files(self):
db.session.add(task_order) db.session.add(task_order)
db.session.commit() db.session.commit()
@celery.task(bind=True)
def create_billing_instruction(self):
clins = TaskOrders.get_clins_for_create_billing_instructions()
for clin in clins:
portfolio = clin.task_order.portfolio
clin_data = clin.to_dictionary()
portfolio_data = portfolio.to_dictionary()
payload = BillingInstructionCSPPayload(
tenant_id=portfolio.csp_data.get("tenant_id"),
billing_account_name=portfolio.csp_data.get("billing_account_name"),
billing_profile_name=portfolio.csp_data.get("billing_profile_name"),
**clin_data,
**portfolio_data,
)
try:
app.csp.cloud.create_billing_instruction(payload)
except (AzureError) as err:
app.logger.exception(err)
continue
clin.last_sent_at = pendulum.now(tz="UTC")
db.session.add(clin)
db.session.commit()

View File

@ -66,11 +66,15 @@ class CLIN(Base, mixins.TimestampsMixin):
) )
def to_dictionary(self): def to_dictionary(self):
return { data = {
c.name: getattr(self, c.name) c.name: getattr(self, c.name)
for c in self.__table__.columns for c in self.__table__.columns
if c.name not in ["id"] if c.name not in ["id"]
} }
data["start_date"] = str(data["start_date"])
data["end_date"] = str(data["end_date"])
return data
@property @property
def is_active(self): def is_active(self):

View File

@ -6,7 +6,8 @@ from smtplib import SMTPException
from azure.core.exceptions import AzureError from azure.core.exceptions import AzureError
from atst.domain.csp.cloud import MockCloudProvider from atst.domain.csp.cloud import MockCloudProvider
from atst.domain.csp.cloud.models import UserRoleCSPResult from atst.domain.csp.cloud.models import BillingInstructionCSPPayload, UserRoleCSPResult
from atst.domain.portfolios import Portfolios
from atst.models import ApplicationRoleStatus, Portfolio, FSMStates from atst.models import ApplicationRoleStatus, Portfolio, FSMStates
from atst.jobs import ( from atst.jobs import (
@ -16,6 +17,7 @@ from atst.jobs import (
dispatch_create_user, dispatch_create_user,
dispatch_create_environment_role, dispatch_create_environment_role,
dispatch_provision_portfolio, dispatch_provision_portfolio,
create_billing_instruction,
create_environment, create_environment,
do_create_user, do_create_user,
do_provision_portfolio, do_provision_portfolio,
@ -489,3 +491,57 @@ class TestSendTaskOrderFiles:
# Check that pdf_last_sent_at has not been updated # Check that pdf_last_sent_at has not been updated
assert not task_order.pdf_last_sent_at assert not task_order.pdf_last_sent_at
class TestCreateBillingInstructions:
def test_update_clin_last_sent_at(self, session):
# create portfolio with one active clin
start_date = pendulum.now().subtract(days=1)
portfolio = PortfolioFactory.create(
csp_data={
"tenant_id": str(uuid4()),
"billing_account_name": "fake",
"billing_profile_name": "fake",
},
task_orders=[{"create_clins": [{"start_date": start_date}]}],
)
unsent_clin = portfolio.task_orders[0].clins[0]
assert not unsent_clin.last_sent_at
# The session needs to be nested to prevent detached SQLAlchemy instance
session.begin_nested()
create_billing_instruction()
session.rollback()
# check that last_sent_at has been updated
assert unsent_clin.last_sent_at
def test_failure(self, monkeypatch, session):
def _create_billing_instruction(MockCloudProvider, object_name):
raise AzureError("something went wrong")
monkeypatch.setattr(
"atst.domain.csp.cloud.MockCloudProvider.create_billing_instruction",
_create_billing_instruction,
)
# create portfolio with one active clin
start_date = pendulum.now().subtract(days=1)
portfolio = PortfolioFactory.create(
csp_data={
"tenant_id": str(uuid4()),
"billing_account_name": "fake",
"billing_profile_name": "fake",
},
task_orders=[{"create_clins": [{"start_date": start_date}]}],
)
unsent_clin = portfolio.task_orders[0].clins[0]
# The session needs to be nested to prevent detached SQLAlchemy instance
session.begin_nested()
create_billing_instruction()
session.rollback()
# check that last_sent_at has not been updated
assert not unsent_clin.last_sent_at