0% found this document useful (0 votes)
42 views111 pages

TAI Odoo Technical Training V1.0 7

Uploaded by

ufukhatti2013
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views111 pages

TAI Odoo Technical Training V1.0 7

Uploaded by

ufukhatti2013
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 111

Odoo Technical Training

September 2019

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Index

● Objectives of this Program


● Reference material
● Preparing the development environment
● Getting started
● Debugging
● Case Study - Partner Certifications
● Get to know the OCA resources
● Key Business Apps in Odoo
● Integration with other systems
● Program Summary

2
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Objectives of this Program

3
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Objectives of this Program

● Understand the Odoo ecosystem.


● Learn different methods to set up an Odoo environment.
● Learn how to develop applications in Odoo, following practical cases.
● Understand how to adopt the best practices from the OCA and to collaborate with other OCA
members.
● Obtain a general understanding of the key Odoo Business Apps, and their technical
architecture.
● Learn the techniques to integrate Odoo with external systems.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Reference material

5
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Reference Material

● Odoo 12 Development Cookbok, Third Edition


https://www.packtpub.com/application-development/odoo-12-development-cookbook-third-edition

● Odoo Technical Documentation


https://www.odoo.com/documentation/12.0/

● OCA Guidelines
https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst

Copyright 2019 Eficent Business and IT Consulting Services S.L.


The Odoo Ecosystem

7
Copyright 2019 Eficent Business and IT Consulting Services S.L.
The Odoo Ecosystem

Partners

OCA Repos
LGPLv3
AGPL v3

Contributors

The Odoo Enterprise contract includes:


● Bugfix support
● Migration services Private
● Proprietary applications Repos
LGPLv3
https://www.odoo.com/page/editions AGPL v3
Private

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the Environment

9
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Preparing the Environment
Learning Objectives

● Install Odoo from source


● Use Pycharm as your development environment
● Manage Odoo databases

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment

11
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Preparing the environment

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment
# Install system dependencies
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install python3-dev python3-pip
sudo apt-get install build-essential libxslt-dev libzip-dev libldap2-dev libsasl2-dev libssl-dev
sudo pip3 install virtualenv
# Install Postgres
sudo apt-get install postgresql
sudo -u postgres createuser --createdb $(whoami)
sudo -u postgres psql
psql=# alter user <username> with encrypted password '<password>';
# Install Odoo
mkdir ~/odoo-dev
cd ~/odoo-dev
git clone https://github.com/odoo/odoo.git -b 12.0 --depth=1
# Install python virtual environment
cd ~/odoo-dev
virtualenv -p python3 env
source ~/odoo-dev/env/bin/activate
pip install -r ~/odoo-dev/odoo/requirements.txt

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment
Run Odoo in PyCharm

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Preparing the environment

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting Started

18
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Getting started
Learning Objectives

● Installing add-on modules from GitHub


● Configuring the add-ons path
● Updating the add-on modules list
● Installing and upgrading local add-on modules
● Organizing the add-on module file structure

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Open the browser and access to http://localhost:8069/

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Install the “Contacts” app

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

Business requirement

Aeronix captures information about the gender of their contacts. It is needed to


find this field in the contact form.
First step would be to search if a module already solves this need in the OCA
(Odoo Community Association) repositories.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Clone the OCA repository partner-contact
Installing add-on modules from
cd ~/odoo-dev GitHub
git clone https://github.com/OCA/partner-contact.git -b 12.0
Configuring the addons path
● Add the new repo to the addons path in PyCharm

--addons-path=/home/<myuser>/od
oo-dev/odoo/addons,/home/<myuse
r>/odoo-dev/odoo/odoo/addons,/ho
me/<myuser>/odoo-dev/partner-con
tact

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Clone the OCA repository partner-contact

cd ~/odoo-dev
git clone https://github.com/OCA/partner-contact.git -b 12.0

● Add the new repo to the addons path in PyCharm

--addons-path=/home/<myuser>/od
oo-dev/odoo/addons,/home/<myuse
r>/odoo-dev/odoo/odoo/addons,/ho
me/<myuser>/odoo-dev/partner-con
tact

Stop and re-run Odoo

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Updating the available modules in Odoo

Go to “Settings > Activate the developer mode”

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Updating the available modules in Odoo
Updating the addons module list
Go to ‘Apps > Update Apps List’

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Install the module
Installing and upgrading local add-on
Search for the module in the apps modules

Tip: some modules are classified as “Apps”, but not all. Remove the filter
during your searches in the apps.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Review the results

Copyright 2019 Eficent Business and IT Consulting Services S.L.


● Organizing the add-on module file structure

Getting started
Organizing the add-on
Exercise module file structure

● Understanding the structure of an Odoo module

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Understanding what happened when you installed the odoo module

Go to ‘Settings / Technical / Database Structure / Models’


- The model ‘res.partner’ has been extended with a new field.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
- In the database, the table “res_partner” has been extended with a new column ‘gender’.

Install DBeaver
https://dbeaver.io/

In dbeaver, select the new database,


and run the following query:

select name, gender from res_partner;

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Understanding what happened when you installed the odoo module

Go to ‘Settings / Technical / User Interface / Views’


- The view Partner Gender is now included in the database.
- Partner Gender View is adding information to its inherited view

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

Business requirement

Aeronix captures information about contact’s driving license. It is needed to find


this field in the contact form.
First step would be to search if a module already solves this need in the OCA
(Odoo Community Association) repositories. In this case, the module does not
solve our necessities, a new one must be created.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started

● Create your GitHub account


● Create a Fork in https://github.com/Eficent/odoo-training-tr

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Preparing our custom modules working directory

cd ~/odoo-dev/
git clone https://github.com/<my_github_user>/odoo-training-tr # Your forked repository
cd odoo-training-tr
git config --global user.email "<[email protected]>"
git config --global user.name "<my_gihub_name>"
printf 'My Odoo Custom Addons\n' > README.md
git add .
git commit -m 'Add Readme'
git push

Note
Now you will have to introduce your username and your password of GitHub.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● For simplicity we copy a similar example to our needs:

● We give a proper name to our new addon:

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
● Sequence of modifications in order to create the new custom module:

1st step: Changes in __manifest__.py

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise
2nd step: Changes in README.rst

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

3rd step: Adding new field to entity res.partner

https://www.odoo.com/documentation/12.0/reference/orm.html#fields

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

4th step: Including the new field in the view

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Add the brand new custom_addons path in PyCharm

--addons-path=/home/<myuser>/od
oo-dev/odoo/addons,/home/<myuse
r>/odoo-dev/odoo/odoo/addons,/ho
me/<myuser>/odoo-dev/partner-con
tact,/home/<myuser>/odoo-dev/odo
o-training-tr

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Updating the available modules in Odoo to include our new module

Go to ‘Apps > Update Apps List’

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Install the module

Search for the module in the apps

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Our module is available!

We can install it now

Tip: You can automatically install the module by putting in the configuration parameters -i
<name_of_the_module> -d <database_name>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

● Review the results

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Getting started
Exercise

- In the database, the table “res_partner” has been extended with a new column ‘driving_license’.

Select a new database:

… and write on the script:

select name, driving_license from res_partner;

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Debugging

49
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Debugging
Learning Objectives

● Debug Odoo using Pycharm


● Understanding the debug mode options
● Useful odoo-bin inline options
● Using the Odoo Community Association maintainer quality tools

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Debugging
Key Concepts

Debug Odoo using Pycharm


○ Add breakpoints
○ Run in debugging mode
○ Debugging Shortcuts
■ F7 -> Step into
■ F8 -> Step over
■ F9 -> Resume program (Go to next breakpoint)
○ Debugger Control Panel

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Debugging
Key Concepts

Understanding the debug mode options


○ Activate the development mode
■ From Settings
■ Adding debug directly in URL
http://localhost:8069/web?debug#action=77&menu_id=4
■ Install Odoo Debug Plugin: Firefox or Chrome
○ Extra information in Field views (hovering a field in a form)
○ Open actual view information (Edit View option)
○ Open View (We can jump to any view in the system)
○ View Metadata (Information about last modification user)
○ Enable view items with group
<field name="request_date" groups="base.group_no_one"/>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Debugging
Key Concepts

Useful odoo-bin inline options


-d Select specific DB
-i Install a module
-u Update a module
--log-level=debug Display debug logs
--test-enable Enable test on install/upd
--without-demo=all Don’t load demo
data
--workers=0 Only one thread to debug
--dev=xml Odoo use xml file views
--stop-after-init Stop odoo after it is load
More info: ./odoo-bin --help
or
https://www.odoo.com/documentation/12.0/reference/cmdline.html

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Debugging
Exercise

Using the debug mode,

● Add breakpoints on certification module methods, and debug them.


● Add breakpoints on partner_certification_status on test and methods,
debug it without starting Odoo browser following the inline options
shown in the previous slide. (tip: Demo data required to do the test)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study
Partner Certifications

55
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Case study - Partner Certifications
Business case

Aeronix needs to record certifications documents of its suppliers, employees and customers to easily manage the
information. The requirements of this module are the following ones:

● Each certificate would be associated to one partner (supplier or customer). It would be designated with a
number as it must be unique. In this certification document it should be a record of the following fields:
○ Certification entity, standard certifications, description, owner...
○ Expiry date, expiry days (days left until expiration), expiry status.
● Standard certifications can be associated to more than one partner. These are general certifications that would
be included in the certification document referred to a unique partner. They must include name and
● Only partners which are certification entities can create certifications documents.
● In the contact form of each partner it must be shown a list of all certifications related to this partner.
● In the contact form it needs to be defined if the contact is a certification entity or not.
● When creating a certificate, only partners which are certification bodies must appear in the selection window
from the form view (hint: Create a domain)
● Create a button to add more days to Expiration Date [1 month]

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Functional design

Certification model Partner Standard model

Certification
● Number:VMA-002P Certificate owner
● Validation Date: ● Aero Fasteners Co.
09/20/2019

Certifying entity
● AEA Quality Advantage
Corporation

