[Odoo 10] Case Study # Travel Umroh -Part 4-

InsyaAllah tulisan ini adalah bagian terakhir dari serial case study travel umroh. Pada tulisan kali ini kita akan membahas menu Paket Perjalanan lebih lanjut.

Pada penjelasan sebelumnya, menu Paket Perjalanan salah satu fungsinya adalah sebagai informasi daftar jamaah umroh yang sudah mendaftar melalui menu Sales Orders. Data jamaah tersebut bisa kita lihat pada tab Jamaah Lines, untuk mengisinya secara otomatis maka kita perlu sebuah method yang akan di jalankan oleh event klik button. Sekarang kita akan lengkapi field tab Jamaah Lines dengan tambahan beberapa field sebagai berikut :



class paket_peserta_line(models.Model):
    _name = "paket.peserta.line"

    paket_perjalanan_id = fields.Many2one('paket.perjalanan', string='Paket Perjalanan', ondelete='cascade')
    partner_id = fields.Many2one('res.partner', string='Jamaah')
    name = fields.Char(string='Name in Passport')
    order_id = fields.Many2one('sale.order', string='Sales Orders')
    jenis_kelamin = fields.Selection([('pria', 'Man'), ('wanita', 'Woman')], string='Gender')
    tipe_kamar = fields.Selection([('d', 'Double'), ('t', 'Triple'), ('q', 'Quad')], string='Room Type')


Selanjutnya kita update file xmlnya dengan tambahan button Update Jamaah:




        <!-- Paket Perjalanan Form View -->

        <record model="ir.ui.view" id="paket_perjalanan_form_view">
            <field name="name">paket.perjalanan.form</field>
            <field name="model">paket.perjalanan</field>
            <field name="arch" type="xml">
                <form string="Form Paket Perjalanan">
                <header>
                    <button name="action_confirm" type="object" string="Confirm" states="draft" groups="aa_travel_umroh.group_paket_perjalanan_manager" class="btn-primary"/>
                    <button name="update_jamaah" type="object" string="Update Jamaah" states="confirm" class="btn-primary"/>
                    <field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
                </header>
                <sheet>
                    <group col="4">
                        <field name="name"/>
                        <field name="product_id"/>
                        <field name="tgl_berangkat"/>
                        <field name="tgl_pulang"/>
                        <field name="quota"/>
                        <field name="quota_progress" widget="progressbar"/>
                    </group>
                    <notebook>
                        <page string="Hotel Lines">
                            <field name="hotel_line">
                                <tree editable="bottom">
                                    <field name="partner_id"/>
                                    <field name="tgl_awal"/>
                                    <field name="tgl_akhir"/>
                                    <field name="kota"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Airline Lines">
                            <field name="pesawat_line">
                                <tree editable="bottom">
                                    <field name="partner_id"/>
                                    <field name="tgl_berangkat"/>
                                    <field name="kota_asal"/>
                                    <field name="kota_tujuan"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Schedule Lines">
                            <field name="acara_line">
                                <tree editable="bottom">
                                    <field name="name"/>
                                    <field name="tgl"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Jamaah Lines">
                            <field name="peserta_line">
                                <tree editable="bottom">
                                    <field name="order_id"/>
                                    <field name="partner_id"/>
                                    <field name="name"/>
                                    <field name="jenis_kelamin" />
                                    <field name="tipe_kamar" />
                                </tree>
                            </field>
                        </page>
                    </notebook>
                    <group>
                        <field name="note" placeholder="Notes" nolabel="1"/>
                    </group>
                </sheet>
                </form>
            </field>
        </record>


Kemudian kita buat methodnya :



