Skip to content

Commit

Permalink
Make it a Celery task
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjamc committed Nov 29, 2024
1 parent 9dd4727 commit 83d7101
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 55 deletions.
3 changes: 3 additions & 0 deletions settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,9 @@
"workbaskets.tasks.check_workbasket": {
"queue": "rule-check",
},
"workbaskets.tasks.call_end_measures": {
"queue": "standard",
},
"workbaskets.tasks.transition": {
"queue": "standard",
},
Expand Down
70 changes: 70 additions & 0 deletions workbaskets/tasks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
from datetime import date

from celery import group
from celery import shared_task
from celery.utils.log import get_task_logger
from django.db.models import F
from django.db.transaction import atomic

from checks.tasks import check_transaction
from checks.tasks import check_transaction_sync
from commodities.models.orm import GoodsNomenclature
from common.celery import app
from common.models.transactions import Transaction
from common.util import TaricDateRange
from common.validators import UpdateType
from measures.models.tracked_models import Measure
from workbaskets.models import WorkBasket
from workbaskets.validators import WorkflowStatus

# Celery logger adds the task id and status and outputs via the worker.
logger = get_task_logger(__name__)
Expand Down Expand Up @@ -64,3 +73,64 @@ def call_check_workbasket_sync(self, workbasket_id: int):
workbasket: WorkBasket = WorkBasket.objects.get(pk=workbasket_id)
workbasket.delete_checks()
check_workbasket_sync(workbasket)


def promote_measure_to_top(promoted_measure, workbasket_transactions):
"""Set the transaction order of `promoted_measure` to be first in the
workbasket, demoting the transactions that came before it."""

top_transaction = workbasket_transactions.first()

if (
not promoted_measure
or not top_transaction
or promoted_measure == top_transaction
):
return

current_position = promoted_measure.order
top_position = top_transaction.order
workbasket_transactions.filter(order__lt=current_position).update(
order=F("order") + 1,
)
promoted_measure.order = top_position
promoted_measure.save(update_fields=["order"])


def end_measures(measures, workbasket):
"""Iterate through measures on commodities, end-date those which have
already began and delete those which have not yet started."""
for measure in measures:
workbasket_transactions = Transaction.objects.filter(
workbasket=workbasket,
workbasket__status=WorkflowStatus.EDITING,
).order_by("order")

commodity = GoodsNomenclature.objects.all().get(
pk=measure.goods_nomenclature_id,
transaction__workbasket=workbasket,
)
if measure.valid_between.lower > commodity.valid_between.upper:
continue
if measure.valid_between.lower > date.today():
new_measure_version = measure.new_version(
workbasket=workbasket,
update_type=UpdateType.DELETE,
)
else:
new_measure_version = measure.new_version(
workbasket=workbasket,
update_type=UpdateType.UPDATE,
valid_between=TaricDateRange(
measure.valid_between.lower,
commodity.valid_between.upper,
),
)
promote_measure_to_top(new_measure_version.transaction, workbasket_transactions)


@app.task
def call_end_measures(measure_pks, workbasket_pk):
workbasket = WorkBasket.objects.all().get(pk=workbasket_pk)
measures = Measure.objects.all().filter(pk__in=measure_pks)
end_measures(measures, workbasket)
60 changes: 5 additions & 55 deletions workbaskets/views/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@
from common.inspect_tap_tasks import TAPTasks
from common.models import Transaction
from common.models.transactions import TransactionPartition
from common.util import TaricDateRange
from common.util import format_date_string
from common.validators import UpdateType
from common.views import SortingMixin
from common.views import WithPaginationListMixin
from common.views import WithPaginationListView
Expand Down Expand Up @@ -75,6 +73,7 @@
from workbaskets.models import WorkBasket
from workbaskets.session_store import SessionStore
from workbaskets.tasks import call_check_workbasket_sync
from workbaskets.tasks import call_end_measures
from workbaskets.validators import WorkflowStatus
from workbaskets.views.decorators import require_current_workbasket
from workbaskets.views.mixins import WithCurrentWorkBasket
Expand Down Expand Up @@ -1794,7 +1793,7 @@ class AutoEndDateMeasures(SortingMixin, WithPaginationListMixin, ListView):
"goods_nomenclature": "goods_nomenclature__item_id",
}

@cached_property
@property
def workbasket(self):
return WorkBasket.objects.get(pk=self.kwargs["wb_pk"])

Expand All @@ -1811,7 +1810,7 @@ def commodities(self):
.values_list("pk")
)

@cached_property
@property
def measures(self):
# Should I only be filtering for measures without an end date?
return Measure.objects.current().filter(
Expand Down Expand Up @@ -1845,64 +1844,15 @@ def get_context_data(self, **kwargs):
def post(self, request, *args, **kwargs):
if request.POST.get("action", None) == "auto-end-date-measures":
self.end_measures()

return redirect(
"workbaskets:workbasket-ui-auto-end-date-measures-confirm",
self.workbasket.pk,
)

@atomic
def end_measures(self):
"""Iterate through measures on commodities, end-date those which have
already began and delete those which have not yet started."""
# TODO: How do you check that the commodity code has actually been updated and it isn't a create or the same date as before
for (
measure
) in self.measures: # Does this need to be here? is this a likely occurence?
commodity = GoodsNomenclature.objects.all().get(
pk=measure.goods_nomenclature_id,
transaction__workbasket=self.workbasket,
)
if measure.valid_between.lower > commodity.valid_between.upper:
continue
if measure.valid_between.lower > date.today():
new_measure_version = measure.new_version(
workbasket=self.workbasket,
update_type=UpdateType.DELETE,
)
else:
new_measure_version = measure.new_version(
workbasket=self.workbasket,
update_type=UpdateType.UPDATE,
valid_between=TaricDateRange(
measure.valid_between.lower,
commodity.valid_between.upper,
),
)
self.promote_measure_to_top(new_measure_version.transaction)

def promote_measure_to_top(self, promoted_measure):
"""Set the transaction order of `promoted_measure` to be first in the
workbasket, demoting the transactions that came before it."""
# Is it better to bulk move all measure transactions at the end?

top_transaction = self.workbasket_transactions().first()

if (
not promoted_measure
or not top_transaction
or promoted_measure == top_transaction
):
return

current_position = promoted_measure.order
top_position = top_transaction.order
self.workbasket_transactions().filter(order__lt=current_position).update(
order=F("order") + 1,
)

promoted_measure.order = top_position
promoted_measure.save(update_fields=["order"])
measure_pks = [measure.pk for measure in self.measures]
call_end_measures.apply_async((measure_pks, self.workbasket.pk))


class AutoEndDateMeasuresConfirm(DetailView):
Expand Down

0 comments on commit 83d7101

Please sign in to comment.