Certification Standard
● AS9003

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Learning Objectives
● Creating and installing a new add-on module ● Using external IDs and namespaces
● Completing the add-on module manifest ● Loading data using XML files
● Organizing the add-on module file structure ● Using the noupdate and forcecreate flags
● Adding models ● Loading data using CSV files
● Adding menu items and views ● Creating security groups and assigning them to users
● Adding Access Security ● Python test cases
● Understanding the model ● Defining a model based on an SQL view
○ Odoo fields and fields attributes ● Defining graph and pivot views
● Extending a model ● Creating QWeb-based PDF reports
● Changing existing views – view inheritance
● Extending a view
● Defining filters on record lists-Domain
● Defining model methods and using API decorators
● Extending the business logic defined in a model
● Reporting errors to the user
● Creating new records
● Updating values of recordset records

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

Creating and installing a new


1st step: create __manifest__.py and__init__.py files add-on module

Completing the add-on


module manifest

Key Concepts

The model layer


Data will be added in ● Data model
the following steps
● Access security
The view layer
● Add menu items
● Add form, tree
views

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Key concepts

● Sample template: https://github.com/OCA/maintainer-tools/tree/master/template/module


● Guidelines on how to name a module
https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#1
1modules
● __manifest__.py
○ Copyrights
○ Licenses - LGPL, AGPL, OPL
○ version - see
https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTIN
G.rst#version-numbers

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

2nd Step: Creation of the model

from odoo import models, fields, api


from odoo import models,fields

class Certification(models.Model):
_name = 'certification'
Note
class CertificationStandard(models.Model):
_description = 'Certification' _name = 'certification.standard' ‘certification_standard.py’
_description = 'Certification Types’ model:
number = fields.Char() Needed to compile all the
date = fields.Date(string='Validation Date') name = fields.Char() certification types that the
description = fields.Text(string='Validation Details') description = fields.Text() company owns.
standard_id =
fields.Many2one(”certification.standard”)
owner_id = fields.Many2one("res.partner")
entity_id = fields.Many2one('res.partner')

Adding models
_name = [Defines internal global identifier for the Model, it gives the name to the database]
_description = [Title to the model]

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Key concepts
Odoo fields and fields
● Basic model fields attributes
● Odoo fields and fields attributes
https://www.odoo.com/documentation/12.0/reference/orm.html#fields

● Relational fields: Many2one, One2many, Many2many


● Text fields: Char, Text, HTML
● Numeric fields: Integer, Float, Monetary
● Datetime fields: Datetime, Date
● Computed fields: Fill fields automatically
● Other related fields: store/non store
● Most used attributes: required, readonly, compute, related, domain, store

