Membuat Custom Report di Odoo 11

Membuat custom report di Odoo 11 sangat berbeda dengan membuat custom report di Odoo 10. Itu dikarenakan di Odoo 11 tidak mempunyai modul report seperti yang ada pada Odoo 10. Dan diperparah lagi dengan dokumentasi yang salah pada website Odoo, seperti yang bisa dilihat di dokumentasi Odoo ini.

Untuk itu, kali ini saya akan membuat tutorial custom report di Odoo 11, sama seperti dengan konsep yang ada pada tutorial custom report sebelumnya di Odoo 10.

Di tutorial ini saya tetap akan menampilkan rekap kehadiran karyawan, dan menampilkan data kehadiran dan ketidakhadiran tiap karyawan.

Hasil akhir dari report adalah seperti ini.

Seperti sebelumnya, sebelum memulai silakan membuat database baru dengan mencentang “Load demonstration data” agar ada data awal yang bisa kita gunakan untuk mengetes program. Lalu install modul hr_attendance. Modul tersebut adalah modul presensi bawaan dari Odoo. Dan jangan lupa memastikan bahwa wkhtmltopdf telah diinstall. Di report ini saya menggunakan wkhtmltopdf versi 0.12.1.

Setelah menginstall modul hr.attendance bisa dilihat data kehadiran dengan demo data sebagai berikut.

 

Buat sebuah model wizard.

Buat sebuah model wizard yang meng-inherit TransientModel.

from odoo import models, fields, api


class AttendanceRecapReportWizard(models.TransientModel):
    _name = 'attendance.recap.report.wizard'

    date_start = fields.Date(string="Start Date", required=True, default=fields.Date.today)
    date_end = fields.Date(string="End Date", required=True, default=fields.Date.today)

    @api.multi
    def get_report(self):
        pass

 

Buat sebuah view xml untuk model wizard yang telah dibuat.

Buat sebuah view untuk menampilkan wizard berdasarkan model wizard diatas.

<odoo>
    <record model="ir.ui.view" id="attendance_recap_report_wizard">
        <field name="name">HR Attendance Custom Recap Report</field>
        <field name="model">attendance.recap.report.wizard</field>
        <field name="type">form</field>
        <field name="arch" type="xml">
            <form string="Attendance Recap Report">
                <group>
                    <group>
                        <field name="date_start"/>
                    </group>
                    <group>
                        <field name="date_end"/>
                    </group>
                </group>
                <footer>
                    <button name="get_report" string="Get Report" type="object" class="oe_highlight"/>
                    <button string="Cancel" special="cancel"/>
                </footer>
            </form>
        </field>
    </record>

    <act_window id="action_attendance_recap_report_wizard"
                name="Attendance Recap Report"
                res_model="attendance.recap.report.wizard"
                view_mode="form"
                target="new"/>

    <menuitem action="action_attendance_recap_report_wizard"
              id="menu_attendance_report_wizard"
              parent="hr_attendance.menu_hr_attendance_report"/>
</odoo>

Setelah membuat wizard maka hasil tampilannya adalah seperti gambar dibawah ini.

 

Ubah class AttendanceRecapReportWizard.

Ubah method get_report() pada model attendance.recap.report.wizard, dan buat sebuah model yang meng-inherit AbstractModel untuk membuat custom report. Hasil akhirnya bisa dilihat pada kode di bawah ini.

from datetime import datetime, timedelta

from odoo import models, fields, api
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT


class AttendanceRecapReportWizard(models.TransientModel):
    _name = 'attendance.recap.report.wizard'

    date_start = fields.Date(string="Start Date", required=True, default=fields.Date.today)
    date_end = fields.Date(string="End Date", required=True, default=fields.Date.today)

    @api.multi
    def get_report(self):
        """Call when button 'Get Report' clicked.
        """
        data = {
            'ids': self.ids,
            'model': self._name,
            'form': {
                'date_start': self.date_start,
                'date_end': self.date_end,
            },
        }

        # use `module_name.report_id` as reference.
        # `report_action()` will call `get_report_values()` and pass `data` automatically.
        return self.env.ref('cj_custom_report.recap_report').report_action(self, data=data)


