Files
enterprise-addons/l10n_ph_reports/models/sawt_qap_report.py
T

693 lines
37 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import defaultdict
from odoo import _, fields, models
from odoo.tools import date_utils, html2plaintext
from odoo.tools.misc import format_date
from odoo.tools.sql import SQL
class L10n_PhSawt_QapReportHandler(models.AbstractModel):
_name = 'l10n_ph.sawt_qap.report.handler'
_inherit = ['l10n_ph.generic.report.handler', 'account.tax.report.handler']
_description = 'Withholding Taxes Custom Handler'
def _custom_options_initializer(self, report, options, previous_options=None):
super()._custom_options_initializer(report, options, previous_options=previous_options)
options.setdefault('buttons', []).append(
{
'name': _('Export SAWT & QAP'),
'sequence': 5,
'action': 'print_report_to_dat',
'file_export_type': _('DAT'),
'branch_allowed': True,
}
)
# First level, month rows
def _build_month_lines(self, report, options):
""" Fetches the months for which we have entries *that have tax grids* and build a report line for each of them. """
month_lines = []
queries = []
# 1) Build the queries to get the months
for column_group_key, column_group_options in report._split_options_per_column_group(options).items():
query = self._get_report_query(report, column_group_options)
# The joins are there to filter out months for which we would not have any lines in the report.
queries.append(SQL(
"""
SELECT (date_trunc('month', account_move_line.date::date) + interval '1 month' - interval '1 day')::date AS taxable_month,
%(column_group_key)s AS column_group_key
FROM %(table_references)s
WHERE %(search_condition)s AND account_tax.l10n_ph_atc IS NOT NULL
GROUP BY taxable_month
ORDER BY taxable_month DESC
""",
column_group_key=column_group_key,
table_references=query.from_clause,
search_condition=query.where_clause,
))
# 2) Make the lines
unfold_all = options['export_mode'] == 'print' or options.get('unfold_all')
for res in self.env.execute_query_dict(SQL(" UNION ALL ").join(queries)):
line_id = report._get_generic_line_id('', '', markup=str(res['taxable_month']))
month_lines.append({
'id': line_id,
'name': format_date(self.env, res['taxable_month'], date_format='MMMM y'),
'unfoldable': True,
'unfolded': line_id in options['unfolded_lines'] or unfold_all,
'columns': [report._build_column_dict(None, _column) for _column in options['columns']],
'level': 0,
'expand_function': '_report_expand_unfoldable_line_l10n_ph_expand_month',
})
return month_lines
def _report_expand_unfoldable_line_l10n_ph_expand_month(self, line_dict_id, groupby, options, progress, offset, unfold_all_batch_data=None):
""" Used to expand a month line and load the second level, being the partner lines. """
report = self.env['account.report'].browse(options['report_id'])
month = report._get_markup(line_dict_id)
partner_lines_values = self._query_partners(report, options, month, offset)
return self._get_report_expand_unfoldable_line_value(report, options, line_dict_id, progress, partner_lines_values,
report_line_method=self._get_report_line_partner)
def _query_partners(self, report, options, month, offset):
""" Query the values for the partner lines.
The partner lines will sum up the values for the different columns while only being filtered for the given month.
"""
limit = report.load_more_limit + 1 if report.load_more_limit and options['export_mode'] != 'print' else None
end_date = fields.Date.from_string(month) # Month is already set to the last day of the month.
start_date = date_utils.start_of(end_date, 'month')
queries = []
extra_domain = [
# Make sure to only fetch records that are in the parent's row month
('date', '>=', start_date),
('date', '<=', end_date),
]
for column_group_key, column_group_options in report._split_options_per_column_group(options).items():
query = self._get_report_query(report, column_group_options, extra_domain=extra_domain)
tail_query = report._get_engine_query_tail(offset, limit)
# Note about the lateral join; we use it because we actually only care about the fact that there is any tax_ids on the line and not which ones.
# This allows us to get that line in the result a single time for it's amount (used as base amount); while the tax details will come from the join using tax_line_id.
queries.append(SQL(
"""
SELECT %(column_group_key)s AS column_group_key,
p.vat AS partner_vat,
COALESCE(
NULLIF(TRIM(CONCAT_WS(' ', p.last_name, p.first_name, p.middle_name)), ''),
p.name
) AS register_name,
p.id AS partner_id,
COALESCE(
NULLIF(TRIM(CONCAT_WS(' ', p.first_name, p.middle_name, p.last_name)), ''),
p.name
) AS partner_name,
%(account_tag_name)s AS tag_name,
SUM(%(balance_select)s
* CASE WHEN %(balance_negate)s THEN -1 ELSE 1 END
) AS balance
FROM %(table_references)s
JOIN res_partner p ON p.id = account_move_line__move_id.commercial_partner_id
%(currency_table_join)s
WHERE %(search_condition)s
GROUP BY p.id, %(account_tag_name)s
ORDER BY p.id
%(tail_query)s
""",
balance_select=report._currency_table_apply_rate(SQL('account_move_line.balance')),
currency_table_join=report._currency_table_aml_join(options),
column_group_key=column_group_key,
account_tag_name=self.env['account.account.tag'].with_context(lang='en_US')._field_to_sql('account_tag', 'name', query),
balance_negate=self.env['account.account.tag']._field_to_sql('account_tag', 'balance_negate', query),
table_references=query.from_clause,
search_condition=query.where_clause,
tail_query=tail_query,
))
results = self.env.execute_query_dict(SQL(" UNION ALL ").join(queries))
return self._process_partner_lines(results, options)
def _process_partner_lines(self, data_dict, options):
""" Taking in the values from the database, this will construct the column values by using the tax grid mapping
set in the option of each report section.
"""
lines_values = {}
# We get the partners to get the correctly formatted address as we don't have by default in the db.
partners = self.env["res.partner"].browse({values["partner_id"] for values in data_dict})
partner_addresses = {
partner.id: partner._display_address(without_company=True).replace('\n\n', '\n').replace('\n', ', ') # Looks better in the Odoo view
for partner in partners
}
for values in data_dict:
# Initialise the move values
if values['partner_id'] not in lines_values:
lines_values[values['partner_id']] = {
'name': values['partner_name'],
'register_name': values['register_name'],
values['column_group_key']: {
'column_group_key': values['column_group_key'],
'partner_vat': values['partner_vat'],
'register_name': values['register_name'],
'partner_address': partner_addresses[values['partner_id']],
}
}
self._eval_report_grids_map(options, values, column_values=lines_values[values['partner_id']][values['column_group_key']])
return self._filter_lines_with_values(options, lines_values)
def _get_report_line_partner(self, report, options, partner_id, line_values, parent_line_id):
""" Format the given values to match the report line format. """
month = report._get_markup(parent_line_id)
line_columns = self._get_line_columns(report, options, line_values)
# Set the markup with the month, we can reuse it to filter the detailed move lines
line_id = report._get_generic_line_id('res.partner', partner_id, markup=month, parent_line_id=parent_line_id)
unfold_all = options['export_mode'] == 'print' or options.get('unfold_all')
return {
'id': line_id,
'parent_id': parent_line_id,
'name': line_values['name'] or line_values['register_name'],
'unfoldable': True,
'unfolded': line_id in options['unfolded_lines'] or unfold_all,
'columns': line_columns,
'level': 1,
'caret_options': 'res.partner',
'expand_function': '_report_expand_unfoldable_line_l10n_ph_expand_partner',
}
def _report_expand_unfoldable_line_l10n_ph_expand_partner(self, line_dict_id, groupby, options, progress, offset, unfold_all_batch_data=None):
""" Used to expand a partner line and load the third level, being the account move lines. """
report = self.env['account.report'].browse(options['report_id'])
month = report._get_markup(line_dict_id)
partner_id = report._get_res_id_from_line_id(line_dict_id, 'res.partner')
lines_values = self._query_atc_lines(report, options, partner_id, month, offset)
return self._get_report_expand_unfoldable_line_value(report, options, line_dict_id, progress, lines_values,
report_line_method=self._get_report_line_atc)
def _query_moves(self, report, options, partner_id, tax_id, month, offset):
""" Query the values for the partner line.
The move line will sum up the values for the different columns, while being filtered for the given month only.
"""
limit = report.load_more_limit + 1 if report.load_more_limit and options['export_mode'] != 'print' else None
end_date = fields.Date.from_string(month)
start_date = date_utils.start_of(end_date, 'month')
queries = []
extra_domain = [
('date', '>=', start_date),
('date', '<=', end_date),
('move_id.commercial_partner_id', '=', partner_id),
]
for column_group_key, column_group_options in report._split_options_per_column_group(options).items():
query = self._get_report_query(report, column_group_options, extra_domain=extra_domain)
tail_query = report._get_engine_query_tail(offset, limit)
queries.append(SQL(
"""
SELECT %(column_group_key)s AS column_group_key,
account_move_line__move_id.id AS move_id,
account_move_line__move_id.name AS move_name,
%(account_tag_name)s AS tag_name,
SUM(%(balance_select)s
* CASE WHEN %(balance_negate)s THEN -1 ELSE 1 END
) AS balance
FROM %(table_references)s
JOIN res_partner partner ON partner.id = account_move_line__move_id.commercial_partner_id
%(currency_table_join)s
WHERE %(search_condition)s
AND %(tax_clause)s
GROUP BY account_move_line__move_id.id, %(account_tag_name)s
ORDER BY account_move_line__move_id.id
%(tail_query)s
""",
balance_select=report._currency_table_apply_rate(SQL('account_move_line.balance')),
column_group_key=column_group_key,
account_tag_name=self.env['account.account.tag'].with_context(lang='en_US')._field_to_sql('account_tag', 'name', query),
balance_negate=self.env['account.account.tag']._field_to_sql('account_tag', 'balance_negate', query),
currency_table_join=report._currency_table_aml_join(options),
tax_clause=SQL('account_tax.id = %s', tax_id),
table_references=query.from_clause,
search_condition=query.where_clause,
tail_query=tail_query,
))
results = self.env.execute_query_dict(SQL(" UNION ALL ").join(queries))
return self._process_moves(results, options)
def _process_moves(self, data_dict, options):
""" Taking in the values from the database, this will construct the column values by using the tax grid mapping
set in the option of each report section.
"""
lines_values = {}
for values in data_dict:
if values['move_id'] not in lines_values:
lines_values[values['move_id']] = {
'name': values['move_name'],
values['column_group_key']: {
'column_group_key': values['column_group_key'],
'move_id': values['move_id'],
'move_name': values['move_name'],
}
}
self._eval_report_grids_map(options, values, column_values=lines_values[values['move_id']][values['column_group_key']])
return self._filter_lines_with_values(options, lines_values)
def _get_report_line_move(self, report, options, move_id, line_values, parent_line_id):
""" Format the given values to match the report line format. """
line_columns = self._get_line_columns(report, options, line_values)
line_id = report._get_generic_line_id('account.move', move_id, parent_line_id=parent_line_id)
return {
'id': line_id,
'parent_id': parent_line_id,
'name': line_values['name'],
'unfoldable': False,
'unfolded': False,
'columns': line_columns,
'level': 3,
'caret_options': 'account.move',
}
def _query_atc_lines(self, report, options, partner_id, month, offset):
""" Query the values for the partner line.
The move line will sum up the values for the different columns, while being filtered for the given move id only.
"""
limit = report.load_more_limit + 1 if report.load_more_limit and options['export_mode'] != 'print' else None
end_date = fields.Date.from_string(month)
start_date = date_utils.start_of(end_date, 'month')
queries = []
extra_domain = [
# Make sure to only fetch records that are in the parent's row month
('move_id.commercial_partner_id', '=', partner_id),
('date', '>=', start_date),
('date', '<=', end_date),
]
for column_group_key, column_group_options in report._split_options_per_column_group(options).items():
query = self._get_report_query(report, column_group_options, extra_domain=extra_domain)
tail_query = report._get_engine_query_tail(offset, limit)
# Note, the multiplication per tax amount sign is there to show positive value for negative withholding taxes.
queries.append(SQL(
"""
SELECT %(column_group_key)s AS column_group_key,
account_tax.id AS tax_id,
account_tax.l10n_ph_atc AS atc,
REGEXP_REPLACE(%(account_tax_description)s, '(<([^>]+)>)', '', 'g') AS tax_description,
ABS(account_tax.amount) AS tax_rate,
%(account_tag_name)s AS tag_name,
SUM(%(balance_select)s
* CASE WHEN %(balance_negate)s THEN -1 ELSE 1 END
) AS balance
FROM %(table_references)s
JOIN res_partner partner ON partner.id = account_move_line__move_id.commercial_partner_id
%(currency_table_join)s
WHERE %(search_condition)s AND account_tax.l10n_ph_atc IS NOT NULL
GROUP BY account_tax.l10n_ph_atc, account_tax.id, %(account_tag_name)s
ORDER BY account_tax.id
%(tail_query)s
""",
balance_select=report._currency_table_apply_rate(SQL('account_move_line.balance')),
column_group_key=column_group_key,
account_tax_description=self.env['account.tax']._field_to_sql('account_tax', 'description', query),
account_tag_name=self.env['account.account.tag'].with_context(lang='en_US')._field_to_sql('account_tag', 'name', query),
balance_negate=self.env['account.account.tag']._field_to_sql('account_tag', 'balance_negate', query),
currency_table_join=report._currency_table_aml_join(options),
table_references=query.from_clause,
search_condition=query.where_clause,
tail_query=tail_query,
))
results = self.env.execute_query_dict(SQL(" UNION ALL ").join(queries))
return self._process_atc_lines(results, options)
def _process_atc_lines(self, data_dict, options):
""" Taking in the values from the database, this will construct the column values by using the tax grid mapping
set in the option of each report section.
"""
lines_values = {}
for values in data_dict:
if values['tax_id'] not in lines_values:
lines_values[values['tax_id']] = {
'name': values['tax_description'],
values['column_group_key']: {
'column_group_key': values['column_group_key'],
'atc': values['atc'],
'tax_rate': values['tax_rate'],
}
}
self._eval_report_grids_map(options, values, column_values=lines_values[values['tax_id']][values['column_group_key']])
return lines_values
def _get_report_line_atc(self, report, options, tax_id, line_values, parent_line_id):
""" Format the given values to match the report line format. """
month = report._get_markup(parent_line_id)
line_columns = self._get_line_columns(report, options, line_values)
line_id = report._get_generic_line_id('account.tax', tax_id, markup=month, parent_line_id=parent_line_id)
unfold_all = options['export_mode'] == 'print' or options.get('unfold_all')
return {
'id': line_id,
'parent_id': parent_line_id,
'name': line_values['name'],
'unfoldable': True,
'unfolded': line_id in options['unfolded_lines'] or unfold_all,
'columns': line_columns,
'level': 2,
'caret_options': 'account.tax',
'expand_function': '_report_expand_unfoldable_line_l10n_ph_expand_atc',
}
def _report_expand_unfoldable_line_l10n_ph_expand_atc(self, line_dict_id, groupby, options, progress, offset, unfold_all_batch_data=None):
""" Used to expand an account move line and load the third level, being the tax lines. """
report = self.env['account.report'].browse(options['report_id'])
month = report._get_markup(line_dict_id)
tax_id = report._get_res_id_from_line_id(line_dict_id, 'account.tax')
partner_id = report._get_res_id_from_line_id(line_dict_id, 'res.partner')
lines_values = self._query_moves(report, options, partner_id, tax_id, month, offset)
return self._get_report_expand_unfoldable_line_value(report, options, line_dict_id, progress, lines_values,
report_line_method=self._get_report_line_move)
# ================
# .DAT file export
# ================
def _get_dat_line_grouping_keys(self):
return ['payee_id', 'tax_id']
def _get_schedule_number(self, form_type_code, tags):
""" Returns the schedule number of the row based on the form type and the tax tags """
schedule_number = ''
if form_type_code == '1601EQ':
if '1601/1604A' in tags or '1601/1604B' in tags:
schedule_number = '1'
elif '1601/1604EX' in tags:
schedule_number = '2'
elif form_type_code == '1604E':
if '1601/1604A' in tags or '1601/1604B' in tags:
schedule_number = '3'
elif '1601/1604EX' in tags:
schedule_number = '4'
return schedule_number
def _sawt_qap_get_header_values(self, options):
""" Each child reports have different fields they want in the header, so we will let them handle it. """
return []
def _sawt_qap_get_line_values(self, line, schedule, sequence, options):
return []
def _sawt_qap_get_schedule_control(self, lines, schedule, options):
return []
def _add_header_line(self, file_rows, categories_summed_amount, options):
""" The header line in the SAWT & QAP reports is quite simple, but will differ based on the exact report & periodicity """
header_row = self._sawt_qap_get_header_values(options)
file_rows.append(','.join(header_row))
def _add_details(self, file_rows, line_details, options):
""" The SAWT & QAP reports have their details grouped by schedule (based on the tax), with a control line at the end of each group. """
grouped_lines = defaultdict(list)
form_type_code = options["form_type_code"]
for line in line_details.values():
schedule_number = self._get_schedule_number(form_type_code, line['tag_name'])
grouped_lines[schedule_number].append(line)
for schedule, lines in sorted(grouped_lines.items()):
for i, line in enumerate(lines):
line_values = self._sawt_qap_get_line_values(line, schedule, i, options)
file_rows.append(','.join(line_values))
control_values = self._sawt_qap_get_schedule_control(lines, schedule, options)
file_rows.append(','.join(control_values))
class L10n_PhSawtReportHandler(models.AbstractModel):
_name = 'l10n_ph.sawt.report.handler'
_inherit = ['l10n_ph.sawt_qap.report.handler']
_description = 'Sales Withholding Taxes Custom Handler'
def _custom_options_initializer(self, report, options, previous_options=None):
super()._custom_options_initializer(report, options, previous_options=previous_options)
options.update({
'journal_type': 'sale',
# This mapping will be used to build the amount for each expression_label based on the grid names.
'report_grids_map': {
'tax_base_amount': ['1701/1702A'],
'withholding_tax_amount': ['1701/1702B'],
}
})
# ================
# .DAT file export
# ================
def _get_available_form_to_export(self):
return '1701Q,1701,1702Q,1702'
def _sawt_qap_get_header_values(self, options):
""" Returns a list containing the information we want to see in the header. """
alpha_type = options["alpha_type"]
form_type_code = options["form_type_code"]
company = self.env["res.company"].browse(options["companies"][0]["id"])
company_vat, company_branch = self._get_partner_vat_branch(company.partner_id)
date_to = self._get_report_date_to(options)
return [
self._format_value(f'H{alpha_type}', 6),
self._format_value(f'H{form_type_code}', 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(company.partner_id.name, 50, quote=True),
self._format_value(company.partner_id.last_name, 30, quote=True),
self._format_value(company.partner_id.first_name, 30, quote=True),
self._format_value(company.partner_id.middle_name, 30, quote=True),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(company.partner_id.l10n_ph_rdo or '', 3),
]
def _sawt_qap_get_line_values(self, line, schedule, sequence, options):
alpha_type = options['alpha_type']
form_type_code = options["form_type_code"]
date_to = self._get_report_date_to(options)
payee = self.env['res.partner'].browse(line.get('payee_id'))
payee_vat, payee_branch = self._get_partner_vat_branch(payee.commercial_partner_id)
return [
self._format_value(f'D{alpha_type}', 6),
self._format_value(f'D{form_type_code}', 7),
str(sequence), # Format value adds decimals, but here we just want a basic int
self._format_value(payee_vat, 9),
self._format_value(payee_branch, 4),
self._format_value(line.get('payee_registered_name', ''), 50, quote=True),
self._format_value(line.get('payee_last_name', ''), 30, quote=True),
self._format_value(line.get('payee_first_name', ''), 30, quote=True),
self._format_value(line.get('payee_middle_name', ''), 30, quote=True),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(html2plaintext(line.get('income_nature', '')), 50, quote=True),
self._format_value(line.get('atc_code', ''), 5),
self._format_value(line.get('tax_rate', 0.0), 14),
self._format_value(line.get('base_amount', 0.0), 14),
self._format_value(line.get('withholding_tax_amount', 0.0), 14),
]
def _sawt_qap_get_schedule_control(self, lines, schedule, options):
alpha_type = options['alpha_type']
form_type_code = options["form_type_code"]
company = self.env["res.company"].browse(options["companies"][0]["id"])
company_vat, company_branch = self._get_partner_vat_branch(company.partner_id)
date_to = self._get_report_date_to(options)
# Sum the amounts in the lines
total_withheld = 0.0
total_base = 0.0
for line in lines:
total_base += line.get("base_amount", 0.0)
total_withheld += line.get("withholding_tax_amount", 0.0)
return [
self._format_value(f'C{alpha_type}', 6),
self._format_value(f'C{form_type_code}', 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(total_base, 14),
self._format_value(total_withheld, 14),
]
class L10n_PhQapReportHandler(models.AbstractModel):
_name = 'l10n_ph.qap.report.handler'
_inherit = ['l10n_ph.sawt_qap.report.handler']
_description = 'Purchase Withholding Taxes Custom Handler'
def _custom_options_initializer(self, report, options, previous_options=None):
super()._custom_options_initializer(report, options, previous_options=previous_options)
options.update({
'journal_type': 'purchase',
# This mapping will be used to build the amount for each expression_label based on the grid names.
'report_grids_map': {
'tax_base_amount': ['1601/1604A', '1601/1604EX'],
'withholding_tax_amount': ['1601/1604B'],
}
})
# ================
# .DAT file export
# ================
def _get_available_form_to_export(self):
return '1601EQ,1604E'
def _sawt_qap_get_header_values(self, options):
""" Returns a list containing the information we want to see in the header. """
alpha_type = options["alpha_type"]
form_type_code = options["form_type_code"]
periodicity = options['periodicity']
company = self.env["res.company"].browse(options["companies"][0]["id"])
company_vat, company_branch = self._get_partner_vat_branch(company.partner_id)
date_to = self._get_report_date_to(options)
if periodicity == 'quarterly':
return [
self._format_value(f'H{alpha_type}', 6),
self._format_value(f'H{form_type_code}', 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(company.partner_id.name, 50, quote=True),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(company.partner_id.l10n_ph_rdo or '', 3),
]
else:
return [
self._format_value(f'H{form_type_code}', 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%d/%Y'), 10),
]
def _sawt_qap_get_line_values(self, line, schedule, sequence, options):
form_type_code = options["form_type_code"]
company = self.env["res.company"].browse(options["companies"][0]["id"])
company_vat, company_branch = self._get_partner_vat_branch(company.partner_id)
payee = self.env['res.partner'].browse(line.get('payee_id'))
payee_vat, payee_branch = self._get_partner_vat_branch(payee.commercial_partner_id)
date_to = self._get_report_date_to(options)
if schedule == '1':
return [
self._format_value(f'D{schedule}', 2),
self._format_value(form_type_code, 7),
str(sequence), # Format value adds decimals, but here we just want a basic int
self._format_value(payee_vat, 9),
self._format_value(payee_branch, 4),
self._format_value(line.get('payee_registered_name', ''), 50, quote=True),
self._format_value(line.get('payee_last_name', ''), 30, quote=True),
self._format_value(line.get('payee_first_name', ''), 30, quote=True),
self._format_value(line.get('payee_middle_name', ''), 30, quote=True),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(line.get('atc_code', ''), 5),
self._format_value(line.get('tax_rate', 0.0), 14),
self._format_value(line.get('base_amount', 0.0), 14),
self._format_value(line.get('withholding_tax_amount', 0.0), 14),
]
elif schedule == '2':
return [
self._format_value(f'D{schedule}', 2),
self._format_value(form_type_code, 7),
str(sequence), # Format value adds decimals, but here we just want a basic int
self._format_value(payee_vat, 9),
self._format_value(payee_branch, 4),
self._format_value(line.get('payee_registered_name', ''), 50, quote=True),
self._format_value(line.get('payee_last_name', ''), 30, quote=True),
self._format_value(line.get('payee_first_name', ''), 30, quote=True),
self._format_value(line.get('payee_middle_name', ''), 30, quote=True),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(line.get('atc_code', ''), 5),
self._format_value(line.get('base_amount', 0.0), 14),
]
elif schedule == '3':
return [
self._format_value(f'D{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%d/%Y'), 10),
str(sequence), # Format value adds decimals, but here we just want a basic int
self._format_value(payee_vat, 9),
self._format_value(payee_branch, 4),
self._format_value(line.get('payee_registered_name', ''), 50, quote=True),
self._format_value(line.get('payee_last_name', ''), 30, quote=True),
self._format_value(line.get('payee_first_name', ''), 30, quote=True),
self._format_value(line.get('payee_middle_name', ''), 30, quote=True),
self._format_value(line.get('atc_code', ''), 5),
self._format_value(line.get('base_amount', 0.0), 14),
self._format_value(line.get('tax_rate', 0.0), 14),
self._format_value(line.get('withholding_tax_amount', 0.0), 14),
]
else:
return [
self._format_value(f'D{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%d/%Y'), 10),
str(sequence), # Format value adds decimals, but here we just want a basic int
self._format_value(payee_vat, 9),
self._format_value(payee_branch, 4),
self._format_value(line.get('payee_registered_name', ''), 50, quote=True),
self._format_value(line.get('payee_last_name', ''), 30, quote=True),
self._format_value(line.get('payee_first_name', ''), 30, quote=True),
self._format_value(line.get('payee_middle_name', ''), 30, quote=True),
self._format_value(line.get('atc_code', ''), 5),
self._format_value(line.get('base_amount', 0.0), 14),
]
def _sawt_qap_get_schedule_control(self, lines, schedule, options):
form_type_code = options["form_type_code"]
company = self.env["res.company"].browse(options["companies"][0]["id"])
company_vat, company_branch = self._get_partner_vat_branch(company.partner_id)
date_to = self._get_report_date_to(options)
# Sum the amounts in the lines
total_withheld = 0.0
total_base = 0.0
for line in lines:
total_base += line.get("base_amount", 0.0)
total_withheld += line.get("withholding_tax_amount", 0.0)
if schedule == '1':
return [
self._format_value(f'C{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(total_base, 14),
self._format_value(total_withheld, 14),
]
elif schedule == '2':
return [
self._format_value(f'C{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%Y'), 7),
self._format_value(total_base, 14),
]
elif schedule == '3':
return [
self._format_value(f'C{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%d/%Y'), 10),
self._format_value(total_withheld, 14),
]
else:
return [
self._format_value(f'C{schedule}', 2),
self._format_value(form_type_code, 7),
self._format_value(company_vat, 9),
self._format_value(company_branch, 4),
self._format_value(date_to.strftime('%m/%d/%Y'), 10),
self._format_value(total_base, 14),
]