Dalam melakukan pemrograman berbasis Odoo 17 kita mungkin akan membuat perhitungan-perhutungan data tertentu misalnya rata-rata pemesanan penjualan, maksimum sales order, total penjualan pada periode tertentu dan lain-lain. Di sini kita memerlukan group by dan fungsi aggregate dan pada Odoo diimplementasikan dengan read_group().
Aggregate data pada pemrograman Odoo 17 adalah seperti pada contoh berikut ini
- Start SSH filesystem
- Model asrama.room
import logging from odoo import fields, models, api from odoo.exceptions import ValidationError, UserError from odoo.tools.translate import _ _logger = logging.getLogger(__name__) class BaseArchive(models.AbstractModel): _name = 'base.archive' active = fields.Boolean(default=True) def do_archive(self): for record in self: record.active = not record.active class AsramaRoom(models.Model): _name = 'asrama.room' _inherit = ['base.archive'] _description = 'Informasi Kamar Asrama' _rec_name = 'room_no' name = fields.Char('Nama kamar',required=True) room_no = fields.Char('No kamar',required=True) floor_no = fields.Integer('No Lantai',default=1, help='No Lantai') currency_id = fields.Many2one('res.currency',string='Mata uang') rent_amount = fields.Monetary('Harga sewa',help='Masukkan harga sewa') hostel_id = fields.Many2one('asrama.hostel','Hostel', help='Nama hostel') student_per_room = fields.Integer('Jml pelajar per kamar',required=True, help='Jml yang dialokasikan per kamar') @api.depends('student_per_room','student_ids') def _compute_check_availability(self): """Mengecek ketersediaan""" for rec in self: rec.availability = rec.student_per_room - len (rec.student_ids.ids) availability = fields.Float(compute='_compute_check_availability',store=True, string='Ketersediaan',help='Ketersediaan kamar pada asrama') student_ids = fields.One2many('asrama.student','room_id','Daftar pelajar', help='Pelajar-pelajar dalam room ini') asrama_amenities_ids = fields.Many2many('asrama.amenities', 'asrama_amenities_rel','room_id','amenity_id', string='Amenities', domain="[('active','=',True)]", help='Pilih fasilitas room' ) _sql_constraints = [('room_no_unique','unique(room_no)','Nomor room harus unik!')] @api.constrains('rent_amount') def _check_rent_amount(self): """Constraint pada nilai negatif""" if self.rent_amount < 0: raise ValidationError(_('Nilai rental tidak boleh negatif')) room_rating = fields.Float('Rata-rata Rating dari Room',digits=(14,4)) state = fields.Selection([ ('draft','Unavailable'), ('available','Available'), ('closed','Closed') ], 'State', default='draft' ) remarks = fields.Text('Remarks') @api.model def create(self,values): if not self.user_has_groups('base.group_allow_export'): if values.get('remarks'): raise UserError('Anda tidak diijinkan membuat remark') return super(AsramaRoom, self).create(values) def write(self,values): if not self.user_has_groups('base.group_allow_export'): if values.get('remarks'): raise UserError('Anda tidak diijinkan mengubah remark') return super(AsramaRoom, self).write(values) def is_allowed_transition(self,old_state,new_state): allowed = [ ('draft','available'), ('available','closed'), ('closed','draft') ] return (old_state,new_state) in allowed def change_state(self,new_state): for room in self: if room.is_allowed_transition(room.state, new_state): room.state = new_state else: msg = _('Pindah dari %s ke %s tidak diperbolehkan!') % (room.state,new_state) raise UserError(msg) def make_available(self): self.change_state('available') def make_closed(self): self.change_state('closed') def log_all_room_members(self): asrama_student_obj = self.env['asrama.student'] all_members = asrama_student_obj.search([]) print('Semua anggota',all_members) return True def create_categories(self): categ1 = { 'name': 'Child category 1', 'description': 'Description for child 1' } categ2 = { 'name': 'Child category 2', 'description': 'Description child 2' } parent_category_val = { 'name': 'Parent category', 'description': 'Description for parent category', 'child_ids': [ (0,0,categ1), (0,0,categ2), ] } record = self.env['asrama.category'].create(parent_category_val) return True def update_room_no(self): self.ensure_one() self.room_no = 'RM2772' def find_room(self): domain = [ '|', '&',('name','ilike','bunga'), ('hostel_id.name','=','Kemayoran'), '&',('name','ilike','galo'), ('hostel_id.name','=','BSD') ] rooms = self.search(domain) #_logger.info('Room ditemukan %s',rooms) print('Room ditemukan %s',rooms) return True def filter_members(self): all_rooms = self.search([]) filtered_rooms = self.rooms_with_multiple_members(all_rooms) #_logger.info('Filtered Rooms: %s',filtered_rooms) print('Filtered Rooms:', filtered_rooms) def rooms_with_multiple_members(self, all_rooms): def predicate(room): if (len(room.student_ids))>1: return True return all_rooms.filtered(predicate) def mapped_rooms(self): all_rooms = self.search([]) room_authors = self.get_member_names(all_rooms) #_logger.info('Room Members: %s', room_authors) print('Room Members:', room_authors) def get_member_names(self,all_rooms): return all_rooms.mapped('student_ids.name') def sort_room(self): all_rooms = self.search([]) rooms_sorted = self.sort_by_rent_amount(all_rooms) #_logger.info('Rooms before sorting: %s', all_rooms) #_logger.info('Rooms after sorting: %s', rooms_sorted) print('Rooms before sorting:', all_rooms) print('Rooms after sorting:', rooms_sorted) def sort_by_rent_amount(self,all_rooms): return all_rooms.sorted(key='rent_amount') def average_rent(self): avg_result = self.read_group( [('rent_amount', '!=', False)], ['category_id','rent_amount:avg'], ['category_id'] ) print('Rata-rata harga sewa %s' % (avg_result)) return True
- View asrama_room
<?xml version='1.0' encoding='utf-8'?> <odoo> <!-- asrama.room tree view --> <record id="asrama_room_view_tree" model="ir.ui.view"> <field name="name">asrama.room.view.tree</field> <field name="model">asrama.room</field> <field name="arch" type="xml"> <tree string='Room'> <field name="name"/> <field name="room_no" /> <field name="floor_no" /> </tree> </field> </record> <!-- asrama.room form view --> <record id="asrama_room_view_form" model="ir.ui.view"> <field name="name">asrama.room.view.form</field> <field name="model">asrama.room</field> <field name="arch" type="xml"> <form string="Room"> <sheet> <header> <field name="state" widget='statusbar'/> </header> <header> <button name="make_available" string="Make Available" type="object"/> <button name="make_closed" string="Make Closed" type="object"/> <button name="log_all_room_members" string="Log semua kamar members" type="object"/> <button name="average_rent" string="Rata-rata sewa" type="object"/> </header> <header> <button name="create_categories" string="Create categories" type="object"/> <button name="update_room_no" string="Update Room No" type="object"/> <button name="find_room" string="Find Room" type="object"/> </header> <header> <button name="filter_members" string="Filter Members" type="object"/> <button name="mapped_rooms" string="Mapped Rooms" type="object"/> <button name="sort_room" string="Sort Room" type="object"/> </header> <group> <group description='Kamar'> <field name="name" /> <field name="room_no" /> <field name="hostel_id" required="1"/> <field name="floor_no" /> <field name="active" /> <field name="category_id" /> <field name="date_terminate" /> </group> <group description='Harga'> <field name="student_per_room"/> <field name="availability"/> <field name="rent_amount" /> <field name="currency_id" /> <field name="remarks" /> </group> </group> <notebook> <page name="room_studennt" string="Para Pelajar"> <field name="student_ids"/> </page> <page name="asrama_amenities" string="Room Amenities"> <group> <field name="asrama_amenities_ids" widget="many2many_tags"/> </group> </page> </notebook> </sheet> </form> </field> </record> <!-- asrama.room action window --> <record id="asrama_room_action" model="ir.actions.act_window"> <field name="name">Room</field> <field name="type">ir.actions.act_window</field> <field name="res_model">asrama.room</field> <field name="view_mode">tree,form</field> <field name="domain">[]</field> <field name="context">{}</field> <field name="help" type="html"> <p class="oe_view_nocontent_create"> Tambah kamar </p> </field> </record> <!-- This Menu Item must have a parent and an action --> <menuitem id="asrama_room_menu" name="Room Asrama" parent="hostel_main_menu" action="asrama_room_action" sequence="2"/> </odoo>
- Start Odoo dengan file log
- Tampilan dengan perhatian pada tombol ‘Rata-rata sewa’
- Tampilan pada console
Kunjungi www.proweb.co.id/implementasi-odoo/ untuk menambah wawasan implementasi Odoo ERP.