Replaced the SQL query in the cash account with the Django model query in the accounting application.

This commit is contained in:
依瑪貓 2020-07-18 10:32:15 +08:00
parent c21f079321
commit ed0c29f360

View File

@ -22,7 +22,7 @@ import re
from datetime import timedelta from datetime import timedelta
from django.db import connection from django.db import connection
from django.db.models import Sum, Case, When, F from django.db.models import Sum, Case, When, F, Q
from django.db.models.functions import TruncMonth, Coalesce from django.db.models.functions import TruncMonth, Coalesce
from django.http import HttpResponseRedirect, Http404 from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render from django.shortcuts import render
@ -149,94 +149,41 @@ def cash(request, subject_code, period_spec):
raise Http404() raise Http404()
# The accounting records # The accounting records
if current_subject.code == "0": if current_subject.code == "0":
select_records = """SELECT r.* records = list(Record.objects.filter(
FROM accounting_records AS r Q(transaction__in=Transaction.objects.filter(
INNER JOIN (SELECT Q(date__gte=period.start),
t1.sn AS sn, Q(date__lte=period.end),
t1.date AS date, (Q(record__subject__code__startswith="11") |
t1.ord AS ord Q(record__subject__code__startswith="12") |
FROM accounting_records AS r1 Q(record__subject__code__startswith="21") |
LEFT JOIN accounting_transactions AS t1 Q(record__subject__code__startswith="22")))),
ON r1.transaction_sn=t1.sn ~Q(subject__code__startswith="11"),
LEFT JOIN accounting_subjects AS s1 ~Q(subject__code__startswith="12"),
ON r1.subject_sn = s1.sn ~Q(subject__code__startswith="21"),
WHERE (s1.code LIKE '11%%' ~Q(subject__code__startswith="22")))
OR s1.code LIKE '12%%' balance_before = Record.objects.filter(
OR s1.code LIKE '21%%' Q(transaction__date__lt=period.start),
OR s1.code LIKE '22%%') (Q(subject__code__startswith="11") |
AND t1.date >= %s Q(subject__code__startswith="12") |
AND t1.date <= %s Q(subject__code__startswith="21") |
GROUP BY t1.sn) AS t Q(subject__code__startswith="21")))\
ON r.transaction_sn=t.sn .aggregate(balance=Coalesce(Sum(Case(When(
LEFT JOIN accounting_subjects AS s ON r.subject_sn = s.sn is_credit=True, then=-1),
WHERE s.code NOT LIKE '11%%' default=1) * F("amount")), 0))["balance"]
AND s.code NOT LIKE '12%%'
AND s.code NOT LIKE '21%%'
AND s.code NOT LIKE '22%%'
ORDER BY
t.date,
t.ord,
CASE WHEN is_credit THEN 1 ELSE 2 END,
r.ord"""
sql_records = SqlQuery(
select_records,
[period.start, period.end])
select_balance_before = """SELECT
SUM(CASE WHEN is_credit THEN 1 ELSE -1 END * amount) AS amount
FROM (%s) AS b""" % select_records
sql_balance_before = SqlQuery(
select_balance_before,
[data_start, period.start - timedelta(days=1)])
else: else:
select_records = """SELECT r.* records = list(Record.objects.filter(
FROM accounting_records AS r Q(transaction__in=Transaction.objects.filter(
INNER JOIN (SELECT Q(date__gte=period.start),
t1.sn AS sn, Q(date__lte=period.end),
t1.date AS date, Q(record__subject__code__startswith=
t1.ord AS ord current_subject.code))),
FROM accounting_records AS r1 ~Q(subject__code__startswith=current_subject.code)))
LEFT JOIN accounting_transactions AS t1 balance_before = Record.objects.filter(
ON r1.transaction_sn=t1.sn transaction__date__lt=period.start,
LEFT JOIN accounting_subjects AS s1 subject__code__startswith=current_subject.code)\
ON r1.subject_sn = s1.sn .aggregate(balance=Coalesce(Sum(Case(When(
WHERE t1.date >= %s is_credit=True, then=-1),
AND t1.date <= %s default=1) * F("amount")), 0))["balance"]
AND s1.code LIKE %s
GROUP BY t1.sn) AS t
ON r.transaction_sn=t.sn
LEFT JOIN accounting_subjects AS s ON r.subject_sn = s.sn
WHERE s.code NOT LIKE %s
ORDER BY
t.date,
t.ord,
CASE WHEN is_credit THEN 1 ELSE 2 END,
r.ord"""
sql_records = SqlQuery(
select_records,
[period.start,
period.end,
current_subject.code + "%",
current_subject.code + "%"])
select_balance_before = f"""SELECT
SUM(CASE WHEN is_credit THEN 1 ELSE -1 END * amount) AS amount
FROM ({select_records})"""
sql_balance_before = SqlQuery(
select_balance_before,
[data_start,
period.start - timedelta(days=1),
current_subject.code + "%",
current_subject.code + "%"])
# The list data
records = list(Record.objects.raw(
sql_records.sql,
sql_records.params))
with connection.cursor() as cursor:
cursor.execute(
sql_balance_before.sql, sql_balance_before.params)
row = cursor.fetchone()
balance_before = row[0]
if balance_before is None:
balance_before = 0
balance = balance_before balance = balance_before
for record in records: for record in records:
sign = 1 if record.is_credit else -1 sign = 1 if record.is_credit else -1
@ -294,6 +241,11 @@ def cash_summary(request, subject_code):
month_definition = "DATE(t.date, 'start of month')" month_definition = "DATE(t.date, 'start of month')"
else: else:
month_definition = None month_definition = None
q = Transaction.objects.filter(
Q(record__subject__code__startswith="11") |
Q(record__subject__code__startswith="12") |
Q(record__subject__code__startswith="21") |
Q(record__subject__code__startswith="22")).values("sn")
if current_subject.code == "0": if current_subject.code == "0":
records = list(RecordSummary.objects.raw( records = list(RecordSummary.objects.raw(
f"""SELECT f"""SELECT