Fixed mailer smtp connection reuse
This commit is contained in:
parent
120506229a
commit
3520b3968b
2
TODO.md
2
TODO.md
|
@ -434,5 +434,3 @@ serailzer self.instance on create.
|
|||
* backendLog store method and language... and use it for display_script with correct lexer
|
||||
|
||||
# process monitor data to represent state, or maybe create new resource datas when period expires?
|
||||
|
||||
# DNS when AAAA is specified include default A register?
|
||||
|
|
|
@ -228,7 +228,8 @@ def amend_bills(modeladmin, request, queryset):
|
|||
}
|
||||
amend = Bill.objects.create(
|
||||
account=bill.account,
|
||||
type=amend_type
|
||||
type=amend_type,
|
||||
amend_of=bill,
|
||||
)
|
||||
context['type'] = _(amend.get_type_display())
|
||||
amend.comments = _("%(type)s of %(related_type)s %(number)s and creation date %(date)s") % context
|
||||
|
|
|
@ -22,9 +22,14 @@ from .models import Bill, Invoice, AmendmentInvoice, Fee, AmendmentFee, ProForma
|
|||
|
||||
|
||||
PAYMENT_STATE_COLORS = {
|
||||
Bill.OPEN: 'grey',
|
||||
Bill.CREATED: 'darkorange',
|
||||
Bill.PROCESSED: 'darkorange',
|
||||
Bill.AMENDED: 'blue',
|
||||
Bill.PAID: 'green',
|
||||
Bill.PENDING: 'darkorange',
|
||||
Bill.EXECUTED: 'darkorange',
|
||||
Bill.BAD_DEBT: 'red',
|
||||
Bill.INCOMPLETE: 'red',
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,10 +96,10 @@ class PaymentStateListFilter(SimpleListFilter):
|
|||
if self.value() == 'OPEN':
|
||||
return queryset.filter(Q(is_open=True)|Q(type=queryset.model.PROFORMA))
|
||||
elif self.value() == 'PAID':
|
||||
zeros = queryset.filter(computed_total=0).values_list('id', flat=True)
|
||||
zeros = queryset.filter(computed_total=0, computed_total__isnull=True).values_list('id', flat=True)
|
||||
ammounts = Transaction.objects.exclude(bill_id__in=zeros).secured().group_by('bill_id')
|
||||
paid = []
|
||||
for bill_id, total in queryset.exclude(computed_total=0).values_list('id', 'computed_total'):
|
||||
for bill_id, total in queryset.exclude(computed_total=0, computed_total__isnull=True, is_open=True).values_list('id', 'computed_total'):
|
||||
try:
|
||||
ammount = sum([t.ammount for t in ammounts[bill_id]])
|
||||
except KeyError:
|
||||
|
@ -107,13 +107,12 @@ class PaymentStateListFilter(SimpleListFilter):
|
|||
else:
|
||||
if abs(total) <= abs(ammount):
|
||||
paid.append(bill_id)
|
||||
return queryset.filter(Q(computed_total=0)|Q(id__in=paid))
|
||||
return queryset.filter(Q(computed_total=0)|Q(computed_total__isnull=True)|Q(id__in=paid)).exclude(is_open=True)
|
||||
elif self.value() == 'PENDING':
|
||||
has_transaction = queryset.exclude(transactions__isnull=True)
|
||||
non_rejected = has_transaction.exclude(transactions__state=Transaction.REJECTED)
|
||||
non_rejected = non_rejected.values_list('id', flat=True).distinct()
|
||||
return queryset.filter(pk__in=non_rejected)
|
||||
elif self.value() == 'BAD_DEBT':
|
||||
non_rejected = queryset.exclude(transactions__state=Transaction.REJECTED)
|
||||
non_rejected = non_rejected.values_list('id', flat=True).distinct()
|
||||
return queryset.exclude(pk__in=non_rejected)
|
||||
closed = queryset.filter(is_open=False).exclude(computed_total=0)
|
||||
return closed.filter(Q(transactions__state=Transaction.REJECTED)|Q(transactions__isnull=True))
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -64,15 +64,17 @@ class Bill(models.Model):
|
|||
PROCESSED = 'PROCESSED'
|
||||
AMENDED = 'AMENDED'
|
||||
PAID = 'PAID'
|
||||
PENDING = 'PENDING'
|
||||
EXECUTED = 'EXECUTED'
|
||||
BAD_DEBT = 'BAD_DEBT'
|
||||
INCOMPLETE = 'INCOMPLETE'
|
||||
PAYMENT_STATES = (
|
||||
(OPEN, _("Open")),
|
||||
(CREATED, _("Created")),
|
||||
(PROCESSED, _("Processed")),
|
||||
(AMENDED, _("Amended")),
|
||||
(PAID, _("Paid")),
|
||||
(PENDING, _("Pending")),
|
||||
(INCOMPLETE, _('Incomplete')),
|
||||
(EXECUTED, _("Executed")),
|
||||
(BAD_DEBT, _("Bad debt")),
|
||||
)
|
||||
BILL = 'BILL'
|
||||
|
@ -92,7 +94,8 @@ class Bill(models.Model):
|
|||
number = models.CharField(_("number"), max_length=16, unique=True, blank=True)
|
||||
account = models.ForeignKey('accounts.Account', verbose_name=_("account"),
|
||||
related_name='%(class)s')
|
||||
# amend_of = models.ForeignKey('self', null=True, blank=True, verbose_name=_("amend of"), related_name='amends')
|
||||
amend_of = models.ForeignKey('self', null=True, blank=True, verbose_name=_("amend of"),
|
||||
related_name='amends')
|
||||
type = models.CharField(_("type"), max_length=16, choices=TYPES)
|
||||
created_on = models.DateField(_("created on"), auto_now_add=True)
|
||||
closed_on = models.DateField(_("closed on"), blank=True, null=True)
|
||||
|
@ -133,14 +136,49 @@ class Bill(models.Model):
|
|||
def payment_state(self):
|
||||
if self.is_open or self.get_type() == self.PROFORMA:
|
||||
return self.OPEN
|
||||
# elif self.amends.filter(is_open=False).exists():
|
||||
# return self.AMENDED
|
||||
# TODO optimize this with a single query
|
||||
secured = self.transactions.secured().amount() or 0
|
||||
if abs(secured) >= abs(self.get_total()):
|
||||
return self.PAID
|
||||
elif self.transactions.exclude_rejected().exists():
|
||||
return self.PENDING
|
||||
elif self.amends.filter(is_open=False).exists():
|
||||
return self.AMENDED
|
||||
secured = 0
|
||||
pending = 0
|
||||
created = False
|
||||
processed = False
|
||||
executed = False
|
||||
rejected = False
|
||||
for transaction in self.transactions.all():
|
||||
if transaction.state == transaction.SECURED:
|
||||
secured += transaction.amount
|
||||
pending += transaction.amount
|
||||
elif transaction.state == transaction.WAITTING_PROCESSING:
|
||||
pending += transaction.amount
|
||||
created = True
|
||||
elif transaction.state == transaction.WAITTING_EXECUTION:
|
||||
pending += transaction.amount
|
||||
processed = True
|
||||
elif transaction.state == transaction.EXECUTED:
|
||||
pending += transaction.amount
|
||||
executed = True
|
||||
elif transaction.state == transaction.REJECTED:
|
||||
rejected = True
|
||||
else:
|
||||
raise TypeError("Unknown state")
|
||||
ongoing = bool(secured != 0 or created or processed or executed)
|
||||
total = self.get_total()
|
||||
if total >= 0:
|
||||
if secured >= total:
|
||||
return self.PAID
|
||||
elif ongoing and pending < total:
|
||||
return self.INCOMPLETE
|
||||
else:
|
||||
if secured <= total:
|
||||
return self.PAID
|
||||
elif ongoing and pending > total:
|
||||
return self.INCOMPLETE
|
||||
if created:
|
||||
return self.CREATED
|
||||
elif processed:
|
||||
return self.PROCESSED
|
||||
elif executed:
|
||||
return self.EXECUTED
|
||||
return self.BAD_DEBT
|
||||
|
||||
def get_total(self):
|
||||
|
|
|
@ -172,13 +172,14 @@ class Domain(models.Model):
|
|||
type=Record.MX,
|
||||
value=mx
|
||||
))
|
||||
if not has_a and not has_aaaa:
|
||||
if not has_a:
|
||||
default_a = settings.DOMAINS_DEFAULT_A
|
||||
if default_a:
|
||||
records.append(AttrDict(
|
||||
type=Record.A,
|
||||
value=default_a
|
||||
))
|
||||
if not has_aaaa:
|
||||
default_aaaa = settings.DOMAINS_DEFAULT_AAAA
|
||||
if default_aaaa:
|
||||
records.append(AttrDict(
|
||||
|
|
|
@ -25,7 +25,8 @@ def send_message(message, num=0, connection=None, bulk=settings.MAILER_BULK_MESS
|
|||
error = None
|
||||
try:
|
||||
connection.connection.sendmail(message.from_address, [message.to_address], smart_str(message.content))
|
||||
except (SocketError, smtplib.SMTPSenderRefused,
|
||||
except (SocketError,
|
||||
smtplib.SMTPSenderRefused,
|
||||
smtplib.SMTPRecipientsRefused,
|
||||
smtplib.SMTPAuthenticationError) as err:
|
||||
message.defer()
|
||||
|
@ -33,6 +34,7 @@ def send_message(message, num=0, connection=None, bulk=settings.MAILER_BULK_MESS
|
|||
else:
|
||||
message.sent()
|
||||
message.log(error)
|
||||
return connection
|
||||
|
||||
|
||||
def send_pending(bulk=settings.MAILER_BULK_MESSAGES):
|
||||
|
@ -41,7 +43,7 @@ def send_pending(bulk=settings.MAILER_BULK_MESSAGES):
|
|||
connection = None
|
||||
num = 0
|
||||
for message in Message.objects.filter(state=Message.QUEUED).order_by('priority'):
|
||||
send_message(message, num, connection, bulk)
|
||||
connection = send_message(message, num, connection, bulk)
|
||||
num += 1
|
||||
now = timezone.now()
|
||||
qs = Q()
|
||||
|
|
62
orchestra/static/orchestra/css/pygments/default.css
Normal file
62
orchestra/static/orchestra/css/pygments/default.css
Normal file
|
@ -0,0 +1,62 @@
|
|||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #808080 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #A0A000 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
61
orchestra/static/orchestra/css/pygments/github.css
Normal file
61
orchestra/static/orchestra/css/pygments/github.css
Normal file
|
@ -0,0 +1,61 @@
|
|||
.hll { background-color: #ffffcc }
|
||||
.c { color: #999988; font-style: italic } /* Comment */
|
||||
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.k { color: #000000; font-weight: bold } /* Keyword */
|
||||
.o { color: #000000; font-weight: bold } /* Operator */
|
||||
.cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||
.cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
|
||||
.c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||
.cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||
.ge { color: #000000; font-style: italic } /* Generic.Emph */
|
||||
.gr { color: #aa0000 } /* Generic.Error */
|
||||
.gh { color: #999999 } /* Generic.Heading */
|
||||
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.go { color: #888888 } /* Generic.Output */
|
||||
.gp { color: #555555 } /* Generic.Prompt */
|
||||
.gs { font-weight: bold } /* Generic.Strong */
|
||||
.gu { color: #aaaaaa } /* Generic.Subheading */
|
||||
.gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.kc { color: #000000; font-weight: bold } /* Keyword.Constant */
|
||||
.kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
|
||||
.kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
|
||||
.kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
|
||||
.kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
|
||||
.kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||
.m { color: #009999 } /* Literal.Number */
|
||||
.s { color: #d01040 } /* Literal.String */
|
||||
.na { color: #008080 } /* Name.Attribute */
|
||||
.nb { color: #0086B3 } /* Name.Builtin */
|
||||
.nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||
.no { color: #008080 } /* Name.Constant */
|
||||
.nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
|
||||
.ni { color: #800080 } /* Name.Entity */
|
||||
.ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||
.nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||
.nl { color: #990000; font-weight: bold } /* Name.Label */
|
||||
.nn { color: #555555 } /* Name.Namespace */
|
||||
.nt { color: #000080 } /* Name.Tag */
|
||||
.nv { color: #008080 } /* Name.Variable */
|
||||
.ow { color: #000000; font-weight: bold } /* Operator.Word */
|
||||
.w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.mf { color: #009999 } /* Literal.Number.Float */
|
||||
.mh { color: #009999 } /* Literal.Number.Hex */
|
||||
.mi { color: #009999 } /* Literal.Number.Integer */
|
||||
.mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.sb { color: #d01040 } /* Literal.String.Backtick */
|
||||
.sc { color: #d01040 } /* Literal.String.Char */
|
||||
.sd { color: #d01040 } /* Literal.String.Doc */
|
||||
.s2 { color: #d01040 } /* Literal.String.Double */
|
||||
.se { color: #d01040 } /* Literal.String.Escape */
|
||||
.sh { color: #d01040 } /* Literal.String.Heredoc */
|
||||
.si { color: #d01040 } /* Literal.String.Interpol */
|
||||
.sx { color: #d01040 } /* Literal.String.Other */
|
||||
.sr { color: #009926 } /* Literal.String.Regex */
|
||||
.s1 { color: #d01040 } /* Literal.String.Single */
|
||||
.ss { color: #990073 } /* Literal.String.Symbol */
|
||||
.bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
.vc { color: #008080 } /* Name.Variable.Class */
|
||||
.vg { color: #008080 } /* Name.Variable.Global */
|
||||
.vi { color: #008080 } /* Name.Variable.Instance */
|
||||
.il { color: #009999 } /* Literal.Number.Integer.Long */
|
Loading…
Reference in a new issue