Commit 74cbe085 authored by Tatuya Kamada's avatar Tatuya Kamada

* Fix

  transform DateTime object into ODF acceptable format
  '2009/04/20' -> '2009-04-20'

* Append
  test cases which confirm fixing the bugs

* Refactoring
  - change method name into mixedCase, according to 
    the naming convention
  - using etree nsmap object instead of to define 
    the namespace-dictionary constant
  - the long test method devide into appropriate
    some methods



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@26344 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 9e86cfeb
...@@ -45,6 +45,7 @@ from copy import deepcopy ...@@ -45,6 +45,7 @@ from copy import deepcopy
from lxml import etree from lxml import etree
from zLOG import LOG, DEBUG, INFO, WARNING from zLOG import LOG, DEBUG, INFO, WARNING
from mimetypes import guess_extension from mimetypes import guess_extension
from DateTime import DateTime
try: try:
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
...@@ -126,7 +127,6 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item): ...@@ -126,7 +127,6 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item):
{'label':'Edit', 'action':'manage_editFormPrintout'}, {'label':'Edit', 'action':'manage_editFormPrintout'},
{'label':'View', 'action': '' }, ) + Item.manage_options) {'label':'View', 'action': '' }, ) + Item.manage_options)
security.declareProtected('View management screens', 'manage_editFormPrintout') security.declareProtected('View management screens', 'manage_editFormPrintout')
manage_editFormPrintout = PageTemplateFile('www/FormPrintout_manageEdit', globals(), manage_editFormPrintout = PageTemplateFile('www/FormPrintout_manageEdit', globals(),
__name__='manage_editFormPrintout') __name__='manage_editFormPrintout')
...@@ -169,14 +169,14 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item): ...@@ -169,14 +169,14 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item):
report_method = None report_method = None
if hasattr(form, 'report_method'): if hasattr(form, 'report_method'):
report_method = getattr(obj, form.report_method) report_method = getattr(obj, form.report_method)
extra_context = dict( container=container, extra_context = dict(container=container,
printout_template=printout_template, printout_template=printout_template,
report_method=report_method, report_method=report_method,
form=form, form=form,
here=obj ) here=obj)
# set property to aquisition # set property to aquisition
content_type = printout_template.content_type content_type = printout_template.content_type
self.strategy = self._create_strategy(content_type) self.strategy = self._createStrategy(content_type)
printout = self.strategy.render(extra_context=extra_context) printout = self.strategy.render(extra_context=extra_context)
REQUEST.RESPONSE.setHeader('Content-Type','%s; charset=utf-8' % content_type) REQUEST.RESPONSE.setHeader('Content-Type','%s; charset=utf-8' % content_type)
REQUEST.RESPONSE.setHeader('Content-disposition', REQUEST.RESPONSE.setHeader('Content-disposition',
...@@ -197,20 +197,13 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item): ...@@ -197,20 +197,13 @@ class FormPrintout(Implicit, Persistent, RoleManager, Item):
% '<br>'.join(self._v_warnings)) % '<br>'.join(self._v_warnings))
return self.manage_editFormPrintout(manage_tabs_message=message) return self.manage_editFormPrintout(manage_tabs_message=message)
def _create_strategy(slef, content_type=''): def _createStrategy(slef, content_type=''):
if guess_extension(content_type) == '.odt': if guess_extension(content_type) == '.odt':
return ODTStrategy() return ODTStrategy()
raise ValueError, 'Do not support the template type:%s' % content_type raise ValueError, 'Do not support the template type:%s' % content_type
InitializeClass(FormPrintout) InitializeClass(FormPrintout)
NAME_SPACE_DICT = {'draw':'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0',
'table':'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
'text':'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
'office':'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
'xlink':'http://www.w3.org/1999/xlink'}
class ODFStrategy(Implicit): class ODFStrategy(Implicit):
"""ODFStrategy creates a ODF Document. """ """ODFStrategy creates a ODF Document. """
...@@ -245,11 +238,11 @@ class ODFStrategy(Implicit): ...@@ -245,11 +238,11 @@ class ODFStrategy(Implicit):
ooo_builder = OOoBuilder(ooo_document) ooo_builder = OOoBuilder(ooo_document)
# content.xml # content.xml
ooo_builder = self._replace_content_xml(ooo_builder=ooo_builder, extra_context=extra_context) ooo_builder = self._replaceContentXml(ooo_builder=ooo_builder, extra_context=extra_context)
# styles.xml # styles.xml
ooo_builder = self._replace_styles_xml(ooo_builder=ooo_builder, extra_context=extra_context) ooo_builder = self._replaceStylesXml(ooo_builder=ooo_builder, extra_context=extra_context)
# meta.xml is not supported yet # meta.xml is not supported yet
# ooo_builder = self._replace_meta_xml(ooo_builder=ooo_builder, extra_context=extra_context) # ooo_builder = self._replaceMetaXml(ooo_builder=ooo_builder, extra_context=extra_context)
# Update the META informations # Update the META informations
ooo_builder.updateManifest() ooo_builder.updateManifest()
...@@ -257,19 +250,19 @@ class ODFStrategy(Implicit): ...@@ -257,19 +250,19 @@ class ODFStrategy(Implicit):
ooo = ooo_builder.render(name=odf_template.title or odf_template.id) ooo = ooo_builder.render(name=odf_template.title or odf_template.id)
return ooo return ooo
def _replace_content_xml(self, ooo_builder=None, extra_context=None): def _replaceContentXml(self, ooo_builder=None, extra_context=None):
content_xml = ooo_builder.extract('content.xml') content_xml = ooo_builder.extract('content.xml')
# mapping ERP5Form to ODF # mapping ERP5Form to ODF
form = extra_context['form'] form = extra_context['form']
here = getattr(self, 'aq_parent', None) here = getattr(self, 'aq_parent', None)
content_element_tree = etree.XML(content_xml) content_element_tree = etree.XML(content_xml)
content_element_tree = self._replace_xml_by_form(element_tree=content_element_tree, content_element_tree = self._replaceXmlByForm(element_tree=content_element_tree,
form=form, form=form,
here=here, here=here,
extra_context=extra_context) extra_context=extra_context)
# mapping ERP5Report report method to ODF # mapping ERP5Report report method to ODF
content_element_tree = self._replace_xml_by_report_section(element_tree=content_element_tree, content_element_tree = self._replaceXmlByReportSection(element_tree=content_element_tree,
extra_context=extra_context) extra_context=extra_context)
content_xml = etree.tostring(content_element_tree) content_xml = etree.tostring(content_element_tree)
if isinstance(content_xml, unicode): if isinstance(content_xml, unicode):
...@@ -280,7 +273,7 @@ class ODFStrategy(Implicit): ...@@ -280,7 +273,7 @@ class ODFStrategy(Implicit):
return ooo_builder return ooo_builder
# this method not supported yet # this method not supported yet
def _replace_styles_xml(self, ooo_builder=None, extra_context=None): def _replaceStylesXml(self, ooo_builder=None, extra_context=None):
""" """
replacing styles.xml file in a ODF document replacing styles.xml file in a ODF document
""" """
...@@ -288,7 +281,7 @@ class ODFStrategy(Implicit): ...@@ -288,7 +281,7 @@ class ODFStrategy(Implicit):
form = extra_context['form'] form = extra_context['form']
here = getattr(self, 'aq_parent', None) here = getattr(self, 'aq_parent', None)
styles_element_tree = etree.XML(styles_xml) styles_element_tree = etree.XML(styles_xml)
styles_element_tree = self._replace_xml_by_form(element_tree=styles_element_tree, styles_element_tree = self._replaceXmlByForm(element_tree=styles_element_tree,
form=form, form=form,
here=here, here=here,
extra_context=extra_context) extra_context=extra_context)
...@@ -300,7 +293,7 @@ class ODFStrategy(Implicit): ...@@ -300,7 +293,7 @@ class ODFStrategy(Implicit):
return ooo_builder return ooo_builder
# this method not implemented yet # this method not implemented yet
def _replace_meta_xml(self, ooo_builder=None, extra_content=None): def _replaceMetaXml(self, ooo_builder=None, extra_content=None):
""" """
replacing meta.xml file in a ODF document replacing meta.xml file in a ODF document
""" """
...@@ -312,36 +305,36 @@ class ODFStrategy(Implicit): ...@@ -312,36 +305,36 @@ class ODFStrategy(Implicit):
ooo_builder.replace('meta.xml', meta_xml) ooo_builder.replace('meta.xml', meta_xml)
return ooo_builder return ooo_builder
def _replace_xml_by_form(self, element_tree=None, form=None, here=None, def _replaceXmlByForm(self, element_tree=None, form=None, here=None,
extra_context=None, render_prefix=None): extra_context=None, render_prefix=None):
field_list = form.get_fields() field_list = form.get_fields()
REQUEST = get_request() REQUEST = get_request()
for (count, field) in enumerate(field_list): for (count, field) in enumerate(field_list):
if isinstance(field, ListBox): if isinstance(field, ListBox):
element_tree = self._append_table_by_listbox(element_tree=element_tree, element_tree = self._appendTableByListbox(element_tree=element_tree,
listbox=field, listbox=field,
REQUEST=REQUEST, REQUEST=REQUEST,
render_prefix=render_prefix) render_prefix=render_prefix)
elif isinstance(field, FormBox): elif isinstance(field, FormBox):
sub_form = getattr(here, field.get_value('formbox_target_id')) sub_form = getattr(here, field.get_value('formbox_target_id'))
content = self._replace_xml_by_formbox(element_tree=element_tree, content = self._replaceXmlByFormbox(element_tree=element_tree,
field_id=field.id, field_id=field.id,
form = sub_form, form = sub_form,
REQUEST=REQUEST) REQUEST=REQUEST)
#elif isinstance(field, ImageField): #elif isinstance(field, ImageField):
# element_tree = self._replace_xml_by_image_field(element_tree=element_tree, # element_tree = self._replaceXmlByImageField(element_tree=element_tree,
# image_field=field) # image_field=field)
else: else:
element_tree = self._replace_node_via_reference(element_tree=element_tree, element_tree = self._replaceNodeViaReference(element_tree=element_tree,
field=field) field=field)
return element_tree return element_tree
def _replace_node_via_reference(self, element_tree=None, field=None): def _replaceNodeViaReference(self, element_tree=None, field=None):
field_id = field.id field_id = field.id
field_value = field.get_value('default') field_value = field.get_value('default')
# text:reference-mark text:name="invoice-date" # text:reference-mark text:name="invoice-date"
reference_xpath = '//text:reference-mark[@text:name="%s"]' % field_id reference_xpath = '//text:reference-mark[@text:name="%s"]' % field_id
reference_list = element_tree.xpath(reference_xpath, namespaces=NAME_SPACE_DICT) reference_list = element_tree.xpath(reference_xpath, namespaces=element_tree.nsmap)
if len(reference_list) > 0: if len(reference_list) > 0:
node = reference_list[0].getparent() node = reference_list[0].getparent()
# remove such a "bbb": <text:p>aaa<br/>bbb</text:p> # remove such a "bbb": <text:p>aaa<br/>bbb</text:p>
...@@ -350,7 +343,7 @@ class ODFStrategy(Implicit): ...@@ -350,7 +343,7 @@ class ODFStrategy(Implicit):
node.text = field_value node.text = field_value
return element_tree return element_tree
def _replace_xml_by_report_section(self, element_tree=None, extra_context=None): def _replaceXmlByReportSection(self, element_tree=None, extra_context=None):
if not extra_context.has_key('report_method') or extra_context['report_method'] is None: if not extra_context.has_key('report_method') or extra_context['report_method'] is None:
return element_tree return element_tree
report_method = extra_context['report_method'] report_method = extra_context['report_method']
...@@ -366,7 +359,7 @@ class ODFStrategy(Implicit): ...@@ -366,7 +359,7 @@ class ODFStrategy(Implicit):
here = report_item.getObject(portal_object) here = report_item.getObject(portal_object)
form_id = report_item.getFormId() form_id = report_item.getFormId()
form = getattr(here, form_id) form = getattr(here, form_id)
element_tree = self._replace_xml_by_form(element_tree=element_tree, element_tree = self._replaceXmlByForm(element_tree=element_tree,
form=form, form=form,
here=here, here=here,
extra_context=extra_context, extra_context=extra_context,
...@@ -374,9 +367,9 @@ class ODFStrategy(Implicit): ...@@ -374,9 +367,9 @@ class ODFStrategy(Implicit):
report_item.popReport(portal_object, render_prefix = render_prefix) report_item.popReport(portal_object, render_prefix = render_prefix)
return element_tree return element_tree
def _replace_xml_by_formbox(self, element_tree=None, field_id=None, form=None, REQUEST=None): def _replaceXmlByFormbox(self, element_tree=None, field_id=None, form=None, REQUEST=None):
draw_xpath = '//draw:frame[@draw:name="%s"]/draw:text-box/*' % field_id draw_xpath = '//draw:frame[@draw:name="%s"]/draw:text-box/*' % field_id
text_list = element_tree.xpath(draw_xpath, namespaces=NAME_SPACE_DICT) text_list = element_tree.xpath(draw_xpath, namespaces=element_tree.nsmap)
if len(text_list) == 0: if len(text_list) == 0:
return element_tree return element_tree
parent = text_list[0].getparent() parent = text_list[0].getparent()
...@@ -392,16 +385,16 @@ class ODFStrategy(Implicit): ...@@ -392,16 +385,16 @@ class ODFStrategy(Implicit):
parent.append(child) parent.append(child)
return element_tree return element_tree
def _replace_xml_by_image_field(self, element_tree=None, image_field=None): def _replaceXmlByImageField(self, element_tree=None, image_field=None):
alt = image_field.get_value('description') or image_field.get_value('title') alt = image_field.get_value('description') or image_field.get_value('title')
image_xpath = '//draw:frame[@draw:name="%s"]/*' % image_field.id image_xpath = '//draw:frame[@draw:name="%s"]/*' % image_field.id
image_list = element_tree.xpath(image_xpath, namespaces=NAME_SPACE_DICT) image_list = element_tree.xpath(image_xpath, namespaces=element_tree.nsmap)
if len(image_list) > 0: if len(image_list) > 0:
image_list[0].set("{%s}href" % NAME_SPACE_DICT['xlink'], image_field.absolute_url()) image_list[0].set("{%s}href" % element_tree.nsmap['xlink'], image_field.absolute_url())
return element_tree return element_tree
def _append_table_by_listbox(self, def _appendTableByListbox(self,
element_tree=None, element_tree=None,
listbox=None, listbox=None,
REQUEST=None, REQUEST=None,
...@@ -409,7 +402,7 @@ class ODFStrategy(Implicit): ...@@ -409,7 +402,7 @@ class ODFStrategy(Implicit):
table_id = listbox.id table_id = listbox.id
table_xpath = '//table:table[@table:name="%s"]' % table_id table_xpath = '//table:table[@table:name="%s"]' % table_id
# this list should be one item list # this list should be one item list
target_table_list = element_tree.xpath(table_xpath, namespaces=NAME_SPACE_DICT) target_table_list = element_tree.xpath(table_xpath, namespaces=element_tree.nsmap)
if len(target_table_list) is 0: if len(target_table_list) is 0:
return element_tree return element_tree
...@@ -418,12 +411,12 @@ class ODFStrategy(Implicit): ...@@ -418,12 +411,12 @@ class ODFStrategy(Implicit):
table_header_rows_xpath = '%s/table:table-header-rows' % table_xpath table_header_rows_xpath = '%s/table:table-header-rows' % table_xpath
table_row_xpath = '%s/table:table-row' % table_xpath table_row_xpath = '%s/table:table-row' % table_xpath
table_header_rows_list = newtable.xpath(table_header_rows_xpath, namespaces=NAME_SPACE_DICT) table_header_rows_list = newtable.xpath(table_header_rows_xpath, namespaces=element_tree.nsmap)
table_row_list = newtable.xpath(table_row_xpath, namespaces=NAME_SPACE_DICT) table_row_list = newtable.xpath(table_row_xpath, namespaces=element_tree.nsmap)
# copy row styles from ODF Document # copy row styles from ODF Document
has_header_rows = len(table_header_rows_list) > 0 has_header_rows = len(table_header_rows_list) > 0
(row_top, row_middle, row_bottom) = self._copy_row_style(table_row_list, (row_top, row_middle, row_bottom) = self._copyRowStyle(table_row_list,
has_header_rows=has_header_rows) has_header_rows=has_header_rows)
# clear original table # clear original table
...@@ -449,21 +442,21 @@ class ODFStrategy(Implicit): ...@@ -449,21 +442,21 @@ class ODFStrategy(Implicit):
listbox_column_list = listboxline.getColumnItemList() listbox_column_list = listboxline.getColumnItemList()
if listboxline.isTitleLine() and not has_header_rows: if listboxline.isTitleLine() and not has_header_rows:
row = deepcopy(row_top) row = deepcopy(row_top)
row = self._update_column_value(row, listbox_column_list) row = self._updateColumnValue(row, listbox_column_list)
newtable.append(row) newtable.append(row)
is_top = False is_top = False
elif listboxline.isDataLine() and is_top: elif listboxline.isDataLine() and is_top:
row = deepcopy(row_top) row = deepcopy(row_top)
row = self._update_column_value(row, listbox_column_list) row = self._updateColumnValue(row, listbox_column_list)
newtable.append(row) newtable.append(row)
is_top = False is_top = False
elif listboxline.isStatLine() or index is last_index: elif listboxline.isStatLine() or index is last_index:
row = deepcopy(row_bottom) row = deepcopy(row_bottom)
row = self._update_column_stat_value(row, listbox_column_list, row_middle) row = self._updateColumnStatValue(row, listbox_column_list, row_middle)
newtable.append(row) newtable.append(row)
elif index > 0 and listboxline.isDataLine(): elif index > 0 and listboxline.isDataLine():
row = deepcopy(row_middle) row = deepcopy(row_middle)
row = self._update_column_value(row, listbox_column_list) row = self._updateColumnValue(row, listbox_column_list)
newtable.append(row) newtable.append(row)
# direct listbox mapping # direct listbox mapping
...@@ -475,7 +468,7 @@ class ODFStrategy(Implicit): ...@@ -475,7 +468,7 @@ class ODFStrategy(Implicit):
return element_tree return element_tree
def _copy_row_style(self, table_row_list=[], has_header_rows=False): def _copyRowStyle(self, table_row_list=[], has_header_rows=False):
row_top = None row_top = None
row_middle = None row_middle = None
row_bottom = None row_bottom = None
...@@ -498,41 +491,43 @@ class ODFStrategy(Implicit): ...@@ -498,41 +491,43 @@ class ODFStrategy(Implicit):
row_bottom = deepcopy(table_row_list[-1]) row_bottom = deepcopy(table_row_list[-1])
return (row_top, row_middle, row_bottom) return (row_top, row_middle, row_bottom)
def _update_column_value(self, row=None, listbox_column_list=[]): def _updateColumnValue(self, row=None, listbox_column_list=[]):
odf_cell_list = row.findall("{%s}table-cell" % NAME_SPACE_DICT['table']) odf_cell_list = row.findall("{%s}table-cell" % row.nsmap['table'])
odf_cell_list_size = len(odf_cell_list) odf_cell_list_size = len(odf_cell_list)
listbox_column_size = len(listbox_column_list) listbox_column_size = len(listbox_column_list)
for (column_index, column) in enumerate(odf_cell_list): for (column_index, column) in enumerate(odf_cell_list):
if column_index >= listbox_column_size: if column_index >= listbox_column_size:
break break
value = listbox_column_list[column_index][1] value = listbox_column_list[column_index][1]
self._set_column_value(column, value) self._setColumnValue(column, value)
return row return row
def _update_column_stat_value(self, row=None, listbox_column_list=[], row_middle=None): def _updateColumnStatValue(self, row=None, listbox_column_list=[], row_middle=None):
"""stat line is capable of column span setting""" """stat line is capable of column span setting"""
if row_middle is None: if row_middle is None:
return row return row
odf_cell_list = row.findall("{%s}table-cell" % NAME_SPACE_DICT['table']) odf_cell_list = row.findall("{%s}table-cell" % row.nsmap['table'])
odf_column_span_list = self._get_odf_column_span_list(row_middle) odf_column_span_list = self._getOdfColumnSpanList(row_middle)
listbox_column_size = len(listbox_column_list) listbox_column_size = len(listbox_column_list)
listbox_column_index = 0 listbox_column_index = 0
for (column_index, column) in enumerate(odf_cell_list): for (column_index, column) in enumerate(odf_cell_list):
if listbox_column_index >= listbox_column_size: if listbox_column_index >= listbox_column_size:
break break
value = listbox_column_list[listbox_column_index][1] value = listbox_column_list[listbox_column_index][1]
self._set_column_value(column, value) self._setColumnValue(column, value)
column_span = self._get_column_span_size(column) column_span = self._getColumnSpanSize(column)
listbox_column_index = self._next_listbox_column_index(column_span, listbox_column_index = self._nextListboxColumnIndex(column_span,
listbox_column_index, listbox_column_index,
odf_column_span_list) odf_column_span_list)
return row return row
def _set_column_value(self, column, value): def _setColumnValue(self, column, value):
self._clear_column_value(column) self._clearColumnValue(column)
if value is None: if value is None:
value = '' value = ''
self._remove_column_value(column) self._removeColumnValue(column)
if isinstance(value, DateTime):
value = value.strftime('%Y-%m-%d')
column_value = unicode(str(value),'utf-8') column_value = unicode(str(value),'utf-8')
column.text = column_value column.text = column_value
column_children = column.getchildren() column_children = column.getchildren()
...@@ -545,47 +540,47 @@ class ODFStrategy(Implicit): ...@@ -545,47 +540,47 @@ class ODFStrategy(Implicit):
if first_child is not None: if first_child is not None:
column.append(first_child) column.append(first_child)
if column_value != '': if column_value != '':
value_attribute = self._get_column_value_attribute(column) value_attribute = self._getColumnValueAttribute(column)
if value_attribute is not None: if value_attribute is not None:
column.set(value_attribute, column_value) column.set(value_attribute, column_value)
def _remove_column_value(self, column): def _removeColumnValue(self, column):
# to eliminate a default value, remove "office:*" attributes. # to eliminate a default value, remove "office:*" attributes.
# if remaining these attribetes, the column shows its default value, # if remaining these attribetes, the column shows its default value,
# such as '0.0', '$0' # such as '0.0', '$0'
attrib = column.attrib attrib = column.attrib
for key in attrib.keys(): for key in attrib.keys():
if key.startswith("{%s}" % NAME_SPACE_DICT['office']): if key.startswith("{%s}" % column.nsmap['office']):
del attrib[key] del attrib[key]
column_children = column.getchildren() column_children = column.getchildren()
for child in column_children: for child in column_children:
column.remove(child) column.remove(child)
def _clear_column_value(self, column): def _clearColumnValue(self, column):
attrib = column.attrib attrib = column.attrib
for key in attrib.keys(): for key in attrib.keys():
value_attribute = self._get_column_value_attribute(column) value_attribute = self._getColumnValueAttribute(column)
if value_attribute is not None: if value_attribute is not None:
column.set(value_attribute, '') column.set(value_attribute, '')
column_children = column.getchildren() column_children = column.getchildren()
for child in column_children: for child in column_children:
child.text = '' child.text = ''
def _get_column_value_attribute(self, column): def _getColumnValueAttribute(self, column):
attrib = column.attrib attrib = column.attrib
for key in attrib.keys(): for key in attrib.keys():
if key.endswith("value"): if key.endswith("value"):
return key return key
return None return None
def _get_column_span_size(self, column=None): def _getColumnSpanSize(self, column=None):
span_attribute = "{%s}number-columns-spanned" % NAME_SPACE_DICT['table'] span_attribute = "{%s}number-columns-spanned" % column.nsmap['table']
column_span = 1 column_span = 1
if column.attrib.has_key(span_attribute): if column.attrib.has_key(span_attribute):
column_span = int(column.attrib[span_attribute]) column_span = int(column.attrib[span_attribute])
return column_span return column_span
def _next_listbox_column_index(self, span=0, current_index=0, column_span_list=[]): def _nextListboxColumnIndex(self, span=0, current_index=0, column_span_list=[]):
hops = 0 hops = 0
index = current_index index = current_index
while hops < span: while hops < span:
...@@ -594,17 +589,16 @@ class ODFStrategy(Implicit): ...@@ -594,17 +589,16 @@ class ODFStrategy(Implicit):
index += 1 index += 1
return index return index
def _get_odf_column_span_list(self, row_middle=None): def _getOdfColumnSpanList(self, row_middle=None):
if row_middle is None: if row_middle is None:
return [] return []
odf_cell_list = row_middle.findall("{%s}table-cell" % NAME_SPACE_DICT['table']) odf_cell_list = row_middle.findall("{%s}table-cell" % row_middle.nsmap['table'])
column_span_list = [] column_span_list = []
for column in odf_cell_list: for column in odf_cell_list:
column_span = self._get_column_span_size(column) column_span = self._getColumnSpanSize(column)
column_span_list.append(column_span) column_span_list.append(column_span)
return column_span_list return column_span_list
class ODTStrategy(ODFStrategy): class ODTStrategy(ODFStrategy):
"""ODTStrategy create a ODT Document from a form and a ODT template""" """ODTStrategy create a ODT Document from a form and a ODT template"""
pass pass
...@@ -31,10 +31,10 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase ...@@ -31,10 +31,10 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from Products.ERP5OOo.OOoUtils import OOoBuilder from Products.ERP5OOo.OOoUtils import OOoBuilder
from zLOG import LOG , INFO from zLOG import LOG , INFO
from lxml import etree
import os import os
class TestFormPrintout(ERP5TypeTestCase): class TestFormPrintout(ERP5TypeTestCase):
quiet = 1
run_all_test = 1 run_all_test = 1
def getTitle(self): def getTitle(self):
...@@ -67,7 +67,6 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -67,7 +67,6 @@ class TestFormPrintout(ERP5TypeTestCase):
ooo_stylesheet='Foo_getODTStyleSheet') ooo_stylesheet='Foo_getODTStyleSheet')
#Foo_viewAsOdt.pt_upload(request, file=foo_file) #Foo_viewAsOdt.pt_upload(request, file=foo_file)
#render_result = Foo_viewAsOdt(REQUEST=request) #render_result = Foo_viewAsOdt(REQUEST=request)
#LOG('testFormPrintout render_result:', INFO, render_result)
builder = OOoBuilder(foo_file) builder = OOoBuilder(foo_file)
content = builder.extract('content.xml') content = builder.extract('content.xml')
Foo_viewAsOdt.pt_edit(content, content_type='application/vnd.oasis.opendocument.text') Foo_viewAsOdt.pt_edit(content, content_type='application/vnd.oasis.opendocument.text')
...@@ -75,16 +74,30 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -75,16 +74,30 @@ class TestFormPrintout(ERP5TypeTestCase):
erp5OOo.addFormPrintout(id='Foo_viewAsPrintout', title='', erp5OOo.addFormPrintout(id='Foo_viewAsPrintout', title='',
form_name='Foo_view', template='Foo_getODTStyleSheet') form_name='Foo_view', template='Foo_getODTStyleSheet')
## append 'test1' data to a listbox
foo_module = self.portal.foo_module
if foo_module._getOb('test1', None) is None:
foo_module.newContent(id='test1', portal_type='Foo')
test1 = foo_module.test1
if test1._getOb("foo_1", None) is None:
test1.newContent("foo_1", portal_type='Foo Line')
if test1._getOb("foo_2", None) is None:
test1.newContent("foo_2", portal_type='Foo Line')
get_transaction().commit()
self.tic()
def login(self): def login(self):
uf = self.getPortal().acl_users uf = self.getPortal().acl_users
uf._doAddUser('tatuya', '', ['Manager'], []) uf._doAddUser('tatuya', '', ['Manager'], [])
user = uf.getUserById('tatuya').__of__(uf) user = uf.getUserById('tatuya').__of__(uf)
newSecurityManager(None, user) newSecurityManager(None, user)
def test_01_Paragraph(self, quiet=0, run=run_all_test): def test_01_Paragraph(self, run=run_all_test):
""" """
mapping a field to a paragraph mapping a field to a paragraph
""" """
if not run: return
portal = self.getPortal() portal = self.getPortal()
foo_module = self.portal.foo_module foo_module = self.portal.foo_module
if foo_module._getOb('test1', None) is None: if foo_module._getOb('test1', None) is None:
...@@ -139,63 +152,44 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -139,63 +152,44 @@ class TestFormPrintout(ERP5TypeTestCase):
self.assertTrue(True) self.assertTrue(True)
def test_02_Table(self, quiet=0, run=run_all_test): def test_02_Table_01_Normal(self, run=run_all_test):
""" """To test listbox and ODF table mapping
To test mapping a listbox(Form) to a table(ODF)
"""
portal = self.getPortal()
## append 'test1' data to a listbox
foo_module = self.portal.foo_module
if foo_module._getOb('test1', None) is None:
foo_module.newContent(id='test1', portal_type='Foo')
test1 = foo_module.test1
if test1._getOb("foo_1", None) is None:
test1.newContent("foo_1", portal_type='Foo Line')
get_transaction().commit()
self.tic()
# test target
foo_printout = portal.foo_module.test1.Foo_viewAsPrintout
# Test Data format * Test Data Format
#
# * ODF table named 'listbox':
# +------------------------------+
# | ID | Title | Quantity |Date |
# |-----+-------+----------+-----|
# | | | | |
# |-----+-------+----------+-----|
# | Total | | |
# +------------------------------+
#
# * ODF table named 'listbox2':
# +-------------------------------+
# | A | B | C | D |
# |-------+-------+-------+-------|
# | | | | |
# +-------+-------+-------+-------+
#
# * ODF table named 'listbox3':
# the table listbox3 has not table header.
# first row is table content, too.
# +-------------------------------+
# | 1 | 2 | 3 | 4 |
# |-------+-------+-------+-------|
# | | | | |
# +-------+-------+-------+-------+
#
# 1. Normal Case: ODF table last row is stat line ODF table named 'listbox':
test1.foo_1.setTitle('foo_title_1') +------------------------------+
| ID | Title | Quantity |Date |
|-----+-------+----------+-----|
| | | | |
|-----+-------+----------+-----|
| Total | | |
+------------------------------+
"""
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view foo_form = test1.Foo_view
listbox = foo_form.listbox listbox = foo_form.listbox
request = self.app.REQUEST request = self.app.REQUEST
request['here'] = test1 request['here'] = test1
# 1. Normal Case: ODF table last row is stat line
test1.foo_1.setTitle('foo_title_1')
message = listbox.ListBox_setPropertyList(
field_list_method = 'objectValues',
field_portal_types = 'Foo Line | Foo Line',
field_stat_method = 'portal_catalog',
field_stat_columns = 'quantity | Foo_statQuantity',
field_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date',)
self.failUnless('Set Successfully' in message)
listboxline_list = listbox.get_value('default', render_format = 'list', listboxline_list = listbox.get_value('default', render_format = 'list',
REQUEST = request) REQUEST = request)
self.assertEqual(len(listboxline_list), 3) self.assertEqual(len(listboxline_list), 4)
self.assertTrue(listboxline_list[0].isTitleLine()) self.assertTrue(listboxline_list[0].isTitleLine())
self.assertTrue(listboxline_list[1].isDataLine()) self.assertTrue(listboxline_list[1].isDataLine())
self.assertTrue(listboxline_list[2].isStatLine()) self.assertTrue(listboxline_list[2].isDataLine())
self.assertTrue(listboxline_list[3].isStatLine())
column_list = listboxline_list[0].getColumnPropertyList() column_list = listboxline_list[0].getColumnPropertyList()
self.assertEqual(len(column_list), 4) self.assertEqual(len(column_list), 4)
self.assertTrue(listboxline_list[1].getColumnProperty('id') == "foo_1") self.assertTrue(listboxline_list[1].getColumnProperty('id') == "foo_1")
...@@ -209,7 +203,17 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -209,7 +203,17 @@ class TestFormPrintout(ERP5TypeTestCase):
content_xml = builder.extract("content.xml") content_xml = builder.extract("content.xml")
self.assertTrue(content_xml.find("foo_title_1") > 0) self.assertTrue(content_xml.find("foo_title_1") > 0)
# 2. Irregular case: listbox columns count smaller than table columns count def test_02_Table_02_SmallerThanListboxColumns(self, run=run_all_test):
"""2. Irregular case: listbox columns count smaller than table columns count"""
if not run: return
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
test1.foo_1.setTitle('foo_title_2') test1.foo_1.setTitle('foo_title_2')
message = listbox.ListBox_setPropertyList( message = listbox.ListBox_setPropertyList(
field_list_method = 'objectValues', field_list_method = 'objectValues',
...@@ -222,10 +226,11 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -222,10 +226,11 @@ class TestFormPrintout(ERP5TypeTestCase):
[('id', 'ID'), ('title', 'Title'), ('quantity', 'Quantity')]) [('id', 'ID'), ('title', 'Title'), ('quantity', 'Quantity')])
listboxline_list = listbox.get_value('default', render_format = 'list', listboxline_list = listbox.get_value('default', render_format = 'list',
REQUEST = request) REQUEST = request)
self.assertEqual(len(listboxline_list), 3) self.assertEqual(len(listboxline_list), 4)
self.assertTrue(listboxline_list[0].isTitleLine()) self.assertTrue(listboxline_list[0].isTitleLine())
self.assertTrue(listboxline_list[1].isDataLine()) self.assertTrue(listboxline_list[1].isDataLine())
self.assertTrue(listboxline_list[2].isStatLine()) self.assertTrue(listboxline_list[2].isDataLine())
self.assertTrue(listboxline_list[3].isStatLine())
self.assertTrue(listboxline_list[1].getColumnProperty('title') == "foo_title_2") self.assertTrue(listboxline_list[1].getColumnProperty('title') == "foo_title_2")
column_list = listboxline_list[0].getColumnPropertyList() column_list = listboxline_list[0].getColumnPropertyList()
...@@ -240,7 +245,17 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -240,7 +245,17 @@ class TestFormPrintout(ERP5TypeTestCase):
self.assertFalse(content_xml.find("foo_title_1") > 0) self.assertFalse(content_xml.find("foo_title_1") > 0)
self.assertTrue(content_xml.find("foo_title_2") > 0) self.assertTrue(content_xml.find("foo_title_2") > 0)
# 3. Irregular case: listbox columns count larger than table columns count def test_02_Table_03_ListboxColumnsLargerThanTable(self, run=run_all_test):
"""3. Irregular case: listbox columns count larger than table columns count"""
if not run: return
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
test1.foo_1.setTitle('foo_title_3') test1.foo_1.setTitle('foo_title_3')
message = listbox.ListBox_setPropertyList( message = listbox.ListBox_setPropertyList(
field_list_method = 'objectValues', field_list_method = 'objectValues',
...@@ -252,13 +267,12 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -252,13 +267,12 @@ class TestFormPrintout(ERP5TypeTestCase):
self.failUnless('Set Successfully' in message) self.failUnless('Set Successfully' in message)
listboxline_list = listbox.get_value('default', render_format = 'list', listboxline_list = listbox.get_value('default', render_format = 'list',
REQUEST = request) REQUEST = request)
self.assertEqual(len(listboxline_list), 3) self.assertEqual(len(listboxline_list), 4)
self.assertTrue(listboxline_list[1].getColumnProperty('title') == "foo_title_3") self.assertTrue(listboxline_list[1].getColumnProperty('title') == "foo_title_3")
column_list = listboxline_list[0].getColumnPropertyList() column_list = listboxline_list[0].getColumnPropertyList()
self.assertEqual(len(column_list), 5) self.assertEqual(len(column_list), 5)
odf_document = foo_printout.index_html(REQUEST=request) odf_document = foo_printout.index_html(REQUEST=request)
LOG('testFormPrintout', INFO, 'content:%s' % content_xml)
#test_output = open("/tmp/test_02_03_Table.odf", "w") #test_output = open("/tmp/test_02_03_Table.odf", "w")
#test_output.write(odf_document) #test_output.write(odf_document)
self.assertTrue(odf_document is not None) self.assertTrue(odf_document is not None)
...@@ -267,13 +281,19 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -267,13 +281,19 @@ class TestFormPrintout(ERP5TypeTestCase):
self.assertFalse(content_xml.find("foo_title_2") > 0) self.assertFalse(content_xml.find("foo_title_2") > 0)
self.assertTrue(content_xml.find("foo_title_3") > 0) self.assertTrue(content_xml.find("foo_title_3") > 0)
# 4. Irregular case: listbox has not a stat line, but table has a stat line def test_02_Table_04_ListboxHasNotStat(self, run=run_all_test):
if test1._getOb("foo_2", None) is None: """4. Irregular case: listbox has not a stat line, but table has a stat line"""
test1.newContent("foo_2", portal_type='Foo Line') if not run: return
get_transaction().commit() # test target
self.tic() test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
test1.foo_1.setTitle('foo_title_4') test1.foo_1.setTitle('foo_title_4')
test1.foo_1.setStartDate('2009-01-01')
message = listbox.ListBox_setPropertyList( message = listbox.ListBox_setPropertyList(
field_list_method = 'objectValues', field_list_method = 'objectValues',
field_portal_types = 'Foo Line | Foo Line', field_portal_types = 'Foo Line | Foo Line',
...@@ -297,7 +317,41 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -297,7 +317,41 @@ class TestFormPrintout(ERP5TypeTestCase):
self.assertFalse(content_xml.find("foo_title_3") > 0) self.assertFalse(content_xml.find("foo_title_3") > 0)
self.assertTrue(content_xml.find("foo_title_4") > 0) self.assertTrue(content_xml.find("foo_title_4") > 0)
# 5. Normal case: the listobx and the ODF table are same layout content = etree.XML(content_xml)
table_row_xpath = '//table:table[@table:name="listbox"]/table:table-row'
odf_table_rows = content.xpath(table_row_xpath, namespaces=content.nsmap)
self.assertEqual(len(odf_table_rows), 2)
# to test copying ODF table cell styles
first_row = odf_table_rows[0]
first_row_columns = first_row.getchildren()
last_row = odf_table_rows[-1]
last_row_columns = last_row.getchildren()
span_attribute = "{%s}number-columns-spanned" % content.nsmap['table']
self.assertFalse(first_row_columns[0].attrib.has_key(span_attribute))
self.assertEqual(int(last_row_columns[0].attrib[span_attribute]), 2)
def test_02_Table_05_NormalSameLayout(self, run=run_all_test):
"""5. Normal case: the listobx and the ODF table are same layout
* Test Data Format:
ODF table named 'listbox2'
+-------------------------------+
| A | B | C | D |
|-------+-------+-------+-------|
| | | | |
+-------+-------+-------+-------+
"""
if not run: return
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
foo_form.manage_renameObject('listbox', 'listbox2', REQUEST=request) foo_form.manage_renameObject('listbox', 'listbox2', REQUEST=request)
listbox2 = foo_form.listbox2 listbox2 = foo_form.listbox2
test1.foo_1.setTitle('foo_title_5') test1.foo_1.setTitle('foo_title_5')
...@@ -325,10 +379,39 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -325,10 +379,39 @@ class TestFormPrintout(ERP5TypeTestCase):
# put back the field name # put back the field name
foo_form.manage_renameObject('listbox2', 'listbox', REQUEST=request) foo_form.manage_renameObject('listbox2', 'listbox', REQUEST=request)
# 6. Normal case: ODF table does not have a header
def test_02_Table_06_TableDoesNotHaveAHeader(self, run=run_all_test):
"""6. Normal case: ODF table does not have a header
* Test Data format:
ODF table named 'listbox3'
the table listbox3 has not table header.
first row is a table content, too.
+-------------------------------+
| 1 | 2 | 3 | 4 |
|-------+-------+-------+-------|
| | | | |
+-------+-------+-------+-------+
"""
if not run: return
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
foo_form.manage_renameObject('listbox', 'listbox3', REQUEST=request) foo_form.manage_renameObject('listbox', 'listbox3', REQUEST=request)
listbox3 = foo_form.listbox3 listbox3 = foo_form.listbox3
test1.foo_1.setTitle('foo_title_6') test1.foo_1.setTitle('foo_title_6')
message = listbox3.ListBox_setPropertyList(
field_list_method = 'objectValues',
field_portal_types = 'Foo Line | Foo Line',
field_stat_method = 'portal_catalog',
field_stat_columns = 'quantity | Foo_statQuantity',
field_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date',)
self.failUnless('Set Successfully' in message)
listboxline_list = listbox3.get_value('default', render_format = 'list', listboxline_list = listbox3.get_value('default', render_format = 'list',
REQUEST = request) REQUEST = request)
self.assertEqual(len(listboxline_list), 4) self.assertEqual(len(listboxline_list), 4)
...@@ -346,26 +429,74 @@ class TestFormPrintout(ERP5TypeTestCase): ...@@ -346,26 +429,74 @@ class TestFormPrintout(ERP5TypeTestCase):
# put back the field name # put back the field name
foo_form.manage_renameObject('listbox3', 'listbox', REQUEST=request) foo_form.manage_renameObject('listbox3', 'listbox', REQUEST=request)
def _test_03_Frame(self, quiet=0, run=run_all_test): def test_02_Table_07_CellFormat(self, run=run_all_test):
"""7. Normal case: cell format cetting"""
if not run: return
# test target
test1 = self.portal.foo_module.test1
foo_printout = test1.Foo_viewAsPrintout
foo_form = test1.Foo_view
listbox = foo_form.listbox
request = self.app.REQUEST
request['here'] = test1
test1.foo_1.setTitle('foo_title_7')
test1.foo_1.setStartDate('2009-04-20')
message = listbox.ListBox_setPropertyList(
field_list_method = 'objectValues',
field_portal_types = 'Foo Line | Foo Line',
field_stat_method = 'portal_catalog',
field_stat_columns = 'quantity | Foo_statQuantity',
field_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date',)
self.failUnless('Set Successfully' in message)
listboxline_list = listbox.get_value('default', render_format = 'list',
REQUEST = request)
self.assertEqual(len(listboxline_list), 4)
self.assertTrue(listboxline_list[1].getColumnProperty('title') == "foo_title_7")
LOG('testFormPrintout start_date', INFO, listboxline_list[1].getColumnProperty('start_date'))
odf_document = foo_printout.index_html(REQUEST=request)
#test_output = open("/tmp/test_02_07_Table.odf", "w")
#test_output.write(odf_document)
self.assertTrue(odf_document is not None)
builder = OOoBuilder(odf_document)
content_xml = builder.extract("content.xml")
self.assertFalse(content_xml.find("foo_title_6") > 0)
self.assertTrue(content_xml.find("foo_title_7") > 0)
content = etree.XML(content_xml)
table_row_xpath = '//table:table[@table:name="listbox"]/table:table-row'
odf_table_rows = content.xpath(table_row_xpath, namespaces=content.nsmap)
LOG('testFormPrintout odf_table_rows', INFO, odf_table_rows)
self.assertEqual(len(odf_table_rows), 3)
# to test ODF table cell number format
first_row = odf_table_rows[0]
first_row_columns = first_row.getchildren()
date_column = first_row_columns[3]
date_value_attrib = "{%s}date-value" % content.nsmap['office']
self.assertTrue(date_column.attrib.has_key(date_value_attrib))
self.assertEqual(date_column.attrib[date_value_attrib], '2009-04-20')
def _test_03_Frame(self, run=run_all_test):
""" """
Frame not supported yet Frame not supported yet
""" """
pass pass
def _test_04_Iteration(self, quiet=0, run=run_all_test): def _test_04_Iteration(self, run=run_all_test):
""" """
Iteration(ReportSection) not supported yet. Iteration(ReportSection) not supported yet.
Probably to support *ReportBox* would be better. Probably to support *ReportBox* would be better.
""" """
pass pass
def _test_05_Styles(self, quiet=0, run=run_all_test): def _test_05_Styles(self, run=run_all_test):
""" """
styles.xml not supported yet styles.xml not supported yet
""" """
pass pass
def _test_06_Meta(self, quiet=0, run=run_all_test): def _test_06_Meta(self, run=run_all_test):
""" """
meta.xml not supported yet meta.xml not supported yet
""" """
......
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