Add celery task for finding unsent TO and sending them to Microsoft
This commit is contained in:
parent
6ec9fb34f9
commit
0af29f485e
@ -1,4 +1,4 @@
|
|||||||
import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
|
|
||||||
from atst.database import db
|
from atst.database import db
|
||||||
@ -41,7 +41,7 @@ class TaskOrders(BaseDomainClass):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def sign(cls, task_order, signer_dod_id):
|
def sign(cls, task_order, signer_dod_id):
|
||||||
task_order.signer_dod_id = signer_dod_id
|
task_order.signer_dod_id = signer_dod_id
|
||||||
task_order.signed_at = datetime.datetime.now()
|
task_order.signed_at = datetime.now()
|
||||||
|
|
||||||
db.session.add(task_order)
|
db.session.add(task_order)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@ -91,3 +91,9 @@ class TaskOrders(BaseDomainClass):
|
|||||||
)
|
)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_pdf_last_sent_at(cls, task_order):
|
||||||
|
task_order.pdf_last_sent_at = datetime.now()
|
||||||
|
db.session.add(task_order)
|
||||||
|
db.session.commit()
|
||||||
|
65
atst/jobs.py
65
atst/jobs.py
@ -14,8 +14,10 @@ from atst.domain.csp.cloud.models import (
|
|||||||
from atst.domain.environments import Environments
|
from atst.domain.environments import Environments
|
||||||
from atst.domain.portfolios import Portfolios
|
from atst.domain.portfolios import Portfolios
|
||||||
from atst.models import JobFailure
|
from atst.models import JobFailure
|
||||||
|
from atst.domain.task_orders import TaskOrders
|
||||||
from atst.models.utils import claim_for_update, claim_many_for_update
|
from atst.models.utils import claim_for_update, claim_many_for_update
|
||||||
from atst.queue import celery
|
from atst.queue import celery
|
||||||
|
from atst.utils.localization import translate
|
||||||
|
|
||||||
|
|
||||||
class RecordFailure(celery.Task):
|
class RecordFailure(celery.Task):
|
||||||
@ -144,6 +146,14 @@ def do_provision_portfolio(csp: CloudProviderInterface, portfolio_id=None):
|
|||||||
fsm.trigger_next_transition()
|
fsm.trigger_next_transition()
|
||||||
|
|
||||||
|
|
||||||
|
def do_send_with_attachment(
|
||||||
|
csp: CloudProviderInterface, recipients, subject, body, attachments
|
||||||
|
):
|
||||||
|
app.mailer.send(
|
||||||
|
recipients=recipients, subject=subject, body=body, attachments=attachments
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@celery.task(bind=True, base=RecordFailure)
|
@celery.task(bind=True, base=RecordFailure)
|
||||||
def provision_portfolio(self, portfolio_id=None):
|
def provision_portfolio(self, portfolio_id=None):
|
||||||
do_work(do_provision_portfolio, self, app.csp.cloud, portfolio_id=portfolio_id)
|
do_work(do_provision_portfolio, self, app.csp.cloud, portfolio_id=portfolio_id)
|
||||||
@ -166,6 +176,32 @@ def create_environment(self, environment_id=None):
|
|||||||
do_work(do_create_environment, self, app.csp.cloud, environment_id=environment_id)
|
do_work(do_create_environment, self, app.csp.cloud, environment_id=environment_id)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(bind=True)
|
||||||
|
def send_with_attachment(self, recipients, subject, body, attachments):
|
||||||
|
do_work(
|
||||||
|
do_send_with_attachment,
|
||||||
|
self,
|
||||||
|
app.csp.cloud,
|
||||||
|
recipients=recipients,
|
||||||
|
subject=subject,
|
||||||
|
body=body,
|
||||||
|
attachments=attachments,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(bind=True)
|
||||||
|
def send_with_attachment(self, recipients, subject, body, attachments):
|
||||||
|
do_work(
|
||||||
|
do_send_with_attachment,
|
||||||
|
self,
|
||||||
|
app.csp.cloud,
|
||||||
|
recipients=recipients,
|
||||||
|
subject=subject,
|
||||||
|
body=body,
|
||||||
|
attachments=attachments,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@celery.task(bind=True)
|
@celery.task(bind=True)
|
||||||
def dispatch_provision_portfolio(self):
|
def dispatch_provision_portfolio(self):
|
||||||
"""
|
"""
|
||||||
@ -193,3 +229,32 @@ def dispatch_create_environment(self):
|
|||||||
pendulum.now()
|
pendulum.now()
|
||||||
):
|
):
|
||||||
create_environment.delay(environment_id=environment_id)
|
create_environment.delay(environment_id=environment_id)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(bind=True)
|
||||||
|
def dispatch_create_atat_admin_user(self):
|
||||||
|
for environment_id in Environments.get_environments_pending_atat_user_creation(
|
||||||
|
pendulum.now()
|
||||||
|
):
|
||||||
|
create_atat_admin_user.delay(environment_id=environment_id)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(bind=True)
|
||||||
|
def dispatch_send_task_order_files(self):
|
||||||
|
task_orders = TaskOrders.get_for_send_task_order_files()
|
||||||
|
recipients = app.config.get("MICROSOFT_TASK_ORDER_EMAIL_ADDRESS")
|
||||||
|
|
||||||
|
for task_order in task_orders:
|
||||||
|
subject = translate(
|
||||||
|
"email.task_order_sent.subject", {"to_number": task_order.number}
|
||||||
|
)
|
||||||
|
body = translate("email.task_order_sent.body", {"to_number": task_order.number})
|
||||||
|
|
||||||
|
file = app.csp.files.download_task_order(task_order.pdf.object_name)
|
||||||
|
file["maintype"] = "application"
|
||||||
|
file["subtype"] = "pdf"
|
||||||
|
|
||||||
|
send_with_attachment.delay(
|
||||||
|
recipients=recipients, subject=subject, body=body, attachments=[file]
|
||||||
|
)
|
||||||
|
TaskOrders.update_pdf_last_sent_at(task_order)
|
||||||
|
@ -13,6 +13,7 @@ from atst.jobs import (
|
|||||||
dispatch_create_application,
|
dispatch_create_application,
|
||||||
dispatch_create_user,
|
dispatch_create_user,
|
||||||
dispatch_provision_portfolio,
|
dispatch_provision_portfolio,
|
||||||
|
dispatch_send_task_order_files,
|
||||||
create_environment,
|
create_environment,
|
||||||
do_create_user,
|
do_create_user,
|
||||||
do_provision_portfolio,
|
do_provision_portfolio,
|
||||||
@ -20,15 +21,17 @@ from atst.jobs import (
|
|||||||
do_create_application,
|
do_create_application,
|
||||||
)
|
)
|
||||||
from tests.factories import (
|
from tests.factories import (
|
||||||
|
ApplicationFactory,
|
||||||
|
ApplicationRoleFactory,
|
||||||
EnvironmentFactory,
|
EnvironmentFactory,
|
||||||
EnvironmentRoleFactory,
|
EnvironmentRoleFactory,
|
||||||
PortfolioFactory,
|
PortfolioFactory,
|
||||||
PortfolioStateMachineFactory,
|
PortfolioStateMachineFactory,
|
||||||
ApplicationFactory,
|
TaskOrderFactory,
|
||||||
ApplicationRoleFactory,
|
|
||||||
UserFactory,
|
UserFactory,
|
||||||
)
|
)
|
||||||
from atst.models import CSPRole, EnvironmentRole, ApplicationRoleStatus, JobFailure
|
from atst.models import CSPRole, EnvironmentRole, ApplicationRoleStatus, JobFailure
|
||||||
|
from atst.utils.localization import translate
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True, scope="function")
|
@pytest.fixture(autouse=True, scope="function")
|
||||||
@ -287,3 +290,52 @@ def test_provision_portfolio_create_tenant(
|
|||||||
# monkeypatch.setattr("atst.jobs.provision_portfolio", mock)
|
# monkeypatch.setattr("atst.jobs.provision_portfolio", mock)
|
||||||
# dispatch_provision_portfolio.run()
|
# dispatch_provision_portfolio.run()
|
||||||
# mock.delay.assert_called_once_with(portfolio_id=portfolio.id)
|
# mock.delay.assert_called_once_with(portfolio_id=portfolio.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dispatch_send_task_order_files(
|
||||||
|
csp, session, celery_app, celery_worker, monkeypatch, app
|
||||||
|
):
|
||||||
|
mock = Mock()
|
||||||
|
monkeypatch.setattr("atst.jobs.send_with_attachment", mock)
|
||||||
|
|
||||||
|
def _download_task_order(MockFileService, object_name):
|
||||||
|
return {"name": object_name}
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"atst.domain.csp.files.MockFileService.download_task_order",
|
||||||
|
_download_task_order,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create 3 new Task Orders
|
||||||
|
for i in range(3):
|
||||||
|
TaskOrderFactory.create(create_clins=[{"number": "0001"}])
|
||||||
|
|
||||||
|
dispatch_send_task_order_files.run()
|
||||||
|
|
||||||
|
# Check that send_with_attachment was called once for each task order
|
||||||
|
assert mock.delay.call_count == 3
|
||||||
|
mock.reset_mock()
|
||||||
|
|
||||||
|
# Create new TO
|
||||||
|
task_order = TaskOrderFactory.create(create_clins=[{"number": "0001"}])
|
||||||
|
assert not task_order.pdf_last_sent_at
|
||||||
|
|
||||||
|
dispatch_send_task_order_files.run()
|
||||||
|
|
||||||
|
# Check that send_with_attachment was called with correct kwargs
|
||||||
|
mock.delay.assert_called_once_with(
|
||||||
|
recipients=app.config.get("MICROSOFT_TASK_ORDER_EMAIL_ADDRESS"),
|
||||||
|
subject=translate(
|
||||||
|
"email.task_order_sent.subject", {"to_number": task_order.number}
|
||||||
|
),
|
||||||
|
body=translate("email.task_order_sent.body", {"to_number": task_order.number}),
|
||||||
|
attachments=[
|
||||||
|
{
|
||||||
|
"name": task_order.pdf.object_name,
|
||||||
|
"maintype": "application",
|
||||||
|
"subtype": "pdf",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert task_order.pdf_last_sent_at
|
||||||
|
Loading…
x
Reference in New Issue
Block a user