diff --git a/TODO.md b/TODO.md index a3c51160..7359957c 100644 --- a/TODO.md +++ b/TODO.md @@ -417,15 +417,19 @@ Greatest Colaesce('total', 'computed_total') Case -# case on payment transaction state ? case when trans.amount > +# SQL case on payment transaction state ? case when trans.amount > # Resource inline links point to custom changelist view that preserve state (breadcrumbs, title, etc) rather than generic changeview with queryarg filtering # ORDER diff Pending vs ALL -# pre-bill confirmation: remove account if lines.count() == 0 ? -# Discount prepaid metric should be more optimal https://orchestra.pangea.org/admin/orders/order/40/ -# -> order.billed_metric besides billed_until +# DELETING RESOURCE RELATED OBJECT SHOULD NOT delete related monitor data for traffic accountancy +# round decimals on every billing operation -# websites directives: redirect strip() and allow empty URL_path +# Serie1 + +# Pangea post-create: lorena no has afegit el webalizer +# cleanup monitor data + +# Add SPF record type diff --git a/orchestra/contrib/orders/filters.py b/orchestra/contrib/orders/filters.py index 850aceb3..97dee626 100644 --- a/orchestra/contrib/orders/filters.py +++ b/orchestra/contrib/orders/filters.py @@ -51,24 +51,12 @@ class BilledOrderListFilter(SimpleListFilter): queryset=MetricStorage.objects.filter(created_on__gt=F('order__billed_on'), created_on__lte=(F('updated_on')-mindelta)) ) - prefetch_billed_metric = Prefetch('metrics', to_attr='billed_metric', - queryset=MetricStorage.objects.filter(order__billed_on__isnull=False, - created_on__lte=F('order__billed_on'), updated_on__gt=F('order__billed_on')) - ) metric_queryset = queryset.exclude(service__metric='').exclude(billed_on__isnull=True) - for order in metric_queryset.prefetch_related(prefetch_valid_metrics, prefetch_billed_metric): - if len(order.billed_metric) != 1: - # corner case of prefetch_billed_metric: Does not always work with latests metrics - latest = order.metrics.latest() - if not latest: - raise ValueError("Data inconsistency #metrics %i != 1." % len(order.billed_metric)) - billed_metric = latest.value - else: - billed_metric = order.billed_metric[0].value + for order in metric_queryset.prefetch_related(prefetch_valid_metrics): for metric in order.valid_metrics: if metric.created_on <= order.billed_on: raise ValueError("This value should already be filtered on the prefetch query.") - if metric.value > billed_metric: + if metric.value > order.billed_metric: metric_pks.append(order.pk) break return metric_pks diff --git a/orchestra/contrib/orders/migrations/0004_auto_20150729_0945.py b/orchestra/contrib/orders/migrations/0004_auto_20150729_0945.py new file mode 100644 index 00000000..3992a5fa --- /dev/null +++ b/orchestra/contrib/orders/migrations/0004_auto_20150729_0945.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('orders', '0003_order_content_object_repr'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='billed_metric', + field=models.DecimalField(verbose_name='billed metric', max_digits=16, decimal_places=2, null=True), + ), + migrations.AlterField( + model_name='order', + name='content_object_repr', + field=models.CharField(verbose_name='content object representation', max_length=256, editable=False), + ), + ] diff --git a/orchestra/contrib/orders/models.py b/orchestra/contrib/orders/models.py index da7a0348..b260512a 100644 --- a/orchestra/contrib/orders/models.py +++ b/orchestra/contrib/orders/models.py @@ -114,13 +114,14 @@ class Order(models.Model): related_name='orders') registered_on = models.DateField(_("registered"), default=timezone.now, db_index=True) cancelled_on = models.DateField(_("cancelled"), null=True, blank=True) - # TODO billed metric billed_on = models.DateField(_("billed"), null=True, blank=True) + billed_metric = models.DecimalField(_("billed metric"), max_digits=16, decimal_places=2, + null=True, blank=True) billed_until = models.DateField(_("billed until"), null=True, blank=True) ignore = models.BooleanField(_("ignore"), default=False) description = models.TextField(_("description"), blank=True) content_object_repr = models.CharField(_("content object representation"), max_length=256, - editable=False) + editable=False, help_text=_("Used for searches.")) content_object = GenericForeignKey() objects = OrderQuerySet.as_manager() @@ -239,13 +240,15 @@ class Order(models.Model): if kwargs: raise AttributeError if len(args) == 2: + # Slot ini, end = args - metrics = self.metrics.filter(updated_on__lt=end, updated_on__gte=ini) + metrics = self.metrics.filter(created_on__lt=end, updated_on__gte=ini) elif len(args) == 1: + # On effect on date date = args[0] date = datetime.date(year=date.year, month=date.month, day=date.day) date += datetime.timedelta(days=1) - metrics = self.metrics.filter(updated_on__lt=date) + metrics = self.metrics.filter(created_on__lte=date) elif not args: return self.metrics.latest('updated_on').value else: @@ -261,7 +264,6 @@ class MetricStorage(models.Model): order = models.ForeignKey(Order, verbose_name=_("order"), related_name='metrics') value = models.DecimalField(_("value"), max_digits=16, decimal_places=2) created_on = models.DateField(_("created"), auto_now_add=True) -# default=lambda: timezone.now()) # TODO time field? updated_on = models.DateTimeField(_("updated")) diff --git a/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html b/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html index 0408c3c1..e5c80f50 100644 --- a/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html +++ b/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html @@ -47,27 +47,35 @@ $(document).ready( function () {