Skip to content

Commit

Permalink
Update tests. Add scenario invoice supplier. Fix issue do not copy po…
Browse files Browse the repository at this point in the history
…s, tipo_comprobante and reference. Update INVOICE_CREDIT codes
  • Loading branch information
lukio committed Apr 23, 2019
1 parent ae71b26 commit da79bc3
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 7 deletions.
29 changes: 25 additions & 4 deletions invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@
'19': ('21', '21-Nota de Crédito E'),
'20': ('21', '21-Nota de Crédito E'),
'21': ('20', '20-Nota de Débito E'),
'27': ('48','48-Nota de Credito Liquidacion CLASE A'),
'28': ('43','43-Nota de Credito Liquidacion CLASE B'),
'29': ('44','44-Nota de Credito Liquidacion CLASE C'),
'51': ('53','53-NotaS de Credito M'),
'81': ('112','112-Tique Nota de Credito A'),
'82': ('113','113-Tique Nota de Credito B'),
'83': ('110','110-Tique Nota de Credito'),
'111': ('114','114-Tique Nota de Credito C'),
'118': ('119','119-Tique Nota de Credito M'),
'201': ('203','203-Nota de Credito Electronica MiPyMEs (FCE) A'),
'206': ('208','208-Nota de Credito Electronica MiPyMEs (FCE) B'),
'211': ('213','213- Nota de Credito Electronica MiPyMEs (FCE) C'),
}

