Wednesday, January 8, 2020

buttons in odoo

ODOO

Buttons

 
On this step we will explain button's types in odoo , there are many types of buttons in odoo just as :

  • object buttons : this type of button is created to call python function
  • action buttons : this type of button is created to call view " to open new view when the user click it'
  • Smart button : actually it's action button but beside open new view it also used to show some information about some objects "we show some fields with this button 
Now let us give an examples to create any type of buttons 

_ object button : let us say that we have a function by name "get_operation_start" and we want to call this function by click on some button , so we can make that button inside our view just as bellow 

<button name="get_operation_start" type="object" string="Start" class="oe_highlight" />

to explain what we did :

name="" here we pass the name of the function that we want to call when we click on this button 
type="" here we defined the type of this button 'object or action'
string="" here we defined the label for this button 
class="" here we defined the class for this button

_ action button : we can define it as bellow 

<button name="module_name.view_button_action" icon="fa-check" type="action" string="Graduated Students" />

now we have to create view_button_action which will call some view as bellow 

@api.multi

def view_button_action(self):

     return {
            'name': _('ModelName'),
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'model.model',
            'view_id': False,
            'type': 'ir.actions.act_window',
            'domain': [],
        }

_ smart button : smart button is that button which contain some fields which are display with this button , and for example we can give the smart button that show the available quantity of the product in the stock which is defined as bellow 

<button class="oe_stat_button"
         name="product_open_quants"
         icon="fa-building-o"
         type="object" attrs="{'invisible':[('type', '!=', 'product')]}">
                 <field name="qty_available" widget="statinfo" string="On Hand"/></button>
 

Watch On YouTube



PREVIOUS STEP            NEXT STEP

Thursday, January 2, 2020

workflow in odoo

ODOO

 

Workflow 


 
In this step we will continue with clinic booking work flow , so we will

  • add booking data for ‘clinic.booking’ object as bellow

state = fields.Selection([('draft','Draft'),('wait_d_meeting','Wait Doctor Meeting'),('stay_on_ward','Stay On Ward'),('medical_bill','Medical Bill')], string='State', default='draft')

patient_id = fields.Many2one('clinic.patient', string='Patient', required=True)

doctor_id = fields.Many2one('clinic.doctor', string='Doctor', required=True)

date = fields.Date(string="Date", default=fields.date.today())

meeting_date = fields.Date(string="Meeting Date", required=True)

paid_fees = fields.Boolean(string="Paid Fees")

note = fields.Html(string="Note")

  • create clinic booking views as bellow
<!-- """Create Form View""" -->

        <record id="clinic_booking_form_view" model="ir.ui.view">
            <field name="name">clinic.booking.form</field>
            <field name="model">clinic.booking</field>
            <field name="arch" type="xml">
                <form string="Doctor">
                    <header>
                        <button name="action_to_wait_d_meeting" states="draft" string="Confirm" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <button name="clinic_ward_action" states="wait_d_meeting" string="Stay On Ward" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <button name="medical_bill_action" states="wait_d_meeting" string="Medical Bill" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <field name="state" widget="statusbar" readonly="1"/>
                    </header>
                    <sheet>
                        <group colspan="4" col="4">
                            <field name="patient_id" />
                            <field name="doctor_id" />
                            <field name="date" />
                            <field name="meeting_date" />
                            <field name="paid_fees" />
                        </group>
                        <group colspan="4" col="4" string="Note">
                            <field name="note" nolabel="1"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>

        <!-- """Create Tree View""" -->

        <record id="clinic_booking_tree_view" model="ir.ui.view">
            <field name="name">clinic.booking.tree</field>
            <field name="model">clinic.booking</field>
            <field name="arch" type="xml">
                <tree string="doctors">
                    <field name="patient_id" />
                    <field name="doctor_id" />
                    <field name="date" />
                    <field name="meeting_date" />
                    <field name="paid_fees" />
                    <field name="state"/>
                </tree>
            </field>
        </record>



  • edit work flow function as bellow

@api.one

def action_to_wait_d_meeting(self):

"""

function to be sure that the paient had registered to meet doctor

"""

if self.paid_fees == False:

raise ValidationError(_("The Patient did not paid fees yet !"))

self.state = 'wait_d_meeting'





@api.one

def clinic_ward_action(self):

"""

function will call if the doctor decied that the patient must stay for sometime in clinin's ward

"""

self.patient_id.write({'met_doctor': True})

self.patient_id.write({'last_meeting': self.meeting_date})

self.state = 'stay_on_ward'



@api.one

def medical_bill_action(self):

"""

function will call if the doctor give the patient a medical bill

"""

self.patient_id.write({'met_doctor': True})

self.patient_id.write({'last_meeting': self.meeting_date})

self.state = 'medical_bill'

Watch On YouTube



 PREVIOUS STEP              NEXT STEP

Monday, December 30, 2019

design workflow in odoo

      In this step we will design work flow for clinic booking process as we had explain in the previous step so to make it we have to 
  • create new object by name ('clinic.booking') as bellow with workflow functions 
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

class ClinicBooking(models.Model):
    ###############################
    #Class for Booking data
    ###############################
    _name = 'clinic.booking'
    _description = "object contain all doctor data"

    state = fields.Selection([('draft','Draft'),('wait_d_meeting','Wait Doctor Meeting'),('stay_on_ward','Stay On Ward'),('medical_bill','Medical Bill')], string='State', default='draft')


    @api.one
    def action_to_wait_d_meeting(self):
        """
        function to be sure that the paient had registered to meet doctor
        """
        self.state = 'wait_d_meeting'


    @api.one
    def clinic_ward_action(self):
        """
        function will call if the doctor decied that the patient must stay for sometime in clinin's ward
        """
        self.state = 'stay_on_ward'

    @api.one
    def medical_bill_action(self):
        """
        function will call if the doctor give the patient a medical bill
        """
        self.state = 'medical_bill'
  • create view for this object as bellow 
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>

        <!-- """Create Form View""" -->

        <record id="clinic_booking_form_view" model="ir.ui.view">
            <field name="name">clinic.booking.form</field>
            <field name="model">clinic.booking</field>
            <field name="arch" type="xml">
                <form string="Doctor">
                    <header>
                        <button name="action_to_wait_d_meeting" states="draft" string="Confirm" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <button name="clinic_ward_action" states="wait_d_meeting" string="Stay On Ward" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <button name="medical_bill_action" states="wait_d_meeting" string="Medical Bill" type="object" class="oe_highlight" style="margin-left:2px;"/>
                        <field name="state" widget="statusbar" readonly="1"/>
                    </header>
                    <sheet>
                    </sheet>
                </form>
            </field>
        </record>

        <!-- """Create Tree View""" -->

        <record id="clinic_booking_tree_view" model="ir.ui.view">
            <field name="name">clinic.booking.tree</field>
            <field name="model">clinic.booking</field>
            <field name="arch" type="xml">
                <tree string="doctors">
                    <field name="state"/>
                </tree>
            </field>
        </record>

        <!-- """Create Action View""" -->

        <record id="clinic_booking_action_view" model="ir.actions.act_window">
            <field name="name">Booking</field>
            <field name="res_model">clinic.booking</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="clinic_booking_tree_view"/>
        </record>

        <!-- """Create the Booking Root menu """ -->

        <menuitem id="clinic_booking_root_menu"
            name="Booking" sequence="1"
        />

        <!-- """Create the Booking Mani menu""" -->

        <menuitem
            name="Booking"
            parent="clinic_booking_root_menu"
            action="clinic_booking_action_view"
            id="clinic_booking_action_menu"
            sequence="2"
        />

    </data>
</odoo>
 


Watch On YouTube



PREVIOUS STEP           NEXT STEP

Tuesday, December 24, 2019

explain workflow in odoo

ODOO 

Workfow 

 

