first commit
This commit is contained in:
6
modules/account_invoice/tests/__init__.py
Normal file
6
modules/account_invoice/tests/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# 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 .test_module import set_invoice_sequences
|
||||
|
||||
__all__ = ['set_invoice_sequences']
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
modules/account_invoice/tests/__pycache__/tools.cpython-311.pyc
Normal file
BIN
modules/account_invoice/tests/__pycache__/tools.cpython-311.pyc
Normal file
Binary file not shown.
@@ -0,0 +1,100 @@
|
||||
================================
|
||||
Cancelling Invoice Move Scenario
|
||||
================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.exceptions import CancelInvoiceMoveWarning
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> ProductCategory = Model.get('product.category')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Warning = Model.get('res.user.warning')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name="Party")
|
||||
>>> party.save()
|
||||
|
||||
Create account category::
|
||||
|
||||
>>> account_category = ProductCategory(name="Account Category")
|
||||
>>> account_category.accounting = True
|
||||
>>> account_category.account_expense = accounts['expense']
|
||||
>>> account_category.account_revenue = accounts['revenue']
|
||||
>>> account_category.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||
>>> 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 invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('40')
|
||||
|
||||
Post invoice and cancel the created move::
|
||||
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> cancel_move = Wizard('account.move.cancel', [invoice.move])
|
||||
>>> cancel_move.form.description = 'Cancel'
|
||||
>>> cancel_move.execute('cancel')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
CancelInvoiceMoveWarning: ...
|
||||
|
||||
Bypass the warning and cancel the move::
|
||||
|
||||
>>> try:
|
||||
... cancel_move.execute('cancel')
|
||||
... except CancelInvoiceMoveWarning as warning:
|
||||
... Warning(user=config.user, name=warning.name).save()
|
||||
>>> cancel_move.execute('cancel')
|
||||
>>> cancel_move.state
|
||||
'end'
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> [bool(l.reconciliation) for l in invoice.move.lines
|
||||
... if l.account == accounts['receivable']]
|
||||
[True]
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
135
modules/account_invoice/tests/scenario_credit_note.rst
Normal file
135
modules/account_invoice/tests/scenario_credit_note.rst
Normal file
@@ -0,0 +1,135 @@
|
||||
====================
|
||||
Credit Note Scenario
|
||||
====================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> receivable = accounts['receivable']
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_cash = accounts['cash']
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> tax.save()
|
||||
|
||||
Create payment method::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> Sequence = Model.get('ir.sequence')
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = 'Cash'
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = account_cash
|
||||
>>> payment_method.debit_account = account_cash
|
||||
>>> payment_method.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> 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.customer_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 credit note::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = -5
|
||||
>>> line.unit_price = Decimal('40')
|
||||
>>> invoice.total_amount
|
||||
Decimal('-220.00')
|
||||
>>> invoice.save()
|
||||
|
||||
Post credit note::
|
||||
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
|
||||
Pay credit note::
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('-220.00')
|
||||
>>> pay.form.amount = Decimal('-120.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.form.type = 'partial'
|
||||
>>> pay.form.amount
|
||||
Decimal('-120.00')
|
||||
>>> len(pay.form.lines_to_pay)
|
||||
1
|
||||
>>> len(pay.form.payment_lines)
|
||||
0
|
||||
>>> len(pay.form.lines)
|
||||
1
|
||||
>>> pay.form.amount_writeoff
|
||||
Decimal('-100.00')
|
||||
>>> pay.execute('pay')
|
||||
>>> pay.state
|
||||
'end'
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('-100.00')
|
||||
>>> pay.form.amount = Decimal('-100.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
>>> sorted(l.debit for l in invoice.reconciliation_lines)
|
||||
[Decimal('100.00'), Decimal('120.00')]
|
||||
435
modules/account_invoice/tests/scenario_invoice.rst
Normal file
435
modules/account_invoice/tests/scenario_invoice.rst
Normal file
@@ -0,0 +1,435 @@
|
||||
================
|
||||
Invoice Scenario
|
||||
================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from stdnum import iso11649
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company, get_company
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual, assertTrue
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Setup company::
|
||||
|
||||
>>> company = get_company()
|
||||
>>> tax_identifier = company.party.identifiers.new()
|
||||
>>> tax_identifier.type = 'eu_vat'
|
||||
>>> tax_identifier.code = 'BE0897290877'
|
||||
>>> company.party.save()
|
||||
|
||||
Set employee::
|
||||
|
||||
>>> User = Model.get('res.user')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> Employee = Model.get('company.employee')
|
||||
>>> employee_party = Party(name="Employee")
|
||||
>>> employee_party.save()
|
||||
>>> employee = Employee(party=employee_party)
|
||||
>>> employee.save()
|
||||
>>> user = User(config.user)
|
||||
>>> user.employees.append(employee)
|
||||
>>> user.employee = employee
|
||||
>>> user.save()
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
>>> period_ids = [p.id for p in fiscalyear.periods]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> receivable = accounts['receivable']
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_tax = accounts['tax']
|
||||
>>> account_cash = accounts['cash']
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> 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 payment method::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> Sequence = Model.get('ir.sequence')
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = 'Cash'
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = account_cash
|
||||
>>> payment_method.debit_account = account_cash
|
||||
>>> payment_method.save()
|
||||
|
||||
Create Write Off method::
|
||||
|
||||
>>> WriteOff = Model.get('account.move.reconcile.write_off')
|
||||
>>> journal_writeoff, = Journal.find(
|
||||
... [('code', '=', 'EXC'), ('type', '=', 'write-off')], limit=1)
|
||||
>>> writeoff_method = WriteOff()
|
||||
>>> writeoff_method.name = 'Rate loss'
|
||||
>>> writeoff_method.journal = journal_writeoff
|
||||
>>> writeoff_method.credit_account = expense
|
||||
>>> writeoff_method.debit_account = expense
|
||||
>>> writeoff_method.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> 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.customer_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='percent', ratio=Decimal('.5'))
|
||||
>>> delta, = line.relativedeltas
|
||||
>>> delta.days = 20
|
||||
>>> line = payment_term.lines.new(type='remainder')
|
||||
>>> delta = line.relativedeltas.new(days=40)
|
||||
>>> payment_term.save()
|
||||
|
||||
Create invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> InvoiceLine = Model.get('account.invoice.line')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> line = InvoiceLine()
|
||||
>>> invoice.lines.append(line)
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('40')
|
||||
>>> line = InvoiceLine()
|
||||
>>> invoice.lines.append(line)
|
||||
>>> line.account = revenue
|
||||
>>> line.description = 'Test'
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(20)
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('220.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('20.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('240.00')
|
||||
>>> invoice.save()
|
||||
>>> bool(invoice.has_report_cache)
|
||||
False
|
||||
|
||||
Test change tax::
|
||||
|
||||
>>> tax_line, = invoice.taxes
|
||||
>>> assertEqual(tax_line.tax, tax)
|
||||
>>> tax_line.tax = None
|
||||
>>> tax_line.tax = tax
|
||||
|
||||
Validate invoice::
|
||||
|
||||
>>> invoice.click('validate_invoice')
|
||||
>>> assertEqual(invoice.validated_by, employee)
|
||||
|
||||
Post invoice::
|
||||
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
>>> assertEqual(invoice.posted_by, employee)
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.tax_identifier.code
|
||||
'BE0897290877'
|
||||
>>> assertTrue(iso11649.validate(invoice.customer_payment_reference))
|
||||
>>> bool(invoice.has_report_cache)
|
||||
True
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('220.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('20.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('240.00')
|
||||
>>> receivable.reload()
|
||||
>>> receivable.debit
|
||||
Decimal('240.00')
|
||||
>>> receivable.credit
|
||||
Decimal('0.00')
|
||||
>>> revenue.reload()
|
||||
>>> revenue.debit
|
||||
Decimal('0.00')
|
||||
>>> revenue.credit
|
||||
Decimal('220.00')
|
||||
>>> account_tax.reload()
|
||||
>>> account_tax.debit
|
||||
Decimal('0.00')
|
||||
>>> account_tax.credit
|
||||
Decimal('20.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_base_code = TaxCode(invoice_base_code.id)
|
||||
... invoice_base_code.amount
|
||||
Decimal('200.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_tax_code = TaxCode(invoice_tax_code.id)
|
||||
... invoice_tax_code.amount
|
||||
Decimal('20.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 with refund::
|
||||
|
||||
>>> credit = Wizard('account.invoice.credit', [invoice])
|
||||
>>> credit.form.with_refund = True
|
||||
>>> credit.form.invoice_date = invoice.invoice_date
|
||||
>>> credit.execute('credit')
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'cancelled'
|
||||
>>> bool(invoice.cancel_move)
|
||||
True
|
||||
>>> bool(invoice.reconciled)
|
||||
True
|
||||
>>> credit_note, = Invoice.find([
|
||||
... ('type', '=', 'out'), ('id', '!=', invoice.id)])
|
||||
>>> credit_note.state
|
||||
'paid'
|
||||
>>> for line in credit_note.lines:
|
||||
... assertEqual(line.taxes_date, today)
|
||||
>>> receivable.reload()
|
||||
>>> receivable.debit
|
||||
Decimal('240.00')
|
||||
>>> receivable.credit
|
||||
Decimal('240.00')
|
||||
>>> revenue.reload()
|
||||
>>> revenue.debit
|
||||
Decimal('220.00')
|
||||
>>> revenue.credit
|
||||
Decimal('220.00')
|
||||
>>> account_tax.reload()
|
||||
>>> account_tax.debit
|
||||
Decimal('20.00')
|
||||
>>> account_tax.credit
|
||||
Decimal('20.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_base_code = TaxCode(invoice_base_code.id)
|
||||
... invoice_base_code.amount
|
||||
Decimal('200.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_tax_code = TaxCode(invoice_tax_code.id)
|
||||
... invoice_tax_code.amount
|
||||
Decimal('20.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... credit_note_base_code = TaxCode(credit_note_base_code.id)
|
||||
... credit_note_base_code.amount
|
||||
Decimal('200.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... credit_note_tax_code = TaxCode(credit_note_tax_code.id)
|
||||
... credit_note_tax_code.amount
|
||||
Decimal('20.00')
|
||||
|
||||
Unreconcile cancelled invoice::
|
||||
|
||||
>>> unreconcile_lines = Wizard(
|
||||
... 'account.move.unreconcile_lines', invoice.move.lines)
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.cancel_move
|
||||
|
||||
Pay invoice::
|
||||
|
||||
>>> invoice, = invoice.duplicate()
|
||||
>>> invoice.click('post')
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('240.00')
|
||||
>>> pay.form.amount = Decimal('120.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('120.00')
|
||||
>>> pay.form.amount = Decimal('20.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.form.type = 'partial'
|
||||
>>> pay.form.amount
|
||||
Decimal('20.00')
|
||||
>>> len(pay.form.lines_to_pay)
|
||||
1
|
||||
>>> len(pay.form.payment_lines)
|
||||
0
|
||||
>>> len(pay.form.lines)
|
||||
1
|
||||
>>> pay.form.amount_writeoff
|
||||
Decimal('100.00')
|
||||
>>> pay.execute('pay')
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('-20.00')
|
||||
>>> pay.form.amount = Decimal('99.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.form.type = 'writeoff'
|
||||
>>> pay.form.writeoff = writeoff_method
|
||||
>>> pay.form.amount
|
||||
Decimal('99.00')
|
||||
>>> len(pay.form.lines_to_pay)
|
||||
1
|
||||
>>> len(pay.form.payment_lines)
|
||||
1
|
||||
>>> len(pay.form.lines)
|
||||
1
|
||||
>>> pay.form.amount_writeoff
|
||||
Decimal('1.00')
|
||||
>>> pay.execute('pay')
|
||||
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
>>> sorted(l.credit for l in invoice.reconciliation_lines)
|
||||
[Decimal('1.00'), Decimal('20.00'), Decimal('99.00'), Decimal('120.00')]
|
||||
|
||||
Create empty invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
|
||||
Create some complex invoice and test its taxes base rounding::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> invoice.invoice_date = today
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('0.0035')
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('0.0035')
|
||||
>>> invoice.save()
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('0.00')
|
||||
>>> assertEqual(invoice.taxes[0].base, invoice.untaxed_amount)
|
||||
>>> empty_invoice, found_invoice = Invoice.find(
|
||||
... [('untaxed_amount', '=', Decimal(0))], order=[('id', 'ASC')])
|
||||
>>> assertEqual(found_invoice, invoice)
|
||||
>>> empty_invoice, found_invoice = Invoice.find(
|
||||
... [('total_amount', '=', Decimal(0))], order=[('id', 'ASC')])
|
||||
>>> assertEqual(found_invoice, invoice)
|
||||
|
||||
Clear company tax_identifier::
|
||||
|
||||
>>> tax_identifier, = company.party.identifiers
|
||||
>>> tax_identifier.type = None
|
||||
>>> tax_identifier.save()
|
||||
|
||||
Create a paid invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('40')
|
||||
>>> invoice.click('post')
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
>>> invoice.tax_identifier
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
|
||||
The invoice is posted when the reconciliation is deleted::
|
||||
|
||||
>>> invoice.payment_lines[0].reconciliation.delete()
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.tax_identifier
|
||||
|
||||
Credit invoice with non line lines::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('40')
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.type = 'comment'
|
||||
>>> line.description = 'Comment'
|
||||
>>> invoice.click('post')
|
||||
>>> credit = Wizard('account.invoice.credit', [invoice])
|
||||
>>> credit.form.with_refund = True
|
||||
>>> credit.execute('credit')
|
||||
@@ -0,0 +1,194 @@
|
||||
===================================
|
||||
Invoice Scenario Alternate Currency
|
||||
===================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.exceptions import InvoiceTaxesWarning
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
>>> tomorrow = today + dt.timedelta(days=1)
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Warning = Model.get('res.user.warning')
|
||||
|
||||
Get currencies::
|
||||
|
||||
>>> currency = get_currency('USD')
|
||||
>>> eur = get_currency('EUR')
|
||||
|
||||
Set alternate currency rates::
|
||||
|
||||
>>> rate = eur.rates.new()
|
||||
>>> rate.date = today
|
||||
>>> rate.rate = eur.rates[0].rate
|
||||
>>> rate = eur.rates.new()
|
||||
>>> rate.date = tomorrow
|
||||
>>> rate.rate = eur.rates[0].rate + Decimal('0.5')
|
||||
>>> eur.save()
|
||||
|
||||
Create fiscal years::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=(today, tomorrow)))
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_tax = accounts['tax']
|
||||
>>> account_cash = accounts['cash']
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> tax.save()
|
||||
|
||||
Create payment method::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = 'Cash'
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = account_cash
|
||||
>>> payment_method.debit_account = account_cash
|
||||
>>> payment_method.save()
|
||||
|
||||
Create writeoff method::
|
||||
|
||||
>>> WriteOff = Model.get('account.move.reconcile.write_off')
|
||||
>>> journal_writeoff = Journal(name='Write-Off', type='write-off')
|
||||
>>> journal_writeoff.save()
|
||||
>>> writeoff = WriteOff()
|
||||
>>> writeoff.name = 'Rate loss'
|
||||
>>> writeoff.journal = journal_writeoff
|
||||
>>> writeoff.credit_account = expense
|
||||
>>> writeoff.debit_account = expense
|
||||
>>> writeoff.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> 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.customer_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 invoice with alternate currency::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.currency = eur
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('80')
|
||||
>>> line.amount
|
||||
Decimal('400.00')
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = revenue
|
||||
>>> line.description = 'Test'
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(20)
|
||||
>>> line.amount
|
||||
Decimal('20.00')
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('420.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('40.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('460.00')
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('420.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('40.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('460.00')
|
||||
|
||||
Create negative tax::
|
||||
|
||||
>>> negative_tax = create_tax(Decimal('-.10'))
|
||||
>>> negative_tax.save()
|
||||
|
||||
Create invoice with alternate currency and negative taxes::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.currency = eur
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('80')
|
||||
>>> _ = line.taxes.pop(0)
|
||||
>>> line.taxes.append(negative_tax)
|
||||
>>> line.amount
|
||||
Decimal('400.00')
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('400.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('-40.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('360.00')
|
||||
>>> try:
|
||||
... invoice.click('post')
|
||||
... except InvoiceTaxesWarning as warning:
|
||||
... Warning(user=config.user, name=warning.name).save()
|
||||
... raise
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvoiceTaxesWarning: ...
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('400.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('-40.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('360.00')
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
=================================================
|
||||
Invoice Scenario Alternate Currency with Exchange
|
||||
=================================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Configuration = Model.get('account.configuration')
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> PaymentTerm = Model.get('account.invoice.payment_term')
|
||||
|
||||
Get currencies::
|
||||
|
||||
>>> currency = get_currency('USD')
|
||||
>>> eur = get_currency('EUR')
|
||||
|
||||
Set alternate currency rates::
|
||||
|
||||
>>> rate, = eur.rates
|
||||
>>> rate.rate = Decimal('0.3')
|
||||
>>> eur.save()
|
||||
|
||||
Create fiscal years::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Configure currency exchange::
|
||||
|
||||
>>> currency_exchange_account, = (
|
||||
... accounts['revenue'].duplicate(
|
||||
... default={'name': "Currency Exchange"}))
|
||||
>>> configuration = Configuration(1)
|
||||
>>> configuration.currency_exchange_credit_account = (
|
||||
... currency_exchange_account)
|
||||
>>> configuration.save()
|
||||
|
||||
Create payment term::
|
||||
|
||||
>>> payment_term = PaymentTerm(name="Payment Term")
|
||||
>>> line = payment_term.lines.new(type='percent', ratio=Decimal('.5'))
|
||||
>>> line = payment_term.lines.new(type='remainder')
|
||||
>>> payment_term.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name="Party")
|
||||
>>> party.save()
|
||||
|
||||
Create invoice::
|
||||
|
||||
>>> invoice = Invoice(party=party)
|
||||
>>> invoice.currency = eur
|
||||
>>> invoice.payment_term = payment_term
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('100.0000')
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.total_amount
|
||||
Decimal('100.00')
|
||||
|
||||
Check accounts::
|
||||
|
||||
>>> accounts['receivable'].reload()
|
||||
>>> accounts['receivable'].balance
|
||||
Decimal('333.34')
|
||||
>>> accounts['receivable'].amount_second_currency
|
||||
Decimal('100.00')
|
||||
|
||||
>>> currency_exchange_account.reload()
|
||||
>>> currency_exchange_account.balance
|
||||
Decimal('-0.01')
|
||||
@@ -0,0 +1,96 @@
|
||||
==============================================
|
||||
Invoice Scenario Alternate Currency Lower Rate
|
||||
==============================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Get currencies::
|
||||
|
||||
>>> currency = get_currency('USD')
|
||||
>>> eur = get_currency('EUR')
|
||||
|
||||
Set alternate currency rates::
|
||||
|
||||
>>> rate = eur.rates.new()
|
||||
>>> rate.date = today
|
||||
>>> rate.rate = Decimal('0.5')
|
||||
>>> eur.save()
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create payment method::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> Sequence = Model.get('ir.sequence')
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = 'Cash'
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = accounts['cash']
|
||||
>>> payment_method.debit_account = accounts['cash']
|
||||
>>> payment_method.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create invoice with alternate currency::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.currency = eur
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.description = "Line"
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('80')
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.total_amount
|
||||
Decimal('400.00')
|
||||
|
||||
Pay the invoice::
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount
|
||||
Decimal('400.00')
|
||||
>>> assertEqual(pay.form.currency, eur)
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.form.date = today
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
@@ -0,0 +1,117 @@
|
||||
===============================================
|
||||
Invoice Scenario Alternate Currency Rate Change
|
||||
===============================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
>>> today = dt.date.today()
|
||||
>>> tomorrow = today + dt.timedelta(days=1)
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Configuration = Model.get('account.configuration')
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
|
||||
Get currencies::
|
||||
|
||||
>>> currency = get_currency('USD')
|
||||
>>> eur = get_currency('EUR')
|
||||
|
||||
Set alternate currency rates::
|
||||
|
||||
>>> rate = eur.rates.new()
|
||||
>>> rate.date = today
|
||||
>>> rate.rate = Decimal('1.20')
|
||||
>>> rate = eur.rates.new()
|
||||
>>> rate.date = tomorrow
|
||||
>>> rate.rate = Decimal('1.10')
|
||||
>>> eur.save()
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Configure currency exchange::
|
||||
|
||||
>>> currency_exchange_account, = (
|
||||
... accounts['revenue'].duplicate(
|
||||
... default={'name': "Currency Exchange"}))
|
||||
>>> configuration = Configuration(1)
|
||||
>>> configuration.currency_exchange_credit_account = (
|
||||
... currency_exchange_account)
|
||||
>>> configuration.save()
|
||||
|
||||
Create payment method::
|
||||
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = "Cash"
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = accounts['cash']
|
||||
>>> payment_method.debit_account = accounts['cash']
|
||||
>>> payment_method.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create invoice with alternate currency::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> invoice.currency = eur
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.description = "Line"
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('80')
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.total_amount
|
||||
Decimal('400.00')
|
||||
|
||||
Pay the invoice::
|
||||
|
||||
>>> pay = Wizard('account.invoice.pay', [invoice])
|
||||
>>> pay.form.amount
|
||||
Decimal('400.00')
|
||||
>>> assertEqual(pay.form.currency, eur)
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.form.date = tomorrow
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
|
||||
>>> accounts['receivable'].reload()
|
||||
>>> abs(accounts['receivable'].balance)
|
||||
Decimal('0.00')
|
||||
>>> currency_exchange_account.reload()
|
||||
>>> currency_exchange_account.balance
|
||||
Decimal('-30.31')
|
||||
@@ -0,0 +1,135 @@
|
||||
==================================
|
||||
Invoice Alternative Payee Scenario
|
||||
==================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
>>> journal_cash, = Journal.find([
|
||||
... ('code', '=', 'CASH'),
|
||||
... ])
|
||||
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = "Cash"
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = accounts['cash']
|
||||
>>> payment_method.debit_account = accounts['cash']
|
||||
>>> payment_method.save()
|
||||
|
||||
Create parties::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party1 = Party(name="Party 1")
|
||||
>>> party1.save()
|
||||
>>> party2 = Party(name="Party 2")
|
||||
>>> party2.save()
|
||||
>>> party3 = Party(name="Party 3")
|
||||
>>> party3.save()
|
||||
|
||||
Post customer invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party1
|
||||
>>> invoice.alternative_payees.append(Party(party2.id))
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(10)
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> len(invoice.lines_to_pay)
|
||||
1
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('10.00')
|
||||
|
||||
>>> party1.reload()
|
||||
>>> party1.receivable
|
||||
Decimal('0')
|
||||
>>> party2.reload()
|
||||
>>> party2.receivable
|
||||
Decimal('10.00')
|
||||
>>> party3.reload()
|
||||
>>> party3.receivable
|
||||
Decimal('0')
|
||||
|
||||
Copying invoice with single alternative payee is kept::
|
||||
|
||||
>>> duplicate_inv, = invoice.duplicate()
|
||||
>>> assertEqual(duplicate_inv.alternative_payees, invoice.alternative_payees)
|
||||
|
||||
Set another payee::
|
||||
|
||||
>>> delegate = Wizard(
|
||||
... 'account.invoice.lines_to_pay.delegate', [invoice])
|
||||
>>> delegate_lines, = delegate.actions
|
||||
>>> delegate_lines.form.party = party3
|
||||
>>> delegate_lines.execute('delegate')
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> len(invoice.lines_to_pay)
|
||||
3
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('10.00')
|
||||
|
||||
>>> party1.reload()
|
||||
>>> party1.receivable
|
||||
Decimal('0')
|
||||
>>> party2.reload()
|
||||
>>> party2.receivable
|
||||
Decimal('0')
|
||||
>>> party3.reload()
|
||||
>>> party3.receivable
|
||||
Decimal('10.00')
|
||||
|
||||
Pay the invoice::
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.payee = party3
|
||||
>>> pay.form.amount = Decimal('10.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
>>> len(invoice.payment_lines)
|
||||
1
|
||||
>>> len(invoice.reconciliation_lines)
|
||||
1
|
||||
|
||||
Copying invoice with many alternative payees remove them::
|
||||
|
||||
>>> duplicate_inv, = invoice.duplicate()
|
||||
>>> duplicate_inv.alternative_payees
|
||||
[]
|
||||
@@ -0,0 +1,86 @@
|
||||
===========================
|
||||
Customer Invoice Sequential
|
||||
===========================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
>>> past_year = today - dt.timedelta(days=365)
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal years::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=past_year))
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
|
||||
>>> renew_fiscalyear.execute('create_')
|
||||
>>> next_fiscalyear, = renew_fiscalyear.actions[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create invoice invoice second period and next year::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
|
||||
>>> invoice = Invoice(type='out')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = fiscalyear.periods[1].start_date
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('10')
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> invoice.click('post')
|
||||
|
||||
>>> invoice = Invoice(type='out')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = next_fiscalyear.periods[0].start_date
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('20')
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> invoice.click('post')
|
||||
|
||||
Try to post invoice on first period::
|
||||
|
||||
>>> invoice = Invoice(type='out')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = fiscalyear.periods[0].start_date
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('5')
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> invoice.save()
|
||||
|
||||
>>> invoice.click('post')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvoiceNumberError: ...
|
||||
|
||||
Post invoice on the third period::
|
||||
|
||||
>>> invoice.invoice_date = fiscalyear.periods[2].start_date
|
||||
>>> invoice.click('post')
|
||||
148
modules/account_invoice/tests/scenario_invoice_group_line.rst
Normal file
148
modules/account_invoice/tests/scenario_invoice_group_line.rst
Normal file
@@ -0,0 +1,148 @@
|
||||
================
|
||||
Invoice Scenario
|
||||
================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> receivable = accounts['receivable']
|
||||
>>> payable = accounts['payable']
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_cash = accounts['cash']
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> journal_cash, = Journal.find([
|
||||
... ('code', '=', 'CASH'),
|
||||
... ])
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Post customer invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = revenue
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(10)
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('10.00')
|
||||
|
||||
Post supplier invoice::
|
||||
|
||||
>>> supplier_invoice = Invoice(type='in')
|
||||
>>> supplier_invoice.party = party
|
||||
>>> supplier_invoice.invoice_date = period.start_date
|
||||
>>> line = supplier_invoice.lines.new()
|
||||
>>> line.account = expense
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(5)
|
||||
>>> supplier_invoice.click('post')
|
||||
>>> supplier_invoice.state
|
||||
'posted'
|
||||
>>> supplier_invoice.amount_to_pay
|
||||
Decimal('5.00')
|
||||
|
||||
Group lines::
|
||||
|
||||
>>> Line = Model.get('account.move.line')
|
||||
>>> lines = Line.find([('account', 'in', [payable.id, receivable.id])])
|
||||
>>> len(lines)
|
||||
2
|
||||
>>> group = Wizard('account.move.line.group', lines)
|
||||
>>> group.form.journal = journal_cash
|
||||
>>> group.execute('group')
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
>>> supplier_invoice.reload()
|
||||
>>> supplier_invoice.state
|
||||
'posted'
|
||||
>>> supplier_invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
|
||||
Receive remaining line::
|
||||
|
||||
>>> Move = Model.get('account.move')
|
||||
>>> move = Move()
|
||||
>>> move.journal = journal_cash
|
||||
>>> move.date = period.start_date
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = account_cash
|
||||
>>> line.debit = Decimal(5)
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = receivable
|
||||
>>> line.party = party
|
||||
>>> line.credit = Decimal(5)
|
||||
>>> move.click('post')
|
||||
|
||||
>>> lines = Line.find([
|
||||
... ('account', '=', receivable.id),
|
||||
... ('reconciliation', '=', None),
|
||||
... ])
|
||||
>>> reconcile_lines = Wizard('account.move.reconcile_lines', lines)
|
||||
>>> reconcile_lines.state
|
||||
'end'
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
>>> supplier_invoice.reload()
|
||||
>>> supplier_invoice.state
|
||||
'paid'
|
||||
>>> supplier_invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
|
||||
Remove the created reconciliation::
|
||||
|
||||
>>> Reconciliation = Model.get('account.move.reconciliation')
|
||||
>>> reconciliation, = Reconciliation.find([('lines', '=', lines[0].id)])
|
||||
>>> Reconciliation.delete([reconciliation])
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
>>> supplier_invoice.reload()
|
||||
>>> supplier_invoice.state
|
||||
'posted'
|
||||
>>> supplier_invoice.amount_to_pay
|
||||
Decimal('0')
|
||||
66
modules/account_invoice/tests/scenario_invoice_in_future.rst
Normal file
66
modules/account_invoice/tests/scenario_invoice_in_future.rst
Normal file
@@ -0,0 +1,66 @@
|
||||
=================
|
||||
Invoice in Future
|
||||
=================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
>>> tomorrow = today + dt.timedelta(days=1)
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=(today, tomorrow)))
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> revenue = accounts['revenue']
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = revenue
|
||||
>>> line.description = 'Test'
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(20)
|
||||
|
||||
Posting an invoice in the future raises a warning::
|
||||
|
||||
>>> invoice.invoice_date = tomorrow
|
||||
>>> invoice.click('post')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvoiceFutureWarning: ...
|
||||
|
||||
Post invoice::
|
||||
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
@@ -0,0 +1,81 @@
|
||||
==================
|
||||
Invoice Manual Tax
|
||||
==================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period_ids = [p.id for p in fiscalyear.periods]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> 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()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name="Party")
|
||||
>>> party.save()
|
||||
|
||||
Post a supplier invoice with manual taxes::
|
||||
|
||||
>>> invoice = Invoice(type='in')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> tax_line = invoice.taxes.new()
|
||||
>>> bool(tax_line.manual)
|
||||
True
|
||||
>>> tax_line.tax = tax
|
||||
>>> tax_line.base = Decimal('100')
|
||||
>>> tax_line.amount
|
||||
Decimal('10.00')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('0.00'), Decimal('10.00'), Decimal('10.00'))
|
||||
|
||||
Post invoice and check tax codes::
|
||||
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('0.00'), Decimal('10.00'), Decimal('10.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')
|
||||
108
modules/account_invoice/tests/scenario_invoice_overpayment.rst
Normal file
108
modules/account_invoice/tests/scenario_invoice_overpayment.rst
Normal file
@@ -0,0 +1,108 @@
|
||||
============================
|
||||
Invoice Overpayment Scenario
|
||||
============================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal years::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create payment method::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> journal_cash, = Journal.find([('type', '=', 'cash')])
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = 'Cash'
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = accounts['cash']
|
||||
>>> payment_method.debit_account = accounts['cash']
|
||||
>>> payment_method.save()
|
||||
|
||||
Create write-off method::
|
||||
|
||||
>>> WriteOff = Model.get('account.move.reconcile.write_off')
|
||||
>>> journal_writeoff = Journal(name='Write-Off', type='write-off')
|
||||
>>> journal_writeoff.save()
|
||||
>>> writeoff = WriteOff()
|
||||
>>> writeoff.name = 'Write-off'
|
||||
>>> writeoff.journal = journal_writeoff
|
||||
>>> writeoff.credit_account = accounts['expense']
|
||||
>>> writeoff.debit_account = accounts['expense']
|
||||
>>> writeoff.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create an invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice(party=party)
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('100')
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> invoice.total_amount
|
||||
Decimal('100.00')
|
||||
|
||||
Overpay the invoice with write-off::
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount = Decimal('110.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.form.type = 'writeoff'
|
||||
>>> pay.form.writeoff = writeoff
|
||||
>>> pay.form.amount_writeoff
|
||||
Decimal('-10.00')
|
||||
>>> pay.execute('pay')
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
|
||||
>>> accounts['receivable'].reload()
|
||||
>>> accounts['receivable'].balance
|
||||
Decimal('0.00')
|
||||
|
||||
Overpay the invoice without write-off::
|
||||
|
||||
>>> invoice, = invoice.duplicate()
|
||||
>>> invoice.click('post')
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount = Decimal('110.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.form.type = 'overpayment'
|
||||
>>> pay.execute('pay')
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
|
||||
>>> accounts['receivable'].reload()
|
||||
>>> accounts['receivable'].balance
|
||||
Decimal('-10.00')
|
||||
@@ -0,0 +1,83 @@
|
||||
================================
|
||||
Invoice Report Revision Scenario
|
||||
================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> Move = Model.get('account.move')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
>>> ProductCategory = Model.get('product.category')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> Sequence = Model.get('ir.sequence')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name="Party")
|
||||
>>> party.save()
|
||||
|
||||
Post an invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.type = 'out'
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('20')
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
|
||||
Check invoice report::
|
||||
|
||||
>>> bool(invoice.invoice_report_cache)
|
||||
True
|
||||
>>> len(invoice.invoice_report_revisions)
|
||||
0
|
||||
>>> invoice.invoice_report_format
|
||||
'odt'
|
||||
|
||||
Execute update invoice report wizard::
|
||||
|
||||
>>> refresh_invoice_report = Wizard(
|
||||
... 'account.invoice.refresh_invoice_report', [invoice])
|
||||
>>> revision, = invoice.invoice_report_revisions
|
||||
>>> bool(revision.invoice_report_cache)
|
||||
True
|
||||
>>> revision.invoice_report_format
|
||||
'odt'
|
||||
>>> revision.filename
|
||||
'Invoice-1.odt'
|
||||
@@ -0,0 +1,102 @@
|
||||
=================================
|
||||
Invoice Reschedule Lines Scenario
|
||||
=================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
>>> journal_cash, = Journal.find([
|
||||
... ('code', '=', 'CASH'),
|
||||
... ])
|
||||
|
||||
>>> payment_method = PaymentMethod()
|
||||
>>> payment_method.name = "Cash"
|
||||
>>> payment_method.journal = journal_cash
|
||||
>>> payment_method.credit_account = accounts['cash']
|
||||
>>> payment_method.debit_account = accounts['cash']
|
||||
>>> payment_method.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Post customer invoice::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal(10)
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> len(invoice.lines_to_pay)
|
||||
1
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('10.00')
|
||||
|
||||
Reschedule line::
|
||||
|
||||
>>> reschedule = invoice.click('reschedule_lines_to_pay')
|
||||
>>> reschedule_lines, = reschedule.actions
|
||||
>>> reschedule_lines.form.total_amount
|
||||
Decimal('10.00')
|
||||
>>> reschedule_lines.form.start_date = period.end_date
|
||||
>>> reschedule_lines.form.frequency = 'monthly'
|
||||
>>> reschedule_lines.form.number = 2
|
||||
>>> reschedule_lines.execute('preview')
|
||||
>>> reschedule_lines.execute('reschedule')
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
>>> len(invoice.lines_to_pay)
|
||||
4
|
||||
>>> len([l for l in invoice.lines_to_pay if not l.reconciliation])
|
||||
2
|
||||
>>> invoice.amount_to_pay
|
||||
Decimal('10.00')
|
||||
|
||||
Pay the invoice::
|
||||
|
||||
>>> pay = invoice.click('pay')
|
||||
>>> pay.form.amount = Decimal('10.00')
|
||||
>>> pay.form.payment_method = payment_method
|
||||
>>> pay.execute('choice')
|
||||
>>> pay.state
|
||||
'end'
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
>>> len(invoice.reconciliation_lines)
|
||||
1
|
||||
244
modules/account_invoice/tests/scenario_invoice_supplier.rst
Normal file
244
modules/account_invoice/tests/scenario_invoice_supplier.rst
Normal file
@@ -0,0 +1,244 @@
|
||||
=========================
|
||||
Invoice Supplier Scenario
|
||||
=========================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period_ids = [p.id for p in fiscalyear.periods]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> payable = accounts['payable']
|
||||
>>> revenue = accounts['revenue']
|
||||
>>> expense = accounts['expense']
|
||||
>>> account_tax = accounts['tax']
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> 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')
|
||||
>>> 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.reference = 'FAC001'
|
||||
>>> invoice.supplier_payment_reference_type = 'creditor_reference'
|
||||
>>> invoice.supplier_payment_reference = 'RF18539007547034'
|
||||
>>> invoice.supplier_payment_reference
|
||||
'RF18 5390 0754 7034'
|
||||
>>> 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.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
|
||||
Decimal('-110.00')
|
||||
>>> credit_note.tax_amount
|
||||
Decimal('-10.00')
|
||||
>>> credit_note.total_amount
|
||||
Decimal('-120.00')
|
||||
|
||||
A warning is raised when creating an invoice with same reference::
|
||||
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.type = 'in'
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> invoice.reference = 'FAC001'
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('20')
|
||||
>>> invoice.click('post')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvoiceSimilarWarning: ...
|
||||
>>> invoice.reference = 'FAC002'
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'posted'
|
||||
|
||||
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
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 1
|
||||
>>> line.unit_price = Decimal('20')
|
||||
>>> invoice.click('post')
|
||||
>>> invoice_draft, = Invoice.duplicate([invoice])
|
||||
|
||||
Cancel draft invoice::
|
||||
|
||||
>>> invoice_draft.click('cancel')
|
||||
>>> invoice_draft.state
|
||||
'cancelled'
|
||||
>>> invoice_draft.move
|
||||
>>> invoice_draft.reconciled
|
||||
|
||||
Cancel posted invoice::
|
||||
|
||||
>>> invoice.click('cancel')
|
||||
>>> invoice.state
|
||||
'cancelled'
|
||||
>>> invoice.cancel_move is not None
|
||||
True
|
||||
>>> bool(invoice.reconciled)
|
||||
True
|
||||
@@ -0,0 +1,117 @@
|
||||
==========================
|
||||
Invoice Supplier Post Paid
|
||||
==========================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
>>> payable = accounts['payable']
|
||||
>>> expense = accounts['expense']
|
||||
>>> cash = accounts['cash']
|
||||
|
||||
Create party::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> party = Party(name='Party')
|
||||
>>> 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.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 validated invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.type = 'in'
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('20')
|
||||
>>> invoice.click('validate_invoice')
|
||||
>>> invoice.state
|
||||
'validated'
|
||||
|
||||
Pay invoice::
|
||||
|
||||
>>> Move = Model.get('account.move')
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> journal_cash, = Journal.find([
|
||||
... ('code', '=', 'CASH'),
|
||||
... ])
|
||||
>>> move = Move()
|
||||
>>> move.period = period
|
||||
>>> move.journal = journal_cash
|
||||
>>> move.date = period.start_date
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = payable
|
||||
>>> line.debit = Decimal('100')
|
||||
>>> line.party = party
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = cash
|
||||
>>> line.credit = Decimal('100')
|
||||
>>> move.save()
|
||||
|
||||
>>> Line = Model.get('account.move.line')
|
||||
>>> lines = Line.find([('account', '=', payable.id)])
|
||||
>>> reconcile = Wizard('account.move.reconcile_lines', lines)
|
||||
|
||||
Check invoice::
|
||||
|
||||
>>> invoice.reload()
|
||||
>>> invoice.state
|
||||
'validated'
|
||||
>>> bool(invoice.reconciled)
|
||||
True
|
||||
|
||||
Post invoice::
|
||||
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.state
|
||||
'paid'
|
||||
@@ -0,0 +1,120 @@
|
||||
======================
|
||||
Invoice Tax Deductible
|
||||
======================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.exceptions import InvoiceTaxesWarning
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> ProductCategory = Model.get('product.category')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> Warning = Model.get('res.user.warning')
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear(today=today))
|
||||
>>> fiscalyear.click('create_period')
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> tax.save()
|
||||
|
||||
Create party::
|
||||
|
||||
>>> party = Party(name="Party")
|
||||
>>> party.save()
|
||||
|
||||
Create account category::
|
||||
|
||||
>>> account_category = ProductCategory(name="Account Category")
|
||||
>>> account_category.accounting = True
|
||||
>>> account_category.account_expense = accounts['expense']
|
||||
>>> account_category.supplier_taxes_deductible_rate = Decimal('.5')
|
||||
>>> account_category.supplier_taxes.append(tax)
|
||||
>>> account_category.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||
>>> template = ProductTemplate()
|
||||
>>> template.name = 'product'
|
||||
>>> template.default_uom = unit
|
||||
>>> template.type = 'service'
|
||||
>>> template.list_price = Decimal('100')
|
||||
>>> template.account_category = account_category
|
||||
>>> template.save()
|
||||
>>> product, = template.products
|
||||
|
||||
Post a supplier invoice with 0% deductible::
|
||||
|
||||
>>> invoice = Invoice(type='in')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 10
|
||||
>>> line.unit_price = Decimal('50')
|
||||
>>> line.taxes_deductible_rate
|
||||
Decimal('0.5')
|
||||
>>> line.taxes_deductible_rate = Decimal(0)
|
||||
>>> line.amount
|
||||
Decimal('550.00')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('550.00'), Decimal('0.00'), Decimal('550.00'))
|
||||
>>> try:
|
||||
... invoice.click('post')
|
||||
... except InvoiceTaxesWarning as warning:
|
||||
... Warning(user=config.user, name=warning.name).save()
|
||||
... raise
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvoiceTaxesWarning: ...
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('550.00'), Decimal('0.00'), Decimal('550.00'))
|
||||
>>> len(invoice.taxes)
|
||||
0
|
||||
|
||||
Post a supplier invoice with 50% deductible rate::
|
||||
|
||||
>>> invoice = Invoice(type='in')
|
||||
>>> invoice.party = party
|
||||
>>> invoice.invoice_date = today
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 10
|
||||
>>> line.unit_price = Decimal('50')
|
||||
>>> line.amount
|
||||
Decimal('525.00')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('525.00'), Decimal('25.00'), Decimal('550.00'))
|
||||
>>> invoice.click('post')
|
||||
>>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount
|
||||
(Decimal('525.00'), Decimal('25.00'), Decimal('550.00'))
|
||||
>>> len(invoice.taxes)
|
||||
1
|
||||
102
modules/account_invoice/tests/scenario_invoice_with_credit.rst
Normal file
102
modules/account_invoice/tests/scenario_invoice_with_credit.rst
Normal file
@@ -0,0 +1,102 @@
|
||||
============================
|
||||
Invoice with credit Scenario
|
||||
============================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model
|
||||
>>> from trytond.modules.account.tests.tools import (
|
||||
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company, create_chart)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(
|
||||
... create_fiscalyear())
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> period_ids = [p.id for p in fiscalyear.periods]
|
||||
|
||||
Get accounts::
|
||||
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create tax::
|
||||
|
||||
>>> TaxCode = Model.get('account.tax.code')
|
||||
>>> Tax = Model.get('account.tax')
|
||||
>>> tax = create_tax(Decimal('.10'))
|
||||
>>> 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')
|
||||
>>> party.save()
|
||||
|
||||
Create invoice::
|
||||
|
||||
>>> Invoice = Model.get('account.invoice')
|
||||
>>> invoice = Invoice()
|
||||
>>> invoice.party = party
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = 5
|
||||
>>> line.unit_price = Decimal('10.0000')
|
||||
>>> line.taxes.append(Tax(tax.id))
|
||||
>>> line = invoice.lines.new()
|
||||
>>> line.account = accounts['revenue']
|
||||
>>> line.quantity = -2
|
||||
>>> line.unit_price = Decimal('5.0000')
|
||||
>>> line.taxes.append(Tax(tax.id))
|
||||
>>> invoice.invoice_date = fiscalyear.start_date
|
||||
>>> invoice.click('post')
|
||||
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('40.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('4.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('44.00')
|
||||
|
||||
Test taxes::
|
||||
|
||||
>>> len(invoice.taxes)
|
||||
2
|
||||
|
||||
>>> accounts['tax'].reload()
|
||||
>>> accounts['tax'].debit, accounts['tax'].credit
|
||||
(Decimal('1.00'), Decimal('5.00'))
|
||||
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_base_code = TaxCode(invoice_base_code.id)
|
||||
... invoice_base_code.amount
|
||||
Decimal('50.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... invoice_tax_code = TaxCode(invoice_tax_code.id)
|
||||
... invoice_tax_code.amount
|
||||
Decimal('5.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... credit_note_base_code = TaxCode(credit_note_base_code.id)
|
||||
... credit_note_base_code.amount
|
||||
Decimal('10.00')
|
||||
>>> with config.set_context(periods=period_ids):
|
||||
... credit_note_tax_code = TaxCode(credit_note_tax_code.id)
|
||||
... credit_note_tax_code.amount
|
||||
Decimal('1.00')
|
||||
99
modules/account_invoice/tests/scenario_renew_fiscalyear.rst
Normal file
99
modules/account_invoice/tests/scenario_renew_fiscalyear.rst
Normal file
@@ -0,0 +1,99 @@
|
||||
=========================
|
||||
Renew Fiscalyear Scenario
|
||||
=========================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import create_fiscalyear
|
||||
>>> from trytond.modules.account_invoice.tests.tools import (
|
||||
... set_fiscalyear_invoice_sequences)
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules('account_invoice', create_company)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> InvoiceSequence = Model.get('account.fiscalyear.invoice_sequence')
|
||||
>>> fiscalyear = create_fiscalyear(today=today)
|
||||
>>> fiscalyear = set_fiscalyear_invoice_sequences(fiscalyear)
|
||||
>>> fiscalyear.click('create_period')
|
||||
>>> inv_seq, = fiscalyear.invoice_sequences
|
||||
>>> seq = inv_seq.out_invoice_sequence
|
||||
>>> for period in fiscalyear.periods:
|
||||
... seq, = seq.duplicate()
|
||||
... _ = inv_seq.duplicate(default={
|
||||
... 'period': period.id,
|
||||
... 'out_invoice_sequence': seq.id,
|
||||
... 'in_invoice_sequence': seq.id,
|
||||
... 'out_credit_note_sequence': seq.id,
|
||||
... 'in_credit_note_sequence': seq.id,
|
||||
... })
|
||||
>>> period = fiscalyear.periods.new()
|
||||
>>> period.name = 'Adjustment'
|
||||
>>> period.start_date = fiscalyear.end_date
|
||||
>>> period.end_date = fiscalyear.end_date
|
||||
>>> period.type = 'adjustment'
|
||||
>>> fiscalyear.save()
|
||||
|
||||
Set the sequence number::
|
||||
|
||||
>>> sequence = fiscalyear.move_sequence
|
||||
>>> sequence.number_next = 10
|
||||
>>> sequence.save()
|
||||
|
||||
>>> for i, seq in enumerate(fiscalyear.invoice_sequences):
|
||||
... seq.out_invoice_sequence.number_next = i
|
||||
... seq.out_invoice_sequence.save()
|
||||
|
||||
Renew fiscal year using the wizard::
|
||||
|
||||
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
|
||||
>>> renew_fiscalyear.form.reset_sequences = False
|
||||
>>> renew_fiscalyear.execute('create_')
|
||||
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
|
||||
>>> len(new_fiscalyear.periods)
|
||||
12
|
||||
>>> int(new_fiscalyear.move_sequence.number_next)
|
||||
10
|
||||
>>> [int(seq.out_invoice_sequence.number_next)
|
||||
... for seq in fiscalyear.invoice_sequences]
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
|
||||
Renew fiscal year resetting sequences::
|
||||
|
||||
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
|
||||
>>> renew_fiscalyear.form.reset_sequences = True
|
||||
>>> renew_fiscalyear.execute('create_')
|
||||
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
|
||||
>>> int(new_fiscalyear.move_sequence.number_next)
|
||||
1
|
||||
>>> [int(seq.out_invoice_sequence.number_next)
|
||||
... for seq in new_fiscalyear.invoice_sequences]
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
|
||||
Set the sequence name::
|
||||
|
||||
>>> for seq in new_fiscalyear.invoice_sequences:
|
||||
... seq.out_invoice_sequence.name = ('Sequence %s' %
|
||||
... new_fiscalyear.name)
|
||||
... seq.out_invoice_sequence.save()
|
||||
|
||||
Renew fiscalyear and test sequence name is updated::
|
||||
|
||||
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
|
||||
>>> renew_fiscalyear.form.reset_sequences = True
|
||||
>>> renew_fiscalyear.execute('create_')
|
||||
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
|
||||
>>> for sequence in new_fiscalyear.invoice_sequences:
|
||||
... assertEqual(
|
||||
... sequence.out_invoice_sequence.name,
|
||||
... 'Sequence %s' % new_fiscalyear.name)
|
||||
255
modules/account_invoice/tests/test_module.py
Normal file
255
modules/account_invoice/tests/test_module.py
Normal file
@@ -0,0 +1,255 @@
|
||||
# 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 datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from trytond.modules.account_invoice.exceptions import (
|
||||
PaymentTermValidationError)
|
||||
from trytond.modules.company.tests import (
|
||||
CompanyTestMixin, PartyCompanyCheckEraseMixin)
|
||||
from trytond.modules.currency.tests import create_currency
|
||||
from trytond.modules.party.tests import PartyCheckReplaceMixin
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
|
||||
|
||||
def set_invoice_sequences(fiscalyear):
|
||||
pool = Pool()
|
||||
Sequence = pool.get('ir.sequence.strict')
|
||||
SequenceType = pool.get('ir.sequence.type')
|
||||
InvoiceSequence = pool.get('account.fiscalyear.invoice_sequence')
|
||||
|
||||
sequence_type, = SequenceType.search([
|
||||
('name', '=', "Invoice"),
|
||||
], limit=1)
|
||||
sequence = Sequence(name=fiscalyear.name, sequence_type=sequence_type)
|
||||
sequence.company = fiscalyear.company
|
||||
sequence.save()
|
||||
invoice_sequence = InvoiceSequence()
|
||||
invoice_sequence.in_invoice_sequence = sequence
|
||||
invoice_sequence.in_credit_note_sequence = sequence
|
||||
invoice_sequence.out_invoice_sequence = sequence
|
||||
invoice_sequence.out_credit_note_sequence = sequence
|
||||
fiscalyear.invoice_sequences = [invoice_sequence]
|
||||
return fiscalyear
|
||||
|
||||
|
||||
class AccountInvoiceTestCase(
|
||||
PartyCompanyCheckEraseMixin, PartyCheckReplaceMixin, CompanyTestMixin,
|
||||
ModuleTestCase):
|
||||
'Test AccountInvoice module'
|
||||
module = 'account_invoice'
|
||||
|
||||
@with_transaction()
|
||||
def test_payment_term(self):
|
||||
'Test payment_term'
|
||||
pool = Pool()
|
||||
PaymentTerm = pool.get('account.invoice.payment_term')
|
||||
|
||||
cu1 = create_currency('cu1')
|
||||
term, = PaymentTerm.create([{
|
||||
'name': '30 days, 1 month, 1 month + 15 days',
|
||||
'lines': [
|
||||
('create', [{
|
||||
'sequence': 0,
|
||||
'type': 'percent',
|
||||
'divisor': 4,
|
||||
'ratio': Decimal('.25'),
|
||||
'relativedeltas': [('create', [{
|
||||
'days': 30,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 1,
|
||||
'type': 'percent_on_total',
|
||||
'divisor': 4,
|
||||
'ratio': Decimal('.25'),
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 2,
|
||||
'type': 'fixed',
|
||||
'amount': Decimal('396.84'),
|
||||
'currency': cu1.id,
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
'days': 30,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 3,
|
||||
'type': 'remainder',
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 2,
|
||||
'days': 30,
|
||||
'day': 15,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}])]
|
||||
}])
|
||||
terms = term.compute(Decimal('1587.35'), cu1,
|
||||
date=datetime.date(2011, 10, 1))
|
||||
self.assertEqual(terms, [
|
||||
(datetime.date(2011, 10, 31), Decimal('396.84')),
|
||||
(datetime.date(2011, 11, 1), Decimal('396.84')),
|
||||
(datetime.date(2011, 12, 1), Decimal('396.84')),
|
||||
(datetime.date(2012, 1, 14), Decimal('396.83')),
|
||||
])
|
||||
|
||||
@with_transaction()
|
||||
def test_payment_term_with_repeating_decimal(self):
|
||||
"Test payment_term with repeating decimal"
|
||||
pool = Pool()
|
||||
PaymentTerm = pool.get('account.invoice.payment_term')
|
||||
|
||||
PaymentTerm.create([{
|
||||
'name': "Repeating Decimal",
|
||||
'lines': [
|
||||
('create', [{
|
||||
'type': 'percent',
|
||||
'divisor': Decimal(3),
|
||||
'ratio': Decimal('0.3333333333'),
|
||||
}, {
|
||||
'type': 'remainder',
|
||||
}]),
|
||||
],
|
||||
}])
|
||||
|
||||
@with_transaction()
|
||||
def test_payment_term_with_invalid_ratio_divisor(self):
|
||||
"Test payment_term with invalid ratio and divisor"
|
||||
pool = Pool()
|
||||
PaymentTerm = pool.get('account.invoice.payment_term')
|
||||
|
||||
with self.assertRaises(PaymentTermValidationError):
|
||||
PaymentTerm.create([{
|
||||
'name': "Invalid ratio and divisor",
|
||||
'lines': [
|
||||
('create', [{
|
||||
'type': 'percent',
|
||||
'divisor': Decimal(2),
|
||||
'ratio': Decimal('0.4'),
|
||||
}, {
|
||||
'type': 'remainder',
|
||||
}]),
|
||||
],
|
||||
}])
|
||||
|
||||
@with_transaction()
|
||||
def test_payment_term_with_empty_value(self):
|
||||
'Test payment_term with empty'
|
||||
pool = Pool()
|
||||
PaymentTerm = pool.get('account.invoice.payment_term')
|
||||
|
||||
cu1 = create_currency('cu1')
|
||||
remainder_term, percent_term = PaymentTerm.create([{
|
||||
'name': 'Remainder',
|
||||
'lines': [
|
||||
('create', [{'type': 'remainder',
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}])]
|
||||
}, {
|
||||
'name': '25% tomorrow, remainder un month later ',
|
||||
'lines': [
|
||||
('create', [{'type': 'percent',
|
||||
'divisor': 4,
|
||||
'ratio': Decimal('.25'),
|
||||
'relativedeltas': [('create', [{
|
||||
'days': 1,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {'type': 'remainder',
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}])]
|
||||
}])
|
||||
terms = remainder_term.compute(Decimal('0.0'), cu1,
|
||||
date=datetime.date(2016, 5, 17))
|
||||
self.assertEqual(terms, [
|
||||
(datetime.date(2016, 5, 17), Decimal('0.0')),
|
||||
])
|
||||
terms = percent_term.compute(Decimal('0.0'), cu1,
|
||||
date=datetime.date(2016, 5, 17))
|
||||
self.assertEqual(terms, [
|
||||
(datetime.date(2016, 5, 17), Decimal('0.0')),
|
||||
])
|
||||
|
||||
@with_transaction()
|
||||
def test_negative_amount(self):
|
||||
'Test payment term with negative amount'
|
||||
pool = Pool()
|
||||
PaymentTerm = pool.get('account.invoice.payment_term')
|
||||
|
||||
cu1 = create_currency('cu1')
|
||||
term, = PaymentTerm.create([{
|
||||
'name': '30 days, 1 month, 1 month + 15 days',
|
||||
'lines': [
|
||||
('create', [{
|
||||
'sequence': 0,
|
||||
'type': 'percent',
|
||||
'divisor': 4,
|
||||
'ratio': Decimal('.25'),
|
||||
'relativedeltas': [('create', [{
|
||||
'days': 30,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 1,
|
||||
'type': 'percent_on_total',
|
||||
'divisor': 4,
|
||||
'ratio': Decimal('.25'),
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 2,
|
||||
'type': 'fixed',
|
||||
'amount': Decimal('4.0'),
|
||||
'currency': cu1.id,
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 1,
|
||||
'days': 30,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}, {
|
||||
'sequence': 3,
|
||||
'type': 'remainder',
|
||||
'relativedeltas': [('create', [{
|
||||
'months': 2,
|
||||
'days': 30,
|
||||
'day': 15,
|
||||
},
|
||||
]),
|
||||
],
|
||||
}])]
|
||||
}])
|
||||
terms = term.compute(Decimal('-10.00'), cu1,
|
||||
date=datetime.date(2011, 10, 1))
|
||||
self.assertListEqual(terms, [
|
||||
(datetime.date(2011, 10, 31), Decimal('-2.5')),
|
||||
(datetime.date(2011, 11, 1), Decimal('-2.5')),
|
||||
(datetime.date(2011, 12, 1), Decimal('-4.0')),
|
||||
(datetime.date(2012, 1, 14), Decimal('-1.0')),
|
||||
])
|
||||
|
||||
|
||||
del ModuleTestCase
|
||||
8
modules/account_invoice/tests/test_scenario.py
Normal file
8
modules/account_invoice/tests/test_scenario.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# 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 trytond.tests.test_tryton import load_doc_tests
|
||||
|
||||
|
||||
def load_tests(*args, **kwargs):
|
||||
return load_doc_tests(__name__, __file__, *args, **kwargs)
|
||||
35
modules/account_invoice/tests/tools.py
Normal file
35
modules/account_invoice/tests/tools.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# 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 proteus import Model
|
||||
|
||||
__all__ = ['set_fiscalyear_invoice_sequences']
|
||||
|
||||
|
||||
def set_fiscalyear_invoice_sequences(fiscalyear, config=None):
|
||||
"Set invoice sequences to fiscalyear"
|
||||
SequenceStrict = Model.get('ir.sequence.strict', config=config)
|
||||
SequenceType = Model.get('ir.sequence.type', config=config)
|
||||
|
||||
sequence_type, = SequenceType.find([
|
||||
('name', '=', "Invoice"),
|
||||
], limit=1)
|
||||
invoice_seq = SequenceStrict(
|
||||
name=fiscalyear.name,
|
||||
sequence_type=sequence_type,
|
||||
company=fiscalyear.company)
|
||||
invoice_seq.save()
|
||||
seq, = fiscalyear.invoice_sequences
|
||||
seq.out_invoice_sequence = invoice_seq
|
||||
seq.in_invoice_sequence = invoice_seq
|
||||
seq.out_credit_note_sequence = invoice_seq
|
||||
seq.in_credit_note_sequence = invoice_seq
|
||||
return fiscalyear
|
||||
|
||||
|
||||
def create_payment_term(config=None):
|
||||
"Create a direct payment term"
|
||||
PaymentTerm = Model.get('account.invoice.payment_term', config=config)
|
||||
|
||||
payment_term = PaymentTerm(name='Direct')
|
||||
payment_term.lines.new(type='remainder')
|
||||
return payment_term
|
||||
Reference in New Issue
Block a user