Technical Training -Part 11-

Alhamdulillah penulis bisa melanjutkan kembali serial tutorial technical training sampai dengan bagian yang ke 11. In syaa Allah pada pertemuan kali ini penulis akan membahas tentang pembuatan report RML dan Webkit pada object training kita.

Seperti kita ketahui sebelumnya, penulis sudah pernah membahas pembuatan report dengan menggunakan RML disini dan juga Webkit disini. Akan tetapi saat ini, kita akan membuat kedua jenis report tersebut berkaitan dengan object training kita.

Pertama yang kita lakukan adalah membuat sebuah file baru yang diberi nama dengan “training_openerp_report.xml” dan jangan lupa untuk menyertakan file tersebut kedalam file __openerp__.py seperti ini :


    "update_xml":[
                  "training_openerp_report.xml",
                  "training_openerp_view.xml", 
                  "training_openerp_workflow.xml",
                  "ir.model.access.csv"
                  ],

Lalu kita isi file “training_openerp_report.xml” dengan action report RML dan Webkit seperti ini :


<?xml version="1.0"?>
<openerp>
	<data>
 
		<report id="report_sesi" string="Report Sesi" 
				model="training.sesi" name="rml.sesi" 
				rml="training_openerp/report/report_sesi.rml"
				auto="False" menu="False"/>

		<report id="report_kursus"  string="Report kursus" 
				model="training.kursus" name="webkit.kursus" 
				file="training_openerp/report/report_kursus.mako" 
				report_type="webkit" auto="False" menu="False"/>
		
	</data>
</openerp>


Selanjutnya kita akan buatkan button yang akan mentrigger action tersebut yang dilakukan oleh user pada kedua object yaitu form kursus dan form sesi.



		<record model="ir.ui.view" id="sesi_form_view">
		     <field name="name">training.sesi.form</field>
		     <field name="model">training.sesi</field>
		     <field name="arch" type="xml">
		         <form string="Form Sesi" version="7.0">
					<header>
                        <button name="draft_sesi" states="confirmed" string="Reset to Draft" icon="terp-stock_effects-object-colorize"/>
	           			<button name="confirm_sesi" states="draft" string="Confirm" icon="gtk-apply"/>
                        <button name="done_sesi" states="confirmed" string="Mark as done" icon="gtk-apply"/>
	           			<button name="%(report_sesi)d" string="Print Report" states="done" type="action" icon="gtk-print"/>
						<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,done" statusbar_colors='{"draft":"red","confirmed":"blue"}'/>
	                </header>                                
					<sheet>
						<group col="4">
							<field name="name" colspan="4"/>
							<field name="instructur_id" />
							<field name="kursus_id"/>
							<field name="tanggal_mulai" />
							<field name="durasi"/>
							<field name="kursi" on_change="onchange_hitung_kuota(kursi, peserta_ids)"/>
							<field name="active"/>
							<field name="kuota_kehadiran_persen" widget="progressbar" colspan="4"/>
							<field name="image"  widget="image" class="oe_avatar oe_left"/>
						</group>
						<separator string="Peserta" colspan="4"/>
						<field name="peserta_ids" colspan="4" nolabel="1" on_change="onchange_hitung_kuota(kursi, peserta_ids)">
							<tree string="Peserta" editable="top">
								<field name="peserta_id"/>
							</tree>
						</field>
					</sheet>
		         </form>
		     </field>
		</record>
		 


		<record model="ir.ui.view" id="kursus_form_view">
		    <field name="name">training.kursus.form</field>
		    <field name="model">training.kursus</field>
		    <field name="arch" type="xml">
		        <form string="Form Kursus" version="7.0">
		        	<header>
                    	<button name="report_kursus" string="Print Report" type="object" icon="gtk-print"/>
					</header>
		            <group>
		                <field name="name" />
		                <field name="koordinator_id" />
		            </group>
		            <notebook colspan="4">
		                <page string="Keterangan">
		                    <field name="keterangan" nolabel="1" colspan="4" />
		                </page>
		                <page string="Sesi">
		                    <field name="sesi_ids" nolabel="1" colspan="4">
		                        <tree string="Sesi Training">
		                            <field name="name"/>
		                            <field name="instructur_id"/>
		                            <field name="tanggal_mulai"/>
		                            <field name="durasi"/>
		                            <field name="kursi"/>
		                        </tree>
		                        <form string="Sesi Training">
		                            <field name="name"/>
		                            <field name="instructur_id"/>
		                            <field name="tanggal_mulai"/>
		                            <field name="durasi"/>
		                            <field name="kursi"/>
		                        </form>
		                    </field>
		                </page>
		            </notebook>
		        </form>
		    </field>
		</record>


Karna button print webkit bertipe object, maka kita harus membuat method pada file python di object ‘training.kursus’ seperti ini :



class Kursus (osv.osv):
    _name = 'training.kursus'

    .........

    def report_kursus(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        datas = {'ids': context.get('active_ids', [])}
        datas['model'] = 'training.kursus'
        datas['form'] = self.read(cr, uid, ids)[0]
 
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'webkit.kursus',
            'report_type': 'webkit',
            'datas': datas,
        }
    
Kursus()



Setelah action dan button siap, selanjutnya kita buatkan file rml dan webkit tersebut, jika kita perhatikan kita membuat path pada kedua file report tersebut didalam folder report (file=”training_openerp/report/report_kursus.mako” dan rml=”training_openerp/report/report_sesi.rml”) sehingga kita harus membuat terlebih dahulu folder report tersebut. Pastikan folder report tersebut telah kita import pada file __init__.py dengan perintah import report.

Selain file __init__.py dan reportnya sendiri (rml dan mako). Kita juga harus membuat sebuah file python yang akan digunakan untuk memparsing data ke report kita. File ini kita beri nama print_report.py dan pastikan telah kita import pada file __init__.py dengan perintah import print_report.

Setelah semua siap, sekarang kita masuk kepada inti pembuatan report yaitu membuat file rml yang telah kita beri nama report_sesi.rml dengan code seperti ini :


<?xml version="1.0"?>
<document filename="Form Sesi.pdf">

  <!-- DEFINISI LAYOUT (Ukuran Kertas) -->
  
  <template pageSize="(595.0, 842.0)" title="Session Report" author="Radio Rodja 756 am (http://radiorodja.com)">
    <pageTemplate id="first">
        
      <!-- Menentukan luas dari canvas yang dapat kita 'tulis' dengan parameter widht & height beserta titik awal penulisan identasi/margin -->
 
      <frame id="first" x1="20.0" y1="485.0" width="538" height="350"/>
      <header>
            <!-- Membuat text/image sesuai dengan presisi yang tepat dengan menggunakan titik koordinat -->
            
			<pageGraphics>
				<setFont name="Helvetica" size="6"/>
				<drawString x="19.0cm" y="1cm"> <pageNumber/></drawString>
			</pageGraphics>
			
		</header>
    </pageTemplate>
  </template>
  
  <!-- DEFINISI STYLE -->
  
  <stylesheet>


	<!-- Mendefiniskan Style Tabel -->
    
    <blockTableStyle id="Table_String">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
    </blockTableStyle>

    
    <blockTableStyle id="List_Order_Reference_Tbl">
      <blockAlignment value="LEFT"/>
      <blockValign value="TOP"/>
        <!-- Kolom ke-1 -->
		<!-- atas --><lineStyle kind="LINEABOVE" colorName="#000000" start="0,0" stop="0,0"/>
		<!-- kanan --><lineStyle kind="LINEBEFORE" colorName="#000000" start="1,-1" stop="1,-1"/>
		<!-- bawah --><lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
		<!-- kiri --><lineStyle kind="LINEBEFORE" colorName="#000000" start="0,0" stop="0,0"/>
		<!-- Kolom ke-2 -->
		<!-- atas --><lineStyle kind="LINEABOVE" colorName="#000000" start="1,0" stop="1,0"/>
		<!-- kanan --><lineStyle kind="LINEBEFORE" colorName="#000000" start="2,-1" stop="2,-1"/>
		<!-- bawah --><lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
		<!-- kiri --><lineStyle kind="LINEBEFORE" colorName="#000000" start="1,0" stop="1,0"/>
    </blockTableStyle>
    
    <initialize>
      <paraStyle name="all" alignment="justify"/>
    </initialize>
       
	<!-- Mendefinisikan Style Huruf -->
    
    <paraStyle name="terp_header" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_table_header" fontName="Helvetica-Bold" fontSize="7.0" leading="8" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
    <paraStyle name="terp_default" fontName="Helvetica" fontSize="7.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
    
    <images/>
  </stylesheet>
  
  <!-- DEFINISI DATA -->
  <story>
  <pto>
 
    <!-- DEFINISI OBJECT ALIAS --> 
  
    <para style="terp_default">[[repeatIn(objects, 'sesi')]] </para>


	<!-- Membuat Judul Report -->
     
    <blockTable colWidths="500.0" style="Table_String">
      <tr><td><para style="terp_header">REPORT SESI</para></td></tr>
    </blockTable>

	<!-- Membuat Header Report -->
    
    <blockTable colWidths="380.0,120.0" style="Table_String">
      <tr>
        <td>
          <para style="terp_default">Judul Sesi : [[ sesi.name ]]</para>
          <para style="terp_default">Instruktur : [[ sesi.instructur_id.name ]]</para>
          <para style="terp_default">Jumlah Kursi : [[ sesi.kursi ]]</para>
        </td>
        <td>
          <para style="terp_default">Kursus : [[ sesi.kursus_id.name ]]</para>
          <para style="terp_default">Tanggal Mulai : [[ sesi.tanggal_mulai ]]</para>
          <para style="terp_default">Durasi : [[ sesi.durasi ]]</para>
        </td>
      </tr>
    </blockTable>
    
	<!-- Membuat Gap/Space Baris Kosong -->
    
	<para style="terp_default"><font color="white">1</font></para>
    
	<!-- Membuat Header Tabel Peserta -->
    
    <blockTable colWidths="350.0,150.0" repeatRows="1" style="List_Order_Reference_Tbl">
      <tr>
        <td><para style="terp_table_header">PESERTA</para></td>
        <td><para style="terp_table_header">PHONE</para></td>
      </tr>
    </blockTable>
    
    <!-- Membuat Looping Data Tabel Peserta (Element Section) -->
    
    <section>
      
	  <para style="terp_default">[[ repeatIn(sesi.peserta_ids, 'x') ]]</para>
      
	  <blockTable colWidths="350.0,150.0" repeatRows="0" style="List_Order_Reference_Tbl">
        <tr>
          <td><para style="terp_default">[[ x.peserta_id.name ]]</para></td>
          <td><para style="terp_default">[[ x.peserta_id.phone ]]</para></td>
        </tr>
      </blockTable>
      
    </section>
    
  </pto>
  </story>
</document>


Untuk melihat referensi ukuran kertas pada rml bisa dilihat disini. Kita lanjutkan dengan membuat file report kedua yaitu report_kursus.mako dengan code seperti ini :


<html>
<head>
<style>

table{
		font-size:10px;
}

#header2 th{
		border-bottom:1px solid #000;
}

