this method is supposed to display only the reporting period within a particular selected financial year that has same fields - input

For clarity here is the code:
class ProgrammeLinking(models.Model):
_name = 'mis.programme.linking'
_description = 'linking and allocations'
_rec_name = "financial_year_id"
financial_year_id = fields.Many2one('res.financial.year',string='Financial Year')
output_indicator_id = fields.Many2one('mis.output.indicator',string='APP Output indicator', store=True)
allowed_output_indicator_ids = fields.Many2many(
'mis.output.indicator',
compute="_compute_allowed_output_indicator_ids"
)
reporting_period_id = fields.Many2one('mis.create.link.national.app', string='Reporting Period')
allowed_reporting_period_ids = fields.Many2many(
'mis.create.link.national.app',
compute="_compute_allowed_reporting_period_ids"
)
def _get_current_fy_programme_linking(self):
for rec in self:
return self.env['mis.create.link.national.app'].search([
('financial_year_id','=', rec.financial_year_id.id)
])
#api.depends('outcome_id')
def _compute_allowed_output_indicator_ids(self):
for rec in self:
if rec.outcome_id:
fy_linkings = self._get_current_fy_programme_linking()
output = fy_linkings \
.filtered(lambda l: l.outcome_id.id == rec.outcome_id.id) \
.mapped('output_indicator_id')
_logger.info(f"Filtered ou {output}")
rec.allowed_output_indicator_ids = output
else:
rec.allowed_output_indicator_ids = False
#api.depends('output_indicator_id')
def _compute_allowed_reporting_period_ids(self):
for rec in self:
if rec.output_indicator_id:
fy_linkings = self._get_current_fy_programme_linking()
period = fy_linkings \
.filtered(lambda l: l.output_indicator_id.id == rec.output_indicator_id.id) \
.mapped('reporting_period')
_logger.info(f"Filtered periods {period}")
rec.allowed_reporting_period_ids = period
else:
rec.allowed_reporting_period_ids = False
the in the view:
<field name="allowed_output_indicator_ids" invisible="1"/>
<field name="output_indicator_id" required="1" options="{'no_create': True, 'no_open': True}" domain="[('id','in', allowed_output_indicator_ids)]"/>
<field name="allowed_reporting_period_ids" invisible="1"/>
<field name="reporting_period_id" required="1" options="{'no_create': True, 'no_open': True}" domain="[('id','in', allowed_reporting_period_ids)]"/>
Now the error I am getting when I click on the field "reporting_period_id"
and the error I am getting is:
Traceback (most recent call last):
File "C:\odoo14\server\odoo\http.py", line 639, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "C:\odoo14\server\odoo\http.py", line 315, in _handle_exception
raise exception.with_traceback(None) from new_cause
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer: "quarterly"
LINE 1: ...p" WHERE ("mis_create_link_national_app"."id" in ('quarterly...
^
the reporting period is a Selection field in the class I am searching and the value of it in the selected financial year is "quarterly" but I am getting this error.
I'd appreciate your help

The error:
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer: "quarterly"
LINE 1: ...p" WHERE ("mis_create_link_national_app"."id" in ('quarterly...
seems not to be directly linked to the code you have provided, because the error concerns:
mis_create_link_national_app.id
which is an integer and the sql operation :
IN
and an integer can t be IN a list of STRING (in your case: 'quaterly')
Solution:
replacing 'quaterly' by its corresponding record-id (you might probably just append .id after the fieldname in your query)

The issue is caused by .mapped('reporting_period'), which will return a list of reporting periods:
['quarterly', ...]
Then Odoo will fail to set/fetch the value of the allowed_reporting_period_ids field
To fix this issue, you can simply remove mapped (Odoo accepts to assign a recordset to a field)

Related

float() argument must be a string or a number, not 'tuple'

