mirror of
https://bitbucket.org/presik/trytonpsk-account_col.git
synced 2023-12-14 05:53:00 +01:00
329 lines
11 KiB
Python
329 lines
11 KiB
Python
|
# 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
|