Tuesday, July 30, 2019

add item to top right menu in odoo

 

ODOO

menus

top right menu 

 

 

we can add item to user drop down menu in odoo by following the steps bellow
  • create web page as we explain before 
  • then we can add the item to the list as bellow 
<?xml version="1.0" encoding="utf-8"?>
 <templates id='template' xmlspace='preserve'>

  <!--Extends UserMenu -->
   <t t-extend="UserMenu" t-name="UserMenu">

     <t t-jquery="li.divider" t-operation="after">
        <li><a href="/new_item" >New Item</a></li>
     </t>
   </t>

</templates>

// here we have to create the web page by "/new_item" link

how to start new page in report in odoo

ODOO

reports


you can start new page in odoo by adding

<div style="page-break-before: always;">

 also you can use &#160; many time to add spaces unit you can start new page

How to make user choose the language of report

ODOO

reports

 

we can let the user choose the language for report with out change his language as bellow
  • define languages field as bellow 
report_language = fields.Many2one('res.lang','Report Language', required=True)
  • define the external template in which we call the language that entered by the user as bellow 
<template id="report_main_temp">
      <t t-call="report.html_container">
        <t t-foreach="docs" t-as="doc">
          <t t-call="certifications.student_file_template" t-lang="doc.certification_language.code"/>
        </t>
      </t>
    </template>  
  • the we will add internal template in which we will define report body for each language we installed in our system 
 EG : for English language 

<template id="report_file_template">
      <!-- <t t-foreach="docs" t-as="o" > -->
        <t t-set="doc" t-value="doc.with_context({'lang':doc.report_language.code})" />
<t t-if="line(data)[0]['c_language'].code == 'en_US'">
""" the report body in English language """
</t>
</t>
</template>

Tuesday, July 23, 2019

many views for one model in odoo

ODOO

views

 

To explain this let us say we have the student object in which we have the level field which is a selection field as bellow 

level = fields.Selection([('first','First'),('second','Second'),('third','Third')], string="Level")

and we want to put each level's students in single view , so we can do it as bellow 

for each level we have to 
  • add the action record
<record model="ir.actions.act_window" id="first_level_student_action">
            <field name="name">The First Level Students</field>
            <field name="type">ir.actions.act_window</field>
            <field name="res_model">student.student</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
              <field name="domain">[('level','=','first')]</field>
              <field name="context">{}</field>
              <field name="search_view_id" ref="module_name.view_student_search" />
        </record>

// this will only get the students of the first level 
  • add the form view 
<record model="ir.actions.act_window.view" id="first_level_student_action_form">
            <field name="act_window_id" ref="first_level_student_action" />
            <field name="sequence" eval="10" />
            <field name="view_mode">form</field>
            <field name="view_id" ref="module_name.view_first_level_student_form" />
        </record>
  • add the tree view 
<record model="ir.actions.act_window.view" id="first_level_student_action_tree">
            <field name="act_window_id" ref="first_level_student_action" />
            <field name="sequence" eval="20" />
            <field name="view_mode">form</field>
            <field name="view_id" ref="module_name.view_first_level_student_tree" />
        </record>
  • add the menuitem
<menuitem id="first_level_menu" sequence="10" parent="module_name.root_menu"
         action="first_level_student_action" />

how to add barcodes to reports in odoo


ODOO

reports

barcodes

 

 

we can generate two types of barcodes in odoo as the image show , so let us show how we can add any one to our reports

we will start with code (1) and we can add it by following steps
  • add the barcode field in our python file as bellow
barcode = fields.Char('Barcode', size=20)
  • add sql constraints to make barcode unique for each report
 _sql_constraints = [
        ('unique_name_barcode',
         'unique(barcode)',
         'Barcode must be unique per Report!'),
    ]
  • add create function which will create the barcode automatically when we create report 
@api.model
    def create(self,vals):
        """
        Method to create sequence for report barcode
        """
        vals['barcode'] = self.env['ir.sequence'].get('student.student')
        return super(student_student, self).create(vals) 
// student.student is the model which is contain the barcode field 
// student_student the of the class that is contain the barcode field
// this function will create the sequence with the barcode 
  • add the barcode to our report as bellow 