In this step we are going to start workflow in odoo , so we have to ask some Qs 
  • What is workflow ?
Workflow is away that we use to define all steps to do some tasks or activities in our organization , and it's away to make our work clear and easy 
Workflow is consist of some activities and some actions which are depends on activities "eg : to migrate student from first class to the second one , he must study at the first one"
  •  How to make workflow in odoo ? 
To design workflow in odoo we have tow main steps 

1- logical design : in this step we define all steps of the task that we want to do , also we define which step must be first and which one must be after which one , also we design the action that must be happened to change from the first step to the second one , also we have to define the user's permissions "which user is allowed to take that action in this workflow" finally we have to design workflow diagram that summarizes our logical design "EG : the diagram bellow "



2- technical design : in this step we write down our logical design as code , to do that we have to 
  • Create state field which is selection field that contain all states of our workflow as bellow       
state = fields.Selection([('draft','Draft'),('unit_manager_approv','Unit Manager Approve'),('general_manager_approv','General Manager Approve')], string="draft", default='draft')

  • Create our functions , and in every one we must put all actions that will be happen in one state , and also every function will change the state from one state to another
Watch On YouTube 


PREVIOUS STEP            NEXT STEP

Monday, December 23, 2019

create notebook view, kanban view in odoo

ODOO

notebook

kanban

 
 
In this step we will create some view 
  • create notebook view
  • create kanban view
Notebook is away to view fields as note that contains many pages , so as example we will create notebook view for 'clinic.doctor' consist of two page ' patients page ' & 'doctor's qualifications' so we will go to 'clinic.doctor' object and add the field of qualifications & specialty as bellow 

qualifications = fields.Html(string="Qualifications")
specialty = fields.Many2one('doctor.specialty', string="Specialty")
academic_degree

and in the 'clinic_doctor.py' file we will add new class by name 'DoctorSpecialty' which will contain all specialties for the doctors 'name field only', just as bellow 

class DoctorSpecialty(models.Model):
    _name = "
doctor.specialty"
    _description = "
Doctor Specialty
      
     name = field.Char(string="Name")

Then we have to go to 'clinic_doctor_view.xml' file and add the notenook view as bellow ..

<notebook>
    <page string="Patients">
         <group colspan="2" col="2">
             <field name="patient_ids" nolabel="1"/>
         </group>
    </page> 
    <page string="Qualifications">
         <group colspan="4" col="4">
              <field name="specialty"/>
              <field name="academic_degree"/>
              <field name="university"/>
              <field name="graduate_year"/>
         </group>
         <group colspan="2" col="2">
             <field name="qualifications" nolabel="1"/>
         </group>
    </page>
</notebook>

Then we will create kanban view for 'clinic.doctor' object in which we will put just the important fields for the doctor just as "name, specialty, image"

Now we will create kanban view for the 'clinic.doctor' object by adding the code bellow to the 'clinic_doctor_view.xml' file

<!-- """Create kanban View""" -->

        <record id="clinic_doctor_kanban_view" model="ir.ui.view">
            <field name="name">clinic.doctor.kanban</field>
            <field name="model">clinic.doctor</field>
            <field name="arch" type="xml">
                <kanban >
                    <field name='id'/>
                    <field name="image"/>
                    <field name="specialty"/>
                    <templates>
                        <t t-name="kanban-box">
                            <div class="oe_kanban_global_click" style=" border: 1px solid #d9d7d7; border-radius: 5px !important;">
                                <div class="o_kanban_image">
                                    <img t-att-src="kanban_image('clinic.doctor','image',record.id.raw_value)" alt="Image"/>
                                </div>
                                <div class="oe_kanban_details">
                                    <ul>
                                        <li style="font-size:16px;color:blue !important;"><b>Name :</b> <field name="name"/></li>
                                        <li><b>Specialty :</b> <field name="specialty"/></li>
                                    </ul>
                                </div>
                                <div class="o_kanban_record_bottom">
                                    <div class="oe_kanban_bottom_left" style="margin-left:8px;">
                                        <b> A.D :</b> <field name="academic_degree"/>
                                    </div>
                                    <div class="oe_kanban_bottom_right" style="margin-right:40px;">
                                        <b> Age :</b> <field name="age_year"/>
                                    </div>
                                </div>
                            </div>
                        </t>
                    </templates>
                </kanban>
            </field>
        </record>


Watch On YouTube



PREVIOUS STEP            NEXT STEP

Tuesday, December 17, 2019

example object in odoo

ODOO

python oop

 
In this step we will start the relational fields so we have to 
  • create 'clinic.doctor' object which will contain doctor's data
  • link the doctor object with the patient object
We can create 'clinic.doctor' object by the same way that we use to create 'clinic.patient' in the file with name 'clinic_doctor_view.xml' so we must first create 'clinic_doctor.py' just as ...

# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

class ClinicDoctor(models.Model):
    ###############################
    #Class for doctor which is contain all doctor data
    ###############################
    _name = 'clinic.doctor'
    _description = "object contain all doctor data"

    first_name = fields.Char(string='First Name', required=True)
    second_name = fields.Char(string='Second Name', required=True)
    third_name = fields.Char(string='Third Name', required=True)
    forth_name = fields.Char(string='Fourth Name', required=True)
    name = fields.Char(string="Name", readonly=True, compute='get_doctor_name')
    image = fields.Binary(string='Image', copy=False)
    gender = fields.Selection([('male','Male'),('female','Female')], string='Gender',default='male')
    birth_day = fields.Date(string='Birthday', required=True)
    age_year = fields.Integer(string="Years", compute='calculate_age')
    age_month = fields.Integer(string="Months", compute='calculate_age')
    age_day = fields.Integer(string="Days", compute='calculate_age')
    country_id = fields.Many2one('res.country', string='Country')
    phone = fields.Char(string="Phone")

    @api.constrains('phone')
    def phone_validation(self):
        """
        function to validate phone data for doctor
        """
        phone_prefix = [1,9]
        phone_type = [0,1,2,6,9]
        check_value = 0

        if self.phone and self.country_id:
            if self.country_id.code == 'SD':
                phone = self.phone
                if len(phone) != 9:
                    raise ValidationError(_("Wrong phone number , it length is not true"))
                if len(phone) == 9:
                    for index in range(0,len(phone_prefix)):
                        if phone[0] == str(phone_prefix[index]):
                            check_value = 1
                    if check_value == 0:
                        raise ValidationError(_("Wrong phone number , it start with wrong key number"))
                    check_value = 0
                    for index in range(0,len(phone_type)):
                        if phone[1] == str(phone_type[index]):
                            check_value = 1
                    if check_value == 0:
                        raise ValidationError(_("Wrong phone number , it not of real phone number"))
                    check_value = 0
                    for index in range(0,len(phone)):
                        check_value = 0
                        for number in range(0,10):
                            if phone[index] == str(number):
                                check_value = 1
                        if check_value == 0:
                            raise ValidationError(_("Wrong phone number , it must not contain charactors"))



    @api.one
    def get_doctor_name(self):
        """
        function to calculate the full name for the doctor
        """
        self.name = self.first_name+' '+self.second_name+' '+self.third_name+' '+self.forth_name


    @api.one
    def calculate_age(self):
        """
        function to calcolate the age of the user

        """
        if self.birth_day :
            birth_day = str(self.birth_day)
            current_date = str(fields.Date.today())

            birth_day_year_as_int =     int(birth_day[0]+birth_day[1]+birth_day[2]+birth_day[3])
            birth_day_month_as_int = int(birth_day[5]+birth_day[6])
            birth_day_day_as_int = int(birth_day[8]+birth_day[9])

            current_date_year_as_int = int(current_date[0]+current_date[1]+current_date[2]+current_date[3])
            current_date_month_as_int = int(current_date[5]+current_date[6])
            current_date_day_as_int = int(current_date[8]+current_date[9])

            period_years = current_date_year_as_int-birth_day_year_as_int
            period_months = current_date_month_as_int-birth_day_month_as_int
            period_days = current_date_day_as_int-birth_day_day_as_int

            months_list_1 = ['04','06','09','11']
            months_list_2 = ['01','03','05','07','08','10','12']

            if period_days < 0:
                if str(current_date_month_as_int) == '02':
                    if current_date_year_as_int%4 == 0:
                        period_days = 29+period_days
                    if current_date_year_as_int%4 != 0:
                        period_days = 28+period_days
                for index in range(0,4):
                    if current_date_month_as_int == int(months_list_1[index]):
                        period_days = 30+period_days
                for index in range(0,7):
                    if current_date_month_as_int == int(months_list_2    [index]):
                        period_days = 31+period_days
                period_months = period_months-1
            if period_months < 0:
                period_months = 12+period_months
                period_years = period_years-1

            self.age_year = period_years
            self.age_month = period_months
            self.age_day = period_days

