Commit 4343ee07 authored by Lingnan Wu's avatar Lingnan Wu Committed by Kazuhiko Shiozaki
Browse files

add HTML based invoice generation.

parent 7eea96ef
......@@ -101,6 +101,18 @@ def getVatId(vat_id):\n
s += \'%s: %s\' % (translateString(\'VAT ID\'), vat_id)\n
return s\n
\n
def getCorporateRegCode(reg_code):\n
s = \'\'\n
if reg_code:\n
s += \'%s: %s\' % (translateString(\'Corporate Registration Code\'), reg_code)\n
return s\n
\n
def getSocialCapital(reg_cap):\n
s = \'\'\n
if reg_cap:\n
s += \'%s: %s€\' % (translateString(\'Social Capital\'), reg_cap)\n
return s\n
\n
preferred_date_order = context.getPortalObject().portal_preferences\\\n
.getPreferredDateOrder() or \'ymd\'\n
separator = \'/\'\n
......@@ -113,7 +125,7 @@ def getOrderedDate(date):\n
\n
def getPaymentConditionText(order):\n
if \'custom\' == order.getPaymentConditionTradeDate():\n
return order.getPaymentConditionPaymentDate()\n
return getOrderedDate(order.getPaymentConditionPaymentDate())\n
end_of_month = order.getPaymentConditionPaymentEndOfMonth()\n
days = order.getPaymentConditionPaymentTerm()\n
if days:\n
......@@ -131,21 +143,16 @@ def getTaxLineList(order):\n
tax_line_list.sort(key=lambda line:line.getTitle())\n
return tax_line_list\n
\n
\n
\n
line_base_contribution_list = []\n
number = 0\n
line_novat_totalprice = 0\n
tax_free_line_totalprice = 0\n
line_list = []\n
line_not_vat = []\n
line_vat = []\n
line_not_vat_has_no_vat = {}\n
line_not_tax = []\n
line_tax = []\n
line_tax_no_rate = {}\n
total_price = 0.0\n
total_vat = 0.0\n
total_vat_price = 0.0\n
vat_total_list = []\n
taxnumber = 0\n
taxname = \'\'\n
total_tax_price = 0.0\n
number_line_not_tax = 0\n
\n
def unicodeDict(d):\n
for k, v in d.items():\n
......@@ -188,22 +195,32 @@ for line in getSubLineList(context):\n
if request.get(\'international_form\'):\n
display_id = \'title\'\n
desc = (\', \'.join([x[0] for x in line.getVariationCategoryItemList(display_id=display_id)]),)\n
is_vat=0\n
is_tax=0\n
portal_preferences = context.getPortalObject().portal_preferences\n
if portal_preferences.getPreferredTaxUseList()==[] :\n
vat="use/trade/tax"\n
is_vat=line.isMemberOf(vat) \n
use_of_tax="use/trade/tax"\n
is_tax=line.isMemberOf(use_of_tax) \n
else:\n
vatlist=portal_preferences.getPreferredTaxUseList() \n
for vat in vatlist:\n
is_vat = is_vat or line.isMemberOf(vat)\n
if not is_vat:\n
if line.getBaseContribution() not in line_base_contribution_list:\n
line_base_contribution_list.append(line.getBaseContribution())\n
taxnumber=line_base_contribution_list.index(line.getBaseContribution())+1\n
tax_list=portal_preferences.getPreferredTaxUseList() \n
for use_of_tax in tax_list:\n
is_tax = is_tax or line.isMemberOf(use_of_tax)\n
\n
#set the not_tax_line with the tax_number and the tax_line with the tax_name\n
tax_number=\'\'\n
tax_name=\'\'\n
if not is_tax:\n
if line.getBaseContributionList()==[]:\n
tax_number=\'0\'\n
else:\n
for contribution in line.getBaseContributionList():\n
if contribution not in line_base_contribution_list:\n
line_base_contribution_list.append(contribution)\n
if tax_number==\'\':\n
tax_number=str(line_base_contribution_list.index(contribution)+1)\n
else:\n
tax_number=tax_number+\',\'+str(line_base_contribution_list.index(contribution)+1)\n
else:\n
taxname=line.getBaseContribution()\n
\n
tax_name=line.getBaseApplication()\n
line_dict = {\n
\'style_name\': \'Table_20_Contents\',\n
\'left_style_name\': \'Table_20_Contents_20_Left\',\n
......@@ -215,10 +232,10 @@ for line in getSubLineList(context):\n
\'description\': desc,\n
\'base_contribution\':line.getBaseContribution() or None,\n
\'use_type\':line.getResourceValue().getUse() or \'\',\n
\'use_type_tax\':is_vat,\n
\'use_type_tax\':is_tax,\n
\'total_quantity\': line.getTotalQuantity() or \'\',\n
\'tax_name\':taxname or \'\',\n
\'tax_number\':taxnumber or \'\',\n
\'tax_name\':tax_name or \'\',\n
\'tax_number\':tax_number or \'\',\n
\'quantity_unit\': line.getQuantityUnitTranslatedTitle() or (\n
line.getResource() and line.getResourceValue().getQuantityUnitTranslatedTitle()) or \'\',\n
\'stop_date\': getOrderedDate(line.getStopDate()) or \'\',\n
......@@ -228,29 +245,32 @@ for line in getSubLineList(context):\n
}\n
\n
if line_dict[\'use_type_tax\']:\n
total_vat_price+=line.getTotalPrice() or 0.0\n
line_vat.append(unicodeDict(line_dict.copy()))\n
total_tax_price+=line.getTotalPrice() or 0.0\n
line_tax.append(unicodeDict(line_dict.copy()))\n
else:\n
number_line_not_tax = number_line_not_tax+1\n
line_dict[\'number_not_tax_line\'] = number_line_not_tax\n
total_price += line.getTotalPrice() or 0.0\n
line_not_vat.append(unicodeDict(line_dict.copy()))\n
line_not_tax.append(unicodeDict(line_dict.copy()))\n
#if one line of product hasn\'t tax, the tax table need to add a taxrate=0 line\n
if line_dict[\'base_contribution\'] is None:\n
line_novat_totalprice = line_novat_totalprice + line_dict[\'total_price\']\n
line_not_vat_has_no_vat = {\n
tax_free_line_totalprice = tax_free_line_totalprice + line_dict[\'total_price\']\n
line_tax_no_rate = {\n
\'tax_name\': None ,\n
\'total_quantity\': line_novat_totalprice,\n
\'total_quantity\': tax_free_line_totalprice,\n
\'base_price\': 0.00 ,\n
\'total_price\': 0.00 ,\n
}\n
line_list.append(unicodeDict(line_dict.copy()))\n
if line_not_vat_has_no_vat != {} :\n
line_vat.append(unicodeDict(line_not_vat_has_no_vat.copy()))\n
for line_each in line_vat:\n
if line_tax_no_rate != {} :\n
line_tax.append(unicodeDict(line_tax_no_rate.copy()))\n
for line_each in line_tax:\n
if line_each[\'tax_name\'] in line_base_contribution_list :\n
vatNumber=line_base_contribution_list.index(line_each[\'tax_name\'])+1\n
number_tax_line=line_base_contribution_list.index(line_each[\'tax_name\'])+1\n
else:\n
vatNumber=0\n
line_each.update({\'vat_number\': vatNumber})\n
line_vat.sort(key=lambda obj:obj.get(\'vat_number\'))\n
number_tax_line=0\n
line_each.update({\'number_tax_line\': number_tax_line})\n
line_tax.sort(key=lambda obj:obj.get(\'number_tax_line\'))\n
\n
inch_cm_ratio = 2.54 / 100.0\n
\n
......@@ -263,6 +283,12 @@ class EmptyOrganisation:\n
return \'\'\n
def getDefaultAddressRegionTitle(self):\n
return \'\'\n
def getTelephoneText(self):\n
return \'\'\n
def getFaxText(self):\n
return \'\'\n
def getEmailText(self):\n
return \'\'\n
def getDefaultImagePath(self):\n
return \'\'\n
def getDefaultImageHeight(self):\n
......@@ -306,32 +332,40 @@ if destination_administration is None:\n
data_dict = {\n
\'source_section_title\': source_section.getProperty(\'corporate_name\') or\\\n
source_section.getTitle(),\n
\'source_section_image_path\': context.getSourceSectionValue() is not None\\\n
and context.getSourceSectionValue().getDefaultImagePath() or \'\',\n
\'source_section_image_width\': context.getSourceSectionValue() is not None\\\n
and context.getSourceSectionValue().getDefaultImageWidth() is not None\\\n
and context.getSourceSectionValue().getDefaultImageWidth() \\\n
\'source_section_image_path\': source_section is not None\\\n
and source_section.getDefaultImagePath() or \'\',\n
\'source_section_image_width\': source_section is not None\\\n
and source_section.getDefaultImageWidth() is not None\\\n
and source_section.getDefaultImageWidth() \\\n
* inch_cm_ratio or \'\',\n
\'source_section_image_height\': context.getSourceSectionValue() is not None\\\n
and context.getSourceSectionValue().getDefaultImageHeight() is not None\\\n
and context.getSourceSectionValue().getDefaultImageHeight() \\\n
\'source_section_image_height\': source_section is not None\\\n
and source_section.getDefaultImageHeight() is not None\\\n
and source_section.getDefaultImageHeight() \\\n
* inch_cm_ratio or \'\',\n
\'source_section_address\': getOneLineAddress(\n
context.getSourceSection() and\n
context.getSourceSectionValue().getDefaultAddressText() or \'\',\n
source_section.getDefaultAddressText() or \'\',\n
context.getSourceSection() and \n
context.getSourceSectionValue().getDefaultAddressRegionTitle() or \'\'),\n
source_section.getDefaultAddressRegionTitle() or \'\'),\n
\'source_section_telfax\': getPhoneAndFax(context.getSourceSection() and \\\n
context.getSourceSectionValue().getTelephoneText() or \'\',\n
source_section.getTelephoneText() or \'\',\n
context.getSourceSection() and \\\n
context.getSourceSectionValue().getFaxText() or \'\'),\n
source_section.getFaxText() or \'\'),\n
\'source_section_email\': getEmail(context.getSourceSection() and\n
context.getSourceSectionValue().getEmailText() or \'\'),\n
source_section.getEmailText() or \'\'),\n
\'source_section_vatid\': getVatId(context.getSourceSection() and\\\n
getattr(context.getSourceSectionValue(), \'getVatCode\', None)\\\n
getattr(source_section, \'getVatCode\', None)\\\n
is not None and\\\n
context.getSourceSectionValue().getVatCode() or \'\'),\n
\n
source_section.getVatCode() or \'\'),\n
\'source_section_corporateregcode\': getCorporateRegCode(context.getSourceSection() and\\\n
getattr(source_section, \'getCorporateRegistrationCode\', None)\\\n
is not None and\\\n
source_section.getCorporateRegistrationCode() or \'\'),\n
\'source_section_registeredcapital\': getSocialCapital(context.getSourceSection() and\\\n
getattr(source_section, \'getSocialCapital\', None)\\\n
is not None and\\\n
source_section.getSocialCapital() or \'\'),\n
\n
\'source_administration_title\': \\\n
source_administration.getProperty(\'corporate_name\') \\\n
or source_administration.getTitle(),\n
......@@ -349,17 +383,17 @@ data_dict = {\n
\'source_title\': source.getProperty(\'corporate_name\') or source.getTitle(),\n
\'source_address\': getOneLineAddress(\n
context.getSource() and\n
context.getSourceValue().getDefaultAddressText() or \'\',\n
source.getDefaultAddressText() or \'\',\n
context.getSource() and \n
context.getSourceValue().getDefaultAddressRegionTitle() or \'\'),\n
source.getDefaultAddressRegionTitle() or \'\'),\n
\'source_telfax\': getPhoneAndFax(context.getSource() and \\\n
context.getSourceValue().getTelephoneText() or \'\',\n
source.getTelephoneText() or \'\',\n
context.getSource() and \\\n
context.getSourceValue().getFaxText() or \'\'),\n
source.getFaxText() or \'\'),\n
\'source_email\': getEmail(context.getSource() and\n
context.getSourceValue().getEmailText() or \'\'),\n
source.getEmailText() or \'\'),\n
\'source_vatid\': getVatId(context.getSource() and\n
context.getSourceValue().getProperty(\'vat_code\', \'\') or \'\'),\n
source.getProperty(\'vat_code\', \'\') or \'\'),\n
\n
\'source_decision_title\': context.getSourceDecisionTitle() or \'\',\n
\'source_decision_image_path\': context.getSourceDecisionValue(portal_type=\'Organisation\') is not None\\\n
......@@ -419,7 +453,7 @@ data_dict = {\n
context.getDestinationSection() and context.getDestinationSectionValue().getFaxText() or \'\'),\n
\'destination_section_email\': getEmail(context.getDestinationSection() and context.getDestinationSectionValue().getEmailText() or \'\'),\n
\'destination_section_vatid\': getVatId(context.getDestinationSection() and\n
context.getDestinationSectionValue().getProperty(\'vat_code\') or \'\'),\n
context.getDestinationSectionValue().getVatCode() or \'\'),\n
\n
\'destination_administration_title\':\\\n
destination_administration.getProperty(\'corporate_name\') or \\\n
......@@ -450,16 +484,13 @@ data_dict = {\n
\'payment_condition\': getPaymentConditionText(context),\n
\'delivery_mode\': context.getDeliveryModeTranslatedTitle() or \'\',\n
\'incoterm\': context.getIncoterm() and context.getIncotermValue().getCodification() or \'\',\n
\n
\'vat_name_list\':line_base_contribution_list,\n
\'total_price\':total_price+total_vat_price,\n
\'total_price_novat\': total_price,\n
\'vat_list\': total_vat,\n
\'vat_total_price\':total_vat_price,\n
\'total_price\':total_price+total_tax_price,\n
\'total_price_exclude_tax\': total_price,\n
\'total_tax_price\':total_tax_price,\n
\'description\': getFieldAsLineList(context.getDescription()),\n
\'specialise_title\': context.getProperty(\'specialise_title\',\'\'),\n
\'line_vat\':line_vat,\n
\'line_not_vat\':line_not_vat,\n
\'line_tax\':line_tax,\n
\'line_not_tax\':line_not_tax,\n
\'line_list\': line_list,\n
}\n
\n
......
File mode changed from 100644 to 100755
......@@ -747,7 +747,7 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<text:p text:style-name=\'Item_20_Table_20_Title_20_Left\'><span tal:replace=\'orig_message\'/></text:p>\n
<text:p text:style-name=\'Item_20_Table_20_Title_20_Left\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/></text:p>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table1.A2\' office:value-type=\'string\' tal:define=\'orig_string string:Vat Code; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<table:table-cell table:style-name=\'Table1.A2\' office:value-type=\'string\' tal:define=\'orig_string string:Tax Code; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'Item_20_Table_20_Title_20_Left\'><span tal:replace=\'orig_message\'/></text:p>\n
<text:p text:style-name=\'Item_20_Table_20_Title_20_Left\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/></text:p>\n
</table:table-cell>\n
......@@ -761,14 +761,13 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
</table:table-cell>\n
</table:table-row>\n
</table:table-header-rows>\n
<tal:block tal:define="global list_number python: 0">\n
<table:table-row table:style-name=\'Table1.3\' tal:repeat=\'line_dict python:data_dict["line_not_vat"]\'>\n
<tal:block>\n
<table:table-row table:style-name=\'Table1.3\' tal:repeat=\'line_dict python:data_dict["line_not_tax"]\'>\n
<tal:block tal:omit-tag=\'\' tal:define=\'style_name python:line_dict["style_name"];\n
left_style_name python:line_dict["left_style_name"];\n
right_style_name python:line_dict["right_style_name"];\n
global list_number python: list_number + 1\'>\n
right_style_name python:line_dict["right_style_name"];\'>\n
<table:table-cell table:style-name=\'Table1.A3\' office:value-type=\'string\'>\n
<text:p text:style-name=\'Table_20_Contents_20_Left\' tal:content= \'list_number\' tal:attributes=\'text:style-name left_style_name\'>100</text:p>\n
<text:p text:style-name=\'Table_20_Contents_20_Left\' tal:content= \'python:line_dict["number_not_tax_line"]\' tal:attributes=\'text:style-name left_style_name\'>100</text:p>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table1.A3\' office:value-type=\'string\'>\n
<text:p text:style-name=\'Table_20_Contents\'\n
......@@ -878,14 +877,14 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<table:table-cell table:style-name="Table3.A1" office:value-type="string">\n
<text:p text:style-name="Table_20_Contents"/>\n
</table:table-cell>\n
<table:table-cell table:style-name="Table3.D2" table:number-columns-spanned="3" office:value-type=\'string\' tal:define=\'orig_string string:Total Excluding VAT; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<table:table-cell table:style-name="Table3.D2" table:number-columns-spanned="3" office:value-type=\'string\' tal:define=\'orig_string string:Total Excluding Tax; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'Table_20_Heading\'><span tal:replace=\'orig_message\'/>:</text:p>\n
<text:p text:style-name=\'Table_20_Heading\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/>:</text:p> \n
</table:table-cell>\n
<table:covered-table-cell/>\n
<table:covered-table-cell/>\n
<table:table-cell table:style-name="Table3.G2" office:value-type="string">\n
<text:p text:style-name=\'Table_20_Contents_20_Right\' tal:content=\'python: price_renderer(data_dict["total_price_novat"])\'>800.000,00</text:p>\n
<text:p text:style-name=\'Table_20_Contents_20_Right\' tal:content=\'python: price_renderer(data_dict["total_price_exclude_tax"])\'>800.000,00</text:p>\n
</table:table-cell>\n
</table:table-row>\n
<table:table-row table:style-name="Table3.3">\n
......@@ -917,7 +916,7 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<table:table-cell table:style-name="Table3.A1" office:value-type="string">\n
<text:p text:style-name="Table_20_Contents"/>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.D4\' office:value-type=\'string\' tal:define=\'orig_string string:Vat Code; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<table:table-cell table:style-name=\'Table3.D4\' office:value-type=\'string\' tal:define=\'orig_string string:Tax Code; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'P9\'><span tal:replace=\'orig_message\'/></text:p>\n
<text:p text:style-name=\'P9\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/></text:p>\n
</table:table-cell>\n
......@@ -929,12 +928,12 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<text:p text:style-name=\'P8\'><span tal:replace=\'orig_message\'/></text:p>\n
<text:p text:style-name=\'P8\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/></text:p>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.D4\' office:value-type=\'string\' tal:define=\'orig_string string:Vat Price; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<table:table-cell table:style-name=\'Table3.D4\' office:value-type=\'string\' tal:define=\'orig_string string:Tax Price; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'P8\'><span tal:replace=\'orig_message\'/></text:p>\n
<text:p text:style-name=\'P8\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/></text:p>\n
</table:table-cell>\n
</table:table-row>\n
<tal:block tal:repeat=\'line_vat_dict python:data_dict["line_vat"]\'>\n
<tal:block tal:repeat=\'line_tax_dict python:data_dict["line_tax"]\'>\n
<table:table-row table:style-name=\'Table3.5\'>\n
<table:table-cell table:style-name=\'Table3.A2\' office:value-type=\'string\'>\n
<text:p text:style-name=\'Table_20_Contents\'/>\n
......@@ -947,47 +946,47 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
</table:table-cell>\n
<tal:block tal:define="global ">\n
<table:table-cell table:style-name=\'Table3.D5\'\n
tal:condition="python: line_vat_dict[\'vat_number\'] != \'\'"\n
tal:condition="python: line_tax_dict[\'number_tax_line\'] != \'\'"\n
office:value-type=\'float\'\n
tal:attributes=\'office:value line_vat_dict/vat_number\'>\n
<text:p text:style-name="P6" tal:content="python: line_vat_dict[\'vat_number\']">:</text:p>\n
tal:attributes=\'office:value line_tax_dict/number_tax_line\'>\n
<text:p text:style-name="P6" tal:content="python: line_tax_dict[\'number_tax_line\']">:</text:p>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.D5\'\n
office:value-type=\'string\'\n
tal:condition="python: line_vat_dict[\'vat_number\'] == \'\'"> \n
tal:condition="python: line_tax_dict[\'number_tax_line\'] == \'\'"> \n
<text:p text:style-name=\'P6\'/>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.E5\'\n
tal:condition="python: line_vat_dict[\'total_quantity\'] != \'\'"\n
tal:condition="python: line_tax_dict[\'total_quantity\'] != \'\'"\n
office:value-type=\'float\'\n
tal:attributes=\'office:value line_vat_dict/total_quantity\'> \n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: price_renderer(line_vat_dict[\'total_quantity\'])">qty</text:p>\n
tal:attributes=\'office:value line_tax_dict/total_quantity\'> \n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: price_renderer(line_tax_dict[\'total_quantity\'])">qty</text:p>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.E5\'\n
office:value-type=\'string\'\n
tal:condition="python: line_vat_dict[\'total_quantity\'] == \'\'"> \n
tal:condition="python: line_tax_dict[\'total_quantity\'] == \'\'"> \n
<text:p text:style-name=\'Table_20_Heading\'/>\n
</table:table-cell>\n
<table:table-cell table:style-name=\'Table3.F5\'\n
tal:condition="python: line_vat_dict[\'base_price\'] != \'\'"\n
tal:condition="python: line_tax_dict[\'base_price\'] != \'\'"\n
office:value-type=\'float\'\n
tal:attributes=\'office:value line_vat_dict/base_price\'>\n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: quantity_renderer(line_vat_dict[\'base_price\']*100*1.00)+\'%\'">:</text:p>\n
tal:attributes=\'office:value line_tax_dict/base_price\'>\n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: quantity_renderer(line_tax_dict[\'base_price\']*100*1.00)+\'%\'">:</text:p>\n
</table:table-cell> \n
<table:table-cell table:style-name=\'Table3.F5\'\n
office:value-type=\'string\'\n
tal:condition="python: line_vat_dict[\'base_price\'] == \'\'"> \n
tal:condition="python: line_tax_dict[\'base_price\'] == \'\'"> \n
<text:p text:style-name=\'Table_20_Heading\'/>\n
</table:table-cell> \n
<table:table-cell table:style-name=\'Table3.G5\'\n
tal:condition="python: line_vat_dict[\'total_price\'] != \'\'"\n
tal:condition="python: line_tax_dict[\'total_price\'] != \'\'"\n
office:value-type=\'float\'\n
tal:attributes=\'office:value line_vat_dict/total_price\'>\n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: price_renderer(line_vat_dict[\'total_price\'])">:</text:p>\n
tal:attributes=\'office:value line_tax_dict/total_price\'>\n
<text:p text:style-name=\'Table_20_Heading\' tal:content="python: price_renderer(line_tax_dict[\'total_price\'])">:</text:p>\n
</table:table-cell> \n
<table:table-cell table:style-name=\'Table3.G5\'\n
office:value-type=\'string\'\n
tal:condition="python: line_vat_dict[\'total_price\'] == \'\'"> \n
tal:condition="python: line_tax_dict[\'total_price\'] == \'\'"> \n
<text:p text:style-name=\'Table_20_Heading\'/>\n
</table:table-cell> \n
</tal:block>\n
......@@ -1015,6 +1014,23 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<table:table-cell table:style-name="Table3.G8">\n
<text:p text:style-name="Table_20_Contents_20_Right"/>\n
</table:table-cell>\n
<table:table-cell table:style-name="Table3.D2" table:number-columns-spanned="3" office:value-type=\'string\' tal:define=\'orig_string string:Total Including VAT; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'Table_20_Heading\'><span tal:replace=\'orig_message\'/> :</text:p>\n
<text:p text:style-name=\'Table_20_Heading\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/>:</text:p> \n
</table:table-cell>\n
<table:covered-table-cell/>\n
<table:covered-table-cell/>\n
<table:table-cell table:style-name=\'Table3.G2\'\n
tal:condition="python: data_dict[\'total_price\'] != \'\'"\n
office:value-type=\'float\'\n
tal:attributes=\'office:value data_dict/total_price\'>\n
<text:p text:style-name=\'Table_20_Contents_20_Right\' tal:content="python: price_renderer(data_dict[\'total_price\'])">:</text:p>\n
</table:table-cell> \n
<table:table-cell table:style-name=\'Table3.G2\'\n
office:value-type=\'string\'\n
tal:condition="python: data_dict[\'total_price\'] == \'\'"> \n
<text:p text:style-name=\'Table_20_Contents_20_Right\'/>\n
</table:table-cell> \n
</table:table-row>\n
<table:table-row table:style-name="Table3.2">\n
<table:table-cell table:style-name="Table3.A2" office:value-type="string">\n
......@@ -1026,7 +1042,7 @@ MQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAACAAIAngAAAOkyAAAAAA==</string> </valu
<table:table-cell table:style-name="Table3.A1" office:value-type="string">\n
<text:p text:style-name="Table_20_Contents"/>\n
</table:table-cell>\n
<table:table-cell table:style-name="Table3.D2" table:number-columns-spanned="3" office:value-type=\'string\' tal:define=\'orig_string string:Total Including VAT; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<table:table-cell table:style-name="Table3.D2" table:number-columns-spanned="3" office:value-type=\'string\' tal:define=\'orig_string string:Total Including Tax; orig_message python:unicode(here.Base_translateString(orig_string, lang=default_language),"utf-8"); translated_message python:unicode(here.Base_translateString(orig_string),"utf-8")\'>\n
<text:p text:style-name=\'Table_20_Heading\'><span tal:replace=\'orig_message\'/> :</text:p>\n
<text:p text:style-name=\'Table_20_Heading\' tal:condition=\'python:translated_message != orig_message\'><span tal:replace=\'translated_message\'/>:</text:p> \n
</table:table-cell>\n
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts58866282.8</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>SaleInvoiceTransaction_getPrintout.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>data</string> </key>
<value> <string encoding="cdata"><![CDATA[
<tal:block define="dummy python: request.RESPONSE.setHeader(\'Content-Type\', \'text/css;; charset=utf-8\')"/>\n
/* From http://www.jonathantneal.com/examples/invoice/style.css */\n
/* reset */\n
\n
*\n
{\n
border: 0;\n
box-sizing: content-box;\n
color: inherit;\n
font-family: inherit;\n
font-size: inherit;\n
font-style: inherit;\n
font-weight: inherit;\n
line-height: inherit;\n
list-style: none;\n
margin: 0;\n
padding: 0;\n
text-decoration: none;\n
vertical-align: top;\n
}\n
\n
/* heading */\n
\n
h1 { font: bold 100% sans-serif; letter-spacing: 0.5em; text-align: center; text-transform: uppercase; }\n
\n
/* table */\n
table { page-break-inside: avoid}\n
tr { page-break-inside:avoid ,page-break-after:avoid,page-break-before:avoid}\n
table { font-size: 75%; table-layout: fixed; width: 100%; }\n
table { border-collapse: separate; border-spacing: 2px; }\n
th, td { border-width: 1px; padding: 0.5em; position: relative; text-align: left; }\n
th, td { border-radius: 0.25em; border-style: solid; }\n
th { background: #EEE; border-color: #BBB; }\n
td { border-color: #DDD; }\n
\n
/* page */\n
\n
html { font: 16px/1 \'Open Sans\', sans-serif; overflow: auto; padding: 0.5in; }\n
html { background: #999; cursor: default; }\n
\n
body { box-sizing: border-box; min-height: 11in; margin: 0 auto; overflow: hidden; padding: 0.5in; width: 8.5in; }\n
body { background: #FFF; border-radius: 1px; box-shadow: 0 0 1in -0.25in rgba(0, 0, 0, 0.5); }\n
\n
/* header */\n
\n
header { margin: 0 0 3em; }\n
header:after { clear: both; content: ""; display: table; }\n
\n
header h1 {background: #EEE; border-style: solid; border-color: #DDD; border-radius: 0.25em; margin: 0 0 1em; padding: 0.5em 0; }\n
header address { float: left; font-size: 75%; font-style: normal; line-height: 1.25; margin: 0 1em 1em 0; }\n
header address p { margin: 0 0 0.25em; }\n
header span, header img { display: block; float: right; }\n
header span { margin: 0 0 1em 1em; max-height: 25%; max-width: 60%; position: relative; }\n
header img { max-height: 100%; max-width: 100%; }\n
header input { cursor: pointer; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; height: 100%; left: 0; opacity: 0; position: absolute; top: 0; width: 100%; }\n
\n
/* article */\n
\n
article, article address, table.meta { margin: 0 0 2em; }\n
article:after { clear: both; content: ""; display: table; }\n
/* article h1 { clip: rect(0 0 0 0); position: absolute; } */\n
article h2:after { \n
content: ":";\n
font-size: 1em;\n
}\n
\n
article address { float: left; font-size: 125%; font-weight: bold; }\n
\n
\n
/* table detail */\n
table.detail { clear: both; width: 100%; margin: 0 0 2em;}\n
table.detail td:nth-child(1) { text-align: right; width: 10%; background: #EEE; border-color: #BBB; }\n
table.detail td:nth-child(2) { text-align: left; width: 28%; }\n
table.detail td:nth-child(3) { text-align: right; width: 10%; background: #EEE; border-color: #BBB; }\n
table.detail td:nth-child(4) { text-align: left; width: 28%; }\n
table.detail td:nth-child(5) { height:100%; text-align: left; width: 24%; padding: 0px;}\n
\n
/* inner table in detail*/\n
table.inner-table {\n
height:100%;\n
border-collapse: collapse;\n
border-style: hidden;\n
}\n
table.inner-table td:nth-child(1) { width: 10%; background: #EEE; border-color: #BBB; }\n
table.inner-table td:nth-child(2) { width: 10%; }\n
\n
/* table items */\n
\n
table.inventory { clear: both; width: 100%; margin: 0 0 2em; }\n
table.inventory th { font-weight: bold; text-align: center; }\n
\n
table.inventory th:nth-child(1) { width: 5%; }\n
table.inventory th:nth-child(2) { width: 15%; }\n
table.inventory th:nth-child(3) { width: 15%; }\n
table.inventory th:nth-child(4) { width: 18%; }\n
table.inventory th:nth-child(5) { width: 10%; }\n
table.inventory th:nth-child(6) { width: 7%; }\n
table.inventory th:nth-child(7) { width: 7%; }\n
table.inventory th:nth-child(8) { width: 10%; }\n
table.inventory th:nth-child(9) { width: 13%; }\n
\n
table.inventory td:nth-child(1) { text-align: right; }\n
table.inventory td:nth-child(2) { text-align: left; }\n
table.inventory td:nth-child(3) { text-align: left; }\n
table.inventory td:nth-child(4) { text-align: left; }\n
table.inventory td:nth-child(5) { text-align: right; }\n
table.inventory td:nth-child(6) { text-align: right; }\n
table.inventory td:nth-child(7) { text-align: right; }\n
table.inventory td:nth-child(8) { text-align: right; }\n
table.inventory td:nth-child(9) { text-align: right; }\n
\n
\n
/* table balance */\n
\n
table.balance { float: right; width: 46%; margin: 0 0 2em; }\n
table.balance th, table.balance td { width: 50%; text-align: right;}\n
table.balance{ clear: both; }\n
table.balance th{ width: 37.5%; }\n
table.balance td{ width: 12.5%; }\n
\n
/* table tax */\n
\n
table.tax { float: right; clear: both; width: 50%; }\n
table.tax th { font-weight: bold; text-align: center; }\n
table.tax td { text-align: right; }\n
table.tax { margin: 0 0 2em; }\n
\n
/* aside */\n
\n
aside h1 { border: none; border-width: 0 0 1px; margin: 0 0 1em; }\n
aside h1 { border-color: #999; border-bottom-style: solid; }\n
\n
/* bottom */\n
\n
footer {\n
font-size: 0.50em;\n
width: 100%;\n
clear: both;\n
text-align: right;\n
margin-top: 3em;\n
}\n
\n
@media print {\n
* { -webkit-print-color-adjust: exact; }\n
html { background: none; padding: 0; }\n
body { box-shadow: none; margin: 0; }\n
span:empty { display: none; }\n
}\n
\n
@page { margin: 0; }
]]></string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>5187</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>SaleInvoiceTransaction_getPrintout.css</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<registered_skin_selection>
<skin_folder_selection>
<skin_folder>erp5_printer</skin_folder>
<skin_selection>View</skin_selection>
</skin_folder_selection>
</registered_skin_selection>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>erp5_printer</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts58844315.59</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>SaleInvoiceTransaction_getEpsonPrintout.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>data</string> </key>
<value> <string encoding="cdata"><![CDATA[
//if the price number length > 13 use the Scientific notation,\n
//if the length==11,12,13 , just need to remove the number after Decimal point\n
function priceControl(price,builder){\n
var content=parseFloat(price).toFixed(2);\n
var content_len=content.length;\n
if(content_len>13)\n
content=parseFloat(content).toExponential(4);\n
else if(content_len>10&&content_len<14)\n
content=parseInt(content);\n
builder.addText(content);\n
}\n
\n
function printInvoiceOnEpson(){\n
// create print data builder object\n
var builder = new epson.ePOSBuilder();\n
\n
// initialize (ank mode, smoothing)\n
builder.addTextLang(\'en\').addTextSmooth(true);\n
\n
//add logo\n
builder.addTextAlign(builder.ALIGN_CENTER);\n
var canvas = $(\'#canvas\')[0];\n
var context = canvas.getContext(\'2d\');\n
context.drawImage($(\'#company_logo\')[0], 0, 0, 330, 75);\n
builder.addImage(context, 0, 0, 330, 75);\n
builder.addFeed();\n
\n
//add company information\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addTextSize(1, 1);\n
$("#company-info div").each(function(){\n
builder.addText($(this).text());\n
builder.addFeed();\n
});\n
\n
//add products information\n
builder.addTextSize(2, 1);\n
builder.addTextStyle(false, false, true);\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addText($.trim($("#invoice_information_title").text()));\n
builder.addTextSize(1, 1);\n
builder.addFeedLine(2);\n
$("#invoice_information_detail div").each(function(){\n
$(this).find("span").each(function(i){\n
if(i==0){\n
builder.addTextStyle(false, false, true);\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addText($.trim($(this).text()));\n
}\n
else{\n
builder.addTextStyle(false, false, false);\n
builder.addTextPosition(350);\n
builder.addText($.trim($(this).text()));\n
} \n
});\n
builder.addFeed();\n
});\n
builder.addFeed();\n
\n
//add products line\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addTextSize(1, 1);\n
builder.addTextFont(builder.FONT_C);\n
builder.addTextStyle(false, false, true);\n
$("#invoice_line thead tr").each(function(j){\n
var textPosition=0;\n
$(this).find("th").each(function(i){\n
builder.addTextPosition(textPosition);\n
builder.addText($.trim($(this).text()));\n
switch(i)\n
{\n
case 0:\n
textPosition+=100;\n
break;\n
case 1:\n
textPosition+=100; \n
break;\n
case 2:\n
textPosition+=125; \n
break;\n
case 3:\n
textPosition+=60;\n
break;\n
} \n
});\n
});\n
builder.addFeed();\n
builder.addTextStyle(false, false, false);\n
$("#invoice_line tbody tr").each(function(){\n
var textPosition=0;\n
$(this).find("td").each(function(i){\n
builder.addTextPosition(textPosition);\n
switch(i)\n
{\n
case 0:\n
var content=$.trim($(this).text());\n
content_len=content.length;\n
if(content_len>8)\n
content=content.substr(0,2)+"..."+content.substr(content_len-4,3)\n
builder.addText(content);\n
textPosition+=100;\n
break;\n
case 1:\n
var content=parseFloat($.trim($(this).text())).toFixed(1);\n
var content_len=content.length;\n
if(content_len>10)\n
content=parseFloat(content).toExponential(2);\n
else if(content_len>8&&content_len<11)\n
content=parseInt(content);\n
builder.addText(content);\n
textPosition+=100;\n
break;\n
case 2:\n
priceControl($.trim($(this).text()),builder)\n
textPosition+=125;\n
break;\n
case 3:\n
var content=$.trim($(this).text());\n
var content_len=content.length;\n
content=content.substr(0,5);\n
builder.addText(content);\n
textPosition+=60;\n
break;\n
case 4:\n
priceControl($.trim($(this).text()),builder)\n
break;\n
}\n
});\n
builder.addFeed();\n
});\n
\n
//add total excluding tax price\n
builder.addTextPosition(360);\n
builder.addText("===========");\n
builder.addFeed();\n
builder.addTextSize(1, 2);\n
builder.addTextStyle(false, false, true);\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addTextPosition(130);\n
builder.addText($.trim($("#total_without_tax tr th").text()));\n
builder.addTextPosition(385);\n
priceControl($.trim($("#total_without_tax tr td").text()),builder)\n
builder.addFeedLine(4);\n
\n
//add the tax line\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addTextSize(1, 1);\n
builder.addTextFont(builder.FONT_C);\n
builder.addTextStyle(false, false, true);\n
$("#tax thead tr").each(function(j){\n
var textPosition=100;\n
$(this).find("th").each(function(i){\n
builder.addTextPosition(textPosition);\n
builder.addText($.trim($(this).text()));\n
switch(i)\n
{\n
case 0:\n
textPosition+=60;\n
break;\n
case 1:\n
textPosition+=125;\n
break;\n
case 2:\n
textPosition+=100;\n
break;\n
}\n
});\n
});\n
builder.addFeed();\n
builder.addTextStyle(false, false, false);\n
$("#tax tbody tr").each(function(){\n
var textPosition=100;\n
$(this).find("td").each(function(i){\n
builder.addTextPosition(textPosition);\n
switch(i)\n
{\n
case 0:\n
builder.addText($.trim($(this).text()));\n
textPosition+=60;\n
break;\n
case 1:\n
priceControl($.trim($(this).text()),builder);\n
textPosition+=125;\n
break;\n
case 2:\n
builder.addText($.trim($(this).text()));\n
textPosition+=100;\n
break;\n
case 3:\n
priceControl($.trim($(this).text()),builder);\n
break;\n
}\n
});\n
builder.addFeed();\n
});\n
builder.addFeed();\n
\n
//add total excluding tax price\n
builder.addTextPosition(360);\n
builder.addText("===========");\n
builder.addFeed();\n
builder.addTextSize(1, 2);\n
builder.addTextStyle(false, false, true);\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
builder.addTextPosition(130);\n
builder.addText($.trim($("#total_price tr th").text()));\n
builder.addTextPosition(385);\n
priceControl($.trim($("#total_price tr td").text()),builder)\n
builder.addFeedLine(4);\n
\n
// append date and time\n
builder.addTextSize(1, 1);\n
builder.addTextAlign(builder.ALIGN_LEFT);\n
var now = new Date();\n
builder.addText(now.toDateString() + \' \' + now.toTimeString().slice(0, 8) + \'\\n\');\n
\n
// append paper cutting\n
builder.addCut(); \n
\n
// create print object\n
var url = \'http://\' + \'192.168.192.168\' + \'/cgi-bin/epos/service.cgi?devid=\' + \'local_printer\' + \'&timeout=\' + \'10000\';\n
var epos = new epson.ePOSPrint(url);\n
\n
// register callback function\n
epos.onreceive = function (res) {\n
// print failure\n
if (!res.success) {\n
console.log("no response")\n
}\n
}\n
\n
// register callback function\n
epos.onerror = function (err) {\n
console.log("error")\n
}\n
\n
// send\n
epos.send(builder.toString());\n
}
]]></string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>6931</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
erp5_jquery
erp5_accounting
\ No newline at end of file
Template for the invoice on EPSON Printer
\ No newline at end of file
lingnan
\ No newline at end of file
1
\ No newline at end of file
1
\ No newline at end of file
erp5_printer | View
\ No newline at end of file
erp5_printer
\ No newline at end of file
erp5_printer
\ No newline at end of file
5.4.7
\ No newline at end of file
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