Print Multi Record Dengan 1 Halaman

Pada beberapa tampilan berupa list / tree dalam setiap menu, Odoo telah menyiapkan fitur default untuk mencetak laporan saat kita memilih (menceklist) beberapa record atau baris data. Hasil laporan yang dicetak sebenarnya sama seperti kita mencetak laporan dalam bentuk form view, bedanya disini kita bisa meringkas waktu tanpa harus membukanya pada setiap form & hasilnya sudah langsung otomatis menjadi gabungan beberapa halaman.

Akan tetapi sebagian kita tidak mengharapkan hal seperti itu. Hasil yang diharapkan adalah beberapa record data yang telah di ceklist menjadi 1 template atau header yang sama. Untuk itu, penulis mencoba berbagi tips untuk melakukan fitur ini. Dalam hal ini, penulis masih setia menggunakan rml ketimbang qweb yang menjadi syntax default dalam setiap laporan Odoo semenjak v8.

Tutorial ini adalah salah satu ‘request’ dari anggota group Odoo di aplikasi telegram. Untuk mendaftarkan diri dan bergabung dengan para profesional baik dari konsultan, praktisi, developer, dosen, mahasiswa dll. Bisa di baca pada halaman ini. Insya Allah sangat bermanfaat.

Untuk awalan, buatlah sebuah folder dengan nama ‘aa_print_muti_invoice’. Nama ini silahkan disesuaikan dengan kebutuhan anda. Selanjutnya buatlah 2 file utama, yaitu __init__.py dan __openerp__.py. Untuk penjelasannya bisa di review kembali pada hal ini.

Setelah itu kita membuat file xml dengan nama ‘multi_view.xml’, nama file ini juga silahkan disesuaikan dengan kebutuhan anda. Jangan lupa untuk memanggil file ‘multi_view.xml’ pada keyword update_xml di file __openerp__.py. Isi dari file ‘multi_view.xml’ adalah sebagai berikut :


<?xml version="1.0" encoding="utf-8"?>
<openerp>
	<data>

		
		<report
            auto="False"
            id="cetak_tagihan_sum"
            model="account.invoice"
            name="cetak.tagihan.sum"
            rml="aa_print_muti_invoice/cetak_tagihan_sum.rml"
            string="Tagihan"
            usage="default"
            />
        
		
		        
        			
	</data>
</openerp>



Fungsi dari syntax diatas adalah kita membuat sebuah button print dengan label ‘Tagihan’ didalam setiap button ‘PRINT’ pada tampilan list view.

Selanjutnya kita buat file python dengan nama ‘multi.py’, dan pastikan file python ini telah di import di dalam file __init__.py. Isi dari file ‘multi.py’ seperti dibawah ini :


import re
import time
from openerp.report import report_sxw

class journal_print(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context):
        super(journal_print, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
            'koma': self.FormatWithCommas,
            'get_no': self.get_no,
            'getall': self.getall,
            'semua': self.semua,
        }) 

        self.no = 0; self.semua = []; self.grandtotal = 0         
        self.re_digits_nondigits = re.compile(r'\d+|\D+')

    def getall(self, dat):
        nama = ''; product = []; invoice = ''; tot = 0; partner = []
        
        for s in dat:
            partner.append(s.partner_id.id)
                
        if len(set(partner)) == 1:        
            for x in dat:
                if x.state == 'paid':
                    invoice = x
                    nama += x.number + '; '
                    for i in x.invoice_line:
                        tot += i.price_subtotal
                        product.append({
                                        'name': i.name,
                                        'invoice': x.number,
                                        'periode': x.period_id.name,
                                        'quantity': i.quantity,
                                        'uom': i.uos_id.name,
                                        'price_unit': i.price_unit,
                                        'price_subtotal': i.price_subtotal
                                        })
            
        self.semua = [nama, product, tot]     
        return [invoice]
    
    def semua(self):
        return self.semua
                    
    def get_no(self):
        self.no = self.no + 1
        return self.no               
        
    def FormatWithCommas(self, format, value):
        parts = self.re_digits_nondigits.findall(format % (value,))
        for i in xrange(len(parts)):
            s = parts[i]
            if s.isdigit():
                parts[i] = self.commafy(s)
                break        
        return ''.join(parts)
    
    def commafy(self, s):
        r = []
        for i, c in enumerate(reversed(s)):
            if i and (not (i % 3)):
                r.insert(0, ',')
            r.insert(0, c)
        return ''.join(r)

        