Additional Exercise: Identify modules that use each one of these fields in the partner-contact repository
(https://github.com/OCA/partner-contact). Install and evaluate them.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

2nd Step: Creation of the model

from . import certification


from . import certification_standard

from . import models

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

3rd Step: Creation of views - Certification Tree view

<record id="certification_view_list" model="ir.ui.view">


<field name="name">Certification</field>
<field name="model">certification</field>
<field name="arch" type="xml">
<tree string="Certification">
<field name="number"/>
<field name="date"/>
<field name="standard_id"/>
<field name="entity_id"/>
<field name="owner_id"/>
</tree>
</field>
</record>
Adding views

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

3rd Step: Creation of views - Certification Form view

<record id="certification_form" model="ir.ui.view">


<field name="name">Certification</field>
<field name="model">certification</field>
<field name="arch" type="xml">
<form string="Certification">
<sheet>
<group>
<field name="number"/>
<field name="description"/>
<field name="date"/>
<field name="standard_id"/>
<field name="entity_id"/>
<field name="owner_id"/>
</group>
</sheet>
</form>
</field>
</record>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

3rd Step: Creation of views - Certification Action and Menu

<record id="certification" model="ir.actions.act_window">


<field name="name">Certification</field>
<field name="res_model">certification</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem
name="Certification"
id="certification_menu"
sequence="5"
action="certification"/>

</odoo>

Adding menu items

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module
3rd Step: Creation of views - Standard View
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="standard_view_list" model="ir.ui.view">
<field name="name">Standards</field>
<field name="model">certification.standard</field> Tree View
<field name="arch" type="xml">
<tree string="Standard">
<field name="name"/>
<field name="description"/>
</tree>
</field>
</record>

<record id="standard_form" model="ir.ui.view">


<field name="name">Standards</field>
<field name="model">certification.standard</field>
<field name="arch" type="xml">
<form string="Standard"> Form View
<sheet>
<group>
<field name="name"/>
<field name="description"/>
</group>
</sheet>
</form>
</field>
</record>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module
3rd Step: Creation of views - Standard View

<record id="open_standard" model="ir.actions.act_window">


<field name="name">Standards</field>
<field name="res_model">certification.standard</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem
Action Menu
id="Standard"
parent="certification_menu"
sequence="5"
action="open_standard"/>
</odoo>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create the certification module

4th Step: Create security folder with a 5th step: Add data on __manifest__.py
ir.access..model.csv file
{
'name': 'Certification',
'summary': "Defines certification for different purposes.",
'author': "Eficent, Odoo Community Association (OCA)",
'website': "https://github.com/<my_github_user>",
'category': 'Certification Management',
'version': '12.0.1.0.0',
'license': 'AGPL-3',
'depends': ['base'],
'data': ['security/ir.model.access.csv',
'views/certification_view.xml',
'views/res_partner_view.xml',
'views/standard_view.xml'
],
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 'demo': ['demo/certification_demo.xml'],
access_certification_user,certification.user,model_certification,base.group_user,1,1,1,1 'development_status': 'Beta',
access_certification_standard_user,certification.standard.user,model_standard,base.group_ 'maintainers': ['ceeficent']
user,1,1,1,1 }

Adding Access Security

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Additional exercise

Aeronix collects information referred to their employees identity documents. The


fields needed to be fulfilled are:
● Employee’s name
● Type (Passport, ID Card, Driving License)
● Identification number

This module must appear on the Main Menu.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Link certifications to partners
● Extending the res.partner model
from odoo import models, fields

class ResPartner(models.Model):
_inherit = 'res.partner'

certification_ids = fields.One2many(comodel_name='certification', inverse_name='owner_id')


is_certification_body = fields.Boolean(string='It is an entity', default='True',
help='Check this box if the contact is a certification entity')

Extending a model

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Link certifications to partners

● Extending res.partner view


Partner form
<page name='internal_notes' string="Internal Notes">
<field name="comment" placeholder="Internal note..."/>
</page>
<page name='sales_purchases' string="Sales &amp;
Purchases">
<group name="container_row_2">

<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">partner.certification.entity.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
Note <field name="arch" type="xml">
<field name="category_id" position="after">
Position: <field name="is_certification_body"/>
● After </field>
<xpath expr="//page[@name='internal_notes']" position="after">
● Before <page name ="certification" string="Certifications List">
● Inside <field name="certification_ids"/>
</page> Extending a view
● Replace
</xpath>
</field> Changing existing views –
</record>
</odoo> view inheritance

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Ensure data integrity in the certificate

● model method Defining model methods and using


● self and self.env API decorators
● API decorator(api.multi, api.model, api.constrains)
Reporting errors to the user
● Add: from odoo.exceptions import ValidationError

@api.constrains('entity_id')
def _check_entity_id(self):
if self.entity_id and self.entity_id.is_certification_body == False:
raise ValidationError('It is not a certification entity')

Reporting error to the user

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Set domain in the certification form

<record id="certification_form" model="ir.ui.view">


<field name="name">Certification</field>
<field name="model">certification</field>
<field name="arch" type="xml">
<form string="Certification">
<sheet>
<group>
<field name="number"/>
<field name="description"/>
<field name="date"/>
<field name="standard_id"/>
<field name="entity_id" domain="[('is_certification_body','=','True')]"/>
<field name="owner_id"/>
<field name="expiry_days"/>
<field name="expiry_status"/>
<field name="owner_id"/>
<button name="update_date_one_month" string="update date 1 month" type="object" />
</group>
</sheet>
</form>
</field>
</record>

Define filters on record list -


Domain

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Creation of a certification entity list

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


<odoo>
<record id="certification_bodies_view_list" model="ir.ui.view">
<field name="name">Certification Bodies</field>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<tree string="Certification Bodies">
<field name="name"/>
<field name="phone"/>
</tree>
</field>
</record>

<record id="action_certification_bodies" model="ir.actions.act_window">


<field name="name">Certification Bodies</field>
<field name="res_model">res.partner</field>
<field name="domain">[('is_certification_body', '=', True)]</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem
id="certification.bodies"
parent="certification_menu"
sequence="5"
action="action_certification_bodies"/>

</odoo>

Note
For this view form it is needed to create a new .xml file.
In this case the domain is used to create a list which compiles all certification entities recorded in our
database.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Key Concepts
Defining filters on record lists – Domain

● Simple domain, list of 3 tuples: [(‘string’, ‘operator’, value)]


● Combination of simple domains using “&” (and operator) and “|” (or operators)
● From operator logic to domain logic:
○ From deeper logic block, move operator inside () at first place beginning. Repeat until all operators
have been move at first place. Then add commas between every element.
((A & B) | (C & D)) Operator logic
((&AB) | (&CD)) First iteration
|((&AB)(&CD)) Second iteration, no more operators to move -> Finished
[“|”, “&”, A, B, “&”, C, D] Domain logic
● Common usages
○ search([(‘entity_id’, ’=’, True)])
○ add a filter_domain to a field, for example:
■ <field name=”entity_id” domain=”[(‘entity_id’, ‘=’, True)]”/>
○ or directly in field definition:
■ entity_id = fields.Many2one(... domain=[(‘entity_id’, ‘=’, True)] ...)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Key Concepts
Domain operators

Operator (equivalent) Usage

= , != [(‘uid’, ‘=’, 1)], [(‘uid’, ‘!=’, 1)]

in, not in [(‘uid’, ‘in’, [‘1’,’2’,’3’])], [(‘uid’, ‘not in’, [‘1’,’2’,’3’])]

<, <=, >, >= [(‘date’, ‘>=’, self.date)]

like, not like name=‘Pepero’; [(‘name’, ‘like’, ‘Pepe’)]

ilike, not ilike Same as above case insensitive

child_of [('location_id', 'child_of', location_id.id)]


Used in models with parent_id
Look for locations children of main location_id

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Adding expiry information to the certificate Extending the business logic defined in a model
Updating values of recordset records
1st step: Add fields to the certificate model 4th step: Extend view
expiry_days = fields.Integer('Expiry Days', readonly=True, <group>
compute='_compute_expiry_days') <field name="number"/>
expiry_status = fields.Selection([ <field name="owner_id"/>
('expired', "Expired"), <field name="description"/>
('available', "Available") <field name="date"/>
], readonly=True, compute='_compute_expiry_days', store=True) <button name="update_date_one_month" string="Update the
validation date one month" type="object"/>
<field name="standard_id"/>
<field name="entity_id"/>
<field name="expiry_days"/>
<field name="expiry_status"/>
</group>

2nd step: Create a method which computes the expiry


status of each certification
3rd step: Add method updating expiry date by 1 month
@api.depends ('date')
def _compute_expiry_days(self):
@api.multi
if self.date:
def update_date_one_month(self):
self.expiry_days = (self.date - fields.Date.today()).days
self.ensure_one()
if self.expiry_days > 0:
if self.date:
self.expiry_status = 'available'
self.write({'date': self.date +
else:
timedelta(days=30)})
self.expiry_status = 'expired'

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Key Concepts
@api.multi
def update_date_one_month(self):
○ Direct Assignation self.ensure_one()
if self.date:
self.date += timedelta(days=30)

@api.multi
def update_date_one_month(self):
○ update() method self.ensure_one()
if self.date:
self.update({'date': self.date +
timedelta(days=30)})

@api.multi
def update_date_one_month(self):
self.ensure_one()
○ write() method if self.date:
self.write({'date': self.date +
timedelta(days=30)})

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Key Concepts
Odoo Shell: CLI in Odoo

# Open a new terminal in Pycharm.


$ export db_name=12.0-odoo-training-tai
$ ./home/$USER/odoo-dev/odoo/odoo-bin
--addons-path=/home/$USER/odoo-dev/odoo/addons,/home/$USER/odoo-dev/odoo/odoo/addons,/home/$U
SER/odoo-dev/partner-contact,/home/$USER/odoo-dev/odoo-training-tr shell -d $db_name
>>> self.env['certification'].create({'name': 'Test Certification 2', 'type': 'eucer'})
>>> test_certificate = self.env['certification'].search([('name', '=', 'Test Certification 2')])
>>> test_certificate.name # Test Certification 2
>>> entity = self.env['res.partner'].create({'name': 'Test Entity', 'entity': True})
>>> test_certificate.write({'entity_id': entity.id})
>>> test_certificate = self.env['certification'].search([('entity_id', '=', entity.id)])
>>> entity_mapped = self.env['certification'].search([('entity_id', '=', entity.id)]).mapped('entity_id')
>>> entity_mapped.name # Test Entity
>>> test_certificate.unlink() # Unlink certification
>>> entity.unlink() # Unlink partner
>>> env.cr.commit() # Commit changes to the database
>>> quit()

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Add demo data
2nd step: Define an Entity, a Supplier, a Standard 3rd step: Add path to __manifest__.py
1st step: Defining demo data directory
and a Certification for demo purposes
{
<?xml version="1.0" encoding="utf-8"?> 'name': 'Certification',
<odoo noupdate="1"> 'summary': "Defines certification for different purposes.",
'author': "Eficent, Odoo Community Association (OCA)",
<record id ="entity_demo"
'website': "https://github.com/<my_github_user>",
model="res.partner">
<field name="name">Entity Demo</field> 'category': 'Certification Management',
<field name="is_certification_body">True</field> 'version': '12.0.1.0.0',
</record> 'license': 'AGPL-3',
'depends': ['base'],
<record id ="supplier_demo" 'data': ['security/ir.model.access.csv',
model="res.partner"> 'views/certification_view.xml',
<field name="name">Supplier Demo</field> 'views/res_partner_view.xml',
<field name="is_certification_body">False</field> 'views/standard_view.xml'
</record> ],
Result in Odoo <record id ="standard_demo" 'demo': ['demo/certification_demo.xml'],
model="standard"> 'development_status': 'Beta',
<field name="name">Standard Demo</field> 'maintainers': ['ceeficent']
</record>
}
<record id ="certification_demo"
model="certification">
<field name="number">Demo Certification</field>
<field name="date">2019-12-31</field>
<field name="standard_id" eval="ref('standard_demo')"/> Loading data using XML files
<field name="entity_id" eval="ref('entity_demo')"/>
<field name="owner_id" eval="ref('supplier_demo')"/>
</record> Using the nonupdate flag
</odoo>
Using external IDs and namespaces

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Additional Exercise

Using the identity documents example, try to add some business logic to that
module.

● Add demo data in the identity documents module. It is mandatory to include


a passport record with its number and expiration date of a Demo Employee.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Define security groups to model Certification

● Defining security groups


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

<record model="ir.module.category" id="module_category_certification">


<field name="name">Certification</field>
<field name="sequence">10</field>
</record>

<record id="group_certification_user" model="res.groups">


<field name="name">Certification User</field>
<field name="category_id" ref="module_category_certification"/>
</record>

<record id="group_certification_manager" model="res.groups">


<field name="name">Certification Manager</field>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
<field name="implied_ids"
eval="[(4, ref('group_certification_user'))]"/>
<field name="category_id" ref="module_category_certification"/>
</record>

</odoo>
Creating security groups and
assigning them to users

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Add Access Control Limitations

Key Concepts
name Name identification
users Users that we want to belong in this group (generally, admin and root user)
implied_ids Inherited groups (generally, Managers belongs to Users group also)
category_id We can define a category to wrap similar groups (model ir_module_category)
domain_force * Not yet! Trickier statement. Coming soon, after explanation about domains.

<record id="group_certification_manager" model="res.groups">


<field name="name">Certification Manager</field>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
<field name="implied_ids"
eval="[(4, ref('group_certification_user'))]"/>
<field name="category_id" ref="module_category_certification"/>
</record>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Add Access Control Limitations Loading data using CSV files

Key Concepts
id It must be an unique identificator in all system
name It will be displayed in ACL rules
model_id:id It needs model_ prefix and model name underscored (ex. model_res_partner)
group_id:id Group name. Namespace is required if group is defined in other module.
perm_* 1 to allow action, 0 to block action (1,0,0,0 Only read, 1,1,1,1 Full CRUD access)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications

Additional Exercise

Using the identity documents example, try to add some business logic to that
module.

● Only the managers can edit the information related to identity documents.
Create two different groups: managers and users. Then, establish the
appropriate security rules.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create a test
2nd step: Create a TestCertification class which will
1st step: Create a test directory
verify the expiry_status operation

import odoo.tests.common as common

class TestCertification(common.TransactionCase):

def setUp(self):
from . import test_certification super(TestCertification, self).setUp()
self.res_partner = self.env['res.partner']
self.partner = self.res_partner.create({
'name': "test1",
'email': "[email protected]"})

def test_certification(self):
certification = self.env['certification'].create({
'number': 'AAA',
'date': '2025-12-31'}) Python test cases
self.assertEqual(certification.expiry_status, 'available')
3rd step: Check if the test has run properly

2019-08-27 10:07:29,128 12621 INFO certification_v2 odoo.addons.certification_v2.tests.test_certification: Ran 1 test in 0.067s


2019-08-27 10:07:29,128 12621 INFO certification_v2 odoo.addons.certification_v2.tests.test_certification: OK

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports

Defining a model based on an SQL view is used:


● To aggregate data from several models in a single table
● Perform operations on data
● Reporting and producing dashboard

Additional Business Requirements

Aeronix needs to define a Certification Analysis report in which they require to appear the following
information:
● The main objective is to obtain a table where there is a record of the certification entities with
the number of certificates they have emitted and their status.
● Certificates that have been emitted need to refer to the standard certification they have been
attached with.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports

1st step: Create a new directory 2nd step: [Recommendation] Defining a model based on
named Reports Create a PostgreSQL Query an SQL view

SELECT
rp.id AS id,
rp.id AS entity_id,
cs.id AS standard_id,
c.expiry_status AS expiry_status,
count(c.id) AS certification_count
from res_partner AS rp
JOIN certification AS c
ON c.entity_id = rp.id
JOIN certification_standard AS cs
ON cs.id = c.standard_id
where rp.is_certification_body is True
GROUP BY
rp.id,
from . import certification_report rp.id,
cs.id,
c.expiry_status
Note
Remember to add it on the
Manifest and give Security to
the model.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports
Include Query into certification_report.py
3rd step: Create certification_report.py model
def _select(self):
select_str = """
Define certification_report.py model: SELECT
rp.id AS id,
rp.id AS entity_id, Execute Query
from psycopg2.extensions import AsIs
cs.id AS standard_id,
c.expiry_status AS expiry_status, @api.model_cr
from odoo import tools count(c.id) AS certification_count def init(self):
from odoo import api, fields, models """
tools.drop_view_if_exists(self.env.cr,
return select_str
self._table)
def _from(self): self.env.cr.execute(
class CertificationReport(models.Model):
from_str = """ """
_name = "certification.report" res_partner AS rp CREATE or REPLACE VIEW %s as (%s
_description = "Certification Report" JOIN certification AS c FROM ( %s ) WHERE ( %s )
_auto = False ON c.entity_id = rp.id
JOIN certification_standard AS cs
%s)""",
ON cs.id = c.standard_id (AsIs(self._table), AsIs(self._select()),
entity_id = fields.Many2one('res.partner', readonly=True)
""" AsIs(self._from()), AsIs(self._where()),
certification_count = fields.Integer(readonly=True) return from_str AsIs(self._group_by())),
standard_id = fields.Many2one('certification.standard')
)
expiry_status = fields.Selection([ def _where(self):
('expired', "Expired"), where_str = """rp.is_certification_body is True"""
('available', "Available") return where_str
], readonly=True)
def _group_by(self):
group_by_str = """
GROUP BY
rp.id,
Note
rp.id,
_auto: Needs to be defined as False due to when creating a new model, Odoo wil
cs.id,
(by default)l create a new table. By positioning this class attribute to False, we
manage the table ourselves. c.expiry_status
"""
return group_by_str

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports
4th step: View definition Defining graph and pivot
views

