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.
		
		
		
		
		
			
		
			
				
					
					
						
							449 lines
						
					
					
						
							22 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							449 lines
						
					
					
						
							22 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								################################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
							 | 
						|
								#    Author: Ammu Raj (odoo@cybrosys.com)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
							 | 
						|
								#
							 | 
						|
								#    This program is distributed in the hope that it will be useful,
							 | 
						|
								#    but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
								#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						|
								#    GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								################################################################################
							 | 
						|
								import calendar
							 | 
						|
								import io
							 | 
						|
								import json
							 | 
						|
								from datetime import datetime
							 | 
						|
								import xlsxwriter
							 | 
						|
								from odoo import api, fields, models
							 | 
						|
								from odoo.tools.date_utils import get_month, get_fiscal_year, \
							 | 
						|
								    get_quarter_number, subtract
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class AccountTrialBalance(models.TransientModel):
							 | 
						|
								    """For creating Trial Balance report"""
							 | 
						|
								    _name = 'account.trial.balance'
							 | 
						|
								    _description = 'Trial Balance Report'
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def view_report(self):
							 | 
						|
								        """
							 | 
						|
								        Generates a trial balance report for multiple accounts.
							 | 
						|
								        Retrieves account information and calculates total debit and credit
							 | 
						|
								        amounts for each account within the specified date range. Returns a list
							 | 
						|
								        of dictionaries containing account details and transaction totals.
							 | 
						|
								
							 | 
						|
								        :return: List of dictionaries representing the trial balance report.
							 | 
						|
								        :rtype: list
							 | 
						|
								        """
							 | 
						|
								        account_ids = self.env['account.move.line'].search([]).mapped(
							 | 
						|
								            'account_id')
							 | 
						|
								        today = fields.Date.today()
							 | 
						|
								        move_line_list = []
							 | 
						|
								        for account_id in account_ids:
							 | 
						|
								            initial_move_line_ids = self.env['account.move.line'].search(
							 | 
						|
								                [('date', '<', get_month(today)[0]),
							 | 
						|
								                 ('account_id', '=', account_id.id),
							 | 
						|
								                 ('parent_state', '=', 'posted')])
							 | 
						|
								            initial_total_debit = round(
							 | 
						|
								                sum(initial_move_line_ids.mapped('debit')), 2)
							 | 
						|
								            initial_total_credit = round(
							 | 
						|
								                sum(initial_move_line_ids.mapped('credit')), 2)
							 | 
						|
								            move_line_ids = self.env['account.move.line'].search(
							 | 
						|
								                [('date', '>=', get_month(today)[0]),
							 | 
						|
								                 ('account_id', '=', account_id.id),
							 | 
						|
								                 ('date', '<=', get_month(today)[1]),
							 | 
						|
								                 ('parent_state', '=', 'posted')])
							 | 
						|
								            total_debit = round(sum(move_line_ids.mapped('debit')), 2)
							 | 
						|
								            total_credit = round(sum(move_line_ids.mapped('credit')), 2)
							 | 
						|
								            sum_debit = initial_total_debit + total_debit
							 | 
						|
								            sum_credit = initial_total_credit + total_credit
							 | 
						|
								            diff_credit_debit = sum_debit - sum_credit
							 | 
						|
								            if diff_credit_debit > 0:
							 | 
						|
								                end_total_debit = diff_credit_debit
							 | 
						|
								                end_total_credit = 0.0
							 | 
						|
								            else:
							 | 
						|
								                end_total_debit = 0.0
							 | 
						|
								                end_total_credit = abs(diff_credit_debit)
							 | 
						|
								            data = {
							 | 
						|
								                'account': account_id.display_name,
							 | 
						|
								                'account_id': account_id.id,
							 | 
						|
								                'journal_ids': self.env['account.journal'].search_read([], [
							 | 
						|
								                    'name']),
							 | 
						|
								                'initial_total_debit': initial_total_debit,
							 | 
						|
								                'initial_total_credit': initial_total_credit,
							 | 
						|
								                'total_debit': total_debit,
							 | 
						|
								                'total_credit': total_credit,
							 | 
						|
								                'end_total_debit': end_total_debit,
							 | 
						|
								                'end_total_credit': end_total_credit
							 | 
						|
								            }
							 | 
						|
								            move_line_list.append(data)
							 | 
						|
								        return move_line_list
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def get_filter_values(self, start_date, end_date, comparison_number,
							 | 
						|
								                          comparison_type, journal_list, analytic, options,
							 | 
						|
								                          method):
							 | 
						|
								        """
							 | 
						|
								        Retrieves and calculates filtered values for generating a financial
							 | 
						|
								        report.
							 | 
						|
								        Retrieves and processes account movement data based on the provided
							 | 
						|
								        filters. Calculates initial, dynamic, and end total debit and credit
							 | 
						|
								        amounts for each account,considering date range, comparison type, and
							 | 
						|
								        other filter criteria.
							 | 
						|
								
							 | 
						|
								        :param str start_date: Start date of the reporting period.
							 | 
						|
								        :param str end_date: End date of the reporting period.
							 | 
						|
								        :param int comparison_number: Number of periods for comparison.
							 | 
						|
								        :param str comparison_type: Type of comparison (month, year, quarter).
							 | 
						|
								        :param list[int] journal_list: List of selected journal IDs.
							 | 
						|
								        :param list[int] analytic: List of selected analytic line IDs.
							 | 
						|
								        :param dict options: Additional filtering options (e.g., 'draft').
							 | 
						|
								        :param dict method: Find the method.
							 | 
						|
								        :return: List of dictionaries representing the financial report.
							 | 
						|
								        :rtype: list
							 | 
						|
								        """
							 | 
						|
								        if options == {}:
							 | 
						|
								            options = None
							 | 
						|
								        if options is None:
							 | 
						|
								            option_domain = ['posted']
							 | 
						|
								        elif 'draft' in options:
							 | 
						|
								            option_domain = ['posted', 'draft']
							 | 
						|
								        if method == {}:
							 | 
						|
								            method = None
							 | 
						|
								        dynamic_total_debit = {}
							 | 
						|
								        dynamic_date_num = {}
							 | 
						|
								        dynamic_total_credit = {}
							 | 
						|
								        account_ids = self.env['account.move.line'].search([]).mapped(
							 | 
						|
								            'account_id')
							 | 
						|
								        move_line_list = []
							 | 
						|
								        start_date_first = \
							 | 
						|
								            get_fiscal_year(datetime.strptime(start_date, "%Y-%m-%d").date())[
							 | 
						|
								                0] if comparison_type == 'year' else datetime.strptime(
							 | 
						|
								                start_date, "%Y-%m-%d").date()
							 | 
						|
								        end_date_first = \
							 | 
						|
								            get_fiscal_year(datetime.strptime(end_date, "%Y-%m-%d").date())[
							 | 
						|
								                1] if comparison_type == 'year' else datetime.strptime(end_date,
							 | 
						|
								                                                                       "%Y-%m-%d").date()
							 | 
						|
								        for account_id in account_ids:
							 | 
						|
								            start_date = start_date_first
							 | 
						|
								            end_date = end_date_first
							 | 
						|
								            if comparison_number:
							 | 
						|
								                if comparison_type == 'month':
							 | 
						|
								                    initial_start_date = subtract(start_date, months=eval(
							 | 
						|
								                        comparison_number))
							 | 
						|
								                elif comparison_type == 'year':
							 | 
						|
								                    initial_start_date = subtract(start_date, years=eval(
							 | 
						|
								                        comparison_number))
							 | 
						|
								                else:
							 | 
						|
								                    initial_start_date = subtract(start_date, months=eval(
							 | 
						|
								                        comparison_number) * 3)
							 | 
						|
								            else:
							 | 
						|
								                initial_start_date = start_date
							 | 
						|
								            domain = [('date', '<', initial_start_date),
							 | 
						|
								                      ('account_id', '=', account_id.id),
							 | 
						|
								                      ('parent_state', 'in', option_domain), ]
							 | 
						|
								            if journal_list:
							 | 
						|
								                domain.append(
							 | 
						|
								                    ('journal_id', 'in', journal_list), )
							 | 
						|
								            if analytic:
							 | 
						|
								                domain.append(
							 | 
						|
								                    ('analytic_line_ids', 'in', analytic))
							 | 
						|
								            if method is not None and 'cash' in method:
							 | 
						|
								                domain.append(('journal_id', 'in',
							 | 
						|
								                               self.env.company.tax_cash_basis_journal_id.ids))
							 | 
						|
								            initial_move_line_ids = self.env['account.move.line'].search(
							 | 
						|
								                domain)
							 | 
						|
								            initial_total_debit = round(
							 | 
						|
								                sum(initial_move_line_ids.mapped('debit')), 2)
							 | 
						|
								            initial_total_credit = round(
							 | 
						|
								                sum(initial_move_line_ids.mapped('credit')), 2)
							 | 
						|
								            if comparison_number:
							 | 
						|
								                if comparison_type == 'year':
							 | 
						|
								                    for i in range(1, eval(comparison_number) + 1):
							 | 
						|
								                        com_start_date = subtract(start_date, years=i)
							 | 
						|
								                        com_end_date = subtract(end_date, years=i)
							 | 
						|
								                        domain = [('date', '>=', com_start_date),
							 | 
						|
								                                  ('account_id', '=', account_id.id),
							 | 
						|
								                                  ('date', '<=', com_end_date),
							 | 
						|
								                                  ('parent_state', 'in', option_domain), ]
							 | 
						|
								                        if journal_list:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('journal_id', 'in', journal_list), )
							 | 
						|
								                        if analytic:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('analytic_line_ids', 'in', analytic))
							 | 
						|
								                        if method is not None and 'cash' in method:
							 | 
						|
								                            domain.append(('journal_id', 'in',
							 | 
						|
								                                           self.env.company.tax_cash_basis_journal_id.ids))
							 | 
						|
								                        move_lines = self.env['account.move.line'].search(
							 | 
						|
								                            domain)
							 | 
						|
								                        dynamic_total_debit[
							 | 
						|
								                            f"dynamic_total_debit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('debit')), 2)
							 | 
						|
								                        dynamic_total_credit[
							 | 
						|
								                            f"dynamic_total_credit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('credit')), 2)
							 | 
						|
								                if comparison_type == 'month':
							 | 
						|
								                    dynamic_date_num[
							 | 
						|
								                        f"dynamic_date_num{0}"] = self.get_month_name(
							 | 
						|
								                        start_date) + ' ' + str(
							 | 
						|
								                        start_date.year)
							 | 
						|
								                    for i in range(1, eval(comparison_number) + 1):
							 | 
						|
								                        com_start_date = subtract(start_date, months=i)
							 | 
						|
								                        com_end_date = subtract(end_date, months=i)
							 | 
						|
								                        domain = [('date', '>=', com_start_date),
							 | 
						|
								                                  ('account_id', '=', account_id.id),
							 | 
						|
								                                  ('date', '<=', com_end_date),
							 | 
						|
								                                  ('parent_state', 'in', option_domain), ]
							 | 
						|
								                        if journal_list:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('journal_id', 'in', journal_list), )
							 | 
						|
								                        if analytic:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('analytic_line_ids', 'in', analytic))
							 | 
						|
								                        if method is not None and 'cash' in method:
							 | 
						|
								                            domain.append(('journal_id', 'in',
							 | 
						|
								                                           self.env.company.tax_cash_basis_journal_id.ids), )
							 | 
						|
								                        move_lines = self.env['account.move.line'].search(
							 | 
						|
								                            domain)
							 | 
						|
								                        dynamic_date_num[
							 | 
						|
								                            f"dynamic_date_num{i}"] = self.get_month_name(
							 | 
						|
								                            com_start_date) + ' ' + str(
							 | 
						|
								                            com_start_date.year)
							 | 
						|
								                        dynamic_total_debit[
							 | 
						|
								                            f"dynamic_total_debit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('debit')), 2)
							 | 
						|
								                        dynamic_total_credit[
							 | 
						|
								                            f"dynamic_total_credit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('credit')), 2)
							 | 
						|
								                if comparison_type == 'quarter':
							 | 
						|
								                    dynamic_date_num[
							 | 
						|
								                        f"dynamic_date_num{0}"] = 'Q' + ' ' + str(
							 | 
						|
								                        get_quarter_number(start_date)) + ' ' + str(
							 | 
						|
								                        start_date.year)
							 | 
						|
								                    for i in range(1, eval(comparison_number) + 1):
							 | 
						|
								                        com_start_date = subtract(start_date, months=i * 3)
							 | 
						|
								                        com_end_date = subtract(end_date, months=i * 3)
							 | 
						|
								                        domain = [('date', '>=', com_start_date),
							 | 
						|
								                                  ('account_id', '=', account_id.id),
							 | 
						|
								                                  ('date', '<=', com_end_date),
							 | 
						|
								                                  ('parent_state', 'in', option_domain), ]
							 | 
						|
								                        if journal_list:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('journal_id', 'in', journal_list), )
							 | 
						|
								                        if analytic:
							 | 
						|
								                            domain.append(
							 | 
						|
								                                ('analytic_line_ids', 'in', analytic))
							 | 
						|
								                        if method is not None and 'cash' in method:
							 | 
						|
								                            domain.append(('journal_id', 'in',
							 | 
						|
								                                           self.env.company.tax_cash_basis_journal_id.ids))
							 | 
						|
								                        move_lines = self.env['account.move.line'].search(
							 | 
						|
								                            domain)
							 | 
						|
								                        dynamic_date_num[
							 | 
						|
								                            f"dynamic_date_num{i}"] = 'Q' + ' ' + str(
							 | 
						|
								                            get_quarter_number(com_start_date)) + ' ' + str(
							 | 
						|
								                            com_start_date.year)
							 | 
						|
								                        dynamic_total_debit[
							 | 
						|
								                            f"dynamic_total_debit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('debit')), 2)
							 | 
						|
								                        dynamic_total_credit[
							 | 
						|
								                            f"dynamic_total_credit_{i}"] = round(
							 | 
						|
								                            sum(move_lines.mapped('credit')), 2)
							 | 
						|
								            domain = [('date', '>=', start_date),
							 | 
						|
								                      ('account_id', '=', account_id.id),
							 | 
						|
								                      ('date', '<=', end_date),
							 | 
						|
								                      ('parent_state', 'in', option_domain), ]
							 | 
						|
								            if journal_list:
							 | 
						|
								                domain.append(
							 | 
						|
								                    ('journal_id', 'in', journal_list), )
							 | 
						|
								            if analytic:
							 | 
						|
								                domain.append(
							 | 
						|
								                    ('analytic_line_ids', 'in', analytic))
							 | 
						|
								            if method is not None and 'cash' in method:
							 | 
						|
								                domain.append(('journal_id', 'in',
							 | 
						|
								                               self.env.company.tax_cash_basis_journal_id.ids))
							 | 
						|
								            move_line_ids = self.env['account.move.line'].search(domain)
							 | 
						|
								            total_debit = round(sum(move_line_ids.mapped('debit')), 2)
							 | 
						|
								            total_credit = round(sum(move_line_ids.mapped('credit')), 2)
							 | 
						|
								            sum_debit = initial_total_debit + sum(
							 | 
						|
								                dynamic_total_debit.values()) + total_debit
							 | 
						|
								            sum_credit = initial_total_credit + sum(
							 | 
						|
								                dynamic_total_credit.values()) + total_credit
							 | 
						|
								            diff_credit_debit = sum_debit - sum_credit
							 | 
						|
								            if diff_credit_debit > 0:
							 | 
						|
								                end_total_debit = diff_credit_debit
							 | 
						|
								                end_total_credit = 0.0
							 | 
						|
								            else:
							 | 
						|
								                end_total_debit = 0.0
							 | 
						|
								                end_total_credit = abs(diff_credit_debit)
							 | 
						|
								            data = {
							 | 
						|
								                'account': account_id.display_name,
							 | 
						|
								                'account_id': account_id.id,
							 | 
						|
								                'journal_ids': self.env['account.journal'].search_read([], [
							 | 
						|
								                    'name']),
							 | 
						|
								                'initial_total_debit': initial_total_debit,
							 | 
						|
								                'initial_total_credit': initial_total_credit,
							 | 
						|
								                'total_debit': total_debit,
							 | 
						|
								                'total_credit': total_credit,
							 | 
						|
								                'end_total_debit': end_total_debit,
							 | 
						|
								                'end_total_credit': end_total_credit
							 | 
						|
								            }
							 | 
						|
								            if comparison_number:
							 | 
						|
								                if dynamic_date_num:
							 | 
						|
								                    data['dynamic_date_num'] = dynamic_date_num
							 | 
						|
								                for i in range(1, eval(comparison_number) + 1):
							 | 
						|
								                    data[f'dynamic_total_debit_{i}'] = dynamic_total_debit.get(
							 | 
						|
								                        f"dynamic_total_debit_{eval(comparison_number) + 1 - i}",
							 | 
						|
								                        0.0)
							 | 
						|
								                    data[
							 | 
						|
								                        f'dynamic_total_credit_{i}'] = dynamic_total_credit.get(
							 | 
						|
								                        f"dynamic_total_credit_{eval(comparison_number) + 1 - i}",
							 | 
						|
								                        0.0)
							 | 
						|
								            move_line_list.append(data)
							 | 
						|
								        return move_line_list
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def get_month_name(self, date):
							 | 
						|
								        """
							 | 
						|
								        Retrieve the abbreviated name of the month for a given date.
							 | 
						|
								        :param date: The date for which to retrieve the month's abbreviated name.
							 | 
						|
								        :type date: datetime.date
							 | 
						|
								        :return: Abbreviated name of the month (e.g., 'Jan', 'Feb', ..., 'Dec').
							 | 
						|
								        :rtype: str
							 | 
						|
								        """
							 | 
						|
								        month_names = calendar.month_abbr
							 | 
						|
								        return month_names[date.month]
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def get_xlsx_report(self, data, response, report_name, report_action):
							 | 
						|
								        """
							 | 
						|
								        Generate an XLSX report based on provided data and response stream.
							 | 
						|
								        Generates an Excel workbook with specified report format, including
							 | 
						|
								        subheadings,column headers, and row data for the given financial report
							 | 
						|
								        data.
							 | 
						|
								        :param str data: JSON-encoded data for the report.
							 | 
						|
								        :param response: Response object to stream the generated report.
							 | 
						|
								        :param str report_name: Name of the financial report.
							 | 
						|
								        """
							 | 
						|
								        data = json.loads(data)
							 | 
						|
								        output = io.BytesIO()
							 | 
						|
								        workbook = xlsxwriter.Workbook(output, {'in_memory': True})
							 | 
						|
								        start_date = data['filters']['start_date'] if \
							 | 
						|
								            data['filters']['start_date'] else ''
							 | 
						|
								        end_date = data['filters']['end_date'] if \
							 | 
						|
								            data['filters']['end_date'] else ''
							 | 
						|
								        head = workbook.add_format(
							 | 
						|
								            {'font_size': 15, 'align': 'center', 'bold': True})
							 | 
						|
								        sheet = workbook.add_worksheet()
							 | 
						|
								        sub_heading = workbook.add_format(
							 | 
						|
								            {'align': 'center', 'bold': True, 'font_size': '10px',
							 | 
						|
								             'border': 1, 'bg_color': '#D3D3D3',
							 | 
						|
								             'border_color': 'black'})
							 | 
						|
								        filter_head = workbook.add_format(
							 | 
						|
								            {'align': 'center', 'bold': True, 'font_size': '10px',
							 | 
						|
								             'border': 1, 'bg_color': '#D3D3D3',
							 | 
						|
								             'border_color': 'black'})
							 | 
						|
								        filter_body = workbook.add_format(
							 | 
						|
								            {'align': 'center', 'bold': True, 'font_size': '10px'})
							 | 
						|
								        side_heading_sub = workbook.add_format(
							 | 
						|
								            {'align': 'left', 'bold': True, 'font_size': '10px',
							 | 
						|
								             'border': 1,
							 | 
						|
								             'border_color': 'black'})
							 | 
						|
								        side_heading_sub.set_indent(1)
							 | 
						|
								        txt_name = workbook.add_format({'font_size': '10px', 'border': 1})
							 | 
						|
								        txt_name.set_indent(2)
							 | 
						|
								        sheet.set_column(0, 0, 30)
							 | 
						|
								        sheet.set_column(1, 1, 20)
							 | 
						|
								        sheet.set_column(2, 2, 15)
							 | 
						|
								        sheet.set_column(3, 3, 15)
							 | 
						|
								        col = 0
							 | 
						|
								        sheet.write('A1:b1', report_name, head)
							 | 
						|
								        sheet.write('B3:b4', 'Date Range', filter_head)
							 | 
						|
								        sheet.write('B4:b4', 'Comparison', filter_head)
							 | 
						|
								        sheet.write('B5:b4', 'Journal', filter_head)
							 | 
						|
								        sheet.write('B6:b4', 'Account', filter_head)
							 | 
						|
								        sheet.write('B7:b4', 'Option', filter_head)
							 | 
						|
								        if start_date or end_date:
							 | 
						|
								            sheet.merge_range('C3:G3', f"{start_date} to {end_date}",
							 | 
						|
								                              filter_body)
							 | 
						|
								        if data['filters']['comparison_number_range']:
							 | 
						|
								            sheet.merge_range('C4:G4',
							 | 
						|
								                              f"{data['filters']['comparison_type']} : {data['filters']['comparison_number_range']}",
							 | 
						|
								                              filter_body)
							 | 
						|
								        if data['filters']['journal']:
							 | 
						|
								            display_names = [journal for
							 | 
						|
								                             journal in data['filters']['journal']]
							 | 
						|
								            display_names_str = ', '.join(display_names)
							 | 
						|
								            sheet.merge_range('C5:G5', display_names_str, filter_body)
							 | 
						|
								        if data['filters']['account']:
							 | 
						|
								            account_keys = [account.get('display_name', 'undefined') for
							 | 
						|
								                            account in data['filters']['account']]
							 | 
						|
								            account_keys_str = ', '.join(account_keys)
							 | 
						|
								            sheet.merge_range('C6:G6', account_keys_str, filter_body)
							 | 
						|
								        if data['filters']['options']:
							 | 
						|
								            option_keys = list(data['filters']['options'].keys())
							 | 
						|
								            option_keys_str = ', '.join(option_keys)
							 | 
						|
								            sheet.merge_range('C7:G7', option_keys_str, filter_body)
							 | 
						|
								        sheet.write(9, col, '', sub_heading)
							 | 
						|
								        sheet.merge_range(9, col + 1, 9, col + 2, 'Initial Balance',
							 | 
						|
								                          sub_heading)
							 | 
						|
								        i = 3
							 | 
						|
								        for date_view in data['date_viewed']:
							 | 
						|
								            sheet.merge_range(9, col + i, 9, col + i + 1, date_view,
							 | 
						|
								                              sub_heading)
							 | 
						|
								            i += 2
							 | 
						|
								        sheet.merge_range(9, col + i, 9, col + i + 1, 'End Balance',
							 | 
						|
								                          sub_heading)
							 | 
						|
								        sheet.write(10, col, '', sub_heading)
							 | 
						|
								        sheet.write(10, col + 1, 'Debit', sub_heading)
							 | 
						|
								        sheet.write(10, col + 2, 'Credit', sub_heading)
							 | 
						|
								        i = 3
							 | 
						|
								        for date_views in data['date_viewed']:
							 | 
						|
								            sheet.write(10, col + i, 'Debit', sub_heading)
							 | 
						|
								            i += 1
							 | 
						|
								            sheet.write(10, col + i, 'Credit', sub_heading)
							 | 
						|
								            i += 1
							 | 
						|
								        sheet.write(10, col + i, 'Debit', sub_heading)
							 | 
						|
								        sheet.write(10, col + (i + 1), 'Credit', sub_heading)
							 | 
						|
								        if data:
							 | 
						|
								            if report_action == 'dynamic_accounts_report.action_trial_balance':
							 | 
						|
								                row = 11
							 | 
						|
								                for move_line in data['data']:
							 | 
						|
								                    sheet.write(row, col, move_line['account'],
							 | 
						|
								                                side_heading_sub)
							 | 
						|
								                    sheet.write(row, col + 1, move_line['initial_total_debit'],
							 | 
						|
								                                txt_name)
							 | 
						|
								                    sheet.write(row, col + 2,
							 | 
						|
								                                move_line['initial_total_credit'], txt_name)
							 | 
						|
								                    j = 3
							 | 
						|
								                    if data['apply_comparison']:
							 | 
						|
								                        number_of_periods = data['comparison_number_range']
							 | 
						|
								                        for num in number_of_periods:
							 | 
						|
								                            sheet.write(row, col + j, move_line[
							 | 
						|
								                                'dynamic_total_debit_' + str(num)], txt_name)
							 | 
						|
								                            sheet.write(row, col + j + 1, move_line[
							 | 
						|
								                                'dynamic_total_credit_' + str(num)], txt_name)
							 | 
						|
								                            j += 2
							 | 
						|
								                    sheet.write(row, col + j, move_line['total_debit'],
							 | 
						|
								                                txt_name)
							 | 
						|
								                    sheet.write(row, col + j + 1, move_line['total_credit'],
							 | 
						|
								                                txt_name)
							 | 
						|
								                    sheet.write(row, col + j + 2, move_line['end_total_debit'],
							 | 
						|
								                                txt_name)
							 | 
						|
								                    sheet.write(row, col + j + 3,
							 | 
						|
								                                move_line['end_total_credit'], txt_name)
							 | 
						|
								                    row += 1
							 | 
						|
								        workbook.close()
							 | 
						|
								        output.seek(0)
							 | 
						|
								        response.stream.write(output.read())
							 | 
						|
								        output.close()
							 | 
						|
								
							 |