Saat kita melakukan pengembangan modul Odoo mungkin kita membutuhkan status yang lebih dari Draft dan available. Di sini kita perlu mengubah state menjadi stage. Supaya stage kita bisa mengikuti kebutuhan pengguna maka kita dapat membuat stage dinamis
Pembuatan stage dinamis dalam pembangunan modul Odoo adalah seperti berikut ini
- Start SSH file system


- Model untuk stage yang dinamis
from odoo import fields, models, _ class AsramaRoomStage(models.Model): _name = 'asrama.room.stage' _description = 'Room Stages' _order = 'sequence,name' name = fields.Char('Name') sequence = fields.Integer('Sequence') fold = fields.Boolean('Fold?') - Model yang menggunakan dynamic stage
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 def action_remove_room_members(self): for student in self.student_ids: student.with_context(is_hostel_room=True).action_remove_room() def action_category_with_amounts(self): sql = 'SELECT name, amount FROM asrama_category WHERE id = %s' % self.category_id.id print('SQL:', sql) self.env.cr.execute(sql) result = self.env.cr.fetchall() print('Result:', result) def _default_room_stage(self): Stage = self.env['asrama.room.stage'] return Stage.search([], limit=1) stage_id = fields.Many2one('asrama.room.stage', default=_default_room_stage) - Model init
from . import hostel from . import asrama_room_stage from . import asrama_room from . import asrama_student from . import asrama_student_copy from . import asrama_amenities from . import asrama_categ from . import res_partner from . import asrama_terminate from . import asrama_room_availability from . import res_config_settings
- View untuk model yang memanggil stage dinamis
<?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="stage_id" widget='statusbar' options="{'clickable': '1', 'fold_field':'fold'}" /> </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"/> <button name="action_remove_room_members" string="Remove Room Members" 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"/> <button name="action_category_with_amounts" string="LOG dengan SQL Query" 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> - View untuk stage dinamis
<?xml version="1.0" encoding="utf-8"?> <odoo> <!-- asrama.room.stage action window --> <record id="asrama_room_stage_action" model="ir.actions.act_window"> <field name="name">Asrama Room Stage</field> <field name="res_model">asrama.room.stage</field> <field name="view_mode">tree,form</field> </record> <menuitem id="asrama_room_stage_menu" name="Asrama Room Stage" parent="hostel_main_menu" action="asrama_room_stage_action" sequence="60"/> </odoo> - File ir.model.access.csv
- Manifest
{ 'name': 'Manajemen Asrama', "data":[ "security/hostel_security.xml", "security/ir.model.access.csv", "data/data.xml", "views/hostel.xml", "views/asrama_room_stage.xml", "views/asrama_room.xml", "views/asrama_student.xml", "views/asrama_room_availability_view.xml", "views/res_config_settings.xml", "wizard/assign_room_student.xml", ], 'pre_init_hook' : 'pre_init_hook_hostel', 'post_init_hook' : 'add_room_hook', 'uninstall_hook' : 'uninstall_hook_user' } - Start Odoo dengan upgrade modul


- Tampilan pengelolaan stage

- Tampilan yang memanggil stage

Kunjungi https://www.proweb.co.id/implementasi-odoo/ untuk menambah wawasan anda mengenai Odoo ERP.
