Commit bd83cb63 authored by Jérome Perrin's avatar Jérome Perrin

New test for VAT and invoices.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@7717 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 056e759c
##############################################################################
#
# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved.
# Jerome Perrin <jerome@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Tests VAT for invoices.
"""
import os, sys
if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py'))
# Needed in order to have a log file inside the current folder
os.environ.setdefault('EVENT_LOG_FILE', 'zLOG.log')
os.environ.setdefault('EVENT_LOG_SEVERITY', '-300')
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager
from DateTime import DateTime
class TestInvoiceVAT(ERP5TypeTestCase):
"""Test VAT for invoices.
"""
RUN_ALL_TESTS = 1
default_region = "europe/west/france"
invoice_portal_type = 'Sale Invoice Transaction'
invoice_line_portal_type = 'Invoice Line'
invoice_cell_portal_type = 'Invoice Cell'
invoice_transaction_line_portal_type = 'Sale Invoice Transaction Line'
def getTitle(self):
return "Invoices and VAT"
def afterSetUp(self):
"""set up """
self.createCategories()
self.login()
def _safeTic(self):
"""Like tic, but swallowing errors, usefull for teardown"""
try:
get_transaction().commit()
self.tic()
except RuntimeError:
pass
def beforeTearDown(self):
"""Clear everything for next test."""
self._safeTic()
for module in [ 'sale_packing_list_module',
'organisation_module',
'person_module',
'currency_module',
'product_module',
'portal_simulation' ]:
folder = getattr(self.getPortal(), module, None)
if folder:
[x.unindexObject() for x in folder.objectValues()]
self._safeTic()
folder.manage_delObjects([x.getId() for x in folder.objectValues()])
accounting_module = self.getPortal().accounting_module
[x.cancel() for x in accounting_module.objectValues()]
accounting_module.manage_delObjects([x.getId() for x in
accounting_module.objectValues()])
self._safeTic()
# cancel remaining messages
activity_tool = self.getPortal().portal_activities
for message in activity_tool.getMessageList():
activity_tool.manageCancel(message.object_path, message.method_id)
ZopeTestCase._print('\nCancelling active message %s.%s()\n'
% (message.object_path, message.method_id) )
get_transaction().commit()
def login(self, quiet=0, run=1):
uf = self.getPortal().acl_users
uf._doAddUser('alex', '', ['Manager', 'Assignee', 'Assignor',
'Associate', 'Auditor', 'Author'], [])
user = uf.getUserById('alex').__of__(uf)
newSecurityManager(None, user)
def createCategories(self):
"""Create the categories for our test. """
# create categories
for cat_string in self.getNeededCategoryList() :
base_cat = cat_string.split("/")[0]
path = self.getPortal().portal_categories[base_cat]
for cat in cat_string.split("/")[1:] :
if not cat in path.objectIds() :
path = path.newContent(
portal_type='Category',
id=cat,
immediate_reindex=1 )
else:
path = path[cat]
# check categories have been created
for cat_string in self.getNeededCategoryList() :
self.assertNotEquals(None,
self.getCategoryTool().restrictedTraverse(cat_string),
cat_string)
def getNeededCategoryList(self):
"""return a list of categories that should be created."""
return ( 'account_type/asset'
'account_type/asset/cash',
'account_type/asset/cash/bank',
'account_type/asset/receivable',
'account_type/asset/receivable/refundable_vat',
'account_type/equity',
'account_type/expense',
'account_type/income',
'account_type/liability',
'account_type/liability/payable',
'account_type/liability/payable/collected_vat',
'region/%s' % self.default_region,
)
def getBusinessTemplateList(self):
""" """
return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',)
def _makeAccount(self, **kw):
"""Creates an Account."""
account = self.getPortal().account_module.newContent(
portal_type='Account',
**kw)
get_transaction().commit()
self.tic()
return account
def _makeOrganisation(self, **kw):
"""Creates an organisation."""
org = self.getPortal().organisation_module.newContent(
portal_type='Organisation',
**kw)
get_transaction().commit()
self.tic()
return org
def _makeSalePackingList(self, **kw):
"""Creates a sale packing list."""
spl = self.getPortal().sale_packing_list_module.newContent(
portal_type='Sale Packing List',)
spl.edit(**kw)
get_transaction().commit()
self.tic()
return spl
def _makeSaleInvoice(self, created_by_builder=0, **kw):
"""Creates a sale invoice."""
sit = self.getPortal().accounting_module.newContent(
portal_type='Sale Invoice Transaction',
created_by_builder=created_by_builder)
sit.edit(**kw)
get_transaction().commit()
self.tic()
return sit
def _makeCurrency(self, **kw):
"""Creates a currency."""
currency = self.getCurrencyModule().newContent(
portal_type = 'Currency', **kw)
get_transaction().commit()
self.tic()
return currency
def _makeResource(self, **kw):
"""Creates a resource."""
resource = self.getPortal().product_module.newContent(
portal_type='Product', **kw)
get_transaction().commit()
self.tic()
return resource
def _makeSimpleInvoiceTransactionRule(self, resource, receivable_account,
vat_account, income_account):
"""A simple invoice transaction rule, with only one accounting cell,
Debit Credit
receivable account 1.1
vat account 0.1
income account 1
"""
itr = self.getPortal().portal_rules.default_invoice_transaction_rule
itr.manage_delObjects([x for x in itr.objectIds()])
pred = itr.newContent(portal_type='Predicate')
pred.setStringIndex('product')
pred.setIntIndex(1) # XXX is it usefull ?
pred.setMembershipCriterionBaseCategoryList('resource')
pred.setMembershipCriterionCategoryList(['resource/%s' %
resource.getRelativeUrl()])
get_transaction().commit()
self.tic()
itr.updateMatrix()
cell_list = itr.getCellValueList(base_id='movement')
self.assertEquals(len(cell_list), 1)
cell = cell_list[0]
cell.newContent(
portal_type = 'Accounting Transaction Line',
source_value = receivable_account,
quantity=-1.1 )
cell.newContent(
portal_type = 'Accounting Transaction Line',
source_value = vat_account,
quantity=.1 )
cell.newContent(
portal_type = 'Accounting Transaction Line',
source_value = income_account,
quantity=1 )
def _stopPackingList(self, packing_list):
"""Stop a packing list, this will trigger invoice generation with
the builder.
"""
packing_list.confirm()
packing_list.setReady()
packing_list.start()
get_transaction().commit()
self.tic()
packing_list.stop()
self.assertEquals(packing_list.getSimulationState(), 'stopped')
get_transaction().commit()
self.tic()
def _makeOnePackingList(self):
"""Returns currency, resource, receivable_account, vat_account,
income_account, section, mirror_section and packing_list.
The packing list is ready to test.
"""
currency = self._makeCurrency()
resource = self._makeResource()
receivable_account = self._makeAccount(
account_type='asset/receivable')
self.assertNotEquals(receivable_account.getAccountTypeValue(), None)
vat_account = self._makeAccount(
account_type='liability/payable/collected_vat')
self.assertNotEquals(vat_account.getAccountTypeValue(), None)
income_account = self._makeAccount(account_type='income')
self.assertNotEquals(income_account.getAccountTypeValue(), None)
self._makeSimpleInvoiceTransactionRule(
resource=resource,
receivable_account=receivable_account,
vat_account=vat_account,
income_account=income_account )
section = self._makeOrganisation(title='Section')
mirror_section = self._makeOrganisation(title='Mirror Section')
packing_list = self._makeSalePackingList(
source_value=section,
source_section_value=section,
destination_value=mirror_section,
destination_section_value=mirror_section,
price_currency_value=currency,
start_date=DateTime())
return (currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, packing_list)
def _makeOneInvoice(self):
"""Returns currency, resource, receivable_account, vat_account,
income_account, section, mirror_section and invoice
The invoice is ready to test.
"""
currency = self._makeCurrency()
resource = self._makeResource()
receivable_account = self._makeAccount(
account_type='asset/receivable')
self.assertNotEquals(receivable_account.getAccountTypeValue(), None)
vat_account = self._makeAccount(
account_type='liability/payable/collected_vat')
self.assertNotEquals(vat_account.getAccountTypeValue(), None)
income_account = self._makeAccount(account_type='income')
self.assertNotEquals(income_account.getAccountTypeValue(), None)
self._makeSimpleInvoiceTransactionRule(
resource=resource,
receivable_account=receivable_account,
vat_account=vat_account,
income_account=income_account )
section = self._makeOrganisation(title='Section')
mirror_section = self._makeOrganisation(title='Mirror Section')
sale_invoice = self._makeSaleInvoice(
source_value=section,
source_section_value=section,
destination_value=mirror_section,
destination_section_value=mirror_section,
price_currency_value=currency,
created_by_builder=1, # XXX this prevent
# init scripts from
# creating lines
start_date=DateTime())
return (currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, sale_invoice)
def _checkInvoiceVAT(self, invoice, total_price, vat_ratio,
total_vat_amount):
"""Check the VAT for this invoice.
This check will first check VAT on the invoice, then confirm the
invoice, so that transaction lines are generated, and make sure
values are still correct when read on the accounting lines rather
than on the simulation.
o invoice: The Invoice object
o total_price: The total price that this invoice is supposed to
have (ie. the receivable quantity)
o vat_ratio: The VAT ratio.
o total_vat_amount: The value for the VAT.
"""
# check vat informations
vat_info = invoice.SaleInvoiceTransaction_getVAT()
self.assertEquals(total_price, sum([line.getTotalPrice() for line in
invoice.getMovementList()]))
self.assertEquals(vat_info['total'], total_vat_amount)
self.assertEquals(vat_info['ratio'], vat_ratio)
# confirm the invoice,
invoice.confirm()
get_transaction().commit()
self.tic()
# this will generate accounting lines
self.assertNotEquals(len(invoice.getMovementList(
portal_type=self.getPortal().getPortalAccountingMovementTypeList())), 0)
# and vat information will still be OK
vat_info = invoice.SaleInvoiceTransaction_getVAT()
self.assertEquals(total_price, sum([line.getTotalPrice() for line in
invoice.getMovementList()]))
self.assertEquals(vat_info['total'], total_vat_amount)
self.assertEquals(vat_info['ratio'], vat_ratio)
# invoice without packing list related
def test_SimpleInvoice(self, quiet=0, run=RUN_ALL_TESTS):
"""Test VAT for a simple invoice created directly. """
( currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, invoice
) = self._makeOneInvoice()
# add lines in the invoice
for i in (1, 2):
line = invoice.newContent(
portal_type='Invoice Line',)
line.edit(quantity=10,
price=100,
resource_value=resource )
invoice.plan()
get_transaction().commit();
self.tic()
# actual values on invoice line should be:
total_price = 2 * 10 * 100
vat_ratio = .1
total_vat_amount = total_price * vat_ratio
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
def test_SimpleInvoiceEmptyLines(self, quiet=0, run=RUN_ALL_TESTS):
"""Test VAT for a simple invoice created directly; empty lines should not
be a problem."""
( currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, invoice
) = self._makeOneInvoice()
# add lines in the invoice
for i in (1, 2):
line = invoice.newContent(
portal_type='Invoice Line',)
line.edit(quantity=10,
price=100,
resource_value=resource )
invoice.plan()
get_transaction().commit();
self.tic()
# actual values on invoice line should be:
total_price = 2 * 10 * 100
vat_ratio = .1
total_vat_amount = total_price * vat_ratio
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
# same if we add an empty invoice line
invoice.newContent(portal_type='Invoice Line')
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
# ... or an empty accouting line
invoice.newContent(portal_type='Accounting Transaction Line')
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
def TODOtest_SimpleInvoiceTwoResources(self, quiet=0, run=RUN_ALL_TESTS):
"""Test VAT, for two resources, where only one requires VAT """
( currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, invoice
) = self._makeOneInvoice()
another_resource = self._makeResource(title='Another resource')
# add lines in the invoice
for res in (resource, another_resource):
line = invoice.newContent(
portal_type='Invoice Line',)
line.edit(quantity=10,
price=100,
resource_value=res )
invoice.plan()
get_transaction().commit();
self.tic()
# actual values on invoice line should be:
total_price = 2 * 10 * 100
vat_ratio = .1
total_vat_amount = 10 * 100 * vat_ratio # only one line with VAT
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
# invoice from a packing list
def test_InvoiceTwoLinesWithSameResource(self, quiet=0,
run=RUN_ALL_TESTS):
"""Test VAT for an invoice that cames from a packing list with two
lines of the same resource.
"""
( currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, packing_list
) = self._makeOnePackingList()
# add lines in the packing list
for i in (1, 2):
line = packing_list.newContent(
portal_type='Sale Packing List Line',)
line.edit(quantity=10,
price=100,
resource_value=resource )
self._stopPackingList(packing_list)
invoice = packing_list.getCausalityRelatedValue(
portal_type='Sale Invoice Transaction')
self.assertNotEquals(invoice, None)
# actual values on invoice line should be:
total_price = 2 * 10 * 100
vat_ratio = .1
total_vat_amount = total_price * vat_ratio
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
def test_InvoiceTwoLinesWithSameResourceDifferentDate(self, quiet=0,
run=RUN_ALL_TESTS):
"""Test VAT for an invoice that cames from a packing list with two
lines of the same resource, with different dates.
"""
( currency, resource, receivable_account, vat_account,
income_account, section, mirror_section, packing_list
) = self._makeOnePackingList()
date = DateTime()
# add lines in the packing list
for i in (1, 2):
line = packing_list.newContent(
portal_type='Sale Packing List Line',)
line.edit(quantity=10,
price=100,
date=date + i,
resource_value=resource )
self._stopPackingList(packing_list)
invoice = packing_list.getCausalityRelatedValue(
portal_type='Sale Invoice Transaction')
self.assertNotEquals(invoice, None)
# actual values on invoice line should be:
total_price = 2 * 10 * 100
vat_ratio = .1
total_vat_amount = total_price * vat_ratio
self._checkInvoiceVAT(invoice, total_price, vat_ratio,
total_vat_amount)
if __name__ == '__main__':
framework()
else:
import unittest
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestInvoiceVAT))
return suite
......@@ -13,6 +13,7 @@ $DIRECTORY/ERP5Type/tests/runUnitTest.py testAlarm >> $DIRECTORY/test_full_outpu
$DIRECTORY/ERP5Type/tests/runUnitTest.py testAccountingRules >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testAccounting >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testInvoice >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testInvoiceVAT >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testResource >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testInteractionWorkflow >> $DIRECTORY/test_full_output 2>&1
$DIRECTORY/ERP5Type/tests/runUnitTest.py testImmobilisation >> $DIRECTORY/test_full_output 2>&1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment