Nested loops in .ods template using relatorio

Hi,
I’m trying to get the same thing as this post, but with ods: Nested loops in .odt or .ods templates using relatorio
For me, with that nested loop structure:

It’s throwing the following error:

  File "/relatorio/templates/opendocument.py", line 876, in generate
    stream = super(Template, self).generate(*args, **kwargs)
  File "/genshi/template/base.py", line 568, in generate
    stream = self.stream
  File "/genshi/template/base.py", line 457, in stream
    self._prepare_self()
  File "/genshi/template/base.py", line 476, in _prepare_self
    self._stream = list(self._prepare(self._stream, inlined))
  File "/genshi/template/base.py", line 499, in _prepare
    yield kind, (directives, list(substream)), pos
  File "/genshi/template/base.py", line 492, in _prepare
    for _, cls, value, namespaces, pos in sorted(data[0]):
TypeError: '<' not supported between instances of 'dict' and 'dict'

And I expect to get something like:
image

Also, in my case his column 3 has the same distribution as the column 2.
From what I have been able to see It’s not possible to add a table in ods format.
Is there any other way to get that?
Thanks beforehand.

As I said, relatorio can not loop inside merged cells.

As you can not loop nested, what you can do is create a property to prepare the data so you can have a property that returns a dict like:

[
{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},

{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
]

So you can have a single loop on the report.

Thanks for your answers,
@acaubet If I’m not wrong likewise I would have to do another loop to get the multiple product_codes and descriptions that can have a certain code and type.

I understand that, but is there any other way to get that?

No, you should be doing any nested loops you want inside the python property to prepare your data.

Yes, I’m doing it, but iterating through the property with the structure you told me previously (and others) don’t let me group the product_code by code and type without another loop (that I can’t use).
Code:

  @property
  def package_dict_list(self):
      code_type_dict = {}
      code_type_list = []

      for package in self.packages:
          code_type_dict['package_code'] = package.code
          code_type_dict['package_type'] = package.type
          for move in package.moves:
              code_type_dict['product_code'] = move.product.code
          code_type_list.append(code_type_dict)
      return code_type_list

For example:

{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XX001', 'description': 'Mr. Robot'}
{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XXX02', 'description': 'Mr. Robot'}

Should result in:

Some modifications on your property:

@property
def package_dict_list(self):
  code_type_list = []

  for package in self.packages:
    for i, move in enumerate(package.moves):
      code_type_dict = {
        'package_code': ''
        'package_type': ''
      }
      if i == 0:
        code_type_dict['package_code'] = package.code
        code_type_dict['package_type'] = package.type
      code_type_dict['product_code'] = move.product.code
      code_type_dict['description'] = move.product.description
      code_type_list.append(code_type_dict)
  return code_type_list

Should produce this:

[
{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},

{'code': 'HELLO', 'type': 'WORLD', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
{'code': '', 'type': '', 'product_code': 'XX001', 'description': 'Mr. Robot'},
]

Then on the report you can do something like this:

for item in report.package_dict_list
item['code'] | item['type'] | item['product_code'] | item['description']
/for

Which should produce:
image

And obviously some modifications to display the style if you want:

for item in report.package_dict_list
if item['code']
row separator
/if
item['code'] | item['type'] | item['product_code'] | item['description']
/for
1 Like

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.