</style>
</head>
<body>

    %for o in get_kursus(data):
	<table width="100%">
		<tr>
			<th style='font-size:12pt'>REPORT KURSUS</th>
		</tr>
		<tr>
			<th style='font-size:10pt' align="left">Nama Kursus : ${o.name}</th>
		</tr>
		<tr>
			<th style='font-size:10pt' align="left">Koordinator : ${o.koordinator_id.name}</th>
		</tr>
		<tr>
			<th style='font-size:10pt' align="left">Keterangan : ${o.keterangan}</th>
		</tr>
	</table>
	
	<table width="100%" cellspacing="0" cellpadding="3px">
		<tr>
			<td colspan="12" style="border-bottom:5px double #000;">&nbsp;</td>
		</tr>
		<tr>
			<th style='font-size:12pt'>Name</th>
			<th style='font-size:12pt'>Tanggal Mulai</th>
			<th style='font-size:12pt'>Durasi</th>
			<th style='font-size:12pt'>Kursi</th>
		</tr>
		<tr id="header2">
			<th style='font-size:12pt'>Peserta</th>
			<th>&nbsp;</th>
			<th>&nbsp;</th>
			<th>&nbsp;</th>
		</tr>
		%for i in o.sesi_ids:
		<tr>
			<td style='font-weight:bold; font-size:10pt' align="center">${i.name}</td>
            <td style='font-weight:bold; font-size:10pt' align="center">${time.strftime('%d %B %Y', time.strptime(i.tanggal_mulai,'%Y-%m-%d'))}</td>
			<td style='font-weight:bold; font-size:10pt' align="center">${i.durasi}</td>
            <td style='font-weight:bold; font-size:10pt' align="center">${i.kursi}</td>
		</tr>
			%for x in i.peserta_ids: 
			<tr>
				<td>${x.peserta_id.name}</td>
			</tr>
			%endfor
		%endfor	
	</table>
	%endfor
   
</body>
</html>

Jika kita perhatikan pada kedua coding report diatas baik rml maupun webkit, disana ada beberapa method dan library yang digunakan yaitu time dan get_kursus(). Inilah fungsi dari file parser yang telah kita buat yaitu print_report.py yang akan kita isi seperti ini :


import time
from report import report_sxw

class ParserStatus(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context):
        super(ParserStatus, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
            'get_kursus': self.get_kursus,
        }) 
        
    def get_kursus(self, form):     
        data = self.pool.get('training.kursus').browse(self.cr, self.uid, [form['form']['id']])
        return data
            
report_sxw.report_sxw('report.rml.sesi', 'training.sesi', 'addons/training_openerp/report/report_sesi.rml', parser = ParserStatus, header = False)
report_sxw.report_sxw('report.webkit.kursus', 'training.kursus', 'addons/training_openerp/report/report_kursus.mako', parser = ParserStatus, header = False)


Alhamdulillah kita telah menyelesaikan pembuatan report baik rml maupun webkit pada modul training kita. Tutorial kali ini adalah tutorial yang terakhir dan menjadi penutup serial technical training kita. Mudah-mudahan apa yang sedikit penulis sampaikan ini bisa memberikan banyak manfaat khususnya bagi mereka yang ingin mengimplementasikan OpenERP sesuai dengan sektor bisnisnya masing-masing.

Akhir kata penulis ucapkan permohonan maaf jika selama ini ada kata-kata yang salah dan pertanyaan yang tidak bisa dijawab oleh penulis. Penulis juga ucapkan banyak terima kasih atas partisipasi, kritik dan saran yang selama ini ditujukan kepada penulis. Semoga bermanfaat …

NB : Technical Memento v7 (Pedoman Programmer)

4 thoughts on “Technical Training -Part 11-

  1. banyak sekali manfaat yang saya dapat dari tutorial Technical Training ini, saya sama sekali awam tentang phyton dan OpenERP, berkat tutorial ini, Alhamdulillah sedikit banyak bisa saya kuasai, insyaa Allah bermanfaat buat diri saya dan orang di sekitar saya, dan semoga amal kebaikan terus mengalir ke diri penulis.

  2. Mas Aziz.. setelah kembali saya meneruskan trainingnya..pada bagian ini sudah saya ikuti semua coding nya.. setelah dijalankan muncul pesan error seperti ini..dibagian print report kursus terdapat error “AttributeError: ‘Kursus’ object has no attribute ‘report_kursus'” dan untuk print report sesi terdapat error “Uncaught SyntaxError: Unexpected end of input
    http://localhost:8069/?db=devcompany2&ts=1423802238707#id=8&view_type=form&model=training.sesi&menu_id=268&action=319:0“… mohon pencerahan.. thanx

Leave a reply to aldenz Cancel reply