Added: Tax LedgerType

Change: Changed unused is_current LedgerType to CashFlowClassification so that cash flow can be properly classified
Fix: Account update (missing get_code function)
Chore: Upgrade to angular 1.6
Feature: Change Cash Flow to new format to match international guidelines.  Still a work in progress.
Fix: Removed memoizing doFilter in the Tokenizer Service as it was giving errors. There is not that much processing, so it may also not be required. Will judge the impact later.
This commit is contained in:
tanshu 2017-02-06 13:09:15 +05:30
parent 71898ceca7
commit 5a2278add5
6 changed files with 100 additions and 69 deletions

@ -274,6 +274,11 @@ class LedgerBase(Base):
return False, 'Account has journal entries' return False, 'Account has journal entries'
return True, '' return True, ''
@classmethod
def get_code(cls, type, dbsession):
code = dbsession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == type).one()[0]
return 1 if code is None else code + 1
@classmethod @classmethod
def all_purchases(cls): def all_purchases(cls):
return uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490') return uuid.UUID('240dd899-c413-854c-a7eb-67a29d154490')
@ -389,30 +394,36 @@ class AttendanceType:
class LedgerType: class LedgerType:
def __init__(self, id, name, balance_sheet=None, debit=None, is_current=None, order=None, show_in_list=None): def __init__(self, id, name, balance_sheet=None, debit=None, cash_flow_classification=None, order=None,
show_in_list=None):
self.id = id self.id = id
self.name = name self.name = name
self.balance_sheet = balance_sheet self.balance_sheet = balance_sheet
self.debit = debit self.debit = debit
self.is_current = is_current self.cash_flow_classification = cash_flow_classification
# Cash flow Classifications are:
# Cash
# Operating
# Investing
# Financing
self.order = order self.order = order
self.show_in_list = show_in_list self.show_in_list = show_in_list
@classmethod @classmethod
def list(cls): def list(cls):
list = [LedgerType(1, 'Cash', True, True, True, 10, True), list = [LedgerType(1, 'Cash', True, True, 'Cash', 10, True),
LedgerType(2, 'Purchase', False, True, True, 20, True), LedgerType(2, 'Purchase', False, True, 'Operating', 20, True),
LedgerType(3, 'Sale', False, False, True, 10, True), LedgerType(3, 'Sale', False, False, 'Operating', 10, True),
LedgerType(4, 'Assets', True, True, False, 20, True), LedgerType(4, 'Assets', True, True, 'Investing', 20, True),
LedgerType(5, 'Capital', True, False, False, 70, True), LedgerType(5, 'Capital', True, False, 'Financing', 70, True),
LedgerType(6, 'Debtors', True, True, True, 30, True), LedgerType(6, 'Debtors', True, True, 'Operating', 30, True),
LedgerType(7, 'Expenses', False, True, True, 40, True), LedgerType(7, 'Expenses', False, True, 'Operating', 40, True),
LedgerType(9, 'Creditors', True, False, True, 60, True), LedgerType(9, 'Creditors', True, False, 'Operating', 60, True),
LedgerType(10, 'Salary', True, True, True, 40, False), LedgerType(10, 'Salary', True, True, 'Operating', 40, False),
LedgerType(11, 'Liabilities', True, False, True, 50, True), LedgerType(11, 'Liabilities', True, False, 'Operating', 50, True),
LedgerType(12, 'Revenue', False, False, True, 30, True)] LedgerType(12, 'Revenue', False, False, 'Operating', 30, True),
LedgerType(13, 'Tax', True, False, 'Operating', 80, True)]
# list.append(LedgerType(8, 'Discount', False, False, True, 30, True)) # list.append(LedgerType(8, 'Discount', False, False, True, 30, True))
# list.append(LedgerType(13, 'Tax', True, False, True, 80, True))
# list.append(LedgerType(14, 'Total', False, False, False, 900, False)) # list.append(LedgerType(14, 'Total', False, False, False, 900, False))
# list.append(LedgerType(15, 'Net', False, False, False, 1000, False)) # list.append(LedgerType(15, 'Net', False, False, False, 1000, False))
return list return list