class paket_perjalanan(models.Model):
    _name = "paket.perjalanan"

    name = fields.Char(string='Reference', readonly=True, default='/')
    product_id = fields.Many2one('product.product', string='Product', required=True, readonly=True, states={'draft': [('readonly', False)]})
    tgl_berangkat = fields.Date(string='Departure Date', required=True, readonly=True, states={'draft': [('readonly', False)]})
    tgl_pulang = fields.Date(string='Return Date', required=True, readonly=True, states={'draft': [('readonly', False)]})
    quota = fields.Integer(string='Quota', readonly=True, states={'draft': [('readonly', False)]})
    quota_progress = fields.Float(string="Quota Progress", compute='_taken_seats')
    note = fields.Text(string='Notes', readonly=True, states={'draft': [('readonly', False)]})
    hotel_line = fields.One2many('paket.hotel.line', 'paket_perjalanan_id', string='Hotel Lines', readonly=True, states={'draft': [('readonly', False)]})
    pesawat_line = fields.One2many('paket.pesawat.line', 'paket_perjalanan_id', string='Airline Lines', readonly=True, states={'draft': [('readonly', False)]})
    acara_line = fields.One2many('paket.acara.line', 'paket_perjalanan_id', string='Schedule Lines', readonly=True, states={'draft': [('readonly', False)]})
    peserta_line = fields.One2many('paket.peserta.line', 'paket_perjalanan_id', string='Jamaah Lines', readonly=True)
    state = fields.Selection([
        ('draft', 'Draft'),
        ('confirm', 'Confirmed'),
    ], string='Status', readonly=True, copy=False, default='draft', track_visibility='onchange')

    @api.multi
    def action_confirm(self):
        self.write({'state': 'confirm'})

    @api.model
    def create(self, vals):
        vals['name'] = self.env['ir.sequence'].next_by_code('paket.perjalanan')
        return super(paket_perjalanan, self).create(vals)

    @api.multi
    def name_get(self):
        return [(this.id, this.name + "#" + " " + this.product_id.partner_ref) for this in self]

    @api.depends('quota', 'peserta_line')
    def _taken_seats(self):
        for r in self:
            if not r.quota:
                r.quota_progress = 0.0
            else:
                r.quota_progress = 100.0 * len(r.peserta_line) / r.quota

    @api.multi
    def update_jamaah(self):
        order_ids = self.env['sale.order'].search([('paket_perjalanan_id', '=', self.id), ('state', 'not in', ('draft', 'cancel'))])
        if order_ids:
            self.peserta_line.unlink()
            for o in order_ids:
                for x in o.passport_line:
                    self.peserta_line.create({
                        'paket_perjalanan_id': self.id,
                        'partner_id': x.partner_id.id,
                        'name': x.name,
                        'order_id': o.id,
                        'jenis_kelamin': x.partner_id.jenis_kelamin,
                        'tipe_kamar': x.tipe_kamar,
                    })



Setelah kita mengklik button Update Jamaah, maka tab Jamaah Lines akan terisi otomatis seperti gambar berikut :

Terakhir kita akan cetak list jamaah tersebut kedalam file excel, karna data ini nantinya akan diperlukan untuk pembagian kunci kamar hotel. Untuk membuat file excel, python menyediakan beberapa library diantaranya xlwt dan xlsxwriter. Dan di odoo apps sudah ada modul base engine untuk membuat excel report dari kedua library tersebut. Pada tulisan kali ini kita akan gunakan library xlwt dengan menggunakan modul engine yang bisa di download disini. Setelah download, simpan modul di dalam folder addons anda kemudian install modul tersebut. Dan jangan lupa untuk menginstall library xlwt.