Then we will it view in 'clinic_doctor_view.xml' just as

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>

        <!-- """Create Form View""" -->

        <record id="clinic_doctor_form_view" model="ir.ui.view">
            <field name="name">clinic.doctor.form</field>
            <field name="model">clinic.doctor</field>
            <field name="arch" type="xml">
                <form string="Doctor">
                    <sheet>
                        <div style="width:100%;">
                            <div style="width:20%;float:left;">
                                <field name="image" widget="image"/>
                            </div>
                            <div style="width:78%;float:right;">
                                <group colspan="2" col="2">
                                    <field name="name" nolabel="1" style="font-size:32px;"/>
                                </group>
                                <table style="width:100%;">
                                    <tr style="width:100%;">
                                        <td style="width:25%;font-size:13px;padding:2px;">
                                            <field name="first_name" placeholder="First Name"/>
                                        </td>
                                        <td style="width:25%;font-size:13px;padding:2px;">
                                            <field name="second_name" placeholder="Second Name"/>
                                        </td>
                                        <td style="width:25%;font-size:13px;padding:2px;">
                                            <field name="third_name" placeholder="Third Name"/>
                                        </td>
                                        <td style="width:25%;font-size:13px;padding:2px;">
                                            <field name="forth_name" placeholder="Fourth Name"/>
                                        </td>
                                    </tr>
                                </table>
                            </div>
                        </div>
                        <br></br><br></br>
                        <group colspan="4" col="4">
                            <field name="gender"/>
                            <field name="birth_day"/>
                            <field name="country_id"/>
                            <field name="phone"/>
                        </group>
                        <table style="width:50%;">
                            <tr>
                                <td style="width:40%;font-size:13px;padding:2px;">
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        years
                                    </center>
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        months
                                    </center>
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        days
                                    </center>
                                </td>
                            </tr>
                            <tr>
                                <td style="width:40%;font-size:13px;padding:2px;">
                                    <b>
                                        Age
                                    </b>
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        <field name="age_year" />
                                    </center>
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        <field name="age_month" />
                                    </center>
                                </td>
                                <td style="width:20%;padding:2px;">
                                    <center>
                                        <field name="age_day" />
                                    </center>
                                </td>
                            </tr>
                        </table>
                    </sheet>
                </form>
            </field>
        </record>

        <!-- """Create Tree View""" -->

        <record id="clinic_doctor_tree_view" model="ir.ui.view">
            <field name="name">clinic.doctor.tree</field>
            <field name="model">clinic.doctor</field>
            <field name="arch" type="xml">
                <tree string="doctors">
                    <field name="name"/>
                    <field name="gender"/>
                    <field name="age_year"/>
                    <field name="phone"/>
                </tree>
            </field>
        </record>

        <!-- """Create Action View""" -->

        <record id="clinic_doctor_action_view" model="ir.actions.act_window">
            <field name="name">doctors</field>
            <field name="res_model">clinic.doctor</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="clinic_doctor_tree_view"/>
        </record>

        <!-- """Create the Configration menu """ -->

        <menuitem id="clinic_doctor_main_menu"
            name="Doctors" sequence="10"
            parent="clinic_root_menu"
        />

        <!-- """Create the Company's Projects menu""" -->

        <menuitem
            name="Doctors"
            parent="clinic_doctor_main_menu"
            action="clinic_doctor_action_view"
            id="doctors_action_menu"
            sequence="15"
        />

    </data>
