You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
705 lines
31 KiB
705 lines
31 KiB
"""Partner Ageing"""
|
|
import io
|
|
import json
|
|
import xlsxwriter
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import ValidationError, UserError
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
FETCH_RANGE = 2500
|
|
|
|
|
|
class PartnerAgeing(models.TransientModel):
|
|
""" Transient class For Ageing partner"""
|
|
_name = "dynamic.ageing.partner"
|
|
|
|
@api.onchange('partner_type')
|
|
def onchange_partner_type(self):
|
|
self.partner_ids = [(5,)]
|
|
if self.partner_type:
|
|
company_id = self.env.user.company_id
|
|
if self.partner_type == 'customer':
|
|
partner_company_domain = [('parent_id', '=', False),
|
|
('customer', '=', True),
|
|
'|',
|
|
('company_id', '=', company_id.id),
|
|
('company_id', '=', False)]
|
|
|
|
self.partner_ids |= self.env['res.partner'].search \
|
|
(partner_company_domain)
|
|
if self.partner_type == 'supplier':
|
|
partner_company_domain = [('parent_id', '=', False),
|
|
('supplier', '=', True),
|
|
'|',
|
|
('company_id', '=', company_id.id),
|
|
('company_id', '=', False)]
|
|
|
|
self.partner_ids |= self.env['res.partner'].search \
|
|
(partner_company_domain)
|
|
|
|
def name_get(self):
|
|
res = []
|
|
for record in self:
|
|
res.append((record.id, 'Ageing'))
|
|
return res
|
|
|
|
as_on_date = fields.Date(string='As on date', required=True,
|
|
default=fields.Date.today())
|
|
bucket_1 = fields.Integer(string='Bucket 1', required=True, default=20)
|
|
bucket_2 = fields.Integer(string='Bucket 2', required=True, default=40)
|
|
bucket_3 = fields.Integer(string='Bucket 3', required=True, default=60)
|
|
bucket_4 = fields.Integer(string='Bucket 4', required=True, default=80)
|
|
bucket_5 = fields.Integer(string='Bucket 5', required=True, default=100)
|
|
include_details = fields.Boolean(string='Include Details', default=True)
|
|
type = fields.Selection([('receivable', 'Receivable Accounts Only'),
|
|
('payable', 'Payable Accounts Only')],
|
|
string='Type')
|
|
partner_type = fields.Selection([('customer', 'Customer Only'),
|
|
('supplier', 'Supplier Only')],
|
|
string='Partner Type')
|
|
|
|
partner_ids = fields.Many2many(
|
|
'res.partner', required=False
|
|
)
|
|
partner_category_ids = fields.Many2many(
|
|
'res.partner.category', string='Partner Tag',
|
|
)
|
|
target_moves = fields.Selection(
|
|
[('draft', 'Draft'),
|
|
('posted', 'Posted')], default='draft', string='Target Moves'
|
|
|
|
)
|
|
company_id = fields.Many2one(
|
|
'res.company', string='Company',
|
|
|
|
)
|
|
|
|
def write(self, vals):
|
|
|
|
if not vals.get('partner_ids'):
|
|
vals.update({
|
|
'partner_ids': [(5, 0, 0)]
|
|
})
|
|
|
|
if vals.get('partner_category_ids'):
|
|
vals.update({'partner_category_ids': [(4, j) for j in vals.get(
|
|
'partner_category_ids')]})
|
|
if vals.get('partner_category_ids') == []:
|
|
vals.update({'partner_category_ids': [(5,)]})
|
|
ret = super(PartnerAgeing, self).write(vals)
|
|
|
|
return ret
|
|
|
|
def validate_data(self):
|
|
if not (self.bucket_1 < self.bucket_2 and
|
|
self.bucket_2 < self.bucket_3 and
|
|
self.bucket_3 < self.bucket_4 and
|
|
self.bucket_4 < self.bucket_5):
|
|
raise ValidationError(_('"Bucket order must be ascending"'))
|
|
return True
|
|
|
|
def get_filters(self, default_filters={}):
|
|
""" shows filters """
|
|
company_id = self.env.user.company_id
|
|
partner_company_domain = [('parent_id', '=', False),
|
|
# '|',
|
|
# ('customer_rank', '=', True),
|
|
# ('supplier_rank', '=', True),
|
|
'|',
|
|
('company_id', '=', company_id.id),
|
|
('company_id', '=', False)]
|
|
|
|
partners = self.partner_ids if self.partner_ids else self.env[
|
|
'res.partner'].search(partner_company_domain)
|
|
categories = self.partner_category_ids if self.partner_category_ids else \
|
|
self.env['res.partner.category'].search([])
|
|
|
|
filter_dict = {
|
|
'partner_ids': self.partner_ids.ids,
|
|
'partner_category_ids': self.partner_category_ids.ids,
|
|
'company_id': self.company_id and self.company_id.id or False,
|
|
'as_on_date': self.as_on_date,
|
|
'type': self.type,
|
|
'target_moves': self.target_moves,
|
|
'partner_type': self.partner_type,
|
|
'bucket_1': self.bucket_1,
|
|
'bucket_2': self.bucket_2,
|
|
'bucket_3': self.bucket_3,
|
|
'bucket_4': self.bucket_4,
|
|
'bucket_5': self.bucket_5,
|
|
'include_details': self.include_details,
|
|
|
|
'partners_list': [(p.id, p.name) for p in partners],
|
|
'category_list': [(c.id, c.name) for c in categories],
|
|
'company_name': self.company_id and self.company_id.name,
|
|
}
|
|
filter_dict.update(default_filters)
|
|
return filter_dict
|
|
|
|
def process_filters(self):
|
|
''' To show on report headers'''
|
|
|
|
data = self.get_filters(default_filters={})
|
|
filters = {}
|
|
filters['bucket_1'] = data.get('bucket_1')
|
|
filters['bucket_2'] = data.get('bucket_2')
|
|
filters['bucket_3'] = data.get('bucket_3')
|
|
filters['bucket_4'] = data.get('bucket_4')
|
|
filters['bucket_5'] = data.get('bucket_5')
|
|
|
|
if data.get('partner_ids', []):
|
|
filters['partners'] = self.env['res.partner'].browse(
|
|
data.get('partner_ids', [])).mapped('name')
|
|
else:
|
|
filters['partners'] = ['All']
|
|
|
|
if data.get('as_on_date', False):
|
|
filters['as_on_date'] = data.get('as_on_date')
|
|
|
|
if data.get('company_id'):
|
|
filters['company_id'] = data.get('company_id')
|
|
else:
|
|
filters['company_id'] = ''
|
|
|
|
if data.get('target_moves') == 'draft':
|
|
|
|
filters['target_moves'] = 'All Entries'
|
|
else:
|
|
filters['target_moves'] = 'Posted Only'
|
|
|
|
if data.get('type') == 'receivable':
|
|
filters['type'] = 'Receivable'
|
|
elif data.get('type') == 'payable':
|
|
filters['type'] = 'Payable'
|
|
else:
|
|
filters['type'] = 'Receivable and Payable'
|
|
|
|
if data.get('partner_type') == 'customer':
|
|
filters['partner_type'] = 'Customer Only'
|
|
elif data.get('partner_type') == 'supplier':
|
|
filters['partner_type'] = 'Supplier Only'
|
|
else:
|
|
filters['partner_type'] = 'Customer And Supplier '
|
|
|
|
if data.get('partner_category_ids', []):
|
|
filters['categories'] = self.env['res.partner.category'].browse(
|
|
data.get('partner_category_ids', [])).mapped('name')
|
|
else:
|
|
filters['categories'] = ['All']
|
|
|
|
if data.get('include_details'):
|
|
filters['include_details'] = True
|
|
else:
|
|
filters['include_details'] = False
|
|
|
|
filters['partners_list'] = data.get('partners_list')
|
|
filters['category_list'] = data.get('category_list')
|
|
filters['company_name'] = data.get('company_name')
|
|
|
|
return filters
|
|
|
|
def prepare_bucket_list(self):
|
|
""" prepare bucket values for partner ageing report"""
|
|
periods = {}
|
|
date_from = self.as_on_date
|
|
date_from = fields.Date.from_string(date_from)
|
|
bucket_list = [self.bucket_1, self.bucket_2, self.bucket_3,
|
|
self.bucket_4, self.bucket_5]
|
|
start = False
|
|
stop = date_from
|
|
name = 'Not'
|
|
periods[0] = {
|
|
'bucket': 'As on',
|
|
'name': name,
|
|
'start': '',
|
|
'stop': stop.strftime('%Y-%m-%d'),
|
|
}
|
|
|
|
stop = date_from
|
|
final_date = False
|
|
for i in range(5):
|
|
start = stop - relativedelta(days=1)
|
|
stop = start - relativedelta(days=bucket_list[i])
|
|
name = 'value_' + str(bucket_list[0]) if i == 0 else str(
|
|
str(bucket_list[i - 1] + 1)) + str(bucket_list[i])
|
|
|
|
final_date = stop
|
|
periods[i + 1] = {
|
|
'bucket': bucket_list[i],
|
|
'name': name,
|
|
'start': start.strftime('%Y-%m-%d'),
|
|
'stop': stop.strftime('%Y-%m-%d'),
|
|
}
|
|
|
|
start = final_date - relativedelta(days=1)
|
|
stop = ''
|
|
name = str(self.bucket_5)
|
|
|
|
periods[6] = {
|
|
'bucket': 'Above',
|
|
'name': name,
|
|
'start': start.strftime('%Y-%m-%d'),
|
|
'stop': '',
|
|
}
|
|
return periods
|
|
|
|
def al_move_lines(self, offset=0, partner=0, fetch_range=FETCH_RANGE):
|
|
""" shows detailed move lines"""
|
|
|
|
as_on_date = self.as_on_date
|
|
period_dict = self.prepare_bucket_list()
|
|
period_list = [period_dict[a]['name'] for a in period_dict]
|
|
company_id = self.env.user.company_id
|
|
type = ('receivable', 'payable')
|
|
if self.type:
|
|
type = tuple([self.type, 'none'])
|
|
arg_list = ('draft', 'posted')
|
|
if self.target_moves == 'posted':
|
|
arg_list = tuple([self.target_moves, 'none'])
|
|
offset = offset * fetch_range
|
|
count = 0
|
|
move_lines = []
|
|
if partner:
|
|
sql = """
|
|
SELECT COUNT(*)
|
|
FROM
|
|
account_move_line AS l
|
|
LEFT JOIN
|
|
account_move AS m ON m.id = l.move_id
|
|
LEFT JOIN
|
|
account_account AS a ON a.id = l.account_id
|
|
LEFT JOIN
|
|
account_account_type AS ty ON a.user_type_id = ty.id
|
|
LEFT JOIN
|
|
account_journal AS j ON l.journal_id = j.id
|
|
WHERE
|
|
l.balance <> 0
|
|
AND m.state IN %s
|
|
AND ty.type IN %s
|
|
AND l.partner_id = %s
|
|
AND l.date <= '%s'
|
|
AND l.company_id = %s
|
|
""" % (arg_list, type, partner, as_on_date, company_id.id)
|
|
self.env.cr.execute(sql)
|
|
count = self.env.cr.fetchone()[0]
|
|
|
|
SELECT = """SELECT m.name AS move_name,
|
|
m.id AS move_id,
|
|
l.date AS date,
|
|
l.date_maturity AS date_maturity,
|
|
j.name AS journal_name,
|
|
cc.id AS company_currency_id,
|
|
a.name AS account_name,
|
|
a.code AS account_code,
|
|
c.symbol AS currency_symbol,
|
|
c.position AS currency_position,
|
|
c.rounding AS currency_precision,
|
|
cc.id AS company_currency_id,
|
|
cc.symbol AS company_currency_symbol,
|
|
cc.rounding AS company_currency_precision,
|
|
cc.position AS company_currency_position,"""
|
|
|
|
for period in period_dict:
|
|
if period_dict[period].get('start') and period_dict[period].get(
|
|
'stop'):
|
|
SELECT += """ CASE
|
|
WHEN
|
|
COALESCE(l.date_maturity,l.date) >= '%s' AND
|
|
COALESCE(l.date_maturity,l.date) <= '%s'
|
|
THEN
|
|
sum(l.balance) +
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE credit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
) -
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE debit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
)
|
|
ELSE
|
|
0
|
|
END AS %s,""" % (
|
|
period_dict[period].get('stop'),
|
|
period_dict[period].get('start'),
|
|
as_on_date,
|
|
as_on_date,
|
|
'range_' + str(period),
|
|
)
|
|
elif not period_dict[period].get('start'):
|
|
SELECT += """ CASE
|
|
WHEN
|
|
COALESCE(l.date_maturity,l.date) >= '%s'
|
|
THEN
|
|
sum(
|
|
l.balance
|
|
) +
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE credit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
) -
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE debit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
)
|
|
ELSE
|
|
0
|
|
END AS %s,""" % (
|
|
period_dict[period].get('stop'), as_on_date, as_on_date,
|
|
'range_' + str(period))
|
|
else:
|
|
SELECT += """ CASE
|
|
WHEN
|
|
COALESCE(l.date_maturity,l.date) <= '%s'
|
|
THEN
|
|
sum(
|
|
l.balance
|
|
) +
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE credit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
) -
|
|
sum(
|
|
COALESCE(
|
|
(SELECT
|
|
SUM(amount)
|
|
FROM account_partial_reconcile
|
|
WHERE debit_move_id = l.id AND max_date <= '%s'), 0
|
|
)
|
|
)
|
|
ELSE
|
|
0
|
|
END AS %s """ % (
|
|
period_dict[period].get('start'), as_on_date,
|
|
as_on_date,
|
|
'range_' + str(period))
|
|
|
|
sql = """
|
|
|
|
FROM
|
|
account_move_line AS l
|
|
LEFT JOIN
|
|
account_move AS m ON m.id = l.move_id
|
|
LEFT JOIN
|
|
account_account AS a ON a.id = l.account_id
|
|
LEFT JOIN
|
|
account_account_type AS ty ON a.user_type_id = ty.id
|
|
LEFT JOIN
|
|
account_journal AS j ON l.journal_id = j.id
|
|
LEFT JOIN
|
|
res_currency AS c ON l.currency_id = c.id
|
|
LEFT JOIN
|
|
res_currency AS cc ON l.company_currency_id = cc.id
|
|
WHERE
|
|
l.balance <> 0
|
|
AND m.state IN %s
|
|
AND ty.type IN %s
|
|
AND l.partner_id = %s
|
|
AND l.date <= '%s'
|
|
AND l.company_id = %s
|
|
GROUP BY
|
|
l.date, l.date_maturity,l.currency_id, m.id, m.name, j.name, a.name,a.code, c.rounding, cc.id, cc.rounding, cc.position, c.position, c.symbol, cc.symbol
|
|
OFFSET %s ROWS
|
|
FETCH FIRST %s ROWS ONLY
|
|
""" % (
|
|
arg_list, type, partner, as_on_date, company_id.id, offset, fetch_range)
|
|
self.env.cr.execute(SELECT + sql)
|
|
final_list = self.env.cr.dictfetchall() or 0.0
|
|
|
|
for m_list in final_list:
|
|
if (m_list['range_0'] or m_list['range_1'] or m_list['range_2'] or
|
|
m_list['range_3'] or m_list['range_4'] or m_list['range_5']):
|
|
move_lines.append(m_list)
|
|
return count, offset, move_lines, period_list
|
|
|
|
def report_data(self):
|
|
""" fetch values from query to get report, prepare bucket values """
|
|
data = self.get_filters(default_filters={})
|
|
|
|
period_dict = self.prepare_bucket_list()
|
|
company_id = self.env.user.company_id
|
|
domain = ['|', ('company_id', '=', company_id.id),
|
|
('company_id', '=', False)]
|
|
if self.partner_type == 'customer':
|
|
domain.append(('customer_rank', '=', True))
|
|
if self.partner_type == 'supplier':
|
|
domain.append(('supplier_rank', '=', True))
|
|
|
|
if self.partner_category_ids:
|
|
domain.append(('category_id', 'in', self.partner_category_ids.ids))
|
|
|
|
partner_ids = self.partner_ids or self.env['res.partner'].search(domain)
|
|
as_on_date = self.as_on_date
|
|
company_currency_id = company_id.currency_id.id
|
|
company_currency_symbol = company_id.currency_id.symbol
|
|
company_currency_position = company_id.currency_id.position
|
|
company_currency_precision = company_id.currency_id.rounding
|
|
|
|
type = ('receivable', 'payable')
|
|
if self.type:
|
|
type = tuple([self.type, 'none'])
|
|
arg_list = ('draft', 'posted')
|
|
if self.target_moves == 'posted':
|
|
arg_list = tuple([self.target_moves, 'none'])
|
|
|
|
partner_dict = {}
|
|
for partner in partner_ids:
|
|
partner_dict.update({partner.id: {}})
|
|
|
|
for partner in partner_ids:
|
|
partner_dict[partner.id].update(
|
|
{'id': partner.id, 'partner_name': partner.name})
|
|
|
|
total_balance = 0.0
|
|
sql = """
|
|
SELECT
|
|
|
|
COUNT(*) AS count
|
|
FROM
|
|
account_move_line AS l
|
|
LEFT JOIN
|
|
account_move AS m ON m.id = l.move_id
|
|
LEFT JOIN
|
|
account_account AS a ON a.id = l.account_id
|
|
LEFT JOIN
|
|
account_account_type AS ty ON a.user_type_id = ty.id
|
|
WHERE
|
|
l.balance <> 0
|
|
AND m.state IN %s
|
|
AND ty.type IN %s
|
|
AND l.partner_id = %s
|
|
AND l.date <= '%s'
|
|
AND l.company_id = %s
|
|
""" % (arg_list, type, partner.id, as_on_date, company_id.id)
|
|
self.env.cr.execute(sql)
|
|
|
|
fetch_dict = self.env.cr.dictfetchone() or 0.0
|
|
|
|
count = fetch_dict.get('count') or 0.0
|
|
|
|
if count:
|
|
for period in period_dict:
|
|
|
|
where = " AND l.date <= '%s' AND l.partner_id = %s " \
|
|
"AND COALESCE(l.date_maturity,l.date) " % (
|
|
as_on_date, partner.id)
|
|
if period_dict[period].get('start') and period_dict[
|
|
period].get('stop'):
|
|
where += " BETWEEN '%s' AND '%s'" % (
|
|
period_dict[period].get('stop'),
|
|
period_dict[period].get('start'))
|
|
elif not period_dict[period].get('start'): # ie just
|
|
where += " >= '%s'" % (period_dict[period].get('stop'))
|
|
else:
|
|
where += " <= '%s'" % (period_dict[period].get('start'))
|
|
|
|
sql = """
|
|
SELECT
|
|
sum(l.balance) AS balance,
|
|
sum(COALESCE((SELECT SUM(amount)FROM account_partial_reconcile
|
|
WHERE credit_move_id = l.id AND max_date <= '%s'), 0)) AS sum_debit,
|
|
sum(COALESCE((SELECT SUM(amount) FROM account_partial_reconcile
|
|
WHERE debit_move_id = l.id AND max_date <= '%s'), 0)) AS sum_credit
|
|
FROM
|
|
account_move_line AS l
|
|
LEFT JOIN
|
|
account_move AS m ON m.id = l.move_id
|
|
LEFT JOIN
|
|
account_account AS a ON a.id = l.account_id
|
|
LEFT JOIN
|
|
account_account_type AS ty ON a.user_type_id = ty.id
|
|
WHERE
|
|
l.balance <> 0
|
|
|
|
AND ty.type IN %s
|
|
AND m.state IN %s
|
|
AND l.company_id = %s
|
|
""" % (as_on_date, as_on_date, type, arg_list, company_id.id)
|
|
amount = 0.0
|
|
self.env.cr.execute(sql + where)
|
|
|
|
fetch_dict = self.env.cr.dictfetchall() or 0.0
|
|
|
|
if not fetch_dict[0].get('balance'):
|
|
amount = 0.0
|
|
else:
|
|
amount = fetch_dict[0]['balance'] + fetch_dict[0][
|
|
'sum_debit'] - fetch_dict[0]['sum_credit']
|
|
total_balance += amount
|
|
|
|
partner_dict[partner.id].update(
|
|
{period_dict[period]['name']: amount})
|
|
|
|
partner_dict[partner.id].update({'count': count})
|
|
|
|
partner_dict[partner.id].update(
|
|
{'pages': self.get_page_list(count)})
|
|
partner_dict[partner.id].update(
|
|
{'single_page': True if count <= FETCH_RANGE else False})
|
|
partner_dict[partner.id].update({'total': total_balance})
|
|
partner_dict[partner.id].update(
|
|
{'company_currency_id': company_currency_id})
|
|
partner_dict[partner.id].update(
|
|
{'company_currency_symbol': company_currency_symbol})
|
|
partner_dict[partner.id].update(
|
|
{'company_currency_position': company_currency_position})
|
|
partner_dict[partner.id].update(
|
|
{'company_currency_precision': company_currency_precision})
|
|
partner_dict[partner.id].update(
|
|
{'partner_move_lines': self.al_move_lines(0, partner.id,
|
|
2500)})
|
|
|
|
else:
|
|
partner_dict.pop(partner.id, None)
|
|
|
|
return period_dict, partner_dict
|
|
|
|
def get_page_list(self, total_count):
|
|
'''
|
|
Helper function to get list of pages from total_count
|
|
:param total_count: integer
|
|
:return: list(pages) eg. [1,2,3,4,5,6,7 ....]
|
|
'''
|
|
page_count = int(total_count / FETCH_RANGE)
|
|
if total_count % FETCH_RANGE:
|
|
page_count += 1
|
|
return [i + 1 for i in range(0, int(page_count))] or []
|
|
|
|
def get_data(self, default_filters={}, data=None):
|
|
""" return period list and filters"""
|
|
filters = self.process_filters()
|
|
period_dict, partner_lines = self.report_data()
|
|
period_list = [period_dict[a]['name'] for a in period_dict]
|
|
return filters, partner_lines, period_dict, period_list
|
|
|
|
def get_xlsx_report(self, data, response, report_data, dfr_data):
|
|
""" xlsx report of Partner Ageing"""
|
|
|
|
i_data = str(data)
|
|
n_data = json.loads(i_data)
|
|
filters = json.loads(report_data)
|
|
output = io.BytesIO()
|
|
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
|
|
cell_format = workbook.add_format(
|
|
{'align': 'center', 'bold': True, 'bg_color': '#d3d3d3;',
|
|
'border': 1})
|
|
sheet = workbook.add_worksheet()
|
|
head = workbook.add_format({'align': 'center', 'bold': True,
|
|
'font_size': '20px'})
|
|
txt = workbook.add_format({'font_size': '10px', 'border': 1})
|
|
sub_heading_sub = workbook.add_format(
|
|
{'align': 'center', 'bold': True, 'font_size': '10px',
|
|
'border': 2,
|
|
'border_color': 'black'})
|
|
sheet.merge_range('E1:I2',
|
|
self.env.user.company_id.name + ':' + ' Partner Ageing',
|
|
head)
|
|
date_head = workbook.add_format({'align': 'center', 'bold': True,
|
|
'font_size': '10px'})
|
|
sheet.merge_range('A3:C3', 'As On Date: ' + filters.get('as_on_date'),
|
|
date_head)
|
|
sheet.merge_range('D3:F3', 'Account Type: ' + filters.get('type'), date_head)
|
|
sheet.merge_range('G3:H3', 'Target Moves: ' + filters.get('target_moves'),
|
|
date_head)
|
|
sheet.merge_range('I3:J3',
|
|
'Partner Type: ' + filters.get('partner_type'),
|
|
date_head)
|
|
sheet.merge_range('D4:F4', ' Partners: ' + ', '.join(
|
|
[lt or '' for lt in
|
|
filters['partners']]), date_head)
|
|
sheet.merge_range('G4:H4', ' Partner Type: ' + ', '.join(
|
|
[lt or '' for lt in
|
|
filters['categories']]),
|
|
date_head)
|
|
sheet.merge_range('A5:C5', 'Partner', cell_format)
|
|
sheet.write('D5', 'Total', cell_format)
|
|
sheet.write('E5', 'Not Due', cell_format)
|
|
sheet.write('F5', '0-20', cell_format)
|
|
sheet.write('G5', '21-40', cell_format)
|
|
sheet.write('H5', '41-60', cell_format)
|
|
sheet.write('I5', '61-80', cell_format)
|
|
sheet.write('J5', '81-100', cell_format)
|
|
sheet.write('K5', '100+', cell_format)
|
|
|
|
lst = []
|
|
for rec in n_data:
|
|
lst.append(rec)
|
|
row = 4
|
|
col = 0
|
|
sheet.set_column(5, 5, 15)
|
|
sheet.set_column(6, 6, 15)
|
|
sheet.set_column(7, 7, 26)
|
|
sheet.set_column(8, 8, 15)
|
|
sheet.set_column(9, 9, 15)
|
|
sheet.set_column(6, 6, 15)
|
|
sheet.set_column(7, 7, 26)
|
|
sheet.set_column(8, 8, 15)
|
|
sheet.set_column(9, 9, 15)
|
|
|
|
for l_rec in lst:
|
|
one_lst = []
|
|
two_lst = []
|
|
|
|
if n_data[l_rec]['count']:
|
|
one_lst.append(n_data[l_rec])
|
|
two_lst = (n_data[l_rec]['partner_move_lines'][2])
|
|
sheet.merge_range(row + 1, col, row + 1, col + 2,
|
|
n_data[l_rec]['partner_name'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 3, n_data[l_rec]['total'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 4, n_data[l_rec]['Not'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 5, n_data[l_rec]['value_20'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 6, n_data[l_rec]['2140'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 7, n_data[l_rec]['4160'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 8, n_data[l_rec]['6180'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 9, n_data[l_rec]['81100'], sub_heading_sub)
|
|
sheet.write(row + 1, col + 10, n_data[l_rec]['100'], sub_heading_sub)
|
|
|
|
row += 2
|
|
sheet.write(row, col, 'Entry Label', cell_format)
|
|
sheet.write(row, col + 1, 'Due Date', cell_format)
|
|
sheet.write(row, col + 2, 'Journal', cell_format)
|
|
sheet.write(row, col + 3, 'Account', cell_format)
|
|
sheet.write(row, col + 4, 'Not Due', cell_format)
|
|
sheet.write(row, col + 5, '0 - 20', cell_format)
|
|
sheet.write(row, col + 6, '21 - 40', cell_format)
|
|
sheet.write(row, col + 7, '41 - 60', cell_format)
|
|
sheet.write(row, col + 8, '61 - 80', cell_format)
|
|
sheet.write(row, col + 9, '81 - 100', cell_format)
|
|
sheet.write(row, col + 10, '100 +', cell_format)
|
|
for r_rec in two_lst:
|
|
row += 1
|
|
sheet.write(row, col, r_rec['move_name'], txt)
|
|
sheet.write(row, col + 1, r_rec['date_maturity'], txt)
|
|
sheet.write(row, col + 2, r_rec['journal_name'], txt)
|
|
sheet.write(row, col + 3, r_rec['account_code'], txt)
|
|
sheet.write(row, col + 4, r_rec['range_0'], txt)
|
|
sheet.write(row, col + 5, r_rec['range_1'], txt)
|
|
sheet.write(row, col + 6, r_rec['range_2'], txt)
|
|
sheet.write(row, col + 7, r_rec['range_3'], txt)
|
|
sheet.write(row, col + 8, r_rec['range_4'], txt)
|
|
sheet.write(row, col + 9, r_rec['range_5'], txt)
|
|
sheet.write(row, col + 10, r_rec['range_6'], txt)
|
|
|
|
workbook.close()
|
|
output.seek(0)
|
|
response.stream.write(output.read())
|
|
output.close()
|
|
|