Kita update view form dari Paket Perjalanan untuk menambahkan kembali button print seperti berikut :



        <!-- Paket Perjalanan Form View -->

        <record model="ir.ui.view" id="paket_perjalanan_form_view">
            <field name="name">paket.perjalanan.form</field>
            <field name="model">paket.perjalanan</field>
            <field name="arch" type="xml">
                <form string="Form Paket Perjalanan">
                <header>
                    <button name="action_confirm" type="object" string="Confirm" states="draft" groups="aa_travel_umroh.group_paket_perjalanan_manager" class="btn-primary"/>
                    <button name="update_jamaah" type="object" string="Update Jamaah" states="confirm" class="btn-primary"/>
                    <button name="cetak_jamaah_xls" type="object" string="Cetak" class="btn-primary" />
                    <field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
                </header>
                <sheet>
                    <group col="4">
                        <field name="name"/>
                        <field name="product_id"/>
                        <field name="tgl_berangkat"/>
                        <field name="tgl_pulang"/>
                        <field name="quota"/>
                        <field name="quota_progress" widget="progressbar"/>
                    </group>
                    <notebook>
                        <page string="Hotel Lines">
                            <field name="hotel_line">
                                <tree editable="bottom">
                                    <field name="partner_id"/>
                                    <field name="tgl_awal"/>
                                    <field name="tgl_akhir"/>
                                    <field name="kota"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Airline Lines">
                            <field name="pesawat_line">
                                <tree editable="bottom">
                                    <field name="partner_id"/>
                                    <field name="tgl_berangkat"/>
                                    <field name="kota_asal"/>
                                    <field name="kota_tujuan"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Schedule Lines">
                            <field name="acara_line">
                                <tree editable="bottom">
                                    <field name="name"/>
                                    <field name="tgl"/>
                                </tree>
                            </field>
                        </page>
                        <page string="Jamaah Lines">
                            <field name="peserta_line">
                                <tree editable="bottom">
                                    <field name="order_id"/>
                                    <field name="partner_id"/>
                                    <field name="name"/>
                                    <field name="jenis_kelamin" />
                                    <field name="tipe_kamar" />
                                </tree>
                            </field>
                        </page>
                    </notebook>
                    <group>
                        <field name="note" placeholder="Notes" nolabel="1"/>
                    </group>
                </sheet>
                </form>
            </field>
        </record>


Setelah ini kita tambahkan report excelnya :



        <report
            id="cetak_jamaah_xls" string="List Jamaah"
            model="paket.perjalanan" report_type="xls"
            name="print.jamaah.xls" file="print.jamaah.xls"
            attachment_use="False"/>



Lalu kita tambahkan kembali method dari button print tersebut :