i need some help i am starting in odoo and i have this
#api.depends('clave_factura')
def set_totales(self):
self.env.cr.execute('select sum(total_detalle) as total from caratulas_detalle where factura_id = %s', (self.clave_factura,))
# fetchone() will return the first element found as dictionary
registros = self.env.cr.fetchall()
totaldtotales = registros[0] if registros else 0
for rec in self:
rec.total_kllevo = totaldtotales
rec.total_resto = rec.total_fac - rec.total_kllevo
and these are my fields
total_kllevo = fields.Float('Lo Agregado', readonly=True, help='Total', compute='set_totales', store=True)
total_resto = fields.Float('Lo Restante', readonly=True, help='Total', compute='set_totales', store=True)
and this is the error
File "c:\program files (x86)\odoo 12.0\server\odoo\addons\prossesa_proyectos\models\prossesa_proyectos.py", line 147, in set_totales
rec.total_kllevo = totaldtotales
File "C:\Program Files (x86)\Odoo 12.0\server\odoo\fields.py", line 1003, in __set__
value = self.convert_to_cache(value, record)
File "C:\Program Files (x86)\Odoo 12.0\server\odoo\fields.py", line 1263, in convert_to_cache
value = float(value or 0.0)
TypeError: float() argument must be a string or a number, not 'tuple'
I know that maybe it is something really easy but my mind crash.
You got that error because the first element of registros is a tuple.
Example:
>>> registros = self.env.cr.fetchall()
>>> registros[0]
(4610.0,)
You can fixt it using the first element of totaldtotales.

ValueError: invalid literal for int() with base 10: 'O'

I am relatively new to python, and as such I don't always understand why I get errors. I keep getting this error:
Traceback (most recent call last):
File "python", line 43, in <module>
ValueError: invalid literal for int() with base 10: 'O'
This is the line it's referring to:
np.insert(arr, [i,num], "O")
I'm trying to change a value in a numpy array.
Some code around this line for context:
hOne = [one,two,three]
hTwo = [four,five,six]
hThree = [seven, eight, nine]
arr = np.array([hOne, hTwo, hThree])
test = "O"
while a != Answer :
Answer = input("Please Enter Ready to Start")
if a == Answer:
while win == 0:
for lists in arr:
print(lists)
place = int(input("Choose a number(Use arabic numerals 1,5 etc.)"))
for i in range(0,len(arr)):
for num in range(0, len(arr[i])):
print(arr[i,num], "test")
print(arr)
if place == arr[i,num]:
if arr[i,num]:
np.delete(arr, [i,num])
np.insert(arr, [i,num], "O")
aiTurn = 1
else:
print(space_taken)
The number variables in the lists just hold the int version of themselves, so one = 1, two = 2 three = 3, etc
I've also tried holding "O" as a variable and changing it that way as well.
Can anyone tell me why I'm getting this error?

Porting addon from Odoo 9 to Odoo 10 - ProgrammingError: can't adapt type 'account.tax'