class ReportAttendanceRecap(models.AbstractModel):
    """Abstract Model for report template.

    for `_name` model, please use `report.` as prefix then add `module_name.report_name`.
    """

    _name = 'report.cj_custom_report.attendance_recap_report_view'

    @api.model
    def get_report_values(self, docids, data=None):
        date_start = datetime.strptime(data['form']['date_start'], DATE_FORMAT)
        date_end = datetime.strptime(data['form']['date_end'], DATE_FORMAT) + timedelta(days=1)
        date_diff = (date_end - date_start).days

        docs = []
        employees = self.env['hr.employee'].search([], order='name asc')
        for employee in employees:
            presence_count = self.env['hr.attendance'].search_count([
                ('employee_id', '=', employee.id),
                ('check_in', '>=', date_start.strftime(DATETIME_FORMAT)),
                ('check_out', '<', date_end.strftime(DATETIME_FORMAT)),
            ])

            absence_count = date_diff - presence_count

            docs.append({
                'employee': employee.name,
                'presence': presence_count,
                'absence': absence_count,
            })

        return {
            'doc_ids': data['ids'],
            'doc_model': data['model'],
            'date_start': date_start.strftime(DATE_FORMAT),
            'date_end': (date_end - timedelta(days=1)).strftime(DATE_FORMAT),
            'docs': docs,
        }

 

Buat file xml template report.

Setelah itu buat file xml untuk template report sesuai dengan kebutuhan.

<odoo>
    <record model="report.paperformat" id="paperformat_attendance_recap_report">
        <field name="name">paperformat.attendance.recap.report</field>
        <field name="default" eval="True"/>
        <field name="format">A4</field>
        <field name="page_width">0</field>
        <field name="page_width">0</field>
        <field name="orientation">Portrait</field>
        <field name="margin_top">30</field>
        <field name="margin_right">5</field>
        <field name="margin_bottom">10</field>
        <field name="margin_left">5</field>
        <field name="header_line" eval="False"/>
        <field name="header_spacing">20</field>
        <field name="dpi">90</field>
    </record>

    <report id="recap_report"
            model="attendance.recap.report.wizard"
            string="Attendance Recap Report"
            report_type="qweb-pdf"
            name="cj_custom_report.attendance_recap_report_view"
            paperformat="paperformat_attendance_recap_report"
            menu="False"/>

    <template id="attendance_recap_report_view">
        <div class="header" style="border-bottom: 2px solid black">
            <h3 class="text-center">Attendance Recap Report</h3>
            <h4 class="text-center">
                <strong>From</strong>:
                <t t-esc="date_start"/>
                <strong>To</strong>:
                <t t-esc="date_end"/>
            </h4>
        </div>
        <div class="article">
            <table class="table table-condensed table-bordered" style="width: 100%">
                <thead>
                    <th class="text-center" style="width: 70%">Employee</th>
                    <th class="text-center" style="width: 15%">Presence</th>
                    <th class="text-center" style="width: 15%">Absence</th>
                </thead>
                <tbody>
                    <t t-foreach="docs" t-as="doc">
                        <tr>
                            <td>
                                <span t-esc="doc['employee']"/>
                            </td>
                            <td class="text-center">
                                <span t-esc="doc['presence']"/>
                            </td>
                            <td class="text-center">
                                <span t-esc="doc['absence']"/>
                            </td>
                        </tr>
                    </t>
                </tbody>
            </table>
        </div>
        <div class="footer">
            <div class="row text-center" style="border-top: 1px solid black;">
                <div class="col-xs-3 col-xs-offset-9 text-right">
                    <ul class="list-inline" style="margin-top:10px;">
                        <li>Page:</li>
                        <li>
                            <span class="page"/>
                        </li>
                        <li>/</li>
                        <li>
                            <span class="topage"/>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </template>
</odoo>

 

Sekian tutorial kali ini, silakan cek repository untuk melihat kodenya secara utuh, atau bisa langsung install modul tersebut untuk mencoba.

Selamat mencoba, semoga bermanfaat.

Baca juga:

Comments

3 komentar untuk “Membuat Custom Report di Odoo 11”

  1. Ping-kembali: Membuat Odoo attachment otomatis di Odoo 10 dan 11 - Cak Juice

  2. Ping-kembali: Membuat Custom Report di Odoo 12 - Cak Juice

  3. Ping-kembali: Cara Menambahkan Image atau Barcode di Report Odoo - Cak Juice

Komentar ditutup.