class paket_perjalanan(models.Model):
    _name = "paket.perjalanan"

    name = fields.Char(string='Reference', readonly=True, default='/')
    product_id = fields.Many2one('product.product', string='Product', required=True, readonly=True, states={'draft': [('readonly', False)]})
    tgl_berangkat = fields.Date(string='Departure Date', required=True, readonly=True, states={'draft': [('readonly', False)]})
    tgl_pulang = fields.Date(string='Return Date', required=True, readonly=True, states={'draft': [('readonly', False)]})
    quota = fields.Integer(string='Quota', readonly=True, states={'draft': [('readonly', False)]})
    quota_progress = fields.Float(string="Quota Progress", compute='_taken_seats')
    note = fields.Text(string='Notes', readonly=True, states={'draft': [('readonly', False)]})
    hotel_line = fields.One2many('paket.hotel.line', 'paket_perjalanan_id', string='Hotel Lines', readonly=True, states={'draft': [('readonly', False)]})
    pesawat_line = fields.One2many('paket.pesawat.line', 'paket_perjalanan_id', string='Airline Lines', readonly=True, states={'draft': [('readonly', False)]})
    acara_line = fields.One2many('paket.acara.line', 'paket_perjalanan_id', string='Schedule Lines', readonly=True, states={'draft': [('readonly', False)]})
    peserta_line = fields.One2many('paket.peserta.line', 'paket_perjalanan_id', string='Jamaah Lines', readonly=True)
    state = fields.Selection([
        ('draft', 'Draft'),
        ('confirm', 'Confirmed'),
    ], string='Status', readonly=True, copy=False, default='draft', track_visibility='onchange')

    @api.multi
    def action_confirm(self):
        self.write({'state': 'confirm'})

    @api.model
    def create(self, vals):
        vals['name'] = self.env['ir.sequence'].next_by_code('paket.perjalanan')
        return super(paket_perjalanan, self).create(vals)

    @api.multi
    def name_get(self):
        return [(this.id, this.name + "#" + " " + this.product_id.partner_ref) for this in self]

    @api.depends('quota', 'peserta_line')
    def _taken_seats(self):
        for r in self:
            if not r.quota:
                r.quota_progress = 0.0
            else:
                r.quota_progress = 100.0 * len(r.peserta_line) / r.quota

    @api.multi
    def update_jamaah(self):
        order_ids = self.env['sale.order'].search([('paket_perjalanan_id', '=', self.id), ('state', 'not in', ('draft', 'cancel'))])
        if order_ids:
            self.peserta_line.unlink()
            for o in order_ids:
                for x in o.passport_line:
                    self.peserta_line.create({
                        'paket_perjalanan_id': self.id,
                        'partner_id': x.partner_id.id,
                        'name': x.name,
                        'order_id': o.id,
                        'jenis_kelamin': x.partner_id.jenis_kelamin,
                        'tipe_kamar': x.tipe_kamar,
                    })

    @api.multi
    def cetak_jamaah_xls(self):
        data = [['No', 'Sales Orders', 'Nama Passport', 'Jenis Kelamin', 'Tipe Kamar']]
        room = {'d': 'Double', 't': 'Triple', 'q': 'Quad'}

        for i, peserta in enumerate(self.peserta_line):
            data.append([
                i + 1,
                peserta.order_id.name,
                peserta.name,
                peserta.jenis_kelamin.title(),
                room[peserta.tipe_kamar]
            ])

        nilai = self.read()[0]
        datas = {'ids': [nilai['id']]}
        datas['model'] = 'paket.perjalanan'
        datas['form'] = nilai
        datas['csv'] = data

        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'print.jamaah.xls',
            'nodestroy': True,
            'datas': datas
        }



Jika report rml dan qweb memiliki file dan syntax khusus, maka untuk menghasilkan file xls, kita cukup gunakan python code, seperti ini :
(Tambahkan source code ini di file report/laporan.py pada baris yang paling bawah)



import xlwt
from odoo.addons.report_xls.report.report_xls import ReportXls

class cetak_excel(ReportXls):

    def generate_xls_report(self, workbook, data, paket):
        sheet = workbook.add_sheet("Rooming List")

        sheet.col(1).width = 256 * 25   # lebar kolom ke-2 selebar 25 karakter
        sheet.col(2).width = 256 * 50   # lebar kolom ke-3 selebar 50 karakter
        sheet.col(3).width = 256 * 25   # lebar kolom ke-4 selebar 25 karakter

        head_style = xlwt.easyxf("""font: bold on, color black;\
                                    borders: left thin, right thin, top thin, bottom thin;\
                                    pattern: pattern solid, fore_color light_green;""")

        body_style = xlwt.easyxf("""font: bold off, color black;\
                                    borders: left thin, right thin, top thin, bottom thin;\
                                    pattern: pattern solid, fore_color white;""")

        for row_index, rows in enumerate(data['csv']):
            for column_index, column_val in enumerate(rows):
                style = head_style if row_index == 0 else body_style
                sheet.write(
                    row_index,
                    column_index,
                    column_val,
                    style
                )

cetak_excel('report.print.jamaah.xls', 'paket.perjalanan')

Alhamdulillah selesai sudah pembuatan aplikasi travel umroh Odoo 10 ini. Untuk proses implementasi ke travel yang lain, mungkin perlu di kembangkan dan di sesuaikan fitur-fitur dan requirementnya. Sebagai penutup, saya buat video tutorial untuk menjelaskan workflow functionalnya seperti dibawah ini :

NB : Download source code disini

Advertisements

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s