diff --git a/MANIFEST.in b/MANIFEST.in index 44969c7156..d57a2cc5b9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -8,3 +8,4 @@ include tryton.cfg include *.xml include *.odt include locale/*.po +include tests/*.rst diff --git a/tests/scenario_invoice.rst b/tests/scenario_invoice.rst new file mode 100644 index 0000000000..a26189ed9e --- /dev/null +++ b/tests/scenario_invoice.rst @@ -0,0 +1,261 @@ +================ +Invoice Scenario +================ + +Imports:: + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from operator import attrgetter + >>> from proteus import config, Model, Wizard + >>> today = datetime.date.today() + +Create database:: + + >>> config = config.set_trytond() + >>> config.pool.test = True + +Install account_invoice:: + + >>> Module = Model.get('ir.module.module') + >>> account_invoice_module, = Module.find( + ... [('name', '=', 'account_invoice')]) + >>> Module.install([account_invoice_module.id], config.context) + >>> Wizard('ir.module.module.install_upgrade').execute('upgrade') + +Create company:: + + >>> Currency = Model.get('currency.currency') + >>> CurrencyRate = Model.get('currency.currency.rate') + >>> currencies = Currency.find([('code', '=', 'USD')]) + >>> if not currencies: + ... currency = Currency(name='US Dollar', symbol=u'$', code='USD', + ... rounding=Decimal('0.01'), mon_grouping='[]', + ... mon_decimal_point='.') + ... currency.save() + ... CurrencyRate(date=today + relativedelta(month=1, day=1), + ... rate=Decimal('1.0'), currency=currency).save() + ... else: + ... currency, = currencies + >>> Company = Model.get('company.company') + >>> company_config = Wizard('company.company.config') + >>> company_config.execute('company') + >>> company = company_config.form + >>> company.name = 'Dunder Mifflin' + >>> company.currency = currency + >>> company_config.execute('add') + >>> company, = Company.find([]) + +Reload the context:: + + >>> User = Model.get('res.user') + >>> config._context = User.get_preferences(True, config.context) + +Create fiscal year:: + + >>> FiscalYear = Model.get('account.fiscalyear') + >>> Sequence = Model.get('ir.sequence') + >>> SequenceStrict = Model.get('ir.sequence.strict') + >>> fiscalyear = FiscalYear(name=str(today.year)) + >>> fiscalyear.start_date = today + relativedelta(month=1, day=1) + >>> fiscalyear.end_date = today + relativedelta(month=12, day=31) + >>> fiscalyear.company = company + >>> post_move_seq = Sequence(name=str(today.year), code='account.move', + ... company=company) + >>> post_move_seq.save() + >>> fiscalyear.post_move_sequence = post_move_seq + >>> invoice_seq = SequenceStrict(name=str(today.year), + ... code='account.invoice', company=company) + >>> invoice_seq.save() + >>> fiscalyear.out_invoice_sequence = invoice_seq + >>> fiscalyear.in_invoice_sequence = invoice_seq + >>> fiscalyear.out_credit_note_sequence = invoice_seq + >>> fiscalyear.in_credit_note_sequence = invoice_seq + >>> fiscalyear.save() + >>> FiscalYear.create_period([fiscalyear.id], config.context) + +Create chart of accounts:: + + >>> AccountTemplate = Model.get('account.account.template') + >>> Account = Model.get('account.account') + >>> account_template, = AccountTemplate.find([('parent', '=', False)]) + >>> create_chart = Wizard('account.create_chart') + >>> create_chart.execute('account') + >>> create_chart.form.account_template = account_template + >>> create_chart.form.company = company + >>> create_chart.execute('create_account') + >>> receivable, = Account.find([ + ... ('kind', '=', 'receivable'), + ... ('company', '=', company.id), + ... ]) + >>> payable, = Account.find([ + ... ('kind', '=', 'payable'), + ... ('company', '=', company.id), + ... ]) + >>> revenue, = Account.find([ + ... ('kind', '=', 'revenue'), + ... ('company', '=', company.id), + ... ]) + >>> expense, = Account.find([ + ... ('kind', '=', 'expense'), + ... ('company', '=', company.id), + ... ]) + >>> account_tax, = Account.find([ + ... ('kind', '=', 'other'), + ... ('company', '=', company.id), + ... ('name', '=', 'Main Tax'), + ... ]) + >>> create_chart.form.account_receivable = receivable + >>> create_chart.form.account_payable = payable + >>> create_chart.execute('create_properties') + +Create tax:: + + >>> TaxCode = Model.get('account.tax.code') + >>> Tax = Model.get('account.tax') + >>> tax = Tax() + >>> tax.name = 'Tax' + >>> tax.description = 'Tax' + >>> tax.type = 'percentage' + >>> tax.percentage = Decimal(10) + >>> tax.invoice_account = account_tax + >>> tax.credit_note_account = account_tax + >>> invoice_base_code = TaxCode(name='invoice base') + >>> invoice_base_code.save() + >>> tax.invoice_base_code = invoice_base_code + >>> invoice_tax_code = TaxCode(name='invoice tax') + >>> invoice_tax_code.save() + >>> tax.invoice_tax_code = invoice_tax_code + >>> credit_note_base_code = TaxCode(name='credit note base') + >>> credit_note_base_code.save() + >>> tax.credit_note_base_code = credit_note_base_code + >>> credit_note_tax_code = TaxCode(name='credit note tax') + >>> credit_note_tax_code.save() + >>> tax.credit_note_tax_code = credit_note_tax_code + >>> tax.save() + +Create party:: + + >>> Party = Model.get('party.party') + >>> party = Party(name='Party') + >>> party.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> Product = Model.get('product.product') + >>> product = Product() + >>> product.name = 'product' + >>> product.default_uom = unit + >>> product.type = 'service' + >>> product.list_price = Decimal('40') + >>> product.cost_price = Decimal('25') + >>> product.account_expense = expense + >>> product.account_revenue = revenue + >>> product.customer_taxes.append(tax) + >>> product.save() + +Create payment term:: + + >>> PaymentTerm = Model.get('account.invoice.payment_term') + >>> PaymentTermLine = Model.get('account.invoice.payment_term.line') + >>> payment_term = PaymentTerm(name='Term') + >>> payment_term_line = PaymentTermLine(type='percent', days=20, + ... percentage=Decimal(50)) + >>> payment_term.lines.append(payment_term_line) + >>> payment_term_line = PaymentTermLine(type='remainder', days=40) + >>> payment_term.lines.append(payment_term_line) + >>> 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 = InvoiceLine() + >>> invoice.lines.append(line) + >>> line.account = revenue + >>> line.description = 'Test' + >>> line.quantity = 1 + >>> line.unit_price = Decimal(20) + >>> invoice.untaxed_amount == Decimal(220) + True + >>> invoice.tax_amount == Decimal(20) + True + >>> invoice.total_amount == Decimal(240) + True + >>> invoice.save() + >>> Invoice.post([invoice.id], config.context) + >>> invoice.reload() + >>> invoice.state + u'posted' + >>> invoice.untaxed_amount == Decimal(220) + True + >>> invoice.tax_amount == Decimal(20) + True + >>> invoice.total_amount == Decimal(240) + True + >>> receivable.reload() + >>> (receivable.debit, receivable.credit) == \ + ... (Decimal(240), Decimal(0)) + True + >>> revenue.reload() + >>> (revenue.debit, revenue.credit) == \ + ... (Decimal(0), Decimal(220)) + True + >>> account_tax.reload() + >>> (account_tax.debit, account_tax.credit) == \ + ... (Decimal(0), Decimal(20)) + True + >>> invoice_base_code.reload() + >>> invoice_base_code.sum == Decimal(200) + True + >>> invoice_tax_code.reload() + >>> invoice_tax_code.sum == Decimal(20) + True + >>> credit_note_base_code.reload() + >>> credit_note_base_code.sum == Decimal(0) + True + >>> credit_note_tax_code.reload() + >>> credit_note_tax_code.sum == Decimal(0) + True + +Credit invoice with refund:: + + >>> credit = Wizard('account.invoice.credit', [invoice]) + >>> credit.form.with_refund = True + >>> credit.execute('credit') + >>> invoice.reload() + >>> invoice.state + u'paid' + >>> receivable.reload() + >>> (receivable.debit, receivable.credit) == \ + ... (Decimal(240), Decimal(240)) + True + >>> revenue.reload() + >>> (revenue.debit, revenue.credit) == \ + ... (Decimal(220), Decimal(220)) + True + >>> account_tax.reload() + >>> (account_tax.debit, account_tax.credit) == \ + ... (Decimal(20), Decimal(20)) + True + >>> invoice_base_code.reload() + >>> invoice_base_code.sum == Decimal(200) + True + >>> invoice_tax_code.reload() + >>> invoice_tax_code.sum == Decimal(20) + True + >>> credit_note_base_code.reload() + >>> credit_note_base_code.sum == Decimal(200) + True + >>> credit_note_tax_code.reload() + >>> credit_note_tax_code.sum == Decimal(20) + True diff --git a/tests/scenario_invoice_supplier.rst b/tests/scenario_invoice_supplier.rst new file mode 100644 index 0000000000..a8c5c0e7ac --- /dev/null +++ b/tests/scenario_invoice_supplier.rst @@ -0,0 +1,242 @@ +========================= +Invoice Supplier Scenario +========================= + +Imports:: + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from operator import attrgetter + >>> from proteus import config, Model, Wizard + >>> today = datetime.date.today() + +Create database:: + + >>> config = config.set_trytond() + >>> config.pool.test = True + +Install account_invoice:: + + >>> Module = Model.get('ir.module.module') + >>> account_invoice_module, = Module.find( + ... [('name', '=', 'account_invoice')]) + >>> Module.install([account_invoice_module.id], config.context) + >>> Wizard('ir.module.module.install_upgrade').execute('upgrade') + +Create company:: + + >>> Currency = Model.get('currency.currency') + >>> CurrencyRate = Model.get('currency.currency.rate') + >>> currencies = Currency.find([('code', '=', 'USD')]) + >>> if not currencies: + ... currency = Currency(name='US Dollar', symbol=u'$', code='USD', + ... rounding=Decimal('0.01'), mon_grouping='[]', + ... mon_decimal_point='.') + ... currency.save() + ... CurrencyRate(date=today + relativedelta(month=1, day=1), + ... rate=Decimal('1.0'), currency=currency).save() + ... else: + ... currency, = currencies + >>> Company = Model.get('company.company') + >>> company_config = Wizard('company.company.config') + >>> company_config.execute('company') + >>> company = company_config.form + >>> company.name = 'Dunder Mifflin' + >>> company.currency = currency + >>> company_config.execute('add') + >>> company, = Company.find([]) + +Reload the context:: + + >>> User = Model.get('res.user') + >>> config._context = User.get_preferences(True, config.context) + +Create fiscal year:: + + >>> FiscalYear = Model.get('account.fiscalyear') + >>> Sequence = Model.get('ir.sequence') + >>> SequenceStrict = Model.get('ir.sequence.strict') + >>> fiscalyear = FiscalYear(name=str(today.year)) + >>> fiscalyear.start_date = today + relativedelta(month=1, day=1) + >>> fiscalyear.end_date = today + relativedelta(month=12, day=31) + >>> fiscalyear.company = company + >>> post_move_seq = Sequence(name=str(today.year), code='account.move', + ... company=company) + >>> post_move_seq.save() + >>> fiscalyear.post_move_sequence = post_move_seq + >>> invoice_seq = SequenceStrict(name=str(today.year), + ... code='account.invoice', company=company) + >>> invoice_seq.save() + >>> fiscalyear.out_invoice_sequence = invoice_seq + >>> fiscalyear.in_invoice_sequence = invoice_seq + >>> fiscalyear.out_credit_note_sequence = invoice_seq + >>> fiscalyear.in_credit_note_sequence = invoice_seq + >>> fiscalyear.save() + >>> FiscalYear.create_period([fiscalyear.id], config.context) + +Create chart of accounts:: + + >>> AccountTemplate = Model.get('account.account.template') + >>> Account = Model.get('account.account') + >>> account_template, = AccountTemplate.find([('parent', '=', False)]) + >>> create_chart = Wizard('account.create_chart') + >>> create_chart.execute('account') + >>> create_chart.form.account_template = account_template + >>> create_chart.form.company = company + >>> create_chart.execute('create_account') + >>> receivable, = Account.find([ + ... ('kind', '=', 'receivable'), + ... ('company', '=', company.id), + ... ]) + >>> payable, = Account.find([ + ... ('kind', '=', 'payable'), + ... ('company', '=', company.id), + ... ]) + >>> revenue, = Account.find([ + ... ('kind', '=', 'revenue'), + ... ('company', '=', company.id), + ... ]) + >>> expense, = Account.find([ + ... ('kind', '=', 'expense'), + ... ('company', '=', company.id), + ... ]) + >>> account_tax, = Account.find([ + ... ('kind', '=', 'other'), + ... ('company', '=', company.id), + ... ('name', '=', 'Main Tax'), + ... ]) + >>> create_chart.form.account_receivable = receivable + >>> create_chart.form.account_payable = payable + >>> create_chart.execute('create_properties') + +Create tax:: + + >>> TaxCode = Model.get('account.tax.code') + >>> Tax = Model.get('account.tax') + >>> tax = Tax() + >>> tax.name = 'Tax' + >>> tax.description = 'Tax' + >>> tax.type = 'percentage' + >>> tax.percentage = Decimal(10) + >>> tax.invoice_account = account_tax + >>> tax.credit_note_account = account_tax + >>> invoice_base_code = TaxCode(name='invoice base') + >>> invoice_base_code.save() + >>> tax.invoice_base_code = invoice_base_code + >>> invoice_tax_code = TaxCode(name='invoice tax') + >>> invoice_tax_code.save() + >>> tax.invoice_tax_code = invoice_tax_code + >>> credit_note_base_code = TaxCode(name='credit note base') + >>> credit_note_base_code.save() + >>> tax.credit_note_base_code = credit_note_base_code + >>> credit_note_tax_code = TaxCode(name='credit note tax') + >>> credit_note_tax_code.save() + >>> tax.credit_note_tax_code = credit_note_tax_code + >>> tax.save() + +Create party:: + + >>> Party = Model.get('party.party') + >>> party = Party(name='Party') + >>> party.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> Product = Model.get('product.product') + >>> product = Product() + >>> product.name = 'product' + >>> product.default_uom = unit + >>> product.type = 'service' + >>> product.list_price = Decimal('40') + >>> product.cost_price = Decimal('20') + >>> product.account_expense = expense + >>> product.account_revenue = revenue + >>> product.supplier_taxes.append(tax) + >>> product.save() + +Create payment term:: + + >>> PaymentTerm = Model.get('account.invoice.payment_term') + >>> PaymentTermLine = Model.get('account.invoice.payment_term.line') + >>> payment_term = PaymentTerm(name='Term') + >>> payment_term_line = PaymentTermLine(type='remainder') + >>> payment_term.lines.append(payment_term_line) + >>> payment_term.save() + +Create invoice:: + + >>> Invoice = Model.get('account.invoice') + >>> InvoiceLine = Model.get('account.invoice.line') + >>> invoice = Invoice() + >>> invoice.type = 'in_invoice' + >>> invoice.party = party + >>> invoice.payment_term = payment_term + >>> invoice.invoice_date = today + >>> line = InvoiceLine() + >>> invoice.lines.append(line) + >>> line.product = product + >>> line.quantity = 5 + >>> 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) + True + >>> invoice.tax_amount == Decimal(10) + True + >>> invoice.total_amount == Decimal(120) + True + >>> invoice.save() + >>> Invoice.post([invoice.id], config.context) + >>> invoice.reload() + >>> invoice.state + u'posted' + >>> invoice.untaxed_amount == Decimal(110) + True + >>> invoice.tax_amount == Decimal(10) + True + >>> invoice.total_amount == Decimal(120) + True + >>> payable.reload() + >>> (payable.debit, payable.credit) == \ + ... (Decimal(0), Decimal(120)) + True + >>> expense.reload() + >>> (expense.debit, expense.credit) == \ + ... (Decimal(110), Decimal(0)) + True + >>> account_tax.reload() + >>> (account_tax.debit, account_tax.credit) == \ + ... (Decimal(10), Decimal(0)) + True + >>> invoice_base_code.reload() + >>> invoice_base_code.sum == Decimal(100) + True + >>> invoice_tax_code.reload() + >>> invoice_tax_code.sum == Decimal(10) + True + >>> credit_note_base_code.reload() + >>> credit_note_base_code.sum == Decimal(0) + True + >>> credit_note_tax_code.reload() + >>> credit_note_tax_code.sum == Decimal(0) + True + +Credit invoice:: + + >>> credit = Wizard('account.invoice.credit', [invoice]) + >>> credit.form.with_refund = False + >>> credit.execute('credit') + >>> credit_note, = Invoice.find([('type', '=', 'in_credit_note')]) + >>> credit_note.state + u'draft' + >>> credit_note.untaxed_amount == invoice.untaxed_amount + True + >>> credit_note.tax_amount == invoice.tax_amount + True + >>> credit_note.total_amount == invoice.total_amount + True diff --git a/tests/test_account_invoice.py b/tests/test_account_invoice.py index 5512f7429b..6fdfcbdc91 100644 --- a/tests/test_account_invoice.py +++ b/tests/test_account_invoice.py @@ -10,12 +10,14 @@ if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import unittest +import doctest import datetime from decimal import Decimal import trytond.tests.test_tryton from trytond.tests.test_tryton import POOL, DB_NAME, USER, CONTEXT, test_view,\ test_depends from trytond.transaction import Transaction +from trytond.backend.sqlite.database import Database as SQLiteDatabase class AccountInvoiceTestCase(unittest.TestCase): @@ -91,10 +93,26 @@ class AccountInvoiceTestCase(unittest.TestCase): ]) +def doctest_dropdb(test): + database = SQLiteDatabase().connect() + cursor = database.cursor(autocommit=True) + try: + database.drop(cursor, ':memory:') + cursor.commit() + finally: + cursor.close() + + def suite(): suite = trytond.tests.test_tryton.suite() suite.addTests(unittest.TestLoader().loadTestsFromTestCase( AccountInvoiceTestCase)) + suite.addTests(doctest.DocFileSuite('scenario_invoice.rst', + setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite('scenario_invoice_supplier.rst', + setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite if __name__ == '__main__':