Create custom excel report from wizard in odoo 15 - odoo

I am trying to generate an excel report from wizard using report_xlsx module but i am getting below error.
Traceback (most recent call last):
File "/home/kabeer/Projects/Odoo15ce/odoo/custom_addons/report_xlsx/controllers/main.py", line 76, in report_download
response = self.report_routes(
File "/home/kabeer/Projects/Odoo15ce/odoo/http.py", line 535, in response_wrap
response = f(*args, **kw)
File "/home/kabeer/Projects/Odoo15ce/odoo/custom_addons/report_xlsx/controllers/main.py", line 32, in report_routes
data.update(json.loads(data.pop("options")))
ValueError: dictionary update sequence element #0 has length 10; 2 is required
Here is what i did.
*.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="open_purchase_order_print_menu" model="ir.actions.report">
<field name="name">Open PO</field>
<field name="model">open.po</field>
<field name="report_type">xlsx</field>
<field name="report_name">transight.open_po</field>
<field name="report_file">transight.open_po</field>
<field name="print_report_name">'Purchase Order'</field>
<!-- <field name="binding_model_id" ref="purchase.model_purchase_order"/> -->
<field name="binding_type">report</field>
</record>
<record id="open_po_view_form" model="ir.ui.view">
<field name="name">open.po.form</field>
<field name="model">open.po</field>
<field name="arch" type="xml">
<form string="Open PO">
<group>
<field name="mode" required="1"/>
</group>
<group col="4">
<field name="purchase_order_id"
widget="many2many_tags"
attrs="{'invisible':[('mode','=','partnumber')]}"/>
<field name="partnumber" attrs="{'invisible':[('mode','=','po')]}"/>
</group>
<footer>
<button string="Print" name="action_print" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_open_po" model="ir.actions.act_window">
<field name="name">Open PO</field>
<field name="res_model">open.po</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem id="menu_open_po_action" name="Open PO" parent="mrp.menu_mrp_configuration" action="action_open_po" sequence="4"/>
</odoo>
*.py
from odoo import fields,models,api,_
class OpenPOXlsx(models.AbstractModel):
_name = 'report.transight.open_po'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, data, partners):
print('data',data)
for obj in partners:
report_name = 'Excel Report test'
# One sheet by partner
sheet = workbook.add_worksheet(report_name[:31])
bold = workbook.add_format({'bold': True})
sheet.write(0, 0, 'Hi Am here', bold)
class OpenPO(models.TransientModel):
_name = 'open.po'
_description = 'OpenPO'
purchase_order_id = fields.Many2many('purchase.order',string='Purchase Order')
partnumber = fields.Char(string="Partnumber")
mode = fields.Selection([('partnumber','Part Number'),('po','Purchase Order')],string="Filter by")
def action_print(self):
if self.mode == 'po':
query = """my query %s """
self.env.cr.execute(query,(tuple(self.purchase_order_id.ids),))
datas = self.env.cr.dictfetchall()
print('data---------',datas)
# return self.env.ref('account_batch_payment.action_print_batch_payment').report_action(self, config=False)
return self.env.ref('transight.open_purchase_order_print_menu').report_action(self,data=datas)

The dictfetchall() method returns a list of dicts and report_action is expecting data (datas) to be a dict.
In previous Odoo versions, we pass record data using form key, for example:
datas = {
'ids': active_ids,
'model': 'hr.contribution.register',
'form': self.read()[0]
}
To fix this issue, add the fetched values to datas:
values = self.env.cr.dictfetchall()
datas['values'] = values
Then use values key in generate_xlsx_report method
Make sure that datas is a dictionary before calling report_action

Related

How do I set a value on a selection via a button