report_sxw.report_sxw('report.cetak.tagihan.sum', 'account.invoice', 'addons/aa_print_muti_invoice/cetak_tagihan_sum.rml', parser=journal_print, header=False)


Fungsi dari file ini adalah untuk memparsing data antara odoo & report rml. Jika kita lihat pada bagian atas, disana terdapat dictionary dengan beberapa key dan value nya. Seperti contoh ‘getall’: self.getall’. Elemen key akan digunakan pada sisi rml, sedangkan elemen value kita gunakan pada bagian python ini.

Diantara fungsi dari beberapa elemen diatas adalah untuk membuat nomor urut, membuat separator / pecahan mata uang, parsing data, dst.

Terakhir, adalah membuat file rml untuk mencetak laporan. Dan file rml ini telah kita panggil sebelumnya pada 2 file diatas, yaitu multi.py dan multi_view.xml. Nama dari file rml itu adalah ‘cetak_tagihan_sum.rml’ yang kita isi dengan syntax dibawah ini :



<?xml version="1.0"?>
<document filename="Invoices.pdf">
  <template pageSize="(23cm,15cm)" title="Invoices" author="Muhammad Azis (abdulaziz.sbs@gmail.com)" allowSplitting="20">
    <pageTemplate id="first">
      <frame id="first" x1="1.0cm" y1="2.0cm" width="20cm" height="13cm"/>
      	<header>
			<pageGraphics>
				<setFont name="Helvetica" size="7"/>
				<drawString x="19.0cm" y="1cm">Hal <pageNumber/></drawString>
				<image x="1.2cm" y="13.4cm" height="35.0" >[[ company.logo or removeParentNode('image') ]]</image>
				<setFont name="Helvetica-Bold" size="12"/>
				<drawString x="3.4cm" y="14.2cm">PT. Company</drawString>
				<setFont name="Helvetica" size="7"/>
			    <drawString x="3.4cm" y="13.9cm">Jl. Jalan Raya</drawString>
			    <drawString x="3.4cm" y="13.6cm">Phone : 021-8888888   Fax : 021-8888888</drawString>
			    
			</pageGraphics>
		</header>
    </pageTemplate>
  </template>
      
  <stylesheet>
    
    <blockTableStyle id="Table_Partner_Address">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
    </blockTableStyle>
    
    <blockTableStyle id="Table_Invoice_General_Header">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="0,0" stop="0,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="1,0" stop="1,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="1,0" stop="1,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="2,0" stop="2,-1"/>
      <lineStyle thickness="0.5" kind="LINEAFTER" colorName="#000000" start="2,0" stop="2,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="2,0" stop="2,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="3,0" stop="3,-1"/>
      <lineStyle thickness="0.5" kind="LINEAFTER" colorName="#000000" start="3,0" stop="3,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="3,0" stop="3,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="4,0" stop="4,-1"/>
      <lineStyle thickness="0.5" kind="LINEAFTER" colorName="#000000" start="4,0" stop="4,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="4,0" stop="4,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="5,0" stop="5,-1"/>
      <lineStyle thickness="0.5" kind="LINEAFTER" colorName="#000000" start="5,0" stop="5,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="5,0" stop="5,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="6,0" stop="6,-1"/>
      <lineStyle thickness="0.5" kind="LINEAFTER" colorName="#000000" start="6,0" stop="6,-1"/>
      <lineStyle thickness="0.5" kind="LINEABOVE" colorName="#000000" start="6,0" stop="6,0"/>
      <lineStyle thickness="0.5" kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
    </blockTableStyle>
    
	<blockTableStyle id="Table23456">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="0,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="1,0" stop="1,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="1,0" stop="1,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="2,0" stop="2,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="2,0" stop="2,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="3,0" stop="3,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="3,0" stop="3,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="4,0" stop="4,-1"/>
      <lineStyle kind="LINEAFTER" colorName="#000000" start="4,0" stop="4,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="4,0" stop="4,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="5,0" stop="5,-1"/>
      <lineStyle kind="LINEAFTER" colorName="#000000" start="5,0" stop="5,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="5,0" stop="5,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="6,0" stop="6,-1"/>
      <lineStyle kind="LINEAFTER" colorName="#000000" start="6,0" stop="6,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="6,0" stop="6,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
      <lineStyle kind="LINEBEFORE" colorName="#000000" start="7,0" stop="7,-1"/>
      <lineStyle kind="LINEAFTER" colorName="#000000" start="7,0" stop="7,-1"/>
      <lineStyle kind="LINEABOVE" colorName="#000000" start="7,0" stop="7,0"/>
      <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
    </blockTableStyle>
	
    <blockTableStyle id="Table21">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="0,0" stop="0,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="1,0" stop="1,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="2,0" stop="2,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="3,0" stop="3,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="4,0" stop="4,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="5,0" stop="5,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="6,0" stop="6,-1"/>
      <lineStyle thickness="0.5" kind="LINEBEFORE" colorName="#000000" start="7,0" stop="7,-1"/>
    </blockTableStyle>

    <initialize>
      <paraStyle name="all" alignment="justify"/>
    </initialize>

    <paraStyle name="terp_default_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default_Center_7" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default_7_BoldItalic" rightIndent="0.0" leftIndent="0.0" fontName="Times-BoldItalic" fontSize="10.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default_Bold_Centre_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default_Right_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default_Bold_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica-Bold" fontSize="8.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>    
    <paraStyle name="terp_tblheader_Details_right" fontName="Helvetica-Bold" fontSize="12.0" leading="11" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
    <paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="1.0"/>
    
    <images/>
  </stylesheet>
  <story>
  <pto>
    <para style="terp_default_8">[[ repeatIn(getall(objects),'o') ]]</para>
    <para style="terp_default_8">[[ setLang(o.partner_id.lang) ]]</para>
    <pto_header><!-- Must be after setLang() -->
    
    <para style="terp_tblheader_Details_Centre"><font color="white">ORDER</font></para>
    <para style="terp_tblheader_Details_Centre"><font color="white">ORDER</font></para>
    <para style="terp_tblheader_Details_Centre"><font color="white">ORDER</font></para>
    <para style="terp_tblheader_Details_Centre"><font color="white">ORDER</font></para>
    
    <blockTable colWidths="25.0,160.0,80.0,60.0,60.0,80.0,90.0" style="Table_Invoice_General_Header">
    <tr>
        <td> <para style="terp_default_Bold_Centre_8">No. </para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Keterangan</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Invoice</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Periode</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Qty</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Harga</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Subtotal</para> </td>
    </tr>
    </blockTable>
    
    </pto_header>


    <blockTable colWidths="500.0" style="Table_Partner_Address">
    <tr>
	    <td>
	      <para style="terp_tblheader_Details_right"><font color="white">ORDER</font></para>
	      <para style="terp_tblheader_Details_right"><font color="white">ORDER</font></para>
	      <para style="terp_tblheader_Details_Centre">INVOICE</para>
	    </td>
    </tr>
    </blockTable>
    
    <para style="terp_default_8"><font color="white">:</font></para>
    

    <blockTable colWidths="35.0,10.0,290.0,70.0,10.0,140.0" style="Table_Partner_Address">
      <tr>
        <td>
		  <para style="terp_default_8">Tanggal</para>
          <para style="terp_default_8">Partner</para>
        </td>
        <td>
		  <para style="terp_default_8">:</para>
          <para style="terp_default_8">:</para>
        </td>
        <td>
		  <para style="terp_default_8">[[ time.strftime('%d %B %Y') ]]</para>
          <para style="terp_default_8">[[ o.partner_id.name ]] </para>
        </td>
        <td>
          <para style="terp_default_8">Akun</para>
          <para style="terp_default_8">Jurnal</para>
        </td>
        <td>
          <para style="terp_default_8">:</para>
          <para style="terp_default_8">:</para>
        </td>
        <td>
          <para style="terp_default_8">[[ o.account_id.name ]]</para>
          <para style="terp_default_8">[[ o.journal_id.name ]]</para>
        </td>
      </tr>
    </blockTable>
        
    <para style="terp_default_8"><font color="white">:</font></para>
    
    <blockTable colWidths="25.0,160.0,80.0,60.0,60.0,80.0,90.0" style="Table_Invoice_General_Header">
    <tr>
        <td> <para style="terp_default_Bold_Centre_8">No. </para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Keterangan</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Invoice</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Periode</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Qty</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Harga</para> </td>
        <td> <para style="terp_default_Bold_Centre_8">Subtotal</para> </td>
    </tr>
    </blockTable>
    
    <section>
    <para style="terp_default_8">[[repeatIn(semua()[1], 'i')]]</para>
    <blockTable colWidths="25.0,160.0,80.0,60.0,60.0,80.0,90.0" style="Table21">
	    <tr>
	      <td><para style="terp_default_8">[[ get_no() ]]</para></td>
	      <td><para style="terp_default_8">[[ i['name'] ]]</para></td>
	      <td><para style="terp_default_8">[[ i['invoice'] ]]</para></td>
	      <td><para style="terp_default_8">[[ i['periode'] ]]</para></td>
	      <td><para style="terp_default_Right_8">[[ koma('%.0f', i['quantity']) ]]   [[ i['uom'] ]]</para></td>
	      <td><para style="terp_default_Right_8">[[ koma('%.0f', i['price_unit']) ]]</para></td>
	      <td><para style="terp_default_Right_8">[[ koma('%.0f', i['price_subtotal']) ]]</para></td>
	    </tr>
    </blockTable>
    </section>
    
    <blockTable colWidths="385.0,80.0,90.0" style="Table_Invoice_General_Header">
    <tr>
        <td linecolor="white">
           <para style="terp_default_8">-</para>
        </td>
        <td>
          <para style="terp_default_8">TOTAL</para>
        </td>
        <td>
          <para style="terp_default_Right_8">[[ koma('%.0f', semua()[2]) ]] </para> 
        </td>
    </tr>
    </blockTable>

    <para style="terp_default_8"><font color="white">:</font></para>
    
        
    <blockTable colWidths="100.0" style="Table_Partner_Address">
	    <tr>
			<td>
			  <blockTable colWidths="100.0" style="Table23456">
				<tr>
					<td><para style="terp_default_Bold_Centre_8">Penerima</para></td>
				</tr>
				<tr>
					<td>
			      		<para style="terp_default_Center_7"><font color="white">t</font></para>
			  			<para style="terp_default_Center_7"><font color="white">t</font></para>
			      		<para style="terp_default_Center_7"><font color="white">t</font></para>
						<para style="terp_default_Center_7">[[ "......................." ]]</para>
					</td>
				</tr>
			  </blockTable>
			</td>
	    </tr>
    </blockTable>
    
  </pto>
  </story>
</document>



Untuk penjelasan file rml diatas, kita bisa mereviewnya pada tutorial ini. Pada rml diatas kita juga mensetting ukuran kertas yaitu A5 atau setengah dari A4.

Inti dari code diatas adalah pada baris ini repeatIn(getall(objects),’o’). Dimana kita tidak langsung melooping data yang di parsing, tetapi ‘menangkap’ nya terlebih dahulu dan mengolahnya didalam sebuah method getall() agar data yang diterima sudah berkelompok.

Pada contoh diatas saya membuat report ini untuk object account.invoice (Customer Invoice), dan cara ini juga bisa dicoba untuk object-object yang lain seperti stock.picking, dan lainnya.

Agar modul terlihat rapih, maka sebaiknya file-file yang telah kita bikin diatas, agar semuanya disatukan dalam folder bernama ‘report’. Dan hasil dari modul diatas seperti berikut ini :

print

Alhamdulillah kita sudah menyelesaikan tutorial ini, untuk mencobanya silahkan di praktekan modul diatas. Selamat mencoba ….

Advertisements

2 thoughts on “Print Multi Record Dengan 1 Halaman

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s