Pivot view: Graph view: Menu item and act_window:

<odoo> <record id="view_certification_report_graph" <act_window


<record id="view_certification_report_pivot" model="ir.ui.view"> id="action_report_certification"
model="ir.ui.view"> <field name="name">certification.report.graph</field> name="Certification Analysis"
<field name="name">certification.report.pivot</field> <field name="model">certification.report</field> res_model="certification.report"
<field name="model">certification.report</field> <field name="arch" type="xml"> view_mode="graph,pivot"
<field name="arch" type="xml"> <graph string="Certification Analysis">
target="current"/>
<pivot string="Certification Analysis" <field name="entity_id" type="column"/>
disable_linking="True"> <field name="standard_id" type="row"/>
<field name="expiry_status" type="column"/> <menuitem
<field name="entity_id" type="col"/>
<field name="expiry_status" type="row"/> <field name="certification_count" id="menu_report_certification"
<field name="standard_id" type="row"/> type="measure"/> parent="certification_menu"
<field name="certification_count" type="measure"/> </graph> action="action_report_certification"
</pivot> </field> sequence="25"/>
</field> </record> </odoo>
</record>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports
5th step: Review results in Odoo
Graph view (I)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports
5th step: Review results in Odoo
Graph view (II)

Available Expired Available Expired

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create analysis reports
5th step: Review results in Odoo

