trytonpsk-account_col/tax.py

329 lines
11 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
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
__all__ = ['Tax', 'TaxesByInvoice', 'TaxesByInvoiceStart',
'PrintTaxesByInvoice', 'TaxesPostedStart', 'TaxesPosted',
'PrintTaxesPosted', 'TaxLine']
_ZERO = Decimal('0.0')
class Tax(metaclass=PoolMeta):
__name__ = 'account.tax'
certificate_type = fields.Selection([
('', ''),
('renta', 'Renta'),
('iva', 'IVA'),
('ica', 'ICA'),
('cree', 'Cree'),
], 'Certificate Type')
classification = fields.Selection([
('', ''),
('renta', 'Renta'),
('iva', 'IVA'),
('ica', 'ICA'),
('cree', 'Cree'),
], 'Classification')
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'),
], 'Classification Tax')
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):
return (self.move_line.credit - self.move_line.debit)
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),
])
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,
}
return action, data
def transition_print_(self):
return 'end'
class TaxesByInvoice(Report):
__name__ = 'account_col.taxes_by_invoice_report'
@classmethod
def get_context(cls, records, data):
report_context = super(TaxesByInvoice, cls).get_context(records, data)
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:
invoice.raise_user_error('missing_invoice_tax', (invoice.number,))
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': [],
}
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
report_context['company'] = company.party.name
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)
@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):
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,
}
return action, data
def transition_print_(self):
return 'end'
class TaxesPosted(Report):
__name__ = 'account_col.taxes_posted_report'
@classmethod
def get_context(cls, records, data):
report_context = super(TaxesPosted, cls).get_context(records, data)
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'])
taxes = Tax.search([], order=[('invoice_account.code', 'ASC')])
taxes_accounts = {}
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)
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
report_context['company'] = company.party.name
report_context['fiscalyear'] = FiscalYear(data['fiscalyear']).name
return report_context
@classmethod
def get_tax_reversed(cls, line):
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
setattr(line, 'base', base)
setattr(line, 'tax_amount', amount)
setattr(line, 'rate', rate)
return line