</odoo>

Then we will create the relation between the patient and the doctor , an we can say ' one doctor will take care of more than one patient ' so it will be 'One2many' form doctor to patient , and also we can say ' many patients have taken care by one doctor' so it will be 'Many2one' from patient to doctor 

Now we can code that by adding many2one field into 'clinic.patient' object as 

doctor_id = fields.Many2one('clinic.doctor', string='Doctor') 

then we will add this field to patient object view file 

Then we must go to 'clinic.doctor' object and add One2many field for patients just as bellow ...

patient_id = fields.One2many('clinic.patient', 'doctor_id', string='Patients')

Then we go to doctor object view and add it  as bellow 

<group colspan="4" col="4" string="Patients">
         <field name="patient_id" nolabel="1"/>

</group> 

Watch On YouTube



PREVIOUS STEP            NEXT STEP

add country,phon fields in odoo

In this step we will continue with 'clinic.patient' object and
  • add country field
  • add phone field with validation function
  • edit tree view 
To add phone number and country fields we have to go to 'clinic.patient' object and add them with validation function as bellow

country_id = fields.Many2one('res.country', string="Country")
phone = fields.Char(string="Phone")
    @api.constrains('phone')
    def phone_validation(self):
        """
        function to validate phone data for patient
        """
        phone_prefix = [1,9]
        phone_type = [0,1,2,6,9]
        check_value = 0

        if self.phone and self.country_id:
            if self.country_id.code == 'SD':
                phone = self.phone
                if len(phone) != 9:
                    raise ValidationError(_("Wrong phone number , it length is not true"))
                if len(phone) == 9:
                    for index in range(0,len(phone_prefix)):
                        if phone[0] == str(phone_prefix[index]):
                            check_value = 1
                    if check_value == 0:
                        raise ValidationError(_("Wrong phone number , it start with wrong key number"))
                    check_value = 0
                    for index in range(0,len(phone_type)):
                        if phone[1] == str(phone_type[index]):
                            check_value = 1
                    if check_value == 0:
                        raise ValidationError(_("Wrong phone number , it not of real phone number"))
                    check_value = 0
                    for index in range(0,len(phone)):
                        check_value = 0
                        for number in range(0,10):
                            if phone[index] == str(number):
                                check_value = 1
                        if check_value == 0:
                            raise ValidationError(_("Wrong phone number , it must not contain charactors"))


Then we have to add it to the view in 'clinic_patient_view.xml' file inside the first group to be as

<group colspan="4" col="4">
        <field name="gender"/>
        <field name="birth_day"/>

        <field name="country_id" />
        <field name="phone"/>
        <field name="met_doctor"/>
        <field name="last_meeting" attrs="{'invisible': [('met_doctor','=',False)],'required':[('met_doctor','=',True)]}"/>

</group>

 Then we will edit the tree view to show the important fields for the patient (name, phone, gender, age'years') so it will be as ...

<record id="clinic_patient_tree_view" model="ir.ui.view">
        <field name="name">clinic.patient.tree</field>
        <field name="model">clinic.patient</field>
        <field name="arch" type="xml">
                <tree string="Patients">
                       <field name="name"/>
                       <field name="gender"/>
                       <field name="phone"/>
                       <field name="age_year"/>
                </tree>
       </field>

</record>
 

Watch On YouTube


PREVIOUS STEP           NEXT STEP

Odoo Invoice Qr code issues

There are two main issues must of us facing with the QR code in Odoo invoice & these issues are 1/ QR code displayed as broken image w...