<img t-att-src="'data:image/png;base64,%s'% (get_barcode('Code128',doc.barcode))"/>

Now we  will code the barcode (2) by following the same steps but in our report template we must show the barcode as bellow 

<img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('QR', doc.barcode, 50, 50)" style="width:150px;height:150px;"/>

Monday, July 22, 2019

how to create sequence in odoo

ODOO

fields

 

Sequence is that field which generated automatically by the system and it's unique for each record in the table in the database and we can create it by following these steps 


  • define the sequence field as bellow 
        reference = fields.Char('Reference', readonly=True)
  • define the function which will create the sequence when we create the record as bellow 
      @api.model
       def create(self,vals):
           vals['reference'] = self.env['ir.sequence'].get('academic.year')
           return super(academic_year, self).create(vals)     
  • define the sequence related model and the name of the sequence and other attributes as bellow 
      <record id="student_reference" model="ir.sequence">
          <field name="name">Student Reference</field>
          <field name="prefix">Stu_</field>
          <field name="padding">6</field>
          <field name="code">student.student</field>
       </record>
  • at last we have to add our field to the tree view or other view we want

Saturday, July 20, 2019

fields attributes in odoo

ODOO

fields

attributes 

 

Here we are going to explain odoo field's attributes one by one , so let as start 

  • String

this attribute allow me to control the label of the field in the GUI 
Eg : name = fields.Char(string="Employee Name")// the label of this field will be Employee Name 

  • Required

this attribute defines that the field must be have an inputed value from the user or not in any created record , so it can be set for true or false
Eg :  name = fields.Char(string="Employee Name", required=True) // here we can't create record of this field if we don't insert a value for it 

  • Domain 

this with define the domain to insert a value for this field 
Eg : employee_id = fields.Many2one('employee.employee', string="Employee", domain=[('age','=',25)])// this will allows me to choose from employees with 25 years old only 

  • Default 

this attribute will give default value for the field 
Eg : gender = fields.Selection([('mail','Mail'),('femail','Femail')], default='mail', string="Gender") //  the make the gender = mail as default 

  • Readonly 

this attribute make the user cann't give a value the field , so it show the field just as label "uneditable" and it can take boolean value as true or false
Eg :  gender = fields.Selection([('mail','Mail'),('femail','Femail')], default='mail', string="Gender", readonly=True)// the user cann't choose the gender here

  • Digits 

this attribute is only use with float fields to control precision of a value to set how value will display 
Eg : price = fields.Float(string="Price", digits=(10,3)) // this will show the price as number of 10 integer digits and 3 decimal digits

  • Store

this attribute will save the value of the field forcefully in the database and it take boolean value "true or flase  

  • help

this attribute uesd to make the field more freindly by adding helping message which will show when the user put the mouse cursor over the field 

  •  Compute 

this attribute make the value of the field computed from a function
Eg : name = fields.Char(string="Name", compute="get_name") // this make the value of name field computed from get_name function which can be defined as 

@api.one
def get_name(self):
      self.name = "ABCD" // the function put ABCD as value for the field

  • Copy

this attribute  takes boolean value to control that if the value of the field will copy or not if we duplicate the record
  • Index

this attribute takes boolean value to control that if the field's index will create in the database or not " the field index help us to search for the field in the database directly "

  •  Inverse

this attribute help us to call function when the vlaue of the field changed 
Eg : age  = fields.Integer(string="Age", inverse="get_full_name") // that means the get_full_name function will call when we  change the value of the age field

  • translate

this attribute make you can translate the value of the field into another language 
Eg : name = fields.Char(string="Name", translate=True) 

change addons path in odoo



 In order to create your own modules in odoo you have to put them with odoo modules , or put them in your own path and then change the addons path as bellow 

  • ./odoo-by --addons-path=/home/pfo/Desktop/odoo-11.1.1/addons,/home/pfo/projects/project1

kill odoo running processes


To kill running odoo process we have to go to the terminal and write 
  • ps aux | grep odoo  // to show all running odoo processes
  • kill -9 17702 // to kill the process with 17702 number
 
 