Pivot View (I) Pivot View (II)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create a QWeb-based PDF report

Creating QWeb-based PDF


reports

1st step: Create report_certification_pdf.xml

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


<odoo>
<report id="report_certification_pdf"
name="certification.certification_template_pdf"
model="certification"
string="Certification Report"
report_type="qweb-pdf" />
</odoo>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Case study - Partner Certifications
Create a QWeb-based PDF report
<?xml version="1.0" encoding="utf-8"?> 2nd step: Create certification_template_pdf.xml
<odoo>
<template id="certification_template_pdf">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc"> Note:
<t t-call="web.internal_layout"> Try to change for web external_layout
<div class="page">
<h1>Certification Number <t t-esc="doc.number"/></h1>
<table class="table table-condensed">
<thead>
<tr>
<th>Standard</th>
<th>Owner</th>
<th>Owner Category</th>
<th>Certification Body</th>
<th>Expiry Date</th>
</tr>
</thead>
<tbody>
<tr>
<td><t t-esc="doc.standard_id.name" /></td>
<td><t t-esc="doc.owner_id.name" /></td>
<td><t t-esc="doc.owner_id.category_id.name" /></td>
<td><t t-esc="doc.entity_id.name" /></td>
<td><t t-esc="doc.date" /></td>
</tr> PDF report
</tbody>
</table>
</div>
</t>
</t> 3rd step: Add both xml files to the __manifest__.py
</t>
</template>
</odoo>

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Get to know the OCA
Resources