@ -35,13 +35,13 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.8.0/math.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.8.0/math.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://code.angularjs.org/1.5.0/i18n/angular-locale_en-in.js"></script> <script src="https://code.angularjs.org/1.6.1/i18n/angular-locale_en-in.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-cookies.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-cookies.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-resource.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-resource.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-sanitize.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.min.js"></script>
<script src="/js/loading-bar.min.js"></script> <script src="/js/loading-bar.min.js"></script>
<script src="/js/ui-bootstrap-custom-0.12.0.min.js"></script> <script src="/js/ui-bootstrap-custom-0.12.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>

@ -31,22 +31,19 @@
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Inflow</th> <th>Flow</th>
<th>Outflow</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="item in info.Body"> <tr ng-repeat="item in info.Body">
<td><a href="{{item.Url}}">{{item.Name}}</a></td> <td><a href="{{item.Url}}">{{item.Name}}</a></td>
<td class="text-right">{{item.Inflow | currency | clr}}</td> <td class="text-right">{{item.Amount | currency | clr}}</td>
<td class="text-right">{{item.Outflow | currency | clr}}</td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr ng-repeat="item in info.Footer"> <tr ng-repeat="item in info.Footer">
<td>{{item.Name}}</td> <td>{{item.Name}}</td>
<td class="text-right">{{item.Inflow | currency | clr}}</td> <td class="text-right">{{item.Amount | currency | clr}}</td>
<td class="text-right">{{item.Outflow | currency | clr}}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>

@ -340,7 +340,7 @@ overlordService.factory('Tokenizer', ['$filter', function ($filter) {
}); });
return {'q': matches, 'o': sorting, 'f': flags}; return {'q': matches, 'o': sorting, 'f': flags};
}; };
var doFilter = _.memoize(function (q, array, matches) { var doFilter = function (q, array, matches) {
var filterExpressions = matches.q, var filterExpressions = matches.q,
sortPredicates = matches.o, sortPredicates = matches.o,
filterCount = filterExpressions.length; filterCount = filterExpressions.length;
@ -351,7 +351,7 @@ overlordService.factory('Tokenizer', ['$filter', function ($filter) {
}); });
arrayCopy = $filter('orderBy')(arrayCopy, sortPredicates); arrayCopy = $filter('orderBy')(arrayCopy, sortPredicates);
return arrayCopy; return arrayCopy;
}); };
return {parseFilterString: parseFilterString, doFilter: doFilter}; return {parseFilterString: parseFilterString, doFilter: doFilter};
}]); }]);

@ -38,7 +38,7 @@ def update(request):
raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name)) raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.name))
new_type = int(request.json_body['Type']) new_type = int(request.json_body['Type'])
if not item.type == new_type: if not item.type == new_type:
item.code = Ledger.get_code(new_type) item.code = Ledger.get_code(new_type, request.dbsession)
item.type = new_type item.type = new_type
item.name = request.json_body['Name'] item.name = request.json_body['Name']
item.is_active = request.json_body['IsActive'] item.is_active = request.json_body['IsActive']

