0

I want to know how to configure a page break through number of columns not number of rows. For example, I want in every page 5 columns. How can I realise that?

 <blockTable colwidths="150,100,100,100,100,100" style="Table1">
  <tr>
<td>
      <para style="P8">NOM EMPLOYÉ</para>
    </td>
    <td>
      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'o', 'td') ]]</para>
      <para style="P7">[[ o['name'] ]]</para>
    </td>      
  </tr>
  <tr>
<td>
      <para style="P8">Matricule</para>
    </td>
    <td>
      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'p', 'td') ]]</para>
      <para style="P7">[[ p['matricule'] ]]</para>
    </td>      
  </tr>
  <tr>
<td>
      <para style="P8">HEURES SUPPLEÉMENTAIRES 100%</para>
    </td>
    <td>
      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'a', 'td') ]]</para>
      <para style="P7">[[ a['hours_overtime_100'] ]]</para>
    </td>      
  </tr>
  <tr>
<td>
      <para style="P8">ABSENCE</para>
    </td>
    <td>
      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'b', 'td') ]]</para>
      <para style="P7">[[ b['seetek_absence_day'] ]]</para>
    </td>      
  </tr>
 <tr>
<td>
      <para style="P8">TOTAL BRUT</para>
    </td>
    <td>
       <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'c', 'td') ]]</para>
       <para style="P7">[[ c['total_brut'] ]]</para>
    </td>      
  </tr>
       </blockTable>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • Not sure that I understand your question. Normally it you who defines what to put in a page. So if you want a table with 5 columns just put a table with five columns. Do you mean that you have an unknown number of columns and you want to fill consecutive pages with them? May you give us a more precise example? – Andrei Boyanov Sep 04 '15 at 11:20
  • I have a loop so the number of columns will depend on the result of that loop. i am unable to define the number of columns that why i want to define in each page i will find five or X columns, with this method i will not loose the informtions because they will be outside the page – Pari Shontelle Riri Sep 04 '15 at 11:22
  • So, what do you think @Andrei Boyanov – Pari Shontelle Riri Sep 04 '15 at 11:29
  • Is it the same about the rows? You have a dynamic number of rows too, I suppose? In this case what will you have on the 2nd page? I think the solution is to divide your table in multiple tables depending of the number of columns. But you'll have difficulties to do it if there are more rows than you can have on one page. – Andrei Boyanov Sep 04 '15 at 11:33
  • No, i have 15 rows but the number of my columns is not fixe. I want to have 5 columns per page to be sure that i will loose nothing. – Pari Shontelle Riri Sep 04 '15 at 11:36
  • May you give an example code of your RML report? – Andrei Boyanov Sep 04 '15 at 11:37
  • i gave you the example. can you help me now – Pari Shontelle Riri Sep 04 '15 at 12:03
  • answer me even if you didnt get the answer to resolve the problem. – Pari Shontelle Riri Sep 04 '15 at 12:20
  • You are very impatient! :) Give me some time to consider your code and to do what is urgent around me meanwhile... – Andrei Boyanov Sep 04 '15 at 12:24
  • so sorry :/ i am patiend but i thought you were gone. Ok i will wait for you :) – Pari Shontelle Riri Sep 04 '15 at 12:26

3 Answers3

0

Why don't you try something like this:

<section>
    <para>
        [[ repeatIn(get_employee_slices(example.company_id,
                                        example.date_start,
                                        example.date_end,
                                        5),
                    "slice") ]]
    </para>
        <blockTable colwidths="150,100,100,100,100,100" style="Table1">
        <tr>
            <td>
                <para style="P8">NOM EMPLOYÉ</para>
            </td>
            <td>
                <para style="P7">
                    [[ repeatIn(get_employee_lines(example.company_id,
                                                   example.date_start, 
                                                   example.date_end,
                                                   slice, 5), 
                                'o', 'td') ]]
                </para>
                <para style="P7">[[ o['name'] ]]</para>
            </td>      
        </tr>
        <tr>
            <td>
                <para style="P8">Matricule</para>
            </td>
            <td>
                <para style="P7">
                    [[ repeatIn(get_employee_lines(example.company_id,
                                                   example.date_start, 
                                                   example.date_end,
                                                   slice, 5), 
                                'o', 'td') ]]
                </para>
                <para style="P7">[[ o['matricule'] ]]</para>
            </td>      
        </tr>
        <!-- .... -->
    </blockTable>