also you can kill all python processes by write
  • kill all python

change odoo server port


      
 Odoo server is run on 8069 as default port but some time we have to change this port for example when we have more than one odoo server in our system , so we can change it as bellow 

$ ./odoo.py --xmlrpc-port='8060' 

in this example we changed it to 8060

install odoo 9 on ubuntu

ODOO

install

 

In order to install odoo 9 on ubuntu you have to open your terminal and write the following commands one by one 
  •  sudo apt-get update  // in order to update your system
  •  sudo apt-get upgrade // in order to upgrade your system's packages 
  • sudo apt-get install python-dateutil python-docutils python-feedparser python-jinja2 python-ldap python-libxslt1 python-lxml python-mako python-mock python-openid python-psycopg2 python-psutil python-pybabel python-pychart python-pydot python-pyparsing python-reportlab python-simplejson python-tz python-unittest2 python-vatnumber python-vobject python-webdav python-werkzeug python-xlwt python-yaml python-zsi poppler-utils python-pip python-pyPdf python-passlib python-decorator  // in order to install all python dependencies for odoo
  • sudo apt-get install gcc python-dev mc bzr python-setuptools python-markupsafe python-reportlab-accel python-zsi python-yaml python-argparse python-openssl python-egenix-mxdatetime python-usb python-serial python-jinja2 python-unittest2 python-mock python-docutils lptools make python-pydot python-psutil python-paramiko poppler-utils python-pdftools antiword //in order to install all supporting packages for Odoo
  • sudo apt-get install -y npm & sudo ln -s /usr/bin/nodejs /usr/bin/node & sudo npm install -g less less-plugin-clean-css // in order to install all web dependencies for odoo
  • sudo apt-get install python-software-properties & sudo apt-get update & sudo apt-get install postgresql // in order to install postgresql
  • sudo su postgres 
  • cd 
  • createuser -s odoo
  • createuser -s your_system_name 
  • exit // by writing this 5 commands we will create two users for the database by names " odoo and your system name"
To run the server open your terminal and go to your server folder path and the write 
  • ./odoo.py  // this will run the server with the default addons , then you have to open your browser and write "localhost:8069" to the database creating window as bellow
 
installation completed successfully :)
 
Now we gonna install the GUI for the database "Pgadmin3" by writing the following command
  • sudo apt-get install pgadmin3
To login the dadabase with user odoo we can use the command
  • sudo -u odoo psql  
and if we forgot the password for this user , we can change it by the command  
  • ALTER USER odoo PASSWORD "your_new_password" 

Friday, July 19, 2019

controllers in odoo


Controllers is a way to make web pages and define unique path "unique URL" for any page
So to create web pages you have to follow these steps 
  • create the controller 
  • create the web page template 


Example :-

Let us say we wanna create login page so we will start with creating controller by create python file with name user_login.py and inside it create the controller as bellow 
    
     from odoo import http

     class user_login(http.Controller):
     @http.route('/user_login_page', type='http', auth='public', website=True)
     def render_login_page(self, **kw):

            user_ids = http.request.env['user.user'].search([])
            check_value = 0
            if kw.get('longin_password') and kw.get('login_email'):
                for rec in user_ids:
                    if rec.passwprd == kw['longin_password'] and rec.email == kw['login_email']:
                        check_value = check_value+1
                        return http.request.render('module_name.login_page_temp', {'docs': rec})
                if check_value == 0:
                    return http.request.render('module_name.login_error_temp', {})

Now let us explain what we did :

 class user_login(http.Controller): // define class user_login as controller class
 @http.route('/user_login_page', type='http', auth='public', website=True)
http.route // to define that we want to make routing 
 /user_login_page // this will be the url of our web page "localhost:8069/web/user_login_page"
 type='http' // to define that our page will run in http 
 auth='public' //  define the page four pubic user 
 website=True // to link the page 
then inside the function we take the email end the password from the web page " if kw.get('longin_password') and kw.get('login_email'): " and compare them with which saved in the database " if rec.passwprd == kw['longin_password'] and rec.email == kw['login_email']:" and return true if it's true or return error page "return http.request.render('module_name.login_error_temp', {})" if it's wrong 