97
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Get to know the OCA resources
https://docs.google.com/presentation/d/114JfhenNkEUDRKrjuIjwQzRKBtFjfJPPTR650feGqGQ

● What is the OCA?


● Target Groups that benefit from OCA
● Benefits to developers
● Benefits to business experts
● Benefits to integrators
● Benefits to customers
● OCA Projects
● Resources
○ Github
○ Maintainer tools
○ Runbot
○ Weblate
● How to contribute
● Sponsorship program

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Key Business
Apps

99
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Key Business Apps

● Review the areas of purchasing, inventory, accounting, maintenance.


● Identify the OCA related repositories and useful additional modules.
● Split in groups and create new modules that extend the functional areas.

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other
systems

101
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Integration with other systems
Learning Objectives

● Logging into/connecting Odoo with XML-RPC


● Searching/reading records through XML-RPC
● Creating/updating/deleting records through XML-RPC
● Calling methods through XML-RPC
● Using JSON-RPC
● The OCA odoorpc library
● Manipulate Postgres DB with psycopg2
● Server actions

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

Logging into/connecting Odoo with XML-RPC


● Running Odoo instance required
(assumption in dev environment: from xmlrpc import client

http://localhost:8069) # Variables required


● XMLRPC python client. server_url = 'http://localhost:8069'
● common endpoint: /xmlrpc/2/common db_name = '12.0-odoo-training-tai'
○ Credentials not required username = 'admin'
password = 'admin'
● authenticate() method : # No authenticate required
○ returns user_id int if username and common = client.ServerProxy('%s/xmlrpc/2/common' % server_url)
password match with an user record # Check Odoo Version
version = common.version()
in the database. print(version)
○ method takes following arguments # Check user connection to database. Return user's ID
■ db_name user_id = common.authenticate(db_name, username, password, {})
print(user_id)
■ username
■ password
■ user environment agent

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

Searching/reading records through XML-RPC


● object endpoint /xmlrpc/2/object -> Database operations
● execute_kw() method takes following arguments:
○ Database name
○ User ID (get from authenticate method)
○ Password
○ Model name, for example, ‘res.partner’
○ Method name, for example, search, read, search_read …
○ An Array of positional arguments
○ A dictionary for keyword arguments (optional), for example, context.
models = client.ServerProxy('%s/xmlrpc/2/object' % server_url)
if user_id:
search_domain = [('entity', '=', True)]
entity_partners = models.execute_kw(db_name, user_id, password,
'res.partner', 'search_read',
[search_domain, ['name', 'entity']],)
print(entity_partners)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

Creating/updating/deleting records through XML-RPC


● Using execute_kw() method just changing method to:
○ create() allow batch creating adding parameters:
create_data = [{'name': 'XMLRPC Certificate'}, {'name': 'XMLRPC 2 Certificate'}]
certs = models.execute_kw(db_name, user_id, password, 'certification', 'create', [create_data])

○ write() to update records on batch also:


■ Do a previous search to get records to be modified or simply add ids in a array
■ Add dictionary with updates
from datetime import date
update_date = {'date': date.today().strftime("%Y-%m-%d")}
models.execute_kw(db_name, user_id, password, 'certification', 'write', [certs, update_date])

○ unlink() + array of ids to be unlink (unlink_ids = [...])


models.execute_kw(db_name, user_id, password, 'certification', 'unlink', [certs])

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

Calling methods through XML-RPC


● Using execute_kw() it is possible also to call any public method different from previous ones:
● We can’t call private method (method prefixed with underscore _ ) from RPC.
● In our implementation of Attendance system:
○ We defined a method for register attendance on hr_attendance_rfid module:
https://github.com/OCA/hr/blob/12.0/hr_attendance_rfid/models/hr_employee.py#L22
○ RAS call it from:
https://github.com/Eficent/ras/blob/v1.2-release/lib/OdooXMLrpc.py#L98

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts import json, random , requests

server_url = 'http://localhost:8069'
db_name = '12.0-odoo-training-tai'
Using JSON RPC username = 'admin'
● Similar to XMLRPC but using JSON password = 'admin'

Formatting json_endpoint = "%s/jsonrpc" % server_url


● Interact with Odoo using HTTP requests headers = { "Content-Type" : "application/json" }

○ python libs like: request, urllib... def get_json_payload(service , method , *args):


● JSON-RPC uses jsonrpc 2.0 return json.dumps({

specification "jsonrpc" : "2.0",


"method" : 'call' ,
○ JSON Header required "params" : {
○ Payload formatting required "service" : service ,
"method" : method ,
● Result is found at ‘result’ key "args" : args ,
},
"id": random.randint( 0, 100000000 ),
})

payload = get_json_payload( "common" , "login" , db_name , username ,


password)
response = requests.post(json_endpoint , data=payload , headers=headers)
user_id = response.json()[ 'result' ]
if user_id:
print("Success: User id is" , user_id)

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

The OCA odoorpc library: https://github.com/OCA/odoorpc


● User-friendly syntax to access Odoo data through RPC pip3 install OdooRPC
import odoorpc

def main():
server_url = input("Server URL: ")
server_port = input("Server Port: ")
username = input("User name: ")
pwd = input("Password: ")
# Instance OdooRPC class
odoo = odoorpc.ODOO(server_url, port=server_port)
odoo.config['timeout'] = 100000
# Login
odoo.login(db_name, username, pwd)
# Get a recordset
cert_model = odoo.env['certification']
cert_ids = cert_model.search([])
cert_recordset = cert_model.browse(cert_ids)

if __name__ == "__main__":
main()

Copyright 2019 Eficent Business and IT Consulting Services S.L.


Integration with other systems
Key Concepts

Manipulate Postgres DB with psycopg2


● Execute SQL Queries using Python scripts def main():
db_name = input("Server URL: ")
● No system limitations, be careful. server_port = input("Server Port: ")
● Useful on DB data fixing username = input("User name: ")
pwd = input("Password: ")

# Define our connection string


conn_string = """dbname=%s user=%s
password=%s""" % (db_name, db_user, db_password)

# print the connection string we will use to connect


print "Connecting to database\n ->%s", conn_string

# get a connection, if a connect cannot be made an exception


# will be raised here
conn = psycopg2.connect(conn_string)

# conn.cursor will return a cursor object, you can use this


cursor
# to perform queries
Copyright 2019 Eficent Business and ITcr = conn.cursor()
Consulting Services S.L.
Program summary

110
Copyright 2019 Eficent Business and IT Consulting Services S.L.
Program Summary

● Objectives achieved
● Lessons learned

THANK YOU!!

Copyright 2019 Eficent Business and IT Consulting Services S.L.

You might also like