trytonpsk-account_col/tax.py

344 lines
12 KiB
Python
Raw Normal View History

2020-04-07 15:34:03 +02:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from collections import OrderedDict
2021-08-14 23:58:07 +02:00
2020-04-07 15:34:03 +02:00
from trytond.model import fields, ModelView
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.transaction import Transaction
from trytond.report import Report
_ZERO = Decimal('0.0')
class Tax(metaclass=PoolMeta):
__name__ = 'account.tax'
certificate_type = fields.Selection([
('', ''),
('renta', 'Renta'),
2021-02-14 05:51:10 +01:00
('ret', 'ReteFuente'),
2020-04-07 15:34:03 +02:00
('iva', 'IVA'),
('ica', 'ICA'),
('cree', 'Cree'),
2021-02-14 05:51:10 +01:00
('ic', 'Impuesto al Consumo'),
2021-04-27 16:47:10 +02:00
('bomberil', 'Impuesto Bomberil'),
('avtableros', 'Impuesto Avisos y Tableros'),
2020-04-07 15:34:03 +02:00
], 'Certificate Type')
classification = fields.Selection([
('', ''),
('renta', 'Renta'),
2021-02-14 05:51:10 +01:00
('ret', 'ReteFuente'),
2020-04-07 15:34:03 +02:00
('iva', 'IVA'),
('ica', 'ICA'),
('cree', 'Cree'),
2021-02-14 05:51:10 +01:00
('ic', 'Impuesto al Consumo'),
2020-08-31 06:46:13 +02:00
], 'Classification For Reports')
2020-04-07 15:34:03 +02:00
classification_tax = fields.Selection([
('', ''),
('01', 'IVA'),
('02', 'IC'),
('03', 'ICA'),
('04', 'INC'),
('05', 'ReteIVA'),
('06', 'ReteFuente'),
('07', 'ReteICA'),
('20', 'FtoHorticultura'),
('21', 'Timbre'),
('22', 'Bolsas'),
('23', 'INCarbono'),
('24', 'INCombustibles'),
('25', 'Sobretasa Combustibles'),
('26', 'Sordicom'),
('ZZ', 'Otro'),
('NA', 'No Aceptada'),
('renta', 'renta'),
('autorenta', 'autorenta'),
2020-08-31 06:46:13 +02:00
], 'Classification Tax Electronic Invoice')
2020-07-02 00:04:01 +02:00
not_printable = fields.Boolean('Not Printable')
base = fields.Numeric('Base', digits=(16, 2))
2020-04-07 15:34:03 +02:00
class TaxLine(metaclass=PoolMeta):
__name__ = 'account.tax.line'
@fields.depends('_parent_move_line.account', 'move_line')
def on_change_with_company(self, name=None):
if self.move_line:
return self.move_line.account.company.id
@fields.depends('tax', 'move_line')
def on_change_with_amount(self, name=None):
2021-09-02 18:31:55 +02:00
if hasattr(self.move_line, 'credit') and hasattr(self.move_line, 'debit'):
return (self.move_line.credit - self.move_line.debit)
2020-04-07 15:34:03 +02:00
class TaxesByInvoiceStart(ModelView):
'Taxes By Invoice Start'
__name__ = 'account_col.print_taxes_by_invoice.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True)
start_period = fields.Many2One('account.period', 'Start Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '<=', (Eval('end_period'), 'start_date')),
], depends=['fiscalyear', 'end_period'], required=True)
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
depends=['fiscalyear', 'start_period'], required=True)
company = fields.Many2One('company.company', 'Company', required=True)
@staticmethod
def default_fiscalyear():
FiscalYear = Pool().get('account.fiscalyear')
return FiscalYear.find(
Transaction().context.get('company'), exception=False)
@staticmethod
def default_company():
return Transaction().context.get('company')
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.start_period = None
self.end_period = None
class PrintTaxesByInvoice(Wizard):
'Print Taxes By Invoice'
__name__ = 'account_col.print_taxes_by_invoice'
start = StateView('account_col.print_taxes_by_invoice.start',
'account_col.print_taxes_by_invoice_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
2021-05-31 19:40:08 +02:00
])
2020-04-07 15:34:03 +02:00
print_ = StateReport('account_col.taxes_by_invoice_report')
def do_print_(self, action):
start_period = self.start.start_period.id
end_period = self.start.end_period.id
data = {
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'start_period': start_period,
'end_period': end_period,
2021-11-26 03:57:38 +01:00
}
2020-04-07 15:34:03 +02:00
return action, data
def transition_print_(self):
return 'end'
class TaxesByInvoice(Report):
__name__ = 'account_col.taxes_by_invoice_report'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Period = pool.get('account.period')
Company = pool.get('company.company')
FiscalYear = pool.get('account.fiscalyear')
Invoice = pool.get('account.invoice')
company = Company(data['company'])
start_period = Period(data['start_period'])
end_period = Period(data['end_period'])
dom_invoices = []
dom_invoices.append([
('invoice_date', '>=', start_period.start_date),
('invoice_date', '<=', end_period.end_date),
('state', 'in', ['posted', 'paid']),
])
invoices = Invoice.search(dom_invoices, order=[('number', 'ASC')])
taxes = {}
for invoice in invoices:
for itax in invoice.taxes:
if not itax.tax:
2021-05-31 19:40:08 +02:00
msg = f'Falta impuestos en la factura {invoice.number}'
raise UserError(msg)
2020-04-07 15:34:03 +02:00
tax_id = itax.tax.id
if tax_id not in taxes.keys():
taxes[tax_id] = {
'name': (itax.account.code or '') + ' - ' + itax.account.name,
'lines': [],
'sum_base': [],
'sum_amount': [],
2021-05-31 19:40:08 +02:00
}
2020-04-07 15:34:03 +02:00
taxes[tax_id]['lines'].append(itax)
taxes[tax_id]['sum_base'].append(itax.base)
taxes[tax_id]['sum_amount'].append(itax.amount)
report_context['records'] = taxes.values()
report_context['start_period'] = start_period.name
report_context['end_period'] = end_period.name
2021-11-26 03:57:38 +01:00
report_context['company'] = company
2020-04-07 15:34:03 +02:00
report_context['fiscalyear'] = FiscalYear(data['fiscalyear']).name
return report_context
class TaxesPostedStart(ModelView):
'Taxes Posted Start'
__name__ = 'account_col.print_taxes_posted.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True)
start_period = fields.Many2One('account.period', 'Start Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '<=', (Eval('end_period'), 'start_date')),
], depends=['fiscalyear', 'end_period'], required=True)
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
depends=['fiscalyear', 'start_period'], required=True)
company = fields.Many2One('company.company', 'Company', required=True)
taxes = fields.Many2Many('account.tax', None, None, 'Tax')
# tax = fields.Many2One('account.tax', 'Tax')
2020-04-07 15:34:03 +02:00
@staticmethod
def default_fiscalyear():
FiscalYear = Pool().get('account.fiscalyear')
return FiscalYear.find(
Transaction().context.get('company'), exception=False)
@staticmethod
def default_company():
return Transaction().context.get('company')
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.start_period = None
self.end_period = None
class PrintTaxesPosted(Wizard):
'Print Taxes Posted'
__name__ = 'account_col.print_taxes_posted'
start = StateView('account_col.print_taxes_posted.start',
'account_col.print_taxes_posted_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.taxes_posted_report')
def do_print_(self, action):
taxes = None
if self.start.taxes:
taxes = [tax.id for tax in self.start.taxes]
2020-04-07 15:34:03 +02:00
data = {
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'start_period': self.start.start_period.id,
'end_period': self.start.end_period.id,
'taxes': taxes,
2021-03-23 18:20:14 +01:00
2020-04-07 15:34:03 +02:00
}
return action, data
def transition_print_(self):
return 'end'
class TaxesPosted(Report):
__name__ = 'account_col.taxes_posted_report'
@classmethod
2021-06-23 17:56:58 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Period = pool.get('account.period')
Company = pool.get('company.company')
FiscalYear = pool.get('account.fiscalyear')
Tax = pool.get('account.tax')
MoveLine = pool.get('account.move.line')
company = Company(data['company'])
start_period = Period(data['start_period'])
end_period = Period(data['end_period'])
2021-03-23 18:20:14 +01:00
dom = []
if data['taxes']:
dom.append(('id', 'in', data['taxes']))
2021-03-23 18:20:14 +01:00
taxes = Tax.search(dom, order=[('invoice_account.code', 'ASC')])
2020-04-07 15:34:03 +02:00
taxes_accounts = {}
2020-04-07 15:34:03 +02:00
def _get_data_tax(acc):
val = {
'code': acc.code,
'name': acc.rec_name,
'rate': '',
'lines': [],
'sum_base': [],
'sum_amount': [],
}
return val
for t in taxes:
for tax_i_acc in (t.invoice_account, t.credit_note_account):
if tax_i_acc and tax_i_acc.id not in taxes_accounts.keys():
taxes_accounts[tax_i_acc.id] = _get_data_tax(tax_i_acc)
periods = Period.search([
('fiscalyear', '=', data['fiscalyear']),
('start_date', '>=', start_period.start_date),
('end_date', '<=', end_period.end_date),
])
period_ids = [p.id for p in periods]
lines = MoveLine.search([
('account', 'in', set(taxes_accounts.keys())),
('move.period', 'in', period_ids),
], order=[('date', 'ASC')])
targets = {}
for line in lines:
line_id = line.account.id
if line_id not in targets.keys():
targets[line_id] = taxes_accounts[line_id]
line_ = cls.get_tax_reversed(line)
targets[line_id]['lines'].append(line_)
targets[line_id]['sum_base'].append(line_['base'])
targets[line_id]['sum_amount'].append(line_['tax_amount'])
2020-04-07 15:34:03 +02:00
ordered_targets = sorted(((v['code'], v) for v in targets.values()), key = lambda tup: tup[0])
ordered_targets = OrderedDict(ordered_targets)
report_context['records'] = ordered_targets.values()
report_context['start_period'] = start_period.name
report_context['end_period'] = end_period.name
2021-11-26 03:57:38 +01:00
report_context['company'] = company
2020-04-07 15:34:03 +02:00
report_context['fiscalyear'] = FiscalYear(data['fiscalyear']).name
return report_context
@classmethod
def get_tax_reversed(cls, line):
line2 = {'line': line}
2020-04-07 15:34:03 +02:00
rate = None
base = _ZERO
amount = line.debit - line.credit
if line.tax_lines:
for tax_line in line.tax_lines:
if tax_line.tax:
rate = tax_line.tax.rate
if rate:
base = amount / abs(rate)
rate = rate * 100
#TODO: Add smart compute deduced from taxes model
line2.update({'base': base, 'tax_amount': amount, 'rate': rate})
return line2