While trying to reuse this Odoo 9 addon https://www.odoo.com/apps/modules/9.0/purchase_recurring_orders/ | github code to Odoo 10, I am facing the following issue:
File "/usr/lib/python2.7/dist-packages/odoo/custom_addons/purchase_recurring_orders/models/recurring_orders.py", line 310, in generate_initial_order
order = self.create_order(self.start_date, agreement_lines)
...
ProgrammingError: can't adapt type 'account.tax'
Full error can be seen here:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 640, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 677, in dispatch
result = self._call_function(**self.params)
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 333, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/service/model.py", line 101, in wrapper
return f(dbname, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 326, in checked_call
result = self.endpoint(*a, **kw)
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 935, in __call__
return self.method(*args, **kw)
File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 506, in response_wrap
response = f(*args, **kw)
File "/usr/lib/python2.7/dist-packages/odoo/addons/web/controllers/main.py", line 889, in call_button
action = self._call_kw(model, method, args, {})
File "/usr/lib/python2.7/dist-packages/odoo/addons/web/controllers/main.py", line 877, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/api.py", line 681, in call_kw
return call_kw_multi(method, model, args, kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/api.py", line 672, in call_kw_multi
result = method(recs, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/custom_addons/purchase_recurring_orders/models/recurring_orders.py", line 310, in generate_initial_order
order = self.create_order(self.start_date, agreement_lines)
File "/usr/lib/python2.7/dist-packages/odoo/custom_addons/purchase_recurring_orders/models/recurring_orders.py", line 259, in create_order
order_line_obj.create(order_line_vals)
File "/usr/lib/python2.7/dist-packages/odoo/addons/purchase/models/purchase.py", line 557, in create
line = super(PurchaseOrderLine, self).create(values)
File "/usr/lib/python2.7/dist-packages/odoo/models.py", line 3830, in create
record = self.browse(self._create(old_vals))
File "/usr/lib/python2.7/dist-packages/odoo/models.py", line 3987, in _create
field.write(self.with_context(rel_context), vals[name])
File "/usr/lib/python2.7/dist-packages/odoo/fields.py", line 2402, in write
link(act[2])
File "/usr/lib/python2.7/dist-packages/odoo/fields.py", line 2367, in link
cr.execute(query, (records.ids, list(sub_ids), tuple(records.ids)))
File "/usr/lib/python2.7/dist-packages/odoo/sql_db.py", line 154, in wrapper
return f(self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/odoo/sql_db.py", line 231, in execute
res = self._obj.execute(query, params)
•ProgrammingError: can't adapt type 'account.tax'
So far I did not modify anything else than the group use.
This is the code of recurring_orders:
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Jesni Banu(<http://www.cybrosys.com>)
# you can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# It is forbidden to publish, distribute, sublicense, or sell copies
# of the Software or modified copies of the Software.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from datetime import timedelta
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import models, fields, api, exceptions, _
import openerp.addons.decimal_precision as dp
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
class Agreement(models.Model):
_name = 'purchase.recurring_orders.agreement'
_inherit = ['mail.thread']
_description = "Recurring orders agreement"
#api.model
def __get_next_term_date(self, date, unit, interval):
if unit == 'days':
return date + timedelta(days=interval)
elif unit == 'weeks':
return date + timedelta(weeks=interval)
elif unit == 'months':
return date + relativedelta(months=interval)
elif unit == 'years':
return date + relativedelta(years=interval)
#api.multi
def _compute_next_expiration_date(self):
for agreement in self:
if agreement.prolong == 'fixed':
agreement.next_expiration_date = agreement.end_date
elif agreement.prolong == 'unlimited':
now = fields.Date.from_string(fields.Date.today())
date = self.__get_next_term_date(
fields.Date.from_string(agreement.start_date),
agreement.prolong_unit, agreement.prolong_interval)
while date < now:
date = self.__get_next_term_date(
date, agreement.prolong_unit,
agreement.prolong_interval)
agreement.next_expiration_date = date
else:
agreement.next_expiration_date = self.__get_next_term_date(
fields.Date.from_string(agreement.last_renovation_date or
agreement.start_date),
agreement.prolong_unit, agreement.prolong_interval)
def _default_company_id(self):
company_model = self.env['res.company']
company_id = company_model._company_default_get('purchase')
return company_model.browse(company_id.id)
name = fields.Char(
string='Name', size=100, index=True, required=True,
help='Name that helps to identify the agreement')
number = fields.Char(
string='Agreement number', index=True, size=32, copy=False,
help="Number of agreement. Keep empty to get the number assigned by a "
"sequence.")
active = fields.Boolean(
string='Active', default=True,
help='Unchecking this field, quotas are not generated')
partner_id = fields.Many2one(
comodel_name='res.partner', string='Supplier', index=True,
change_default=True, required=True,
help="Supplier you are making the agreement with")
company_id = fields.Many2one(
comodel_name='res.company', string='Company', required=True,
help="Company that signs the agreement", default=_default_company_id)
start_date = fields.Date(
string='Start date', index=True, copy=False,
help="Beginning of the agreement. Keep empty to use the current date")
prolong = fields.Selection(
selection=[('recurrent', 'Renewable fixed term'),
('unlimited', 'Unlimited term'),
('fixed', 'Fixed term')],
string='Prolongation', default='unlimited',
help="Sets the term of the agreement. 'Renewable fixed term': It sets "
"a fixed term, but with possibility of manual renew; 'Unlimited "
"term': Renew is made automatically; 'Fixed term': The term is "
"fixed and there is no possibility to renew.", required=True)
end_date = fields.Date(
string='End date', help="End date of the agreement")
prolong_interval = fields.Integer(
string='Interval', default=1,
help="Interval in time units to prolong the agreement until new "
"renewable (that is automatic for unlimited term, manual for "
"renewable fixed term).")
prolong_unit = fields.Selection(
selection=[('days', 'days'),
('weeks', 'weeks'),
('months', 'months'),
('years', 'years')],
string='Interval unit', default='years',
help='Time unit for the prolongation interval')
agreement_line = fields.One2many(
comodel_name='purchase.recurring_orders.agreement.line',
inverse_name='agreement_id', string='Agreement lines')
order_line = fields.One2many(
comodel_name='purchase.order', copy=False, inverse_name='agreement_id',
string='Orders', readonly=True)
renewal_line = fields.One2many(
comodel_name='purchase.recurring_orders.agreement.renewal', copy=False,
inverse_name='agreement_id', string='Renewal lines', readonly=True)
last_renovation_date = fields.Date(
string='Last renovation date',
help="Last date when agreement was renewed (same as start date if not "
"renewed)")
next_expiration_date = fields.Date(
compute="_compute_next_expiration_date", string='Next expiration date')
state = fields.Selection(
selection=[('empty', 'Without orders'),
('first', 'First order created'),
('orders', 'With orders')],
string='State', readonly=True, default='empty')
renewal_state = fields.Selection(
selection=[('not_renewed', 'Agreement not renewed'),
('renewed', 'Agreement renewed')],
string='Renewal state', readonly=True, default='not_renewed')
notes = fields.Text('Notes')
_sql_constraints = [
('number_uniq', 'unique(number)', 'Agreement number must be unique !'),
]
#api.constrains('start_date', 'end_date')
def _check_dates(self):
for record in self:
if record.end_date and record.end_date < record.start_date:
raise exceptions.Warning(
_('Agreement end date must be greater than start date'))
#api.model
def create(self, vals):
if not vals.get('start_date'):
vals['start_date'] = fields.Date.today()
if not vals.get('number'):
vals['number'] = self.env['ir.sequence'].get(
'purchase.r_o.agreement.sequence')
return super(Agreement, self).create(vals)
#api.multi
def write(self, vals):
value = super(Agreement, self).write(vals)
if (any(vals.get(x) is not None for x in
['active', 'number', 'agreement_line', 'prolong', 'end_date',
'prolong_interval', 'prolong_unit', 'partner_id'])):
self.unlink_orders(fields.Date.today())
return value
#api.model
def copy(self, id, default=None):
agreement_record = self.browse(id)
default.update({
'state': 'empty',
'active': True,
'name': '%s*' % agreement_record['name'],
})
return super(Agreement, self).copy(id, default=default)
#api.multi
def unlink(self):
for agreement in self:
if any(agreement.mapped('order_line')):
raise exceptions.Warning(
_('You cannot remove agreements with confirmed orders!'))
self.unlink_orders(fields.Date.from_string(fields.Date.today()))
return models.Model.unlink(self)
#api.multi
def onchange_start_date(self, start_date=False):
if not start_date:
return {}
result = {'value': {'last_renovation_date': start_date}}
return result
#api.model
def revise_agreements_expirations_planned(self):
for agreement in self.search([('prolong', '=', 'unlimited')]):
if agreement.next_expiration_date <= fields.Date.today():
agreement.write({'prolong': 'unlimited'})
return True
#api.model
def _prepare_purchase_order_vals(self, agreement, date):
order_vals = {
'date_order': date,
'date_confirm': date,
'origin': agreement.number,
'partner_id': agreement.partner_id.id,
'state': 'draft',
'company_id': agreement.company_id.id,
'from_agreement': True,
'agreement_id': agreement.id,
'location_id': 1,
'fiscal_position_id': self.env['account.fiscal.position'].with_context(company_id=agreement.company_id.id).get_fiscal_position(agreement.partner_id.id),
'payment_term_id': agreement.partner_id.property_supplier_payment_term_id.id,
'currency_id': agreement.partner_id.property_purchase_currency_id.id or self.env.user.company_id.currency_id.id,
}
order_vals['user_id'] = agreement.partner_id.user_id.id
return order_vals
#api.model
def _prepare_purchase_order_line_vals(self, agreement_line, order):
product_lang = agreement_line.product_id.with_context({
'lang': order.partner_id.lang,
'partner_id': order.partner_id.id,
})
fpos = order.fiscal_position_id
order_line_vals = {
'order_id': order.id,
'product_id': agreement_line.product_id.id,
'product_qty': agreement_line.quantity,
'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'price_unit': 0.0,
'product_qty': 1.0,
'product_uom': agreement_line.product_id.uom_po_id.id or agreement_line.product_id.uom_id.id,
'name': product_lang.display_name,
'taxes_id': fpos.map_tax(agreement_line.product_id.supplier_taxes_id.filtered(lambda r: r.company_id.id == self.company_id.id))
}
if agreement_line.specific_price:
order_line_vals['price_unit'] = agreement_line.specific_price
order_line_vals['taxes_id'] = [(6, 0, tuple(order_line_vals['taxes_id']))]
if agreement_line.additional_description:
order_line_vals['name'] += " %s" % (
agreement_line.additional_description)
return order_line_vals
#api.multi
def create_order(self, date, agreement_lines):
self.ensure_one()
order_line_obj = self.env['purchase.order.line'].with_context(
company_id=self.company_id.id)
order_vals = self._prepare_purchase_order_vals(self, date)
order = self.env['purchase.order'].create(order_vals)
for agreement_line in agreement_lines:
order_line_vals = self._prepare_purchase_order_line_vals(
agreement_line, order)
order_line_obj.create(order_line_vals)
agreement_lines.write({'last_order_date': fields.Date.today()})
if self.state != 'orders':
self.state = 'orders'
return order
#api.multi
def _get_next_order_date(self, line, start_date):
self.ensure_one()
next_date = fields.Date.from_string(self.start_date)
while next_date <= start_date:
next_date = self.__get_next_term_date(
next_date, line.ordering_unit, line.ordering_interval)
return next_date
#api.multi
def generate_agreement_orders(self, start_date, end_date):
self.ensure_one()
if not self.active:
return
lines_to_order = {}
exp_date = fields.Date.from_string(self.next_expiration_date)
if exp_date < end_date and self.prolong != 'unlimited':
end_date = exp_date
for line in self.agreement_line:
if not line.active_chk:
continue
next_order_date = self._get_next_order_date(line, start_date)
while next_order_date <= end_date:
if not lines_to_order.get(next_order_date):
lines_to_order[next_order_date] = self.env[
'purchase.recurring_orders.agreement.line']
lines_to_order[next_order_date] |= line
next_order_date = self._get_next_order_date(
line, next_order_date)
dates = lines_to_order.keys()
dates.sort()
for date in dates:
order = self.order_line.filtered(
lambda x: (
fields.Date.to_string(
fields.Datetime.from_string(x.date_order)) ==
fields.Date.to_string(date)))
if not order:
self.create_order(
fields.Date.to_string(date), lines_to_order[date])
#api.multi
def generate_initial_order(self):
self.ensure_one()
agreement_lines = self.mapped('agreement_line').filtered('active_chk')
order = self.create_order(self.start_date, agreement_lines)
self.write({'state': 'first'})
order.signal_workflow('order_confirm')
return {
'domain': "[('id', '=', %s)]" % order.id,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'purchase.order',
'context': self.env.context,
'res_id': order.id,
'view_id': [self.env.ref('purchase.purchase_order_form').id],
'type': 'ir.actions.act_window',
'nodestroy': True
}
#api.model
def generate_next_orders_planned(self, years=1, start_date=None):
if start_date:
start_date = fields.Date.from_string(start_date)
self.search([]).generate_next_orders(
years=years, start_date=start_date)
#api.multi
def generate_next_year_orders(self):
return self.generate_next_orders(years=1)
#api.multi
def generate_next_orders(self, years=1, start_date=None):
if not start_date:
start_date = fields.Date.from_string(fields.Date.today())
end_date = start_date + relativedelta(years=years)
for agreement in self:
agreement.generate_agreement_orders(start_date, end_date)
return True
#api.model
def confirm_current_orders_planned(self):
tomorrow = fields.Date.to_string(
fields.Date.from_string(fields.Date.today()) + timedelta(days=1))
orders = self.env['purchase.order'].search([
('agreement_id', '!=', False),
('state', 'in', ('draft', 'sent')),
('date_order', '<', tomorrow)
])
for order in orders:
order.signal_workflow('order_confirm')
#api.multi
def unlink_orders(self, start_date):
orders = self.mapped('order_line').filtered(
lambda x: (x.state in ('draft', 'sent') and
x.date_order >= start_date))
orders.unlink()
class AgreementLine(models.Model):
_name = 'purchase.recurring_orders.agreement.line'
uom_id = fields.Many2one('product_uom', string="Uom")
active_chk = fields.Boolean(
string='Active', default=True,
help='Unchecking this field, this quota is not generated')
agreement_id = fields.Many2one(
comodel_name='purchase.recurring_orders.agreement',
string='Agreement reference', ondelete='cascade')
product_id = fields.Many2one(
comodel_name='product.product', string='Product', ondelete='set null',
required=True)
name = fields.Char(
related="product_id.name", string='Description', store=False)
additional_description = fields.Char(
string='Add. description', size=30,
help='Additional description that will be added to the product '
'description on orders.')
quantity = fields.Float(
string='Quantity', required=True, help='Quantity of the product',
default=1.0)
discount = fields.Float(string='Discount (%)', digits=(16, 2))
ordering_interval = fields.Integer(
string='Interval', required=True, default=1,
help="Interval in time units for making an order of this product")
ordering_unit = fields.Selection(
selection=[('days', 'days'),
('weeks', 'weeks'),
('months', 'months'),
('years', 'years')],
string='Interval unit', required=True, default='months')
last_order_date = fields.Date(
string='Last order', help='Date of the last Purchase order generated')
specific_price = fields.Float(
string='Specific price', digits_compute=dp.get_precision('Purchase Price'),
help='Specific price for this product. Keep empty to use the list '
'price while generating order')
list_price = fields.Float(
related='product_id.list_price', string="List price", readonly=True)
_sql_constraints = [
('line_qty_zero', 'CHECK (quantity > 0)',
'All product quantities must be greater than 0.\n'),
('line_interval_zero', 'CHECK (ordering_interval > 0)',
'All ordering intervals must be greater than 0.\n'),
]
#api.multi
def onchange_product_id(self, product_id=False):
result = {}
if product_id:
product = self.env['product.product'].browse(product_id)
if product:
result['value'] = {'name': product['name']}
return result
class AgreementRenewal(models.Model):
_name = 'purchase.recurring_orders.agreement.renewal'
agreement_id = fields.Many2one(
comodel_name='purchase.recurring_orders.agreement',
string='Agreement reference', ondelete='cascade', select=True)
date = fields.Date(string='Date', help="Date of the renewal")
comments = fields.Char(
string='Comments', size=200, help='Renewal comments')
I have found that this post might be relevant for this issue:
https://github.com/adhoc-dev/odoo-addons/issues/113
I have suspected that this line:
'taxes_id': fpos.map_tax(agreement_line.product_id.supplier_taxes_id.filtered(lambda r: r.company_id.id == self.company_id.id))
might be the issue so I used a print statement:
print fpos.map_tax(agreement_line.product_id.supplier_taxes_id.filtered(lambda r: r.company_id.id == self.company_id.id))
account.tax(6,)
But I do not know how to continue further.
Any help/tip on where the issue could be is welcomed.
The below code
fpos.map_tax(agreement_line.product_id.supplier_taxes_id.filtered(lambda r: r.company_id.id == self.company_id.id))
returns a recordset but database doesn't store record set. that's why it fails with the message.
ProgrammingError: can't adapt type 'account.tax'
Solution
recordset.id // for singleton recordset
result : id (integer)
recordset.ids // for multi recordset
result : list of ids []
now it depends on which type of field you are going to write this value. If it is a Many2one field then it is supposed to be an integer. that you may get with recordset.id
NOTE 1 -
Be careful recordset can be recordsets that means mutliple records that will look like account.tax(6,7,12,34). In this case if you say recordset.id, it will fail because there are multiple Ids and it is not sure which one you want. So to get IDs from the recordset you can do recordset.ids that would result a list like [6,7,12,34] or [] in case a blank recordset.
NOTE2 -
If you were trying to write in a Many2many field. You can do something like
self.taxes_id = [(6,0, recordset.ids)]

Odoo 9 context value missing in override method

in odoo9 I override the search_read method. The super method works ok. With the data returned I want to make a filter, the filter is on the context, the value was asigned on the click of the button comming from the view.
<button name="status_instalacion" string="Instalación" type="action" icon="fa-wrench fa-2x" context="{'stage_id' : 1, 'current_id': active_id}"/>
The problem occurs when I query the context in the search_read method. It exists but doesn't have the values I placed
context on click of button:
self._context
{u'lang': u'en_US', u'stage_id': 1, u'tz': False, u'uid': 1, u'current_id': 40, u'tipo_validacion': u'Sistemas Cr\xedticos', u'sistema_critico': u'AGUA'}
the stage_id is the value I want
context on read_search:
self._context
{u'lang': u'en_US', u'bin_size': True, u'tipo_validacion': u'Sistemas Cr\xedticos', u'tz': False, u'uid': 1,
u'active_test': False, u'sistema_critico': u'AGUA'}
as you can see the 'stage_id' value is missing
Tried also assigning the value to a property of the class, but the value never changes it is always the initial value.
from logging import getLogger
from openerp import api, fields, models
_logger = getLogger(__name__)
class MgmtsystemSistemasEquipos(models.Model):
""" Equipos."""
_name = 'mgmtsystem.sistemas.equipos'
dmy = 99 # ---> this value never changes
def dummy(self): # ---> tried calling a function. not work
return self.dmy
def set_dummy(self, id): # ----> set the value
self.dmy = id or self.dmy
codigo = fields.Char(
string=u'Código',
help=u"Código equipo",
required=True,
size=30)
name = fields.Char(
string=u'Nombre equipo',
required=True,
readonly=False,
index=True,
help="Nombre corto equipo",
size=30)
stage_id = fields.Many2one(
'mgmtsystem.action.stage',
'Fase',
default=_default_stage,
readonly=True)
#api.multi
def status_instalacion(self):
import pudb
pu.db
# save value to variable dmy to retrieve later
id = self._context.get('stage_id')
self.set_dummy(id)
#api.model
def search_read(
self, domain=None, fields=None, offset=0,
limit=None, order=None):
import pudb
pu.db
# here the variable allways has the original value (99)
current_stage_id = self.dmy
current_stage_id = self.dummy()
current_stage_id = getattr(self, dmy)
res = super(MgmtsystemSistemasEquipos, self).search_read(
domain, fields, offset, limit, order)
current_id = res[0]['id']
valid_protocols_ids = self._get_ids(
current_stage_id, current_id,
'mgmtsystem_equipos_protocolos',
'mgmtsystem_equipos_protocolos_rel',
'protocolo_id')
# # remove ids
res[0]['protocolos_ids'] = valid_protocols_ids
res[0]['informes_ids'] = valid_informes_ids
res[0]['anexos_ids'] = valid_anexos_ids
return res
# #api.multi
def _get_ids(self, current_stage_id, current_id, model, model_rel, field_rel):
import pudb
pu.db
# in this method the value of the variable is allways the original
current_stage_id = self.dummy()
sql = """ select a.id from
%s as a
join %s as b
on a.id = b.%s where b.equipo_id = %s
and a.stage_id = %s; """ % (model, model_rel, field_rel,
current_id, current_stage_id)
import psycopg2
try:
self.env.cr.execute(sql)
except psycopg2.ProgrammingError, ex:
message = 'Error trying to download data from server. \n {0} \n {1}'.format(ex.pgerror, sql)
_logger.info(message)
return False
rows = self.env.cr.fetchall()
list_of_ids = []
for row in rows:
list_of_ids.append(row[0])
return list_of_ids
I don't know Python very well, and thats the cause of my misunderstanding of how to read the value of the variable.
But then again, Why is the context modified in the search_read method?.
Thank you.
You should try following.
#api.model
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
import pudb
pu.db
# Here you need to get the value from the context.
current_stage_id = self._context.get('stage_id', getattr(self, dmy))
res = super(MgmtsystemSistemasEquipos, self).search_read(domain=domain, fields=fields, offset=offset, limit=limit, order=order)
current_id = res[0]['id']
valid_protocols_ids = self._get_ids(
current_stage_id, current_id,
'mgmtsystem_equipos_protocolos',
'mgmtsystem_equipos_protocolos_rel',
'protocolo_id')
# # remove ids
res[0]['protocolos_ids'] = valid_protocols_ids
res[0]['informes_ids'] = valid_informes_ids
res[0]['anexos_ids'] = valid_anexos_ids
return res
In your code those lines won't work just because there is no recordset available in self (it's correct behaviour search_read must have #api.model decorator).
# here the variable allways has the original value (99)
current_stage_id = self.dmy
current_stage_id = self.dummy()
current_stage_id = getattr(self, dmy)
So just remove those and lines and apply some other logic to get data.

Read line by line odoo 9

How can I print using the new api line by line in myrecord_ids field(name)
#api.multi
def func(self):
for line in self.browse(myrecord_ids):
print(line.name)
I want print this line: https://postimg.org/image/nvl45fuuh/
#api.multi
def func(self):
for line in self.myrecord_ids:
print(line.name)
If you encounter unexpected output you can print all values of your related field by doing the following.
#api.multi
def func(self):
for line in self.myrecord_ids:
print(line.read([]))
if self.myrecord_ids returns myrecord_ids(1,) myrecord_ids(2,) myrecord_ids(3,) then you are working with a recordset, so you can use list comprehension to get all names:
list_of_names = [i.name for i in self.myrecord_ids]
and then simply print it in loop or with ', '.join(list_of_names).
In case you want to see IDs, put it in expression, for example:
list_with_ids = ["%d: %s" % (i.id, i.name) for i in self.myrecord_ids]