Odoo – Membuat Controller Bag 2

Pada bagian pertama kita sudah membahas bagaimana membuat controller pada Odoo sebagai service api. Pada bagian ini kita akan membuat controller untuk merender view (tampilan html) dan mengolah input user.

Render view dari 0

Odoo sudah menyediakan template untuk view, dimana file jquery, bootstrap dan file-file lainnya sudah diload, terutama jika kita meng-install module website. Tapi pada bagian ini kita akan membahas terlebih dahulu bagaimana membuat view dari 0, tanpa meng-inherit view dari module website.

Pertama buat controller.

@http.route('/sale/list', type='http')
def get_sale_list(self, **kwargs):

    orders = request.env['sale.order'].sudo().search([])

    data = {
        'orders' : orders 
    }
    
    return request.render('tutorial_controller.sale_list', data)

Perhatikan method render diatas. Parameter pertama adalah view / template yang akan kita render. Format penulisannya adalah nama_module.id_template_view. Sedangkan parameter kedua adalah data yang akan kita kirim ke view dengan tipe data berupa dictionary.

Selanjutnya kita buat view / template-nya.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
	<template id="sale_list" name="Daftar Sales">&lt;!DOCTYPE html&gt;
		<html>
			<head>
				<title>Latihan Controller Odoo</title>

				<!-- CDN Asset -->
				<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
				<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

				<!-- Custom Asset -->
				<link rel="stylesheet" href="/tutorial_controller/static/css/custom.css"/>
				<script type="text/javascript" src="/tutorial_controller/static/js/custom.js"></script>
			</head>
		</html>
		<body>
			<div class="container">
				<div class="row">
					<div class="col-12">
						<h2 class="sale-title">Daftar Sales Order</h2>
						<table class="table table-hover">
							<tr>
								<th>No Dokumen</th>
								<th>Customer</th>
								<th>Total</th>
								<th>Action</th>
							</tr>
							<t t-foreach="orders" t-as="order">
								<tr>
									<td>
										<t t-esc="order.name" />
									</td>
									<td>
										<t t-esc="order.partner_id.name" />
									</td>
									<td>
										<t t-esc="order.amount_total" />
									</td>
									<td>
										<button class="btn btn-sm btn-danger btn-delete-sale" t-att-data-sale-number="order.name">Delete</button>
									</td>
								</tr>
							</t>
						</table>
					</div>
				</div>
			</div>
		</body>
	</template>
</odoo>

Pada satu module, id suatu template / view harus unik. Misal pada kode diatas kita menggunakan id sale_list. Maka kita tidak bisa menggunakan id ini di file lain di module yang sama, tetapi bisa digunakan di module yang berbeda. Oleh karena itu dicontroller saat kita me-render view kita perlu memasukkan nama module-nya.

Untuk me-load file css dan javascript format penulisan path-nya adalah /nama_module/nama_folder_dan_nama_file. Dan pastikan module yang terdapat file tersebut sudah diinstall.

Untuk menampilkan data dari controller di view kita menggunakan Qweb templating. Qweb adalah templating bawaan odoo untuk mengolah html. Klik link berikut untuk lebih tahu mengenai Qweb

Jika kita membuka http://localhost:8069/sale/list kira-kira tampilannya akan seperti ini

Inherit dari module Website

Untuk membuat view yang inherit ke module website, kita perlu menambahkan parameter website di controller. Misalnya seperti ini.

@http.route('/web/sale/list', type='http', website=True)
def get_web_sale_list(self, **kwargs):

    orders = request.env['sale.order'].sudo().search([])

    data = {
        'orders' : orders 
    }
    
    return request.render('tutorial_controller.website_sale_list', data)

Perlu kita ketahui module website sudah me-load file bootstrap, jquery dll di template website.assets_frontend jadi kita perlu inherit ke template tersebut untuk memasukkan file css dan javascript custom milik kita. Seperti ini contohnya.

<template id="assets_frontend_inherit" inherit_id="website.assets_frontend">
	<!-- masukkan file css custom paling bawah -->
    <xpath expr="link[last()]" position="after">
        <link rel="stylesheet" href="/tutorial_controller/static/css/custom.css"/>
    </xpath>
    <!-- masukkan file javascript custom paling bawah -->
    <xpath expr="script[last()]" position="after">
        <script type="text/javascript" src="/tutorial_controller/static/js/custom.js"></script>
    </xpath>
</template>

Terakhir adalah membuat view. Yang perlu anda perhatikan adalah jangan lupa memanggil template website.layout agar navbar dan menu-menu-nya tampil. Seperti kode dibawah ini

<template id="website_sale_list" name="Daftar Sales Website">
	<!-- panggil view website.layout agar navbar dll tampil -->
    <t t-call="website.layout">
    	<!-- tambah judul halaman -->
    	<t t-set="additional_title" t-value="'Daftar Sales'" />
        <div id="wrap">
            <div class="container">
				<div class="row">
					<div class="col-12">
						<h2 class="sale-title">Daftar Sales Order</h2>
						<table class="table table-hover">
							<tr>
								<th>No Dokumen</th>
								<th>Customer</th>
								<th>Total</th>
								<th>Action</th>
							</tr>
							<t t-foreach="orders" t-as="order">
								<tr>
									<td>
										<t t-esc="order.name" />
									</td>
									<td>
										<t t-esc="order.partner_id.name" />
									</td>
									<td>
										<t t-esc="order.amount_total" />
									</td>
									<td>
										<button class="btn btn-sm btn-danger btn-delete-sale" t-att-data-sale-number="order.name">Delete</button>
									</td>
								</tr>
							</t>
						</table>
					</div>
				</div>
			</div>
        </div>
    </t>
</template>

Tampilan akhirnya akan jadi seperti ini.

Menangani Form

Buat 2 controller. Controller pertama berfungsi untuk merender form, sedangkan controller kedua untuk mengolah data-nya.

@http.route('/sale/support', type='http', website=True)
def sale_support(self, **kwargs):
    # controller ini hanya untuk merender form
    return request.render('tutorial_controller.sale_support')

@http.route('/sale/support/response', type='http', website=True)
def sale_support_response(self, **kwargs):
    # controller ini untuk menerima input user
    # input user disimpan di parameter kwargs singkatan dari keyword argument
    # kwargs ini bisa diganti dengan nama lain misal post atau data
    # kwargs bertipe distionary

    data = {
        'name' : kwargs.get('name',''),
        'email' : kwargs.get('email',''),
        'issue' : kwargs.get('issue','')
    }
    
    return request.render('tutorial_controller.sale_support_response', data)

Selanjutnya buat 2 buah view juga.

<template id="sale_support" name="Sales Support">
    <t t-call="website.layout">
        <t t-set="additional_title" t-value="'Sales Support'" />
        <div id="wrap">
            <div class="container">
                <div class="row">
                    <div class="col-12">
                        <h2 class="sale-title">Sales Support</h2>   
                        <form action="/sale/support/response" method="post">
                            <!-- 
                                set csrf token, agar lebih secure,
                                jika tidak diset, pastikan pada controller paremeter csrf diset False
                            -->
                            <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
                            <div class="row">
                                <div class="col-md-6">
                                    <div class="form-group">
                                        <label class="col-form-label">Nama</label>
                                        <input type="text" name="name" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="form-group">
                                        <label class="col-form-label">Email</label>
                                        <input type="email" name="email" class="form-control" />
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-12">
                                    <div class="form-group">
                                        <label class="col-form-label">Keluhan</label>
                                        <textarea rows="5" class="form-control" name="issue"></textarea>
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-12">
                                    <button type="submit" class="btn btn-success">Kirim</button>
                                </div>
                            </div>
                        </form>                     
                    </div>                      
                </div>
            </div>
        </div>
    </t>
</template>

<template id="sale_support_response" name="Sales Support Response">
    <t t-call="website.layout">
        <t t-set="additional_title" t-value="'Sales Support'" />
        <div id="wrap">
            <div class="container">
                <div class="row">
                    <div class="col-12">
                        <h2 class="sale-title">Sales Support</h2>   
                        <h3>Terima kasih atas feedback anda. Berikut ini adalah data yang anda masukkan</h3>
                        <h3>Nama : <t t-esc="name"/></h3>
                        <h3>Email : <t t-esc="email"/></h3>     
                        <h3>Keluhan : <t t-esc="issue"/></h3>   
                    </div>                      
                </div>
            </div>
        </div>
    </t>
</template>

Jika kita ketik alamat http://localhost:8069/sale/support akan muncul form seperti dibawah ini.

Jika kita isi dan klik tombol kirim akan diarahkan ke halaman http://localhost:8069/sale/support/response dengan tampilan seperti dibawah ini.

Demikian tutorial controller pada odoo bagian kedua ini. Jika ada kesempatan pada bagian selanjutnya kita akan membahas bagaimana menangani file upload dan download serta cara override controller atau view yang sudah ada.

Download Source Code

Leave a Reply

Your email address will not be published. Required fields are marked *