I need to create a button which will define a ticket the value of the state variable to cloturé.
And when a ticket is cloturé, it will on read only.
How can i do it ?
The ticket's model is helpdesk.ticket
view.xml :
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="helpdesk_ticket_view_form_inherit_header_modifie" model="ir.ui.view">
<field name="name">helpdesk.ticket.modifie.header</field>
<field name="model">helpdesk.ticket</field>
<field name="inherit_id" ref="helpdesk_fsm.helpdesk_ticket_view_form" />
<field name="arch" type="xml">
<xpath expr="//button[#name='action_generate_fsm_task']" position="attributes" >
<attribute name="string">Planifier tache</attribute>
</xpath>
</field>
</record>
</odoo>
ticket.py :
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class ticket_inherit(models.Model):
_inherit = "helpdesk.ticket"
state = fields.Selection(['test','annulé','cloturé'],'selection')
#What i want to do
def cloture_le_ticket(self):
state = 'cloturé'
You can just use write().
state = fields.Selection(string="State", selection=[
('test', 'Test),
('annulé', 'Annulé'),
('cloturé', 'Cloturé')
])
def cloture_le_ticket(self):
self.write({
'state': 'cloturé'
})
To force the ticket to be read-only:
def write(self, vals):
for record in self:
if record.state == 'cloturé':
raise exceptions.UserError("Sorry but the ticket is read only")
return super(HelpdeskTicket, self).write(vals)

Odoo. Tree/form display field data

I have some problem with tree/form view in Odoo.
My model have such classes: https://yadi.sk/d/sCLVo3gHtbVEu
class URLList(models.Model):
_name = 'webvisitorcalc.url_list'
url = fields.Char(string="URL", required=True)
url_parametes = fields.Char(string="URL parameters") #пераметры URLб всё что идёт после ?
target_session_id = fields.One2many('webvisitorcalc.session_visitor', 'target_url_ids', string='Target URL')
site_trip_prevouse_id = fields.One2many('webvisitorcalc.site_trip', 'url_prevouse_ids', string='Prevouse URL')
site_trip_current_id = fields.One2many('webvisitorcalc.site_trip', 'url_current_ids', string='Current URL')
remote_sites_id = fields.One2many('webvisitorcalc.remote_sites', 'site_url_ids', string='Remote site page with URL')
remote_sites_target_url_id = fields.One2many('webvisitorcalc.remote_sites', 'target_url_ids', string='URL on remote site page')
#api.multi
def url_exist(self, cr, SUPERUSER_ID, urlForCheck):
_logger.error("Check URL exist in DB ")
result = False
if (self.search_count(cr, SUPERUSER_ID, [('url', '=', urlForCheck)])>0):
result = True
return result
class SiteTrip(models.Model):
_name = 'webvisitorcalc.site_trip'
session_ids = fields.Many2one('webvisitorcalc.session_visitor', string='Session ID', index=True)
url_prevouse_ids = fields.Many2one('webvisitorcalc.url_list', string='Prevouse URL', index=True)
url_current_ids = fields.Many2one('webvisitorcalc.url_list', string='Current URL', index=True)
Template for this model: https://yadi.sk/d/Ob0o65PutbVFA
<record model="ir.actions.act_window" id="site_trip_list_action">
<field name="name">Site trip</field>
<field name="res_model">webvisitorcalc.site_trip</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first record for site trip
</p>
</field>
</record>
<record model="ir.actions.act_window" id="url_list_list_action">
<field name="name">URL list</field>
<field name="res_model">webvisitorcalc.url_list</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first url
</p>
</field>
</record>
<record model="ir.ui.view" id="site_trip_tree_view">
<field name="name">site_trip.tree</field>
<field name="model">webvisitorcalc.site_trip</field>
<field name="arch" type="xml">
<tree string="URL list tree">
<field name="session_ids"/>
<field name="url_prevouse_ids" string="PrevURL">
</field>
<!--<field name="url_prevouse_ids"/>-->
<field name="url_current_ids"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="url_list_tree_view">
<field name="name">url_list.tree</field>
<field name="model">webvisitorcalc.url_list</field>
<field name="arch" type="xml">
<tree string="URL list tree">
<field name="url"/>
<field name="url_parametes"/>
</tree>
</field>
</record>
<menuitem id="site_trip_menu" name="Site trip" parent="webvisitorcalc_menu"
action="site_trip_list_action"/>
<menuitem id="url_list_menu" name="URL list" parent="webvisitorcalc_menu"
action="url_list_list_action"/>
Screenshots are here:
Tree view for class SiteTrip
http://i.stack.imgur.com/FjRDK.png
Form view for class SiteTrip
http://i.stack.imgur.com/uDbOp.png
Tree view for class URLList
http://i.stack.imgur.com/tXzqL.png
Form view for class URLList
http://i.stack.imgur.com/oVnqg.png
As you see URLList displayed fine. For class SiteTrip present problem. Field is displaying not data from URLList. This is field stored element such webvisitorcalc.url_list.ID (array?). How I can display real data in this field (for example URL: http://some-site.com/page.html)?
URL in URLList must be uniq. SiteTrip must have stored only ID of URLList record.
UPD:
class RemoteSites(models.Model):
_name = 'webvisitorcalc.remote_sites'
site_id = advert_company_id = fields.One2many('webvisitorcalc.site_list', 'remote_sites_ids', string='Site')
site_url_ids = fields.Many2one('webvisitorcalc.url_list', string='URL page ')
target_url_ids = fields.Many2one('webvisitorcalc.url_list', string='URL target page')
You obviously have no name field on your webvisitorcalc.url_list model. Odoo needs this to use it as name in webclient wherever you use this model as e.g. many2one field or in the breadcrumb navigation.
So either you define a name field or you set _name on your class with another field identifier.
You can also (re-)define the method display_name on your model (enough examples in Odoo code) where you can do more cool stuff with the record display name :-)

How to solve IO error in odoo?

i want inherit model in odoo, and i upgrade my modul, error showing like this :
File "/usr/lib/python2.7/dist-packages/openerp/tools/misc.py", line 199, in file_open
return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo, basename=basename)File "/usr/lib/python2.7/dist-packages/openerp/tools/misc.py", line 246, in _fileopen
raise IOError('File not found: %s' % basename)IOError: File not found: estate_vehicle/views/inherit_transfertomn_spb_view
this my python code :
class InheritSPB(models.Model):
_inherit ='estate.nursery.seeddo'
timesheet_ids = fields.One2many('estate.timesheet.activity.transport','owner_id','Timesheet ids')
And this my view code :
record model="ir.ui.view" id="inherit_view_field_view_timesheet_transfermn_activity">
<field name="name">Inherit timesheet SPB</field>
<field name="model">estate.nursery.seeddo</field>
<field name="inherit_id" ref="estate_nursery.view_form_seeddo"/>
<field name="arch" type="xml">
<xpath expr="//page[#name='detail_transportir'']" position="after">
<page string="Vehicle Information">
<tree>
<field name="vehicle_timesheet_ids" track_visibility="onchange" attrs="{'required': [('state','=','draft')],
'readonly': [('state','=','done')]}"
context="{'tree_view_ref' : 'estate_nursery.view_tree_timesheet_activity_transport',
'default_dc_type' : 2}"/>
</tree>
</page>
</xpath>
</field>
</record>
In your case, file should be inherit_transfertomn_spb_view.xml
You need to check your files in module estate_vehicle views folder with inherit_transfertomn_spb_view.xml file name is available or not.
Now check your __openerp__.py
For example:
"data" : [
#new of file with proper destination
views/inherit_transfertomn_spb_view.xml
]