INCOTERMS = [
Expand Down Expand Up @@ -403,6 +415,13 @@ def copy(cls, invoices, default=None):
default['pyafipws_cae_due_date'] = None
default['pyafipws_barcode'] = None
default['pyafipws_number'] = None
default['pyafipws_number'] = None
default['pos'] = None
default['invoice_type'] = None
default['ref_pos_number'] = None
default['ref_voucher_number'] = None
default['reference'] = None
default['tipo_comprobante'] = None
return super(Invoice, cls).copy(invoices, default=default)

@classmethod
Expand Down Expand Up @@ -529,8 +548,7 @@ def check_unique_reference(self):
self.raise_user_error('reference_unique')

def pre_validate_fields(self):
if (self.tipo_comprobante is None or self.tipo_comprobante == ''
or self.reference == ''):
if not self.reference and not self.tipo_comprobante:
self.raise_user_error('in_invoice_validate_failed')

@fields.depends('party', 'tipo_comprobante', 'type', 'reference')
Expand Down Expand Up @@ -645,10 +663,13 @@ def _credit(self):

credit = super(Invoice, self)._credit()
if self.type == 'in':
invoice_type, invoice_type_desc = INVOICE_CREDIT_AFIP_CODE[
str(int(self.tipo_comprobante))
]
credit.tipo_comprobante = invoice_type.rjust(3, '0')
credit.reference = None
return credit

credit.taxes = [tax._credit() for tax in self.taxes]

credit.pos = self.pos
credit.invoice_date = Date.today()
invoice_type, invoice_type_desc = INVOICE_CREDIT_AFIP_CODE[
Expand Down
16 changes: 15 additions & 1 deletion tests/scenario_invoice.rst
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,23 @@ Credit invoice with refund::
... credit_note_tax_code.amount
Decimal('20.00')

Pay invoice::
Attempt to post invoice without pos::

>>> invoice, = invoice.duplicate()
>>> invoice.state
'draft'
>>> invoice.click('post') # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
UserError: ...
>>> invoice.state
'draft'

Pay invoice::

>>> invoice.pos = pos
>>> invoice.invoice_type == invoice_types['1']
True
>>> invoice.click('post')

>>> pay = Wizard('account.invoice.pay', [invoice])
Expand Down
294 changes: 294 additions & 0 deletions tests/scenario_invoice_supplier.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
=========================
Invoice Supplier Scenario
=========================

Imports::
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from operator import attrgetter
>>> from proteus import Model, Wizard
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> 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
>>> from trytond.modules.account_invoice_ar.tests.tools import \
... create_tax_groups
>>> today = datetime.date.today()

Install account_invoice::

>>> config = activate_modules('account_invoice_ar')

Create company::

>>> currency = get_currency('ARS')
>>> _ = create_company(currency=currency)
>>> company = get_company()
>>> tax_identifier = company.party.identifiers.new()
>>> tax_identifier.type = 'ar_cuit'
>>> tax_identifier.code = '11111111113'
>>> company.party.iva_condition = 'responsable_inscripto'
>>> company.party.save()

Create fiscal year::

>>> fiscalyear = set_fiscalyear_invoice_sequences(
... create_fiscalyear(company))
>>> fiscalyear.click('create_period')
>>> period_ids = [p.id for p in fiscalyear.periods]

Create chart of accounts::

>>> _ = create_chart(company)
>>> accounts = get_accounts(company)
>>> payable = accounts['payable']
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> account_tax = accounts['tax']

Create tax groups::

>>> tax_groups = create_tax_groups()

Create tax::

>>> TaxCode = Model.get('account.tax.code')
>>> tax = create_tax(Decimal('.10'))
>>> tax.group = tax_groups['iva']
>>> 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 party::

>>> Party = Model.get('party.party')
>>> party = Party(name='Party',
... iva_condition='responsable_inscripto',
... vat_number='33333333339')
>>> party.save()

Create account category::

>>> ProductCategory = Model.get('product.category')
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_expense = expense
>>> account_category.account_revenue = revenue
>>> account_category.supplier_taxes.append(tax)
>>> account_category.save()

Create product::

>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.list_price = Decimal('40')
>>> template.account_category = account_category
>>> template.save()
>>> product, = template.products

Create payment term::

>>> PaymentTerm = Model.get('account.invoice.payment_term')
>>> payment_term = PaymentTerm(name='Term')
>>> line = payment_term.lines.new(type='remainder')
>>> payment_term.save()

Create invoice::

>>> Invoice = Model.get('account.invoice')
>>> InvoiceLine = Model.get('account.invoice.line')
>>> invoice = Invoice()
>>> invoice.type = 'in'
>>> invoice.party = party
>>> invoice.payment_term = payment_term
>>> invoice.invoice_date = today
>>> invoice.tipo_comprobante = '001'
>>> invoice.ref_pos_number = '1'
>>> invoice.ref_voucher_number = '312'
>>> line = InvoiceLine()
>>> invoice.lines.append(line)
>>> line.product = product
>>> line.quantity = 5
>>> line.unit_price = Decimal('20')
>>> line = InvoiceLine()
>>> invoice.lines.append(line)
>>> line.account = expense
>>> line.description = 'Test'
>>> line.quantity = 1
>>> line.unit_price = Decimal(10)
>>> invoice.untaxed_amount
Decimal('110.00')
>>> invoice.tax_amount
Decimal('10.00')
>>> invoice.total_amount
Decimal('120.00')
>>> invoice.save()
>>> invoice.reference
'00001-00000312'
>>> invoice.state
'draft'
>>> bool(invoice.move)
False
>>> invoice.click('validate_invoice')
>>> invoice.state
'validated'
>>> bool(invoice.move)
True
>>> invoice.move.state
'draft'
>>> invoice.click('post')
>>> invoice.state
'posted'
>>> bool(invoice.move)
True
>>> invoice.move.state
'posted'
>>> invoice.untaxed_amount
Decimal('110.00')
>>> invoice.tax_amount
Decimal('10.00')
>>> invoice.total_amount
Decimal('120.00')
>>> payable.reload()
>>> payable.debit
Decimal('0.00')
>>> payable.credit
Decimal('120.00')
>>> expense.reload()
>>> expense.debit
Decimal('110.00')
>>> expense.credit
Decimal('0.00')
>>> account_tax.reload()
>>> account_tax.debit
Decimal('10.00')
>>> account_tax.credit
Decimal('0.00')
>>> with config.set_context(periods=period_ids):
... invoice_base_code = TaxCode(invoice_base_code.id)
... invoice_base_code.amount
Decimal('100.00')
>>> with config.set_context(periods=period_ids):
... invoice_tax_code = TaxCode(invoice_tax_code.id)
... invoice_tax_code.amount
Decimal('10.00')
>>> with config.set_context(periods=period_ids):
... credit_note_base_code = TaxCode(credit_note_base_code.id)
... credit_note_base_code.amount
Decimal('0.00')
>>> with config.set_context(periods=period_ids):
... credit_note_tax_code = TaxCode(credit_note_tax_code.id)
... credit_note_tax_code.amount
Decimal('0.00')

Credit invoice::

>>> credit = Wizard('account.invoice.credit', [invoice])
>>> credit.form.with_refund = False
>>> credit.execute('credit')
>>> credit_note, = Invoice.find(
... [('type', '=', 'in'), ('id', '!=', invoice.id)])
>>> credit_note.state
'draft'
>>> credit_note.untaxed_amount == -invoice.untaxed_amount
True
>>> credit_note.tax_amount == -invoice.tax_amount
True
>>> credit_note.total_amount == -invoice.total_amount
True
>>> credit_note.tipo_comprobante == '003'
True
>>> credit_note.reference

Create a draft and post invoice::

>>> invoice = Invoice()
>>> invoice.type = 'in'
>>> invoice.party = party
>>> invoice.payment_term = payment_term
>>> invoice.invoice_date = today
>>> invoice.tipo_comprobante = '081'
>>> invoice.ref_pos_number = '5'
>>> invoice.ref_voucher_number = '333'
>>> line = invoice.lines.new()
>>> line.product = product
>>> line.quantity = 1
>>> line.unit_price = Decimal('20')
>>> invoice.click('post')
>>> invoice.reference
'00005-00000333'

Credit invoice::

>>> credit = Wizard('account.invoice.credit', [invoice])
>>> credit.form.with_refund = False
>>> credit.execute('credit')
>>> credit_note, = Invoice.find(
... [('type', '=', 'in'), ('id', '!=', invoice.id)])
>>> credit_note.state
'draft'
>>> credit_note.untaxed_amount == -invoice.untaxed_amount
True
>>> credit_note.tax_amount == -invoice.tax_amount
True
>>> credit_note.total_amount == -invoice.total_amount
True
>>> credit_note.tipo_comprobante == '112'
True
>>> credit_note.reference

Create a posted and a draft invoice to cancel::

>>> invoice = Invoice()
>>> invoice.type = 'in'
>>> invoice.party = party
>>> invoice.payment_term = payment_term
>>> invoice.invoice_date = today
>>> invoice.tipo_comprobante = '001'
>>> invoice.ref_pos_number = '1'
>>> invoice.ref_voucher_number = '123'
>>> line = invoice.lines.new()
>>> line.product = product
>>> line.quantity = 1
>>> line.unit_price = Decimal('20')
>>> invoice.click('post')
>>> invoice.reference
'00001-00000123'
>>> invoice_draft, = Invoice.duplicate([invoice])


Cancel draft invoice::

>>> invoice_draft.tipo_comprobante
>>> invoice_draft.reference
>>> invoice_draft.click('cancel')
>>> invoice_draft.state
'cancel'
>>> invoice_draft.move
>>> invoice_draft.reconciled

Cancel posted invoice::

>>> invoice.click('cancel')
>>> invoice.state
'cancel'
>>> invoice.cancel_move is not None
True
>>> invoice.reconciled == today
True
4 changes: 4 additions & 0 deletions tests/test_account_invoice_ar.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ def suite():
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
suite.addTests(doctest.DocFileSuite('scenario_invoice_supplier.rst',
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite
Loading

0 comments on commit da79bc3

Please sign in to comment.