first commit
This commit is contained in:
217
modules/account_be/account.py
Normal file
217
modules/account_be/account.py
Normal file
@@ -0,0 +1,217 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import stdnum.exceptions
|
||||
from sql.aggregate import Min, Sum
|
||||
|
||||
try:
|
||||
from stdnum.be import ogm_vcs
|
||||
except ImportError:
|
||||
from . import ogm_vcs
|
||||
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.modules.account.exceptions import FiscalYearNotFoundError
|
||||
from trytond.modules.currency.fields import Monetary
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class CreateChart(metaclass=PoolMeta):
|
||||
__name__ = 'account.create_chart'
|
||||
|
||||
def default_properties(self, fields):
|
||||
pool = Pool()
|
||||
ModelData = pool.get('ir.model.data')
|
||||
defaults = super().default_properties(fields)
|
||||
for lang in ['fr', 'nl']:
|
||||
try:
|
||||
template_id = ModelData.get_id('account_be.root_' + lang)
|
||||
except KeyError:
|
||||
continue
|
||||
if self.account.account_template.id == template_id:
|
||||
defaults['account_receivable'] = self.get_account(
|
||||
'account_be.400_' + lang)
|
||||
defaults['account_payable'] = self.get_account(
|
||||
'account_be.440_' + lang)
|
||||
break
|
||||
return defaults
|
||||
|
||||
|
||||
class BEVATCustomer(ModelSQL, ModelView):
|
||||
__name__ = 'account.be.vat_customer'
|
||||
|
||||
company_tax_identifier = fields.Many2One(
|
||||
'party.identifier', "Company Tax Identifier")
|
||||
party_tax_identifier = fields.Many2One(
|
||||
'party.identifier', "Party Tax Identifier")
|
||||
turnover = Monetary("Turnover", currency='currency', digits='currency')
|
||||
vat = Monetary("VAT", currency='currency', digits='currency')
|
||||
currency = fields.Many2One('currency.currency', "Currency")
|
||||
|
||||
@classmethod
|
||||
def tax_groups(cls):
|
||||
for group in ['group_tva_vente_biens', 'group_tva_vente_services',
|
||||
'tva_vente_biens_coco', 'tva_vente_services_coco']:
|
||||
for lang in ['fr', 'nl']:
|
||||
yield 'account_be', '%s_%s' % (group, lang)
|
||||
|
||||
@classmethod
|
||||
def table_query(cls):
|
||||
pool = Pool()
|
||||
Identifier = pool.get('party.identifier')
|
||||
Invoice = pool.get('account.invoice')
|
||||
InvoiceTax = pool.get('account.invoice.tax')
|
||||
ModelData = pool.get('ir.model.data')
|
||||
Move = pool.get('account.move')
|
||||
Period = pool.get('account.period')
|
||||
Tax = pool.get('account.tax')
|
||||
context = Transaction().context
|
||||
company_identifier = Identifier.__table__()
|
||||
party_identifier = Identifier.__table__()
|
||||
invoice = Invoice.__table__()
|
||||
invoice_tax = InvoiceTax.__table__()
|
||||
move = Move.__table__()
|
||||
period = Period.__table__()
|
||||
tax = Tax.__table__()
|
||||
|
||||
groups = []
|
||||
for module, fs_id in cls.tax_groups():
|
||||
try:
|
||||
groups.append(ModelData.get_id(module, fs_id))
|
||||
except KeyError:
|
||||
# table_query can be called before the XML is loaded
|
||||
continue
|
||||
|
||||
where = ((invoice.company == context.get('company'))
|
||||
& (period.fiscalyear == context.get('fiscalyear')))
|
||||
where &= invoice.type == 'out'
|
||||
where &= ((company_identifier.code.ilike('BE%')
|
||||
& (company_identifier.type == 'eu_vat'))
|
||||
| (company_identifier.type == 'be_vat'))
|
||||
where &= ((party_identifier.code.ilike('BE%')
|
||||
& (party_identifier.type == 'eu_vat'))
|
||||
| (party_identifier.type == 'be_vat'))
|
||||
where &= tax.group.in_(groups)
|
||||
return (invoice_tax
|
||||
.join(invoice,
|
||||
condition=invoice_tax.invoice == invoice.id)
|
||||
.join(tax, condition=invoice_tax.tax == tax.id)
|
||||
.join(move, condition=invoice.move == move.id)
|
||||
.join(period, condition=move.period == period.id)
|
||||
.join(company_identifier,
|
||||
condition=invoice.tax_identifier == company_identifier.id)
|
||||
.join(party_identifier,
|
||||
condition=invoice.party_tax_identifier == party_identifier.id)
|
||||
.select(
|
||||
Min(invoice_tax.id).as_('id'),
|
||||
invoice.tax_identifier.as_('company_tax_identifier'),
|
||||
invoice.party_tax_identifier.as_('party_tax_identifier'),
|
||||
Sum(invoice_tax.base).as_('turnover'),
|
||||
Sum(invoice_tax.amount).as_('vat'),
|
||||
invoice.currency.as_('currency'),
|
||||
where=where,
|
||||
group_by=[
|
||||
invoice.tax_identifier,
|
||||
invoice.party_tax_identifier,
|
||||
invoice.currency,
|
||||
]))
|
||||
|
||||
|
||||
class BEVATCustomerContext(ModelView):
|
||||
__name__ = 'account.be.vat_customer.context'
|
||||
|
||||
company = fields.Many2One('company.company', "Company", required=True)
|
||||
fiscalyear = fields.Many2One(
|
||||
'account.fiscalyear', "Fiscal Year", required=True,
|
||||
domain=[
|
||||
('company', '=', Eval('company', -1)),
|
||||
])
|
||||
|
||||
@classmethod
|
||||
def default_company(cls):
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@classmethod
|
||||
def default_fiscalyear(cls):
|
||||
pool = Pool()
|
||||
FiscalYear = pool.get('account.fiscalyear')
|
||||
context = Transaction().context
|
||||
if 'fiscalyear' not in context:
|
||||
try:
|
||||
fiscalyear = FiscalYear.find(
|
||||
cls.default_company(), test_state=False)
|
||||
except FiscalYearNotFoundError:
|
||||
return None
|
||||
return fiscalyear.id
|
||||
return context['fiscalyear']
|
||||
|
||||
|
||||
class Invoice(metaclass=PoolMeta):
|
||||
__name__ = 'account.invoice'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.supplier_payment_reference_type.selection.append(
|
||||
('ogm_vcs', "Belgian structured communication"))
|
||||
|
||||
@classmethod
|
||||
def _format_supplier_payment_reference_ogm_vcs(cls, reference):
|
||||
try:
|
||||
return ogm_vcs.format(reference)
|
||||
except stdnum.exceptions.ValidationError:
|
||||
return reference
|
||||
|
||||
@classmethod
|
||||
def _search_customer_payment_reference(cls, value):
|
||||
yield from super()._search_customer_payment_reference(value)
|
||||
if ogm_vcs.is_valid(value):
|
||||
yield ('number_digit', '=', int(ogm_vcs.compact(value)[:-2]))
|
||||
|
||||
def _customer_payment_reference_type(self):
|
||||
type = super()._customer_payment_reference_type()
|
||||
if (self.invoice_address.country
|
||||
and self.invoice_address.country.code == 'BE'):
|
||||
type = 'ogm_vcs'
|
||||
return type
|
||||
|
||||
def _format_customer_payment_reference_ogm_vcs(self, source):
|
||||
number = self._customer_payment_reference_number_digit(source)
|
||||
if number:
|
||||
number = number % 10**10
|
||||
check_digit = ogm_vcs.calc_check_digits(str(number))
|
||||
reference = f'{self.number_digit:0>10}{check_digit}'
|
||||
return f'+++{ogm_vcs.format(reference)}+++'
|
||||
|
||||
def _check_supplier_payment_reference_ogm_vcs(self):
|
||||
return ogm_vcs.is_valid(self.supplier_payment_reference)
|
||||
|
||||
|
||||
class Payment(metaclass=PoolMeta):
|
||||
__name__ = 'account.payment'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.reference_type.selection.append(
|
||||
('ogm_vcs', "Belgian structured communication"))
|
||||
|
||||
@classmethod
|
||||
def _format_reference_ogm_vcs(cls, reference):
|
||||
try:
|
||||
return ogm_vcs.format(reference)
|
||||
except stdnum.exceptions.ValidationError:
|
||||
return reference
|
||||
|
||||
def _check_reference_ogm_vcs(self):
|
||||
return ogm_vcs.is_valid(self.reference)
|
||||
|
||||
|
||||
class StatementRuleLine(metaclass=PoolMeta):
|
||||
__name__ = 'account.statement.rule.line'
|
||||
|
||||
@classmethod
|
||||
def _party_payment_reference(cls, value):
|
||||
yield from super()._party_payment_reference(value)
|
||||
if ogm_vcs.is_valid(value):
|
||||
yield ('code_digit', '=', int(ogm_vcs.compact(value)[:-2]))
|
||||
Reference in New Issue
Block a user