Add extra dependency of aeat_349 to consider cost invoice as ammendment in 349 report.
This commit refs #26881
This commit is contained in:
parent
c4a41da4c0
commit
f904d51495
|
@ -25,3 +25,8 @@ def register():
|
|||
intrastat.InvoiceLine,
|
||||
module='sale_cost_apply_invoice', type_='model',
|
||||
depends=['intrastat'])
|
||||
Pool.register(
|
||||
sale_cost.CostType349,
|
||||
invoice.InvoiceLine349,
|
||||
module='sale_cost_apply_invoice', type_='model',
|
||||
depends=['aeat_349'])
|
||||
|
|
24
invoice.py
24
invoice.py
|
@ -90,3 +90,27 @@ class InvoiceLineSaleInfo(metaclass=PoolMeta):
|
|||
attributes.remove(attribute)
|
||||
|
||||
return attributes
|
||||
|
||||
|
||||
class InvoiceLine349(metaclass=PoolMeta):
|
||||
__name__ = 'account.invoice.line'
|
||||
|
||||
def _get_aeat_349_ammendment_line(self):
|
||||
pool = Pool()
|
||||
SaleLine = pool.get('sale.line')
|
||||
SaleCost = pool.get('sale.cost')
|
||||
|
||||
if (self.origin
|
||||
and isinstance(self.origin, SaleCost)
|
||||
and self.origin.type_.aeat_349_ammendment
|
||||
and self.origin.sale.invoices):
|
||||
for line in self.origin.sale.invoices[0].lines:
|
||||
if (line.type == 'line'
|
||||
and line.origin
|
||||
and isinstance(line.origin, SaleLine)
|
||||
and line.origin.sale == self.origin.sale):
|
||||
return line
|
||||
else:
|
||||
return
|
||||
|
||||
return super()._get_aeat_349_ammendment_line()
|
||||
|
|
|
@ -58,4 +58,8 @@ msgstr "Todo"
|
|||
|
||||
msgctxt "field:sale.cost.type,declare_intrastat:"
|
||||
msgid "Declare Intrastat"
|
||||
msgstr "Declarar en Intrastat"
|
||||
msgstr "Declarar en Intrastat"
|
||||
|
||||
msgctxt "field:sale.cost.type,aeat_349_ammendment:"
|
||||
msgid "AEAT 349 ammendment"
|
||||
msgstr "Rectificación en AEAT 349"
|
||||
|
|
11
sale_cost.py
11
sale_cost.py
|
@ -2,7 +2,7 @@
|
|||
# copyright notices and license terms.
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.model import fields
|
||||
from trytond.pyson import Eval, Not, And, In
|
||||
from trytond.pyson import Eval, Not, And, In, Equal
|
||||
from trytond.modules.document_cost_apply_invoice.cost import (
|
||||
ApplyMethodCostMixin, ApplyMethodCostDocumentMixin,
|
||||
ApplyInvoiceAccountMixin
|
||||
|
@ -96,3 +96,12 @@ class SaleCostDiscount(metaclass=PoolMeta):
|
|||
line.discount = 0
|
||||
line.gross_unit_price = line.unit_price
|
||||
return lines
|
||||
|
||||
|
||||
class CostType349(metaclass=PoolMeta):
|
||||
__name__ = 'sale.cost.type'
|
||||
|
||||
aeat_349_ammendment = fields.Boolean('AEAT 349 ammendment',
|
||||
states={
|
||||
'invisible': Not(Equal(Eval('apply_method', ''), 'invoice_out'))
|
||||
}, depends=['apply_method'])
|
||||
|
|
|
@ -94,4 +94,11 @@
|
|||
<field name="group" ref="sale_cost.group_sale_cost"/>
|
||||
</record>
|
||||
</data>
|
||||
<data depends="aeat_349">
|
||||
<record model="ir.ui.view" id="cost_type_349_view_form">
|
||||
<field name="model">sale.cost.type</field>
|
||||
<field name="inherit" ref="sale_cost.cost_type_view_form"/>
|
||||
<field name="name">cost_type_349_form</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
|
@ -0,0 +1,378 @@
|
|||
================================
|
||||
Sale Cost Apply Invoice Scenario
|
||||
================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
>>> from dateutil.relativedelta import relativedelta
|
||||
>>> from decimal import Decimal
|
||||
>>> from operator import attrgetter
|
||||
>>> from proteus import Model, Wizard, Report
|
||||
>>> from trytond.modules.company.tests.tools import create_company, \
|
||||
... get_company
|
||||
>>> from trytond.modules.account.tests.tools import create_fiscalyear, \
|
||||
... create_chart, get_accounts, create_tax, create_tax_code
|
||||
>>> from trytond.modules.account_invoice.tests.tools import \
|
||||
... set_fiscalyear_invoice_sequences, create_payment_term
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
|
||||
|
||||
Install sale_cost_apply_invoice::
|
||||
|
||||
>>> config = activate_modules(['sale_cost_apply_invoice', 'aeat_349'])
|
||||
|
||||
|
||||
Get Models::
|
||||
|
||||
>>> A349Type = Model.get('aeat.349.type')
|
||||
>>> CostTemplate = Model.get('sale.cost.template')
|
||||
>>> CostType = Model.get('sale.cost.type')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> Product = Model.get('product.product')
|
||||
>>> ProductCategory = Model.get('product.category')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> Report = Model.get('aeat.349.report')
|
||||
>>> Sale = Model.get('sale.sale')
|
||||
>>> SaleCost = Model.get('sale.cost')
|
||||
>>> Tax = Model.get('account.tax')
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
>>> InvoiceLine = Model.get('account.invoice.line')
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
|
||||
|
||||
Create company::
|
||||
|
||||
>>> eur = get_currency('EUR')
|
||||
>>> _ = create_company(currency=eur)
|
||||
>>> company = get_company()
|
||||
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(company))
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> today = datetime.date.today()
|
||||
|
||||
Create chart of accounts::
|
||||
|
||||
>>> _ = create_chart(company)
|
||||
>>> accounts = get_accounts(company)
|
||||
>>> receivable = accounts['receivable']
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_tax = accounts['tax']
|
||||
|
||||
|
||||
Create AEAT 349::
|
||||
|
||||
>>> operation_key_e, = A349Type.find([('operation_key', '=', 'E')])
|
||||
>>> operation_key_a, = A349Type.find([('operation_key', '=', 'A')])
|
||||
>>> operation_key_a_e, = A349Type.find([('operation_key', '=', 'A-E')])
|
||||
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> tax.aeat349_operation_keys.append(operation_key_e)
|
||||
>>> tax.aeat349_operation_keys.append(operation_key_a)
|
||||
>>> tax.aeat349_operation_keys.append(operation_key_a_e)
|
||||
>>> tax.aeat349_default_out_operation_key = operation_key_e
|
||||
>>> tax.aeat349_default_in_operation_key = operation_key_a
|
||||
>>> tax.aeat349_default_out_ammendment_key = operation_key_a_e
|
||||
>>> tax.save()
|
||||
|
||||
>>> invoice_base_code = create_tax_code(tax, 'base', 'invoice')
|
||||
>>> invoice_base_code.save()
|
||||
|
||||
>>> invoice_tax_code = create_tax_code(tax, 'tax', 'invoice')
|
||||
>>> invoice_tax_code.save()
|
||||
|
||||
>>> credit_note_base_code = create_tax_code(tax, 'base', 'credit')
|
||||
>>> credit_note_base_code.save()
|
||||
|
||||
>>> credit_note_tax_code = create_tax_code(tax, 'tax', 'credit')
|
||||
>>> credit_note_tax_code.save()
|
||||
|
||||
|
||||
Create account categories::
|
||||
|
||||
>>> account_category = ProductCategory(name="Account Category")
|
||||
>>> account_category.accounting = True
|
||||
>>> account_category.account_expense = expense
|
||||
>>> account_category.account_revenue = revenue
|
||||
>>> account_category.save()
|
||||
|
||||
>>> account_category_tax, = account_category.duplicate()
|
||||
>>> account_category_tax.customer_taxes.append(tax)
|
||||
>>> account_category_tax.save()
|
||||
|
||||
|
||||
Create parties::
|
||||
|
||||
>>> customer = Party(name='Customer')
|
||||
>>> customer.save()
|
||||
>>> address = customer.addresses.new()
|
||||
>>> address.name = 'Address 2'
|
||||
>>> customer.save()
|
||||
|
||||
|
||||
Create product::
|
||||
|
||||
>>> kg, = ProductUom.find([('name', '=', 'Kilogram')])
|
||||
>>> gram, = ProductUom.find([('name', '=', 'Gram')])
|
||||
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||
|
||||
>>> template = ProductTemplate()
|
||||
>>> template.name = 'product 1'
|
||||
>>> template.default_uom = kg
|
||||
>>> template.type = 'goods'
|
||||
>>> template.salable = True
|
||||
>>> template.list_price = Decimal('10')
|
||||
>>> template.cost_price = Decimal('5')
|
||||
>>> template.cost_price_method = 'fixed'
|
||||
>>> template.account_category = account_category_tax
|
||||
>>> template.save()
|
||||
>>> product1 = template.products[0]
|
||||
|
||||
>>> template = ProductTemplate()
|
||||
>>> template.name = 'product 2'
|
||||
>>> template.default_uom = kg
|
||||
>>> template.type = 'goods'
|
||||
>>> template.salable = True
|
||||
>>> template.list_price = Decimal('30')
|
||||
>>> template.cost_price = Decimal('10')
|
||||
>>> template.cost_price_method = 'fixed'
|
||||
>>> template.account_category = account_category_tax
|
||||
>>> template.save()
|
||||
>>> product2 = template.products[0]
|
||||
|
||||
>>> template = ProductTemplate()
|
||||
>>> template.name = 'service'
|
||||
>>> template.default_uom = unit
|
||||
>>> template.type = 'service'
|
||||
>>> template.salable = True
|
||||
>>> template.list_price = Decimal('50')
|
||||
>>> template.cost_price = Decimal('20')
|
||||
>>> template.cost_price_method = 'fixed'
|
||||
>>> template.account_category = account_category_tax
|
||||
>>> template.save()
|
||||
>>> service = template.products[0]
|
||||
|
||||
Create payment term::
|
||||
|
||||
>>> payment_term = create_payment_term()
|
||||
>>> payment_term.save()
|
||||
|
||||
|
||||
Create cost type invoice out::
|
||||
|
||||
>>> cost_type_invoice_out = CostType(name='Invoice out')
|
||||
>>> cost_type_invoice_out.product = service
|
||||
>>> cost_type_invoice_out.apply_method = 'invoice_out'
|
||||
>>> cost_type_invoice_out.formula = '0.3*untaxed_amount'
|
||||
>>> cost_type_invoice_out.aeat_349_ammendment = True
|
||||
>>> cost_type_invoice_out.invoice_party = customer
|
||||
>>> cost_type_invoice_out.manual = True
|
||||
>>> cost_type_invoice_out.save()
|
||||
|
||||
|
||||
Sale 2 products::
|
||||
|
||||
>>> sale = Sale()
|
||||
>>> sale.party = customer
|
||||
>>> sale.payment_term = payment_term
|
||||
>>> sale.invoice_method = 'order'
|
||||
>>> sale_line = sale.lines.new()
|
||||
>>> sale_line.product = product1
|
||||
>>> sale_line.quantity = 2.0
|
||||
>>> sale_line = sale.lines.new()
|
||||
>>> sale_line.product = product2
|
||||
>>> sale_line.quantity = 300.0
|
||||
>>> sale_line.unit = gram
|
||||
>>> cost = sale.costs.new()
|
||||
>>> cost.type_ = cost_type_invoice_out
|
||||
>>> sale.click('distribute_costs')
|
||||
>>> sale.click('quote')
|
||||
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
|
||||
(Decimal('29.00'), Decimal('2.90'), Decimal('31.90'))
|
||||
>>> sale.click('confirm')
|
||||
|
||||
|
||||
Get invoice::
|
||||
|
||||
>>> sale.reload()
|
||||
>>> invoice, = sale.invoices
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
|
||||
|
||||
Create invoice cost::
|
||||
|
||||
>>> invoice_cost_line, = InvoiceLine.find([
|
||||
... ('origin', 'like', 'sale.cost%'),
|
||||
... ('invoice', '=', None)])
|
||||
|
||||
>>> invoice_cost_line.amount
|
||||
Decimal('-8.70')
|
||||
>>> invoice_cost_line.aeat349_operation_key == operation_key_a_e
|
||||
True
|
||||
|
||||
>>> invoice_cost = Invoice()
|
||||
>>> invoice_cost.invoice_date = today
|
||||
>>> invoice_cost.party = customer
|
||||
>>> invoice_cost.payment_term = payment_term
|
||||
>>> invoice_cost.lines.append(invoice_cost_line)
|
||||
>>> invoice_cost.save()
|
||||
>>> invoice_cost_line, = invoice_cost.lines
|
||||
>>> invoice_cost.click('post')
|
||||
|
||||
|
||||
Generate 349 Report::
|
||||
|
||||
>>> report = Report()
|
||||
>>> report.year = today.year
|
||||
>>> report.period = "%02d" % (today.month)
|
||||
>>> report.company_vat = '123456789'
|
||||
>>> report.contact_name = 'Guido van Rosum'
|
||||
>>> report.contact_phone = '987654321'
|
||||
>>> report.representative_vat = '22334455'
|
||||
>>> report.click('calculate')
|
||||
>>> report.operation_amount
|
||||
Decimal('20.30')
|
||||
>>> report.ammendment_amount
|
||||
Decimal('0.0')
|
||||
>>> len(report.operations)
|
||||
1
|
||||
>>> len(report.ammendments)
|
||||
0
|
||||
|
||||
|
||||
Refund invoice::
|
||||
|
||||
>>> credit = Wizard('account.invoice.credit', [invoice])
|
||||
>>> credit.form.with_refund = True
|
||||
>>> credit.form.invoice_date = today
|
||||
>>> credit.execute('credit')
|
||||
|
||||
|
||||
Recompute 349 Report::
|
||||
|
||||
>>> report.click('draft')
|
||||
>>> report.click('calculate')
|
||||
>>> report.operation_amount
|
||||
Decimal('-8.70')
|
||||
>>> report.ammendment_amount
|
||||
Decimal('0.0')
|
||||
>>> len(report.operations)
|
||||
1
|
||||
>>> len(report.ammendments)
|
||||
0
|
||||
|
||||
|
||||
Sale2 2 products::
|
||||
|
||||
>>> sale2 = Sale()
|
||||
>>> sale2.party = customer
|
||||
>>> sale2.payment_term = payment_term
|
||||
>>> sale2.invoice_method = 'order'
|
||||
>>> sale_line = sale2.lines.new()
|
||||
>>> sale_line.product = product1
|
||||
>>> sale_line.quantity = 2.0
|
||||
>>> sale_line = sale2.lines.new()
|
||||
>>> sale_line.product = product2
|
||||
>>> sale_line.quantity = 300.0
|
||||
>>> sale_line.unit = gram
|
||||
>>> cost = sale2.costs.new()
|
||||
>>> cost.type_ = cost_type_invoice_out
|
||||
>>> sale2.click('distribute_costs')
|
||||
>>> sale2.click('quote')
|
||||
>>> sale2.click('confirm')
|
||||
>>> sale2.untaxed_amount
|
||||
Decimal('29.00')
|
||||
|
||||
|
||||
Get invoice2::
|
||||
|
||||
>>> sale2.reload()
|
||||
>>> invoice2, = sale2.invoices
|
||||
>>> invoice2.invoice_date = today
|
||||
>>> invoice2.click('post')
|
||||
|
||||
Create invoice cost::
|
||||
|
||||
>>> invoice_date = today + relativedelta(months=1)
|
||||
|
||||
>>> invoice_cost_line, = InvoiceLine.find([
|
||||
... ('origin', 'like', 'sale.cost%'),
|
||||
... ('invoice', '=', None)])
|
||||
|
||||
>>> invoice_cost_line.amount
|
||||
Decimal('-8.70')
|
||||
|
||||
>>> invoice_cost2 = Invoice()
|
||||
>>> invoice_cost2.invoice_date = invoice_date
|
||||
>>> invoice_cost2.party = customer
|
||||
>>> invoice_cost2.payment_term = payment_term
|
||||
>>> invoice_cost2.lines.append(invoice_cost_line)
|
||||
>>> invoice_cost2.click('post')
|
||||
|
||||
|
||||
Recompute 349 Report::
|
||||
|
||||
>>> report.click('draft')
|
||||
>>> report.click('calculate')
|
||||
>>> report.operation_amount
|
||||
Decimal('20.30')
|
||||
>>> report.ammendment_amount
|
||||
Decimal('0.0')
|
||||
>>> len(report.operations)
|
||||
1
|
||||
>>> len(report.ammendments)
|
||||
0
|
||||
|
||||
|
||||
Generate 349 Report next month::
|
||||
|
||||
>>> report2 = Report()
|
||||
>>> report2.year = invoice_date.year
|
||||
>>> report2.period = "%02d" % (invoice_date.month)
|
||||
>>> report2.company_vat = '123456789'
|
||||
>>> report2.contact_name = 'Guido van Rosum'
|
||||
>>> report2.contact_phone = '987654321'
|
||||
>>> report2.representative_vat = '22334455'
|
||||
>>> report2.click('calculate')
|
||||
>>> report2.operation_amount
|
||||
Decimal('0.0')
|
||||
>>> report2.ammendment_amount
|
||||
Decimal('8.70')
|
||||
>>> len(report2.operations)
|
||||
0
|
||||
>>> len(report2.ammendments)
|
||||
1
|
||||
|
||||
Refund invoice (today + 1 month)::
|
||||
|
||||
>>> credit = Wizard('account.invoice.credit', [invoice2])
|
||||
>>> credit.form.with_refund = True
|
||||
>>> credit.form.invoice_date = invoice_date
|
||||
>>> credit.execute('credit')
|
||||
|
||||
|
||||
Generate 349 Report (today + 1 month)::
|
||||
|
||||
>>> report2.click('draft')
|
||||
>>> report2.click('calculate')
|
||||
>>> report2.operation_amount
|
||||
Decimal('0.0')
|
||||
>>> report2.ammendment_amount
|
||||
Decimal('37.70')
|
||||
>>> len(report2.operations)
|
||||
0
|
||||
>>> len(report2.ammendments)
|
||||
1
|
||||
>>> len(report2.ammendments[0].invoice_lines)
|
||||
3
|
|
@ -0,0 +1,42 @@
|
|||
# The COPYRIGHT file at the top level of this repository contains
|
||||
# the full copyright notices and license terms.
|
||||
import unittest
|
||||
|
||||
import doctest
|
||||
|
||||
from trytond.tests.test_tryton import ModuleTestCase
|
||||
from trytond.tests.test_tryton import suite as test_suite
|
||||
from trytond.tests.test_tryton import doctest_teardown
|
||||
from trytond.tests.test_tryton import doctest_checker
|
||||
|
||||
|
||||
class SaleCostApplyInvoiceTestCase(ModuleTestCase):
|
||||
"""Test Sale Cost Apply Invoice module"""
|
||||
module = 'sale_cost_apply_invoice'
|
||||
|
||||
|
||||
def suite():
|
||||
suite = test_suite()
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
|
||||
SaleCostApplyInvoiceTestCase))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_sale_cost_apply_invoice.rst',
|
||||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_sale_cost_apply_invoice_account.rst',
|
||||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_sale_cost_intrastat.rst',
|
||||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_sale_cost_apply_invoice_349.rst',
|
||||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
return suite
|
|
@ -10,6 +10,7 @@ extras_depend:
|
|||
account_invoice_line_sale_info
|
||||
account_invoice_discount
|
||||
intrastat
|
||||
aeat_349
|
||||
|
||||
xml:
|
||||
sale_cost.xml
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/group[@id='checkboxes']" position="inside">
|
||||
<label name="aeat_349_ammendment"/>
|
||||
<field name="aeat_349_ammendment" xexpand="0" width="100"/>
|
||||
</xpath>
|
||||
</data>
|
Loading…
Reference in New Issue