</section>

I added additional loop which will create N different tables (depending of the amount of employees you have. I called the different portions of employees 'slices'. To have this working you need two things more:

  • create a method inside your python code called get_employee_slices. This method should return a list of consecutive numbers from 0 to N - 1:
  • modify you existing method get_employee_lines adding two additional arguments - number_of_slices and number_of_columns. This method should now return only the employees belonging to a given slice - from example from employee 5 to employee 9.

Hope the idea is quite clear. I didn't test it so there are may be some errors.

Follows a suggestion for the get_employee_slices() implementation:

def get_employee_slices(self, company, date_start, date_end,
                        columns, context=None):

    payslip_pool = self.pool.get('hr.payslip')
    ids = payslip_pool.search(self.cr, self.uid,
                              [('date', '>=', date_start),
                               ('date', '<=', date_end),
                               ('company_id', '=', company.id)])
    taille = int(len(ids) / columns) + \
                (len(ids) % columns > 0 and 1 or 0)
    return range(taille)
Andrei Boyanov
  • 2,309
  • 15
  • 18
  • The idea is so clear my friend. Thanks a lot but i didnt know how to create the get_employee_slices – Pari Shontelle Riri Sep 04 '15 at 13:30
  • Look in the code of your report. It's in some .py file nearby you .rml file. This is the same file which contains get_employee_lines(). Or may you find difficulties implementing the logic of this method? Tell me if this is the case. – Andrei Boyanov Sep 04 '15 at 13:45
  • I have tried it my friend but i got this as an error:except_osv: (u"name 'slice' is not defined", (, NameError("name 'slice' is not defined",), )) – Pari Shontelle Riri Sep 04 '15 at 13:55
  • Try to debug why it cannot recognize your new 'slice' variable in the method call `get_employee_lines(example.company_id,example.date_start,example.date_end, slice, 5)`. I don't see the reason... Try putting the same in the next call to this method - for the Matricule row... – Andrei Boyanov Sep 04 '15 at 14:46
  • And don't put parts of your question as answer - the admins of the site wont be happy with that :) – Andrei Boyanov Sep 04 '15 at 14:47
  • Friend it dont recognize not the slice of get_employee_lines but of get_employee_slices. And thanks for the advice :) – Pari Shontelle Riri Sep 04 '15 at 14:52
  • here is what i have got:015-09-04 14:53:42,036 13909 ERROR openerp openerp.tools.safe_eval: Cannot eval "repeatIn(get_employee_slices(example.company_id,example.date_start, example.date_end, 5), 'test')" Traceback (most recent call last): File "/opt/openerp/v7/server/openerp/tools/safe_eval.py", line 288, in safe_eval return eval(test_expr(expr, _SAFE_OPCODES, mode=mode), globals_dict, locals_dict) for id in lst: TypeError: 'int' object is not iterable File "", line 1, in NameError: name 'test' is not defined – Pari Shontelle Riri Sep 04 '15 at 14:54
  • Hey Andrei you still here please!! – Pari Shontelle Riri Sep 04 '15 at 15:52
  • Did you put the code in the same class where the method get_employee_lines resides? – Andrei Boyanov Sep 04 '15 at 16:37
  • You have also problems in your code. It.s enough to do something like this: 'return range(int(len(obj_ids) / var) + 1)'. Why `var` by the way? :) – Andrei Boyanov Sep 04 '15 at 16:42
  • yes certainly. bt what i want to know is number_of_slices, number_of_columns in get_employee_lines how are they used in the function – Pari Shontelle Riri Sep 04 '15 at 16:42
  • I repeat - your method must return `list`, not am integer. – Andrei Boyanov Sep 04 '15 at 16:43
  • because in the rml you used [[ repeatIn(get_employee_slices(example.company_id, example.date_start, example.date_end, 5), 'slice') ]] ( is for what) – Pari Shontelle Riri Sep 04 '15 at 16:44
  • Would you sir please correct the code for me please please – Pari Shontelle Riri Sep 04 '15 at 16:44
  • ok i have corrected that: for i in range (taille): i = i +1 obj2 = [] obj2 = i res_list2.append(obj2) print res_list2 return res_list2 – Pari Shontelle Riri Sep 04 '15 at 16:50
  • See my updated answer. It's not tested but please try to inspire yourself from this code – Andrei Boyanov Sep 04 '15 at 16:55