then we will create template with name user_login_page to design the web page as bellow 

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

      <template id="user_login_page_id" name="User Login Page" page="True">
    <t t-call="website.layout">
      <div class="oe_structure oe_empty">
        <div class="container">
          <center>
            <br></br><br></br><br></br>
            <form class="oe_login_form" role="form" t-attf-action="/user_login_page{{ '?debug' if debug else '' }}" method="post" >
              <div class="form-group form-field o_website_form_required_custom">   
                <label class="col-md-4 col-sm-5 control-label" for="login_email" style="color:#6666ff;">
                                 
                </label>
                <div class="col-md-5 col-sm-6">      
                  <input type="text" class="form-control o_website_form_input" name="login_email" required="1" style="width:250px;text-align:center;border-color:#e67300;" placeholder="Email"/>  
                </div>
                <br></br><br></br>
                <label class="col-md-4 col-sm-5 control-label" for="longin_password" style="color:#6666ff;">
                           
                </label>
                <div class="col-md-5 col-sm-6">      
                  <input type="longin_password" class="form-control o_website_form_input" name="longin_password" required="1" style="width:250px;text-align:center;border-color:#e67300;" placeholder="password"/>  
                </div>
              </div>
              <br></br><br></br> 
              <div class="form-group">
                <div class="col-md-offset-3 col-sm-offset-4 col-sm-8 col-md-7">
                  <input type="hidden" name="redirect" t-att-value="redirect"/>
                  <button type="submit" class="btn" style="background-color:#e67300;">Login</button>
                </div>
              </div>
            </form>
          </center>
        </div>
      </div>
    </t>
  </template>

</data>
</openerp> 

The last important thing that we have to create the login_error_temp page which will called if there is an error with the entered login data with error message in the same way of creating the user_login_temp

odoo.exceptions.UserError: ("No inverse field None found for '_unknown'", '')

ODOO

errors

 

This error usually happens with relational field when they defined in wrong way for example 

student_id = fields.One2many(string="Student")

here I don't defined the relational object for this field , so that will make the same error

Tuesday, July 16, 2019

thread in odoo


Let us say we have 10000 employees record and we want to increase the performance of processes on these records , in this case we can use the thread 

So :
 

Tread is away to distribute the work into many processes which are running at the same time , and that will increase the performance of our server


Example :- 

   let us say that we want to display the multiplication table of number inserted by the user 

   we will define the object which contain the fields and the functions , then create four function each one make the multiplication table for the number with only 3 numbers , then we will call the four functions at the same time by using threads


from odoo import models, fields, api, _ 
import threading

class
multiplication_table(models.Model):
    _name = '
multiplication.table'
    
    number = fields.Interger('Number', required=True)

    def thread1(self):
          for x in xrange(1,4):
                print (self.number," * ",x,"=",self.number*x)
   
    def thread2(self):
          for x in xrange(4,7):
                print (self.number," * ",x,"=",self.number*x)

    def thread3(self):
          for x in xrange(7,10):
                print (self.number," * ",x,"=",self.number*x)

    def thread4(self):
          for x in xrange(10,13):
                print (self.number," * ",x,"=",self.number*x)

    t1= threading.Thread(target=self.thread1, args=())
    t2= threading.Thread(target=self.thread2, args=())
    t3= threading.Thread(target=self.thread3, args=())
    t4= threading.Thread(target=self.thread4, args=())

    t1.start()
    t2.start()
    t3.start()
    t4.start()  
          

Thursday, July 11, 2019

report from wizard in odoo

 
To show how to generate report from wizard let me give a simple definition of report in odoo 
  • The  report is a xml template read and show data from python file 
so if we want to generate report we have to pass the data form the python file to the template we designed , so we can say that we have 2 cases here 
  1. we want to generate report for single record , so we can linked the model with the template directly and read the fields that we want to show in our template 
  2. we want to show data from multi records and depends on some conditions , so we must get the data we want first and then pass it to the template and that can make by using wizard by following the steps below 
  • create the transient model "the wizard model" which will contain the function that will pass the needed data to the report template , and of course create it view "the wizard view"
  • create template and design it's form
  • link the model with the template to make data move form the model to the template 
Now let us make an example

let us say we have model contain the student data by name student.py as below , and we want to generate report of students who age is in range defined by the user 


from openerp import models, fields, api, _

class Student(models.Model):
    _name = 'student.student'

    """
        contain all student data
    """
    name = fields.Char('Name', required=True)
    age = fields.Integer('Age', required=True)
    phone = fields.Integer('Phone', required=True)
    email = fields.Char('Email', required=True)
so first we gonna create wizard by name student_report_wiz.py and we gonna add two integers fields to make the user define the range of age , after that we will take the two values which entered by the user and go to the student model and get the id of any student whose age is less than the max value and larger than the min value which are defined by the user , and push all ids in dictionary which passed to the template , as below

from openerp import models, api

class student_report_wiz(models.TransientModel):
    """
        get students by age range
    """
   
    _name = 'student.report.wiz'
      
    max_age = fields.Integer('Max Age', required=True)
    min_age = fields.Integer('Min Age', required=True)

    @api.multi
    def get_students(self):
           student_ids = self.env['student.student'].search([])
           student_list = []

           for rec in student_ids :
                 if rec.age > self.min_age and rec.age < self.max_age"
                        student_list.append(rec.id)
           student_dic = {stud_list: student_list}
           return student_dic
           return self.pool['report'].get_action(cr, uid, [],          'module_name.students_age_report_temp', data=student_dic, context=context)
Now we get all student we want in student_dic , then we will create the report py file by name students_age_report.py as below 

    class students_age_report(report_sxw.rml_parse):

    def __init__(self, cr, uid, name, context):
        self.context = context
        super(students_age_report, self).__init__(cr, uid, name, context)
        self.localcontext.update({
            'line':self._getdata,
        })

    def _getdata(self,data):

        """
        method that return student's in age range
        """

        lines = {}
        lines = data['form']
        return lines
   
class students_age_report_details(osv.AbstractModel):
    _name = 'report.module_name.students_age_report_temp'
    _inherit = 'report.abstract_report'
    _template = 'module_name.students_age_report_temp'
    _wrapped_report_class = students_age_report
                                                                                                                                                                        then we will create template by id students_age_report_temp as below 
                                                                                                                                                  <?xml version="1.0" encoding="utf-8" ?>
<openerp>
    <data >

        <!-- ...Define Template... -->

        <template id="students_age_report_temp">
            <t t-call="report.html_container">
                <div class="page">
                    <header>
                        <center>
                            <div style="float:left; width:80%;">
                                <div style="float:right; width:75%;">
                                    <b style="font-family:Georgia, serif;font-size:16px;">
                                        student by age range
                                    </b>
                                    <br></br><br></br>
                                </div>
                                <div>
                                        <table>
                                                 <th>
                                                        <td>
                                                               <b style="size:16px;">
                                                                     name
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     age
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     phone
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     email
                                                               </b>
                                                         </td>
                                                 </th>
                                               <t t-foreach="line(data)" t-as="line" >
                                                 <tr>
                                                        <td>
                                                               <b style="size:16px;">
                                                                     <span t-esc="line(data).name"/>
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     <span t-esc="line(data).age"/>
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     <span t-esc="line(data).phone"/>
                                                               </b>
                                                         </td>
                                                         <td>
                                                               <b style="size:16px;">
                                                                     <span t-esc="line(data).email"/>
                                                               </b>
                                                         </td>
                                                 </tr>
                                        </table
                                </div>
                        </div>
                    </p>
                </div>
            </t>
        </template>

        <!-- """create report """ -->

        <report
        id="students_age_report_id"
        string="Students By Age Report"
        model="student.student"
        report_type="qweb-pdf"
        name="maodule_name.students_age_report_temp"
        menu="False"
        />
        <record id="report.paperformat_euro" model="report.paperformat">
            <field name="margin_top">15</field>
            <field name="margin_bottom">15</field>
            <field name="margin_left">15</field>
            <field name="margin_right">15</field>
            <field name="header_spacing">15</field>
        </record>

    </data>
</openerp>
                                                                                                                                                          >>>DONE

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...