OpenERP - Show child_ids invoices of a partner

I'd like to show invoices adressed to child partner in the parent partner form view.
I've already a inherited res_partner model as follow :
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'invoice_ids': fields.one2many('account.invoice', 'partner_id', 'Invoices'),
}
And a view displaying invoices as follow :
<?xml version="1.0"?>
<openerp>
<data>
<!-- Partners inherited form -->
<record id="view_history_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.cap_history.form.inherit</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<page string="Accounting" position="after" version="7.0">
<page string="History" name="cap_history_tab">
<group name="grp_invoice_history" string="Invoices History">
<field name="invoice_ids" colspan="4" nolabel="1">
<tree string="Partner Invoices" create="false" delete="false">
<field name="number" readonly="True"/>
<field name="origin" readonly="True"/>
<field name="name" string="Reference" readonly="True"/>
<field name="date_invoice" readonly="True"/>
<field name="x_category" readonly="True"/>
<field name="state" readonly="True"/>
<field name="payment_term" readonly="True"/>
<field name="amount_total" readonly="True"/>
</tree>
</field>
</group>
</page>
</page>
</field>
</record>
With this code I can see invoices that are directly adressed to a company or a person on their respective form view.
But if an invoice is adressed to person, and none is adressed to the parent company, when I am on the company form view, I won't see the invoice adressed to the child contact.
Is there a way to make visible the contact's invoice in the parent partner form view ?
Thank you for your help !
Cheers
One way to do this is to add a new field, all_invoice_ids, as a function field, and then have the function return both the contents of invoice_ids, plus the contents of any child's invoice_ids.
Something like this (untested):
'all_invoice_ids': fields.function(
_get_invoice_ids,
type='one2many',
obj='account.invoice',
method=True,
string='Invoices',
),
and _get_invoice_ids (which should be defined before columns) like this (also untested):
def _get_invoice_ids(self, cr, uid, ids, field_name, arg, context=None):
res = {}
if isinstance(ids, (int, long)):
ids = [ids] # in case an id was passed in directly
for main_partner in self.browse(cr, uid, ids, context=context):
main_invoices = main_partner.invoice_ids or [] # in case it was False
invoices = [inv.id for inv in main_invoices]
for child_partner in main_partner.child_ids:
child_invoices = child_partner.invoice_ids or []
invoices.extend([inv.id for inv in child_invoices])
# at this point we should have all the invoice ids
# use a set to get rid of duplicates
invoices = list(set(invoices))
# and store in res to be returned
res[main_partner.id] = invoices
return res