0

here is my code:

def get_employee_slices(self, company_id, date_start, date_end, var, context=None):
    res_list=[]
    i = 0
    obj2 = company_id.id
    payslip_line = self.pool.get('hr.payslip')
    obj_ids = payslip_line.search(self.cr, self.uid, [('date_from', '=', date_start), ('date_to', '=', date_end), ('company_id', '=', obj2)])
    for res in payslip_line.read(self.cr, self.uid, obj_ids, ['id', 'employee_id','seetek_worked_day','hours_overtime_100','seetek_absence_day','total_brut','retenue_source','net_payer'], context=False):
        print res['employee_id'][1]
        obj = {}
        obj['name'] = res['employee_id'][1]
        res_list.append(obj)
    taille = len (res_list)
    while i < taille:
        print i
        i = i +1
        return i

And the RML:

 <section>
    <para>
    [[ repeatIn(get_employee_slices(example.company_id,
                                    example.date_start,
                                    example.date_end,
                                    5),
                'slice') ]]
</para>
<blockTable colwidths="150,100,100,100,100,100" style="Table1">

  <tr>
<td>

      <para style="P8">NOM EMPLOYÉ</para>
    </td>
    <td>

      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end, slice, 5), 'o', 'td') ]]</para>

      <para style="P7">[[ o['name'] ]]</para>
    </td>      
  </tr>
  <tr>
<td>
      <para style="P8">Matricule</para>
    </td>
    <td>
      <para style="P7">[[ repeatIn(get_employee_lines(example.company_id,example.date_start,example.date_end), 'p', 'td') ]]</para>
      <para style="P7">[[ p['matricule'] ]]</para>
    </td>      
  </tr>
0

Of course, there is a better solution. Instead of calling first a method giving you the number of slices and after that, calling N times another method returning some part of you employees, you can just modify your existing get_employee_lines in such a way to return you a 2-dimentional array with the required number of values in each row.

You modified method should be something like this:

def get_employee_lines(self, company, date_start, date_end,
                        columns, context=None):

    payslip_pool = self.pool.get('hr.payslip')
    payslip_ids = payslip_pool.search(self.cr, self.uid,
                                       [('date', '>=', date_start),
                                        ('date', '<=', date_end),
                                        ('company_id', '=', company.id)])
    records = payslip_line.read(self.cr, self.uid, payslip_ids,
                                ['id', 'employee_id',
                                 'seetek_worked_day',
                                 'hours_overtime_100',
                                 'seetek_absence_day',
                                 'total_brut',
                                 'retenue_source',
                                 'net_payer'],
                                context=context)
    rows_count = int(len(records) / columns) + \
                    (len(records) % columns > 0 and 1 or 0)
    result = [list()] * rows_count
    for i in xrange(rows_count):
        for j in xrange(columns):
            if len(records) <= 0:
                break
            result[i].append(records.pop())
    return result 

Then you can use it in your RML report in the following way:

<section>
    <para>
        [[ repeatIn(get_employee_lines(example.company_id,
                                        example.date_start,
                                        example.date_end,
                                        5),
                    "row") ]]
    </para>
        <blockTable colwidths="150,100,100,100,100,100" style="Table1">
        <tr>
            <td>
                <para style="P8">NOM EMPLOYÉ</para>
            </td>
            <td>
                <para style="P7">
                    [[ repeatIn( row ), 'employee', 'td') ]]
                </para>
                <para style="P7">[[ employee['employee_id'][1] ]]</para>
            </td>      
        </tr>
        <tr>
            <td>
                <para style="P8">Matricule</para>
            </td>
            <td>
                <para style="P7">
                    [[ repeatIn(row, 'employee', 'td') ]]
                </para>
                <para style="P7">[[ employee['matricule'] ]]</para>
            </td>      
        </tr>
        <!-- .... -->
    </blockTable>
</section>

Again, it's not tested. It's up to you to test it and tune it according your needs.

Andrei Boyanov
  • 2,309
  • 15
  • 18