Remove dead and untested code

VAT is now calculated in a completely different way.
parent ac81e74b
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_text</string> </key>
<value> <unicode encoding="cdata"><![CDATA[
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n
\n
<html>\n
\n
<head>\n
<meta http-equiv="content-type" content="text/html;charset=utf-8">\n
<title tal:content="here/getTitle">Nexedi</title>\n
\n
</head>\n
\n
<body bgcolor="#ffffff"\n
tal:define="packing_list python:here.getDefaultValue(\'causality\',spec=[\'Sale Packing List\']);\n
invoice_line_list python:here.contentValues(filter={\'portal_type\':\'Invoice Line\'});\n
from_organisation python:here.getSourceSectionValue();\n
client_invoice python:here.getDefaultValue(\'destination_section\',spec=[\'Organisation\', \'Person\']);\n
client_delivery python:here.getDefaultValue(\'destination\',spec=[\'Organisation\', \'Person\']);\n
client_delivery python:client_delivery or here.getDefaultValue(\'destination_section\',spec=[\'Organisation\', \'Person\']);\n
total_price python:here.getTotalPrice();\n
VAT_infos python:here.SaleInvoiceTransaction_getVAT()">\n
\n
\n
<table width=100%>\n
<tr>\n
<td colspan=3><img src="logo.png"></td>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: from_organisation.getCorporateName()" colspan="2" />\n
<td align=right tal:content="python: \'Invoice date / Wystawiona: %s\' % here.getStartDate().Date()"/>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: \'Tel: %s\' % from_organisation.getDefaultTelephone().asText()" colspan="2"/>\n
<td align=right tal:content="python: \'Pay Before / Termin płatności: %s\' % here.SaleInvoiceTransaction_getDueDate().Date()"/>\n
</tr>\n
<tr>\n
<td tal:content="python: from_organisation.getDefaultAddress().getStreetAddress()" colspan="2"/>\n
<td align=right> Invoice / Faktura nr: <span tal:replace="python: here.getReference() or here.getId()"/> </td>\n
</tr>\n
<tr>\n
<td tal:content="python: \'%s %s\' %\n
(from_organisation.getDefaultAddress().getZipCode(),\n
from_organisation.getDefaultAddress().getCity())" colspan="3"/>\n
</tr>\n
<tr>\n
<td tal:content="python: from_organisation.getDefaultAddress().getRegionTitle()" colspan="3"/>\n
</tr>\n
\n
<tr>\n
<th colspan=3>\n
<h2 tal:condition="python:here.getSimulationState() not in (\'draft\',\'planned\')">INVOICE / FAKTURA</h2>\n
<h2 tal:condition="python:here.getSimulationState() in (\'draft\',\'planned\')">PROFORMA INVOICE / FAKTURA PROFORMA</h2>\n
<h3 tal:content="here/Title"></h3>\n
</th>\n
</tr>\n
\n
</table>\n
\n
<br/>\n
\n
<table width=100%>\n
<tr bgcolor=000000>\n
<th align=left><font color=ffffff size=-2>INVOICE ADDRESS / ADRES NABYWCY</font></th>\n
<th align=left><font color=ffffff size=-2>DELIVERY ADDRESS / ADRES ODBIORCY</font></th>\n
</tr>\n
\n
<tr>\n
<td align=left tal:content="client_invoice/getCorporateName | client_invoice/getTitle"/>\n
<td align=left tal:content="client_delivery/getCorporateName | client_delivery/getTitle"/>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: client_invoice.getDefaultAddress().getStreetAddress()" tal:on-error="nothing"/>\n
<td align=left tal:content="python: client_delivery.getDefaultAddress().getStreetAddress()" tal:on-error="nothing"/>\n
</tr>\n
<tr>\n
<td align=left>\n
<tal:block tal:replace="python: client_invoice.getDefaultAddress().getZipCode()" tal:on-error="nothing"/>\n
<tal:block tal:replace="python: client_invoice.getDefaultAddress().getCity()" tal:on-error="nothing"/>\n
</td>\n
<td align=left>\n
<tal:block tal:replace="python: client_delivery.getDefaultAddress().getZipCode()" tal:on-error="nothing"/>\n
<tal:block tal:replace="python: client_delivery.getDefaultAddress().getCity()" tal:on-error="nothing"/>\n
</td>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: client_invoice.getDefaultAddress().getRegionTitle()" tal:on-error="nothing"/>\n
<td align=left tal:content="python: client_delivery.getDefaultAddress().getRegionTitle()" tal:on-error="nothing"/>\n
</tr>\n
</table>\n
\n
<br/>\n
\n
<table width=100%>\n
<tr bgcolor=000000>\n
<th align=left nowrap><font color=ffffff size=-2>Nr / Nr</font></th>\n
<th align=left nowrap><font color=ffffff size=-2>Description / Opis</font></th>\n
<th nowrap><font color=ffffff size=-2>Qty / Ilość</th>\n
<th nowrap><font color=ffffff size=-2>Unit / jm</font></th>\n
<th nowrap><font color=ffffff size=-2>Price / Cena jedn.</font></th>\n
<th nowrap><font color=ffffff size=-2>Price / Razem</font></th>\n
</tr>\n
<tal:block tal:condition="python: packing_list is not None">\n
<span tal:define="ordered_line_list python:packing_list.contentValues(filter={\'portal_type\':\'Delivery Line\'})"\n
tal:repeat="line ordered_line_list">\n
<tr valign=top tal:condition="python:line.getTotalQuantity()>0">\n
\n
<td align=left tal:content="python:line.getId()"></td>\n
<td tal:content="python: line.getResourceTitle()" tal:condition="python: line.getDescription() == \'\'"></td>\n
<td tal:content="python: line.getDescription()" tal:condition="python: line.getDescription() != \'\'"></td>\n
<td align=right tal:content="python: \'%.0f\' % line.getTotalQuantity()"></td>\n
<td align=right tal:content="python: line.getQuantityUnitTitle() or line.getQuantityUnit()">n/a</td>\n
<td align=right tal:content="python: \'%.02f\' % line.getPrice()"></td>\n
<td align=right tal:content="python: \'%.02f\' % line.getTotalPrice()"></td>\n
</tr>\n
</span>\n
</tal:block>\n
<tal:block tal:condition="python: invoice_line_list is not None">\n
<tal:block tal:repeat="line invoice_line_list">\n
<tr valign=top tal:condition="python:float(line.getTotalQuantity()) != 0.0">\n
\n
<td align=left tal:content="python:line.getId()"></td>\n
<td tal:content="python: line.getResourceTitle()" tal:condition="python: line.getDescription() == \'\'"></td>\n
<td tal:content="python: line.getDescription()" tal:condition="python: line.getDescription() != \'\'"></td>\n
<td align=right tal:content="python: \'%.0f\' % line.getTotalQuantity()"></td>\n
<td align=right tal:content="python: line.getQuantityUnitTitle() or line.getQuantityUnit()">n/a</td>\n
<td align=right tal:content="python: \'%.02f\' % line.getPrice()"></td>\n
<td align=right tal:content="python: \'%.02f\' % line.getTotalPrice()"></td>\n
</tr>\n
</tal:block>\n
</tal:block>\n
<tr>\n
<td colspan=6><hr noshade></td>\n
</tr>\n
<tr>\n
<th colspan=5 align=right>Razem\n
(<span tal:replace="python:here.getPriceCurrencyTitle() or here.getResourceTitle() or \'\'"/>)</th>\n
<td colspan=1 align=right tal:content="python: \'%.02f\' % round(here.getTotalPrice(), 2)" tal:on-error="nothing"></td>\n
</tr>\n
<tr>\n
<td colspan=2 align=left tal:content="python:here.getDescription()"></td>\n
<th colspan=3 align=right> \n
<tal:block tal:replace="python: VAT_infos[\'title\']">TVA / VAT</tal:block> <br> \n
<tal:block tal:replace="python: 100.0 * (VAT_infos[\'ratio\'] or 0.0)"/> % (<span tal:replace="python:here.getPriceCurrencyTitle() or here.getResourceTitle() or \'\'"/>)</th>\n
<td colspan=1 align=right tal:content="python: \'%.02f\' % round(VAT_infos[\'total\'], 2)"></td>\n
</tr>\n
<tr>\n
<td colspan=3>&nbsp;</td>\n
<td colspan=3><hr noshade></td>\n
</tr>\n
<tr>\n
<td colspan=3>To be paid within <b tal:content="python: here.getPaymentConditionPaymentTerm(30)">0</b> days from the invoice date.\n
<br>Do zapłaty w ciągu <b tal:replace="python: here.getPaymentConditionPaymentTerm(30)">0</b> dni od daty wystawienia faktury.</td>\n
\n
<th colspan=2 align=right nowrap>Total Amount<br>Do zapłaty\n
(<span tal:replace="python:here.getPriceCurrencyTitle() or here.getResourceTitle() or \'\'"/>)</th>\n
<th colspan=1 align=right tal:content="python: \'%.02f\' % (round(VAT_infos[\'total\'], 2) + round(here.getTotalPrice(), 2))" tal:on-error="nothing"></th>\n
</tr>\n
<tr>\n
<td>&nbsp;</td>\n
</tr>\n
</table>\n
\n
<table width="100%">\n
<tr>\n
<td><center>\n
<span tal:content="python:from_organisation.getCorporateName()"></span><br/><br/>\n
<span tal:define="accs python:from_organisation.searchFolder(portal_type=\'Bank Account\',validation_state=\'valid\');" tal:condition="accs">\n
<span tal:define="acc python:accs[0].getObject()">\n
Bank name / Nazwa banku: <span tal:content="acc/getSourceTitle"></span><br/>\n
Bank account / Numer rachunku bankowego: <span tal:content="acc/getBankAccountNumber"></span><br/><br/>\n
</span>\n
</span>\n
VAT code / NIP: <span tal:content="from_organisation/getVatCode"></span>\n
\n
\n
</center></td>\n
</tr>\n
</table>\n
\n
\n
</body>\n
\n
</html>\n
<!--\n
# vim:syntax=html\n
-->\n
]]></unicode> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_viewAsHTML</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
57
\ No newline at end of file
58
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""Calculates the VAT for this invoice, returning a dict with keys:\n
\n
* total: The amount of VAT\n
* ratio: The ratio of the VAT\n
* title: The title of this VAT, actually this is the title of the\n
account used in the invoice transaction rule.\n
\n
This scripts first look in the accounting lines related to this invoice, and\n
uses the sum of all accounts of type collected_vat. If nothing is found, it\n
will look in the simulation tree to find all movements which uses a\n
collected_vat account as source.\n
\n
TODO: It\'s now clear that this script now needs a complete rewrite, because it\n
doesn\'t support different VAT rates for different lines and retrieving the VAT\n
rate associated with an invoice line.\n
\n
This API will probably change.\n
"""\n
if REQUEST is not None:\n
from zExceptions import Unauthorized\n
raise Unauthorized, script.getId()\n
\n
vat_infos = {\n
\'total\' : 0,\n
}\n
\n
invoice = context\n
portal = context.getPortalObject()\n
accounting_movement_list = invoice.getMovementList(\n
portal_type=portal.getPortalAccountingMovementTypeList())\n
\n
# 1) the invoice contains accounting lines.\n
if len(accounting_movement_list):\n
for movement in accounting_movement_list:\n
account = movement.getSourceValue(portal_type=\'Account\')\n
if account is None : continue\n
if account.getAccountTypeId() == \'collected_vat\' :\n
vat_infos.setdefault(\'title\', account.getTitle())\n
vat_infos.update({\'total\': vat_infos[\'total\'] + movement.getQuantity()})\n
vat_infos[\'ratio\'] = vat_infos[\'total\'] /\\\n
(float(invoice.getTotalPrice(\n
portal_type=portal.getPortalInvoiceMovementTypeList(),\n
fast=0)) or 1)\n
\n
# 2) no accounting lines => we must look in the simulation\n
if not vat_infos.has_key(\'title\') :\n
for invoice_movement in invoice.getMovementList(\n
portal_type=portal.getPortalInvoiceMovementTypeList() ) :\n
aggregated_simulation_movements = {}\n
for simulation_movement in ( invoice_movement.getDeliveryRelatedValueList(\n
portal_type = \'Simulation Movement\') +\n
invoice_movement.getOrderRelatedValueList(\n
portal_type = \'Simulation Movement\') ):\n
if aggregated_simulation_movements.has_key(\n
simulation_movement.getPath()):\n
continue\n
aggregated_simulation_movements[simulation_movement.getPath()] = 1\n
\n
for applied_rule in simulation_movement.objectValues():\n
# inside we got accounting movements\n
for movement in applied_rule.objectValues() :\n
account = movement.getSourceValue(portal_type=\'Account\')\n
if account is None : continue\n
if account.getAccountTypeId() == \'collected_vat\':\n
vat_infos.setdefault(\'title\', account.getTitle())\n
vat_infos.update( { \'total\':\n
vat_infos[\'total\'] + movement.getQuantity() } )\n
\n
vat_infos[\'ratio\'] = vat_infos[\'total\'] /\\\n
(float(invoice.getTotalPrice(\n
portal_type=portal.getPortalInvoiceMovementTypeList(),\n
fast=0)) or 1)\n
\n
vat_infos.setdefault(\'title\', "")\n
vat_infos.setdefault(\'ratio\', 0)\n
return vat_infos\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_getVAT</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_text</string> </key>
<value> <unicode encoding="cdata"><![CDATA[
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n
\n
<html>\n
\n
<head>\n
<meta http-equiv="content-type" content="text/html;charset=UTF-8">\n
<title tal:content="here/getTitle">Nexedi</title>\n
\n
</head>\n
\n
<body bgcolor="#ffffff"\n
tal:define="packing_list python:here.getDefaultValue(\'causality\',spec=[\'Sale Packing List\']);\n
invoice_line_list python:here.contentValues(filter={\'portal_type\':\'Invoice Line\'});\n
from_organisation python:here.getSourceSectionValue();\n
client_invoice python:here.getDefaultValue(\'destination_section\',spec=[\'Organisation\', \'Person\']);\n
client_delivery python:here.getDefaultValue(\'destination\',spec=[\'Organisation\', \'Person\']);\n
client_delivery python:client_delivery or here.getDefaultValue(\'destination_section\',spec=[\'Organisation\', \'Person\']);\n
total_price python:here.getTotalPrice();\n
VAT_infos python:here.SaleInvoiceTransaction_getVAT()">\n
\n
\n
<table width=100%>\n
<tr>\n
<td colspan=3><img src="logo.png"></td>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: from_organisation.getCorporateName(\'\')" colspan="2" />\n
<td align=right tal:content="python: \'Invoice / Date Facture: %s\' % here.getStartDate().Date()"/>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: \'Tel: %s\' % from_organisation.getDefaultTelephoneText(\'\')" colspan="2"/>\n
<td align=right tal:content="python: \'Pay Before / Payer avant: %s\' % here.SaleInvoiceTransaction_getDueDate().Date()"/>\n
</tr>\n
<tr>\n
<td tal:content="python: from_organisation.getDefaultAddressStreetAddress()" colspan="2"/>\n
<td align=right> Invoice / Facture No: ERP5 <span tal:replace="python: here.getReference() or here.getId()"/> </td>\n
</tr>\n
<tr>\n
<td tal:content="python: \'%s %s\' %\n
(from_organisation.getDefaultAddressZipCode(\'\'),\n
from_organisation.getDefaultAddressCity(\'\'))" colspan="3"/>\n
</tr>\n
<tr>\n
<td tal:content="python: from_organisation.getDefaultAddressRegionTitle(\'\')" colspan="3"/>\n
</tr>\n
\n
<tr>\n
<th colspan=3>\n
<h2 tal:condition="python:here.getSimulationState() not in (\'draft\',\'planned\')">INVOICE / FACTURE</h2>\n
<h2 tal:condition="python:here.getSimulationState() in (\'draft\',\'planned\')">PROFORMA INVOICE / FACTURE PROFORMA</h2>\n
</th>\n
</tr>\n
\n
</table>\n
\n
<br/>\n
\n
<table width=100%>\n
<tr bgcolor=000000>\n
<th align=left><font color=ffffff size=-2>INVOICE ADDRESS / ADRESSE FACTURATION</font></th>\n
<th align=left><font color=ffffff size=-2>DELIVERY ADDRESS / ADRESSE LIVRAISON </font></th>\n
</tr>\n
\n
<tr>\n
<td align=left tal:content="client_invoice/getCorporateName | client_invoice/getTitle"/>\n
<td align=left tal:content="client_delivery/getCorporateName | client_delivery/getTitle"/>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: client_invoice.getDefaultAddressStreetAddress(\'\')"/>\n
<td align=left tal:content="python: client_delivery.getDefaultAddressStreetAddress(\'\')"/>\n
</tr>\n
<tr>\n
<td align=left>\n
<tal:block tal:replace="python: client_invoice.getDefaultAddressZipCode(\'\')"/>\n
<tal:block tal:replace="python: client_invoice.getDefaultAddressCity(\'\')"/>\n
</td>\n
<td align=left>\n
<tal:block tal:replace="python: client_delivery.getDefaultAddressZipCode(\'\')"/>\n
<tal:block tal:replace="python: client_delivery.getDefaultAddressCity(\'\')"/>\n
</td>\n
</tr>\n
<tr>\n
<td align=left tal:content="python: client_invoice.getDefaultAddressRegionTitle(\'\')"/>\n
<td align=left tal:content="python: client_delivery.getDefaultAddressRegionTitle(\'\')"/>\n
</tr>\n
</table>\n
\n
<br/>\n
\n
<table width=100%>\n
<tr bgcolor=000000>\n
<th align=left nowrap><font color=ffffff size=-2>Nbr / No</font></th>\n
<th align=left nowrap><font color=ffffff size=-2>Description</font></th>\n
<th nowrap><font color=ffffff size=-2>Qty / Qté</th>\n
<th nowrap><font color=ffffff size=-2>Unit</font></th>\n
<th nowrap><font color=ffffff size=-2>Price / Prix Unit.</font></th>\n
<th nowrap><font color=ffffff size=-2>Price / Prix Total</font></th>\n
</tr>\n
<tal:block tal:condition="python: packing_list is not None">\n
<span tal:define="ordered_line_list python:packing_list.contentValues(filter={\'portal_type\':\'Delivery Line\'})"\n
tal:repeat="line ordered_line_list">\n
<tr valign=top tal:condition="python:line.getTotalQuantity()>0">\n
\n
<td align=left tal:content="python:line.getId()"></td>\n
<td tal:content="python: line.getResourceTitle()" tal:condition="python: line.getDescription() == \'\'"></td>\n
<td tal:content="python: line.getDescription()" tal:condition="python: line.getDescription() != \'\'"></td>\n
<td align=right tal:content="python: \'%.0f\' % line.getTotalQuantity()"></td>\n
<td align=right tal:content="python: line.getQuantityUnitTitle() or line.getQuantityUnit()">n/a</td>\n
<td align=right tal:content="python: \'%.02f\' % line.getPrice()"></td>\n
<td align=right tal:content="python: \'%.02f\' % line.getTotalPrice()"></td>\n
</tr>\n
</span>\n
</tal:block>\n
<tal:block tal:condition="python: invoice_line_list is not None">\n
<tal:block tal:repeat="line invoice_line_list">\n
<tr valign=top tal:condition="python:float(line.getTotalQuantity()) != 0.0">\n
\n
<td align=left tal:content="python:line.getId()"></td>\n
<td tal:content="python: line.getResourceTitle()" tal:condition="python: line.getDescription() == \'\'"></td>\n
<td tal:content="python: line.getDescription()" tal:condition="python: line.getDescription() != \'\'"></td>\n
<td align=right tal:content="python: \'%.0f\' % line.getTotalQuantity()"></td>\n
<td align=right tal:content="python: line.getQuantityUnitTitle() or line.getQuantityUnit()">n/a</td>\n
<td align=right tal:content="python: \'%.02f\' % line.getPrice()"></td>\n
<td align=right tal:content="python: \'%.02f\' % line.getTotalPrice()"></td>\n
</tr>\n
</tal:block>\n
</tal:block>\n
<tr>\n
<td colspan=6><hr noshade></td>\n
</tr>\n
<tr>\n
<th colspan=5 align=right>Total\n
(<span tal:replace="python:here.getPriceCurrencyId() or here.getResourceId() or \'\'"/>)</th>\n
<td colspan=1 align=right tal:content="python: \'%.02f\' % round(here.getTotalPrice(), 2)" tal:on-error="nothing"></td>\n
</tr>\n
<tal:block tal:condition="python: VAT_infos[\'ratio\'] != 0">\n
<tr>\n
<td colspan=2 align=left>\n
<tal:block tal:repeat="description_line python:here.getDescription().split(\'\\n\')">\n
<p tal:content="description_line">\n
</p>\n
</tal:block>\n
</td>\n
<th colspan=3 align=right>\n
<tal:block tal:replace="python: VAT_infos[\'title\']">TVA / VAT</tal:block> <br> \n
<tal:block tal:replace="python: \'%.02f\' % ((VAT_infos[\'ratio\'] or 0.0) * 100.0)"/> % (<span tal:replace="python:here.getPriceCurrencyId() or here.getResourceId() or \'\'"/>)</th>\n
<td colspan=1 align=right tal:content="python: \'%.02f\' % round(VAT_infos[\'total\'], 2)"></td>\n
</tr>\n
</tal:block>\n
<tr>\n
<td colspan=3>&nbsp;</td>\n
<td colspan=3><hr noshade></td>\n
</tr>\n
<tr>\n
<td colspan=3>A régler dans <b tal:content="python: here.getPaymentConditionPaymentTerm(30)">0</b> jours au plus tard.\n
<br><font size="-3">Conditions de réglement: par chéque ou virement, à <b tal:replace="python: here.getPaymentTerm(30)">0</b> jours date de la facture. Paiement accepté en euros.\n
Tout retard de réglement donnera lieu à une pénalité de 1,5% du montant dé par mois.\n
Réserve de propriété nous conservons la pleine propriété des marchandises jusqu\'au paiement intégral du prix, des taxes et accessoires.</font></td>\n
\n
<th colspan=2 align=right nowrap>Montant Total<br>Total Amount\n
(<span tal:replace="python:here.getPriceCurrencyId() or here.getResourceId() or \'\'"/>)</th>\n
<th colspan=1 align=right tal:content="python: \'%.02f\' % (round(VAT_infos[\'total\'], 2) + round(here.getTotalPrice(), 2))" tal:on-error="nothing"></th>\n
</tr>\n
<tr>\n
<td>&nbsp;</td>\n
</tr>\n
</table>\n
\n
<table width="100%">\n
<tr>\n
<td><center><h6>RCS Roubaix Tourcoing 440 047 504<br>\n
Banque:&nbsp;30027&nbsp;Guichet:&nbsp;17503&nbsp;Compte:&nbsp;00065894401&nbsp;RIB:&nbsp;62<br>IBAN: FR76 3002 7175 0300 0658 9440 162<br>\n
\n
VAT FR72440047504</h6></center></td>\n
</tr>\n
</table>\n
\n
\n
</body>\n
\n
</html>\n
]]></unicode> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_viewAsHTML</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
375
\ No newline at end of file
376
\ No newline at end of file
##############################################################################
#
# 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.
Warning: this tests an obsolete API; the test is disabled.
"""
import unittest
import transaction
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager
from Testing.ZopeTestCase import _print
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()
self.validateRules()
def _safeTic(self):
"""Like tic, but swallowing errors, usefull for teardown"""
try:
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)
_print('\nCancelling active message %s.%s()\n'
% (message.object_path, message.method_id) )
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,)
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',
'erp5_invoicing', 'erp5_simplified_invoicing')
def _makeAccount(self, **kw):
"""Creates an Account."""
account = self.getPortal().account_module.newContent(
portal_type='Account',
**kw)
transaction.commit()
self.tic()
return account
def _makeOrganisation(self, **kw):
"""Creates an organisation."""
org = self.getPortal().organisation_module.newContent(
portal_type='Organisation',
**kw)
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)
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)
transaction.commit()
self.tic()
return sit
def _makeCurrency(self, **kw):
"""Creates a currency."""
currency = self.getCurrencyModule().newContent(
portal_type = 'Currency', **kw)
transaction.commit()
self.tic()
return currency
def _makeResource(self, **kw):
"""Creates a resource."""
resource = self.getPortal().product_module.newContent(
portal_type='Product', **kw)
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_simulation_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()])
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()
transaction.commit()
self.tic()
packing_list.stop()
self.assertEquals(packing_list.getSimulationState(), 'stopped')
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()
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()
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()
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='Sale Invoice 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()
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)
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestInvoiceVAT))
return suite
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