//create a module
sudo odoo scaffold <module_name>
Run odoo in server from Command line
Run under root user permission
python3.6 ./odoo-bin --addons=~/odoo/odoo/addons,~/odoo/pranav/<custom module>,~/odoo/accounting_reports --xmlrpc-port=8085 -d <database name>
Run under different user with different DB server(Eg:Odoo)
- First switch to odoo user:
sudo su - odoo -s /bin/bash
- Run the script
./odoo-bin --addons-path=/opt/odoo/addons,/opt/test_addons --db_host=<ip address> --db_port=<port> --db_password=<password> --database=<db name> -u <user name> --db-filter=<db name> --xmlrpc-port=1122
Nohup-to run a service without writing service file :-
nohup python3.6 ./odoo-bin --addons=~/odoo/odoo/addons,~/odoo/pranav/<custom module>,~/odoo/accounting_reports --xmlrpc-port=8085 -d <database name> &
ODOO
QWEB
Datetime operation
------------------------------------
<span t-set="d1" t-value="datetime.datetime.now()"/>
<t t-set="d2" t-value="datetime.datetime.strptime(line.date_maturity,'%Y-%m-%d')"/>
<span t-esc="(d1-d2).days"/>
<t t-esc="d1"/>
Change Date Format
----------------------------------------
<span t-esc="datetime.datetime.strptime(o.date_stop, '%Y-%m-%d').strftime('%m/%d/%Y')"/>
Add 2 decimal precision
------------------------------
<span t-esc=”’%.2f’%(t.amount)”></span
Or
<span t-esc="'{0:,.2f}'.format(float(line['amount']))"/>
Add total under a field
-----------------------------
<table>
<tr>
…...
<td style="border:1px solid #000;border-collapse: collapse;">
<span t-esc="line['number']"/>
<t t-set="total" t-value="total + line['number']"/>
</td>
………
</tr>
<tr>
…….
<td><span t-esc=”total”/>
</tr>
</table>
Time only Field
---------------------
start_time: fields.float('Start Time')
<field name="start_time" widget="float_time"/>
<field name="start_time" widget="float_time"/>
Space After invoice lines
------------------------------------------------
<tr t-foreach="range(10-int(len(o.invoice_line_ids)%10))" style="height:10mm;border-right:1px solid black;" t-as="i">
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
<td style="border:1px solid black;"/>
</tr>
Odoo Tree/Form View
Confirm Message On Button Click
-----------------------------------------------
<button name="download_attendance" type="object" string="Download Data" class="oe_highlight" icon="fa-download " confirm="Are you sure you want to do this?" />
Tree view color
----------------------------------------
Version 11:
<tree colors="your_color:field== 'value'">
Eg: <tree colors="grey:state == 'cancel'">
decoration-bf - shows the line in BOLD
decoration-it - shows the line in ITALICS
decoration-danger - shows the line in LIGHT RED
decoration-info - shows the line in LIGHT BLUE
decoration-muted - shows the line in LIGHT GRAY
decoration-primary - shows the line in LIGHT PURPLE
decoration-success - shows the line in LIGHT GREEN
decoration-warning - shows the line in LIGHT BROWN
<tree decoration-success="state=='done'">
Show total of a field in tree view
----------------------------------------
<field name=”name” sum=”total”>
Header button
------------------
<header>
<button class="oe_stat_button" type="action" name="271" context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}" icon="fa-tasks" string="Contracts">
</button>
</header>
Add attribute to hide a field
----------------------------------
<field name="hours_spend_visa" attrs="{'invisible':[('is_visa', '=', False)]}"/>
Add multiple fields inline
------------------------------
<label for="hours_spend_visa" string="Hours Spend" class="oe_inline" attrs="{'invisible':[('is_visa', '=', False)]}"/>
<field name="hours_spend_visa" style="width:10%" class="oe_inline" attrs="{'invisible':[('is_visa', '=', False)]}"/>
Inherit Page/Notebook
----------------------------
<xpath expr="//notebook[last()]" position="inside">
</xpath
Or
<xpath expr="//page[last()]" position="inside">
</xpath>
Comma Seperator
-----------------------------------
<td><span t-esc="'{:,}'.format(l.price_subtotal)"/></td>
Total in words
---------------
<strong>
Dirhams
<span t-esc=”o.amount” t-esc-options=’{“widget”:”num2words”,”case”:”capital”}’/>
Only
</strong>
Drag and drop tree view lines
-----------------------------------------------------------
name="sequence" widget="handle"
Alter record rule with noupdate true
--------------------------------------------------------------------
Change noupdate to False first
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value eval="[('module', '=', 'portal_sale'), ('name', '=', 'portal_personal_contact')]"/>
</function>
<value eval="{'noupdate': False}" />
</function>
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value eval="[('module', '=', 'base'), ('name', '=', 'res_partner_portal_public_rule')]"/>
</function>
<value eval="{'noupdate': False}" />
</function>
Now alter the record rule
<function name="search" model="ir.model.data">
<value eval="[('module', '=', 'portal_sale'), ('name', '=', 'portal_personal_contact')]"/>
</function>
<value eval="{'noupdate': False}" />
</function>
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value eval="[('module', '=', 'base'), ('name', '=', 'res_partner_portal_public_rule')]"/>
</function>
<value eval="{'noupdate': False}" />
</function>
Now alter the record rule
<record id="portal_sale.portal_personal_contact" model="ir.rule">
<field eval="False" name="active"/>
<field eval="False" name="noupdate"/>
</record>
<record model="ir.rule" id="base.res_partner_portal_public_rule">
<field eval="False" name="active"/>
<field eval="False" name="noupdate"/>
</record>
PYTHON
Decorators
Class methods required single invoking object (Single Browsable Record) to invoke the method and suppose it will call by multiple invoking objects (Browsable Recordsets) then method is not able to identify for which object it should process, therefore it will raise an error Expected Singleton.
New API decorator is used to define method calling pattern whether methods allows only single object or multiple objects to invoke this method.
@api.one
This decorator loops automatically on Records of RecordSet for you. Self is redefined as current record
Note: Caution: the returned value is put in a list. This is not always supported by the web client, e.g. on button action methods. In that case, you should use @api.multi to decorate your method, and probably call self.ensure_one() in the method definition.
@api.multi
Self will be the current RecordSet without iteration. It is the default behavior (multiple browsable objects). Methods which returns non premitive type data(list, dictionary, function) must be decorated with @api.multi
@api.model
This decorator will convert old API calls to decorated function to new API signature. It allows to be polite when migrating code. Self does not contain any record/recordset in methods which are decorated by this decorator.
Create Many2many field from script
(0, 0, { values }) link to a new record that needs to be created with the given values dictionary
(1, ID, { values }) update the linked record with id = ID (write values on it)
(2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
(3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
(4, ID) link to existing record with id = ID (adds a relationship)
(5) unlink all (like using (3,ID) for all linked records)
(6, 0, [IDs]) replace the list of linked IDs (like using (5) then (4,ID) for each ID
(1, ID, { values }) update the linked record with id = ID (write values on it)
(2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
(3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
(4, ID) link to existing record with id = ID (adds a relationship)
(5) unlink all (like using (3,ID) for all linked records)
(6, 0, [IDs]) replace the list of linked IDs (like using (5) then (4,ID) for each ID
HR Payroll
If creating allowance or deduction with dynamic value
In salary rule mention below fields like:-
Amount Type Python Code
From Payslip:-
result = -payslip.total_paid(For deduction)
result = payslip.total_paid(For allowance)
From Salary Rule Category:-
result = categories.BASIC(Give category total)
Mention a float field in employee payslip , it should have same name as mentioned above.
OR
/*Add below python script in salary rule with corresponding methord*/
result=payslip.env['hr.payslip'].advance_grat(employee.id,payslip.date_from,payslip.date_to)
/*In ‘hr.payslip’ class add below method for transactions’*/
@api.multi
def advance_grat(self,emp_id,date_from,date_to):
rule_id = self.env['hr.salary.rule'].search([('code','=','AGR')])
amount = 0
if rule_id:
amount=self.env['hr.payroll.transactions'].search([('rule_id','=',rule_id.id),
('date','<=',date_to),('date','>=',date_from),
('employee_id','=',emp_id)]).amount
return amount
SCRIPTING
Create key value easily
c_exist.setdefault(follower.channel_id.id, list()).append(follower.res_id)
Smart Button
@api.multi
def action_show_booking(self):
action = self.env.
ref('orchid_travels_v10.act_od_view_booking').read()[0]
opp_id = self.id
booking_ids = []
booking_lines = self.env['travel.booking'].search([('opportunity_id','=',opp_id)])
for line in booking_lines:
booking_ids.append(line.opportunity_id and line.opportunity_id.id)
domain = []
if not booking_ids:
raise Warning("no contract found")
domain.append(('id','in',booking_ids))
action['domain'] = domain
action['context'] = "{'default_opportunity_id':"+str(self.id)+"}"
return action
Server action
id=[310]
orders = env['pos.order'].browse(id)
for order in orders:
discount_product_id = order and order.session_id and order.session_id.config_id and order.session_id.config_id.discount_product_id and order.session_id.config_id.discount_product_id.id or False
if order.statement_ids:
for stmt in order.statement_ids:
if stmt.journal_id.od_is_discount:
vals={
'product_id':discount_product_id,
'qty':1,
'price_unit':-(stmt.amount),
'order_id':order.id,
'od_cost':0,
}
env['pos.order.line'].create(vals)
//No need of self
Create lines from onchange
@api.onchange('kg_sf_id')
def onchange_sale_forcast(self):
prod_shft_line_objs = self.env['kg.prod.shift.line']
for record in self:
if self.kg_sf_id:
for line in self.kg_sf_id.kg_lines:
data = {
'kg_product':line.kg_product_id and line.kg_product_id.id,
'kg_qty':line.kg_net,
}
line = prod_shft_line_objs.new(data)
prod_shft_line_objs += line
record.kg_shift_lines = prod_shft_line_objs
XML
Filters for Date Field
This week
<filter string="This Week" name="This Week" separator="1"
domain="[('date_from','>=', ((context_today()).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d')))]"
help="This Week"/>
Last Week
<filter string="Last Week" name="Last Week" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=-7)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()).strftime('%Y-%m-%d')))]"
help="This Week"/>
yesterday
<filter string="Yesterday" name="Yesterday" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=-1)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=-1)).strftime('%Y-%m-%d')))]"
help="Yesterday"/>
Today
<filter string="Today" name="Today" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d')))]"
help="Today"/>
Tomorrow
<filter string="Tomorrow" name="Tomorrow" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')))]"
help="Tomorrow"/>
Expiry
<filter string="Immediate Expiry" name="Immediate Expiry" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=45)).strftime('%Y-%m-%d')))]"
help="Immediate Expiry"/>
Last Month
<filter icon="terp-go-month" string="Last Month"
domain="[('date_from','<=', (context_today()-relativedelta(day=31, months=1)).strftime('%Y-%m-%d')),
('date_from','>=',(context_today()-relativedelta(day=1,months=1)).strftime('%Y-%m-%d'))]"
help="last month"/>
Current Month
<filter string="Current Month" name="current_month" domain="[('date_from','<',(context_today()+relativedelta(months=1)).strftime('%Y-%m-01')), ('date_from','>=',time.strftime('%Y-%m-01'))]"/>
Last Year
<filter icon="terp-go-month" string="Last Year"
domain="[('date', '>=' ,(context_today()-relativedelta(years=1)).strftime('%Y-01-01')),('date','<=',time.strftime('%Y-01-01'))]" help="last year"/>
This Year
<filter icon="terp-go-year" string="Year"
domain="[('date_from','<=', time.strftime('%Y-%m-%d')),('date_from','>=',time.strftime('%Y-01-01'))]"
help="Current Year"/>
Filters for Date Field
This week
<filter string="This Week" name="This Week" separator="1"
domain="[('date_from','>=', ((context_today()).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d')))]"
help="This Week"/>
Last Week
<filter string="Last Week" name="Last Week" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=-7)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()).strftime('%Y-%m-%d')))]"
help="This Week"/>
yesterday
<filter string="Yesterday" name="Yesterday" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=-1)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=-1)).strftime('%Y-%m-%d')))]"
help="Yesterday"/>
Today
<filter string="Today" name="Today" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d')))]"
help="Today"/>
Tomorrow
<filter string="Tomorrow" name="Tomorrow" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')))]"
help="Tomorrow"/>
Expiry
<filter string="Immediate Expiry" name="Immediate Expiry" separator="1"
domain="[('date_from','>=', ((context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))), ('date_from','<=', ((context_today()+datetime.timedelta(days=45)).strftime('%Y-%m-%d')))]"
help="Immediate Expiry"/>
Last Month
<filter icon="terp-go-month" string="Last Month"
domain="[('date_from','<=', (context_today()-relativedelta(day=31, months=1)).strftime('%Y-%m-%d')),
('date_from','>=',(context_today()-relativedelta(day=1,months=1)).strftime('%Y-%m-%d'))]"
help="last month"/>
Current Month
<filter string="Current Month" name="current_month" domain="[('date_from','<',(context_today()+relativedelta(months=1)).strftime('%Y-%m-01')), ('date_from','>=',time.strftime('%Y-%m-01'))]"/>
Last Year
<filter icon="terp-go-month" string="Last Year"
domain="[('date', '>=' ,(context_today()-relativedelta(years=1)).strftime('%Y-01-01')),('date','<=',time.strftime('%Y-01-01'))]" help="last year"/>
This Year
<filter icon="terp-go-year" string="Year"
domain="[('date_from','<=', time.strftime('%Y-%m-%d')),('date_from','>=',time.strftime('%Y-01-01'))]"
help="Current Year"/>
ODOO-8.0
SCRIPTING
Server action
id=[21]
vals = self.pool['sale.order'].browse(cr, uid, 21, context)
for val in vals:
if val.id==21:
val.write({'state':'draft'})
Odoo Setup
Create a custom module
sudo odoo scaffold <module_name>
Or
python ../odoo/odoo-bin scaffold <module_name>
POSTGRES
Kill session from psql
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname ='aasons_live';
CREATE NEW USER
createuser --createdb --username postgres --no-createrole --pwprompt <user_name>
JOINING TABLES
a)Table:CUSTOMERS
b)Table:ORDERS
Now, let us join these two tables in our SELECT statement as follows:
SELECT ID, NAME, AGE, AMOUNT FROM CUSTOMERS, ORDERS
WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
This would produce the following result:
1.Left Joining
The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in right table, the join will still return a row in the result, but with NULL in each column from right table.
This means that a left join returns all the values from the left table, plus matched values from the right table or NULL in case of no matching join predicate.
Syntax:
The basic syntax of LEFT JOIN is as follows:
SELECT table1.column1, table2.column2...
FROM table1
LEFT JOIN table2
ON table1.common_field = table2.common_field;
Now, let us join these two tables using LEFT JOIN as follows:
SELECT ID, NAME, AMOUNT, DATE FROM CUSTOMERS
LEFT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
2.Inner Joining
The INNER JOIN creates a new result table by combining column values of two tables (table1 and table2) based upon the join-predicate. The query compares each row of table 1 with each row of table2 to find all pairs of rows which satisfy the join-predicate. When the join-predicate is satisfied, column values for each matched pair of rows of A and B are combined into a result row.
Syntax:
The basic syntax of INNER JOIN is as follows:
SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field;
Example:
Now, let us join these two tables using INNER JOIN as follows:
SELECT ID, NAME, AMOUNT, DATE FROM CUSTOMERS
INNER JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
3.Right Joining
The SQL RIGHT JOIN returns all rows from the right table, even if there are no matches in the left table. This means that if the ON clause matches 0 (zero) records in left table, the join will still return a row in the result, but with NULL in each column from left table.
This means that a right join returns all the values from the right table, plus matched values from the left table or NULL in case of no matching join predicate.
Syntax:
The basic syntax of RIGHT JOIN is as follows:
SELECT table1.column1, table2.column2...
FROM table1
RIGHT JOIN table2
ON table1.common_field = table2.common_field;
Now, let us join these two tables using RIGHT JOIN as follows:
SELECT ID, NAME, AMOUNT, DATE FROM CUSTOMERS
RIGHT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
This would produce the following result:
4.Full Joining
The SQL FULL JOIN combines the results of both left and right outer joins.
The joined table will contain all records from both tables, and fill in NULLs for missing matches on either side.
Syntax:
The basic syntax of FULL JOIN is as follows:
SELECT table1.column1, table2.column2...
FROM table1
FULL JOIN table2
ON table1.common_field = table2.common_field;
Now, let us join these two tables using FULL JOIN as follows:
SELECT ID, NAME, AMOUNT, DATE FROM CUSTOMERS
FULL JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
This would produce the following result:
5.Self Joining
The SQL SELF JOIN is used to join a table to itself as if the table were two tables, temporarily renaming at least one table in the SQL statement.
Syntax:
The basic syntax of SELF JOIN is as follows:
SELECT a.column_name, b.column_name...
FROM table1 a, table1 b
WHERE a.common_field = b.common_field;
Now, let us join this table using SELF JOIN as follows:
SELECT a.ID, b.NAME, a.SALARY FROM CUSTOMERS a, CUSTOMERS b
WHERE a.SALARY < b.SALARY;
This would produce the following result:
6.Cartesian Product
The CARTESIAN JOIN or CROSS JOIN returns the Cartesian product of the sets of records from the two or more joined tables. Thus, it equates to an inner join where the join-condition always evaluates to True or where the join-condition is absent from the statement.
Syntax:
The basic syntax of CARTESIAN JOIN is as follows:
SELECT table1.column1, table2.column2...
FROM table1, table2 [, table3 ]
Now, let us join these two tables using CARTESIAN JOIN as follows:
SELECT ID, NAME, AMOUNT, DATE
FROM CUSTOMERS, ORDERS;
This would produce the following result:
Comments
Post a Comment