@ -52,32 +52,46 @@ def build_report(request, start_date, finish_date):
.filter(sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ .filter(sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
.filter(sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')).subquery() .filter(sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')).subquery()
query = request.dbsession.query(LedgerBase.type, func.sum(Journal.signed_amount)) \ query = request.dbsession.query(
.join(Journal, Voucher.journals) \ LedgerBase.type, func.sum(Journal.signed_amount)
.join(LedgerBase, Journal.ledger) \ ).join(
.filter(Voucher.id.in_(sub_query)) \ Journal, Voucher.journals
.filter(LedgerBase.type != LedgerType.by_name('Cash').id) \ ).join(
.group_by(LedgerBase.type) \ LedgerBase, Journal.ledger
.order_by(func.sum(Journal.signed_amount)).all() ).filter(
Voucher.id.in_(sub_query)
).filter(
LedgerBase.type != LedgerType.by_name('Cash').id
).group_by(
LedgerBase.type
).order_by(
func.sum(Journal.signed_amount)
).all()
total_inflow = 0 total_amount = 0
total_outflow = 0 cf = {'Operating': [], 'Investing': [], 'Financing': []}
for ledgerType, amount in query: for ledgerType, amount in query:
lt = LedgerType.by_id(ledgerType) lt = LedgerType.by_id(ledgerType)
inflow = amount * -1 if amount < 0 else 0 total_amount += (amount * -1)
outflow = amount if amount >= 0 else 0 cf[lt.cash_flow_classification].append(
total_inflow += (amount * -1) if amount < 0 else 0 {
total_outflow += amount if amount >= 0 else 0 'Name': lt.name,
report['Body'].append({'Name': lt.name, 'Url': request.route_url('cash_flow_id', id=str(lt.id), 'Url': request.route_url(
_query={'StartDate': start_date, 'cash_flow_id',
'FinishDate': finish_date}), id=str(lt.id),
'Inflow': inflow, 'Outflow': outflow}) _query={'StartDate': start_date, 'FinishDate': finish_date}
),
'Amount': amount * -1
}
)
for key, value in cf.items():
if len(value) == 0:
continue
report['Body'].append({'Name': 'Cash flow from ' + key + ' activities'})
for item in value:
report['Body'].append(item)
report['Footer'].append({'Name': 'Total', 'Inflow': total_inflow, 'Outflow': total_outflow}) report['Footer'].append({'Name': 'Net Cash Flow', 'Amount': total_amount})
net_inflow = total_inflow - total_outflow
report['Footer'].append({'Name': 'Net', 'Inflow': (net_inflow if net_inflow >= 0 else 0),
'Outflow': (net_inflow * -1 if net_inflow < 0 else 0)})
return report return report
@ -87,12 +101,19 @@ def build_report_id(request, ledger_type, start_date, finish_date):
sub_journal = aliased(Journal) sub_journal = aliased(Journal)
sub_ledger = aliased(LedgerBase) sub_ledger = aliased(LedgerBase)
sub_query = request.dbsession.query(sub_voucher.id) \ sub_query = request.dbsession.query(
.join(sub_journal, sub_voucher.journals) \ sub_voucher.id
.join(sub_ledger, sub_journal.ledger) \ ).join(
.filter(sub_ledger.type == LedgerType.by_name('Cash').id) \ sub_journal, sub_voucher.journals
.filter(sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \ ).join(
.filter(sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')).subquery() sub_ledger, sub_journal.ledger
).filter(
sub_ledger.type == LedgerType.by_name('Cash').id
).filter(
sub_voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')
).filter(
sub_voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')
).subquery()
query = request.dbsession.query(LedgerBase, func.sum(Journal.signed_amount)) \ query = request.dbsession.query(LedgerBase, func.sum(Journal.signed_amount)) \
.join(Journal, Voucher.journals) \ .join(Journal, Voucher.journals) \
@ -102,17 +123,19 @@ def build_report_id(request, ledger_type, start_date, finish_date):
.group_by(LedgerBase) \ .group_by(LedgerBase) \
.order_by(desc(func.sum(Journal.amount))).all() .order_by(desc(func.sum(Journal.amount))).all()
total_inflow = 0 total_amount = 0
total_outflow = 0
for ledger, amount in query: for ledger, amount in query:
inflow = amount * -1 if amount < 0 else 0 total_amount += (amount * -1)
outflow = amount if amount >= 0 else 0 report['Body'].append(
total_inflow += (amount * -1) if amount < 0 else 0 {
total_outflow += amount if amount >= 0 else 0 'Name': ledger.name,
report['Body'].append({'Name': ledger.name, 'Url': request.route_url('ledger_id', id=ledger.id, 'Url': request.route_url(
_query={'StartDate': start_date, 'ledger_id', id=ledger.id,
'FinishDate': finish_date}), _query={'StartDate': start_date, 'FinishDate': finish_date}
'Inflow': inflow, 'Outflow': outflow}) ),
'Amount': amount * -1
}
)
report['Footer'].append({'Name': 'Total', 'Inflow': total_inflow, 'Outflow': total_outflow}) report['Footer'].append({'Name': 'Total', 'Amount': total_amount})
return report return report