openerp to download attendance machine

Please me to solve this problems. I'm using openerp to download attendance machine and insert that data into my table but i have to view the data from the machine into grid using using one2many field how could I passing the data after I downloaded this my script. I'm using zkclock module to get the data.
hr_machinezem560.py
....
import zkclock
import from osv import osv, fields
....
class hr_machinezem560(osv.osv):
_name = "hr_machinezem560"
_columns = {
'date_from':fields.date("Date From"),
'date_to':fields.date("Date To"),
'proses_id':fields.one2many('hr.machinezem560_details', 'proses_id', 'Prosess Download')
}
def action_download(self, cr, uid, ids, context=None):
domain = {}
params = self.browse(cr, uid, ids, context=context)[0]
start_date = date_object = datetime.datetime.strptime(params.date_from, '%Y-%m-%d')
end_date = date_object = datetime.datetime.strptime(params.date_to, '%Y-%m-%d')
date_list = [dt.strftime("%Y-%m-%d") for dt in rrule(DAILY, dtstart=start_date, until=end_date)]
host = '192.168.1.201'
port = 4370
password = ''
s, r = zkclock.connect(host, port, password)
r = zkclock.disable(s, r)
r, userdata = zkclock.get_user_data(s, r)
r, logdata = zkclock.get_log_data(s, r)
r = zkclock.enable(s, r)
r = zkclock.disconnect(s, r)
if userdata and logdata:
logdata = zkclock.assemble_log_data_from_packets(logdata)
users = zkclock.unpack_users_to_dict(userdata)
logging.debug(users)
loglist = []
while((len(logdata)/LOG_DATA_SIZE) >=1):
loglist.append(logdata[:LOG_DATA_SIZE])
logdata = logdata[LOG_DATA_SIZE:]
logs = []
for i in loglist:
log_entry = zkclock.unpack_log(i)
timestamp = zkclock.decode_time(log_entry.time)
verification_method = log_entry.decode_verified()
try:
user_name = users[log_entry.uid].name
except KeyError:
user_name = "Unknown user: %s" % log_entry.uid
logs.append([timestamp,str(log_entry.uid), verification_method])
attance_det = self.pool.get("hr.machinezem560_details")
for log in logs:
if log[0].strftime('%Y-%m-%d') in date_list:
values = {
'employee': log[1],
'timesheet': log[0],
'status':log[2]
}
attance_det.create(cr, uid, values, context=context)
hr_machinezem560()
class hr_machinezem560_details(osv.osv):
_name = "hr.machinezem560_details"
_columns = {
'employee': fields.char("Employee Name", size=80),
'timesheet':fields.datetime("Time Sheet"),
'status': fields.char("Status", size=10),
'proses_id':fields.many2one('hr_machinezem560','Prosess Download')
}
hr_machinezem560_details()
view:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="hr_batch_machine_view_form" model="ir.ui.view">
<field name="name">Attendance Machine Batch Process</field>
<field name="model">hr_machinezem560</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Download ZEM560 Data" version="7.0">
<group name="up">
<label for="date_from" string="Timesheet Period"/>
<div>
<field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/>
<div class="oe_right oe_button_box" name="right_top_button">
<button name="action_download" string="Download" type="object"/>
</div>
</div>
</group>
<group name="down">
<field name="proses_id" colspan="3" nolabel="1" readonly="1">
<tree string="Attendance Data">
<field name="employee"/>
<field name="timesheet"/>
<field name="status"/>
</tree>
</field>
</group>
</form>
</field>
</record>
<record id="action_batch_hr_machine_view" model="ir.actions.act_window">
<field name="name">Attendance Machine Batch Proses</field>
<field name="res_model">hr_machinezem560</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
id="menu_hr_absensiRoot"
name="Absensi"
sequence="3"
parent="hr.menu_hr_root"
/>
<menuitem
id="menu_hr_mesin_Absensi"
name="Mesin Absensi ZEM560"
sequence="1"
parent="menu_hr_absensiRoot"
action="action_batch_hr_machine_view"
/>
</data>
</openerp>