Fixes on billing and mailman traffic backend
This commit is contained in:
parent
8753b94b8c
commit
332ad49b64
18
TODO.md
18
TODO.md
|
@ -156,7 +156,6 @@ require_once(‘/etc/moodles/’.$moodle_host.‘config.php’);``` moodle/drupl
|
|||
# * add ini, end dates on bill lines and breakup quanity into size(defaut:1) and metric
|
||||
# * threshold for significative metric accountancy on services.handler
|
||||
# * http://orchestra.pangea.org/admin/orders/order/6418/
|
||||
# * http://orchestra.pangea.org/admin/orders/order/6495/bill_selected_orders/
|
||||
|
||||
* move normurlpath to orchestra.utils from websites.utils
|
||||
|
||||
|
@ -183,22 +182,11 @@ ugettext("Description")
|
|||
|
||||
* saas validate_creation generic approach, for all backends. standard output
|
||||
|
||||
* html code x: × for bill line verbose quantity
|
||||
|
||||
* periodic task to cleanup backendlogs, monitor data and metricstorage
|
||||
* create orchestrate databases.Database pk=1 -n --dry-run | --noinput --action save (default)|delete --backend name (limit to this backend) --help
|
||||
|
||||
* uwsgi --max-requests=5000 \ # respawn processes after serving 5000 requests and
|
||||
celery max-tasks-per-child
|
||||
|
||||
* generate settings.py more like django (installed_apps, middlewares, etc,,,)
|
||||
* periodic task to cleanup metricstorage
|
||||
# create orchestrate databases.Database pk=1 -n --dry-run | --noinput --action save (default)|delete --backend name (limit to this backend) --help
|
||||
|
||||
* postupgradeorchestra send signals in order to hook custom stuff
|
||||
|
||||
* autoscale celery workers http://docs.celeryproject.org/en/latest/userguide/workers.html#autoscaling
|
||||
|
||||
|
||||
glic3rinu's django-fluent-dashboard
|
||||
* gevent is not ported to python3 :'(
|
||||
|
||||
# FIXME account deletion generates an integrity error
|
||||
|
@ -248,8 +236,6 @@ https://code.djangoproject.com/ticket/24576
|
|||
# Determine the difference between data serializer used for validation and used for the rest API!
|
||||
# Make PluginApiView that fills metadata and other stuff like modeladmin plugin support
|
||||
|
||||
# TODO orchestra related services code reload: celery/uwsgi reloading find aonther way without root and implement reload
|
||||
|
||||
# reset setting button
|
||||
|
||||
# admin edit relevant djanog settings
|
||||
|
|
|
@ -271,6 +271,7 @@ class MailmanTraffic(ServiceMonitor):
|
|||
'Nov': '11',
|
||||
'Dec': '12',
|
||||
}}
|
||||
mailman_addr = re.compile(r'.*-(admin|bounces|confirm|join|leave|owner|request|subscribe|unsubscribe)@.*')
|
||||
|
||||
def prepare(object_id, list_name, ini_date):
|
||||
global lists
|
||||
|
@ -283,12 +284,15 @@ class MailmanTraffic(ServiceMonitor):
|
|||
try:
|
||||
with open(postlog, 'r') as postlog:
|
||||
for line in postlog.readlines():
|
||||
month, day, time, year, __, __, __, list_name, __, __, size = line.split()[:11]
|
||||
month, day, time, year, __, __, __, list_name, __, addr, size = line.split()[:11]
|
||||
try:
|
||||
list = lists[list_name]
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
# discard mailman messages because of inconsistent POST logging
|
||||
if mailman_addr.match(addr):
|
||||
continue
|
||||
date = year + months[month] + day + time.replace(':', '')
|
||||
if list[0] < int(date) < end_date:
|
||||
size = size[5:-1]
|
||||
|
|
|
@ -202,6 +202,7 @@ class MonitorDataAdmin(ExtendedModelAdmin):
|
|||
change_readonly_fields = fields
|
||||
list_select_related = ('content_type',)
|
||||
search_fields = ('content_object_repr',)
|
||||
date_hierarchy = 'created_at'
|
||||
|
||||
display_created = admin_date('created_at', short_description=_("Created"))
|
||||
|
||||
|
|
|
@ -189,7 +189,11 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
|
||||
def get_price_size(self, ini, end):
|
||||
rdelta = relativedelta.relativedelta(end, ini)
|
||||
if self.billing_period == self.MONTHLY:
|
||||
anual_prepay_of_monthly_pricing = bool(
|
||||
self.billing_period == self.ANUAL and
|
||||
self.payment_style == self.PREPAY and
|
||||
self.get_pricing_period() == self.MONTHLY)
|
||||
if self.billing_period == self.MONTHLY or anual_prepay_of_monthly_pricing:
|
||||
size = rdelta.years * 12
|
||||
size += rdelta.months
|
||||
days = calendar.monthrange(end.year, end.month)[1]
|
||||
|
@ -508,7 +512,9 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
recharges = []
|
||||
rini = order.billed_on
|
||||
rend = min(bp, order.billed_until)
|
||||
bmetric = order.billed_metric or 0
|
||||
bmetric = order.billed_metric
|
||||
if bmetric is None:
|
||||
bmetric = order.get_metric(order.billed_on)
|
||||
bsize = self.get_price_size(rini, order.billed_until)
|
||||
prepay_discount = self.get_price(account, bmetric) * bsize
|
||||
prepay_discount = round(prepay_discount, 2)
|
||||
|
@ -580,6 +586,17 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
line = self.generate_line(order, price, cini, cend, metric=metric,
|
||||
discounts=discounts)
|
||||
lines.append(line)
|
||||
elif self.get_pricing_period() in (self.MONTHLY, self.ANUAL):
|
||||
if self.payment_style == self.PREPAY:
|
||||
# Traffic Prepay
|
||||
metric = order.get_metric(timezone.now().date())
|
||||
if metric > 0:
|
||||
price = self.get_price(account, metric)
|
||||
for cini, cend in self.get_pricing_slots(ini, bp):
|
||||
line = self.generate_line(order, price, cini, cend, metric=metric)
|
||||
lines.append(line)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import calendar
|
||||
import decimal
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
@ -70,9 +71,8 @@ class Service(models.Model):
|
|||
"<tt> contractedplan.plan.name == 'association_fee''</tt><br>"
|
||||
"<tt> instance.active</tt>"))
|
||||
handler_type = models.CharField(_("handler"), max_length=256, blank=True,
|
||||
help_text=_("Handler used for processing this Service. A handler "
|
||||
"enables customized behaviour far beyond what options "
|
||||
"here allow to."),
|
||||
help_text=_("Handler used for processing this Service. A handler enables customized "
|
||||
"behaviour far beyond what options here allow to."),
|
||||
choices=ServiceHandler.get_choices())
|
||||
is_active = models.BooleanField(_("active"), default=True)
|
||||
ignore_superusers = models.BooleanField(_("ignore %s") % _ignore_types, default=True,
|
||||
|
@ -87,16 +87,16 @@ class Service(models.Model):
|
|||
),
|
||||
default=ANUAL, blank=True)
|
||||
billing_point = models.CharField(_("billing point"), max_length=16,
|
||||
help_text=_("Reference point for calculating the renewal date "
|
||||
"on recurring invoices"),
|
||||
help_text=_("Reference point for calculating the renewal date on recurring invoices"),
|
||||
choices=(
|
||||
(ON_REGISTER, _("Registration date")),
|
||||
(FIXED_DATE, _("Fixed billing date")),
|
||||
(FIXED_DATE, _("Every %(month)s") % {
|
||||
'month': calendar.month_name[settings.SERVICES_SERVICE_ANUAL_BILLING_MONTH]
|
||||
}),
|
||||
),
|
||||
default=FIXED_DATE)
|
||||
is_fee = models.BooleanField(_("fee"), default=False,
|
||||
help_text=_("Designates whether this service should be billed as "
|
||||
" membership fee or not"))
|
||||
help_text=_("Designates whether this service should be billed as membership fee or not"))
|
||||
order_description = models.CharField(_("Order description"), max_length=128, blank=True,
|
||||
help_text=_(
|
||||
"Python <a href='https://docs.python.org/2/library/functions.html#eval'>expression</a> "
|
||||
|
|
Loading…
Reference in New Issue