I have 2 models "Inventory" and "Scrap". There is a button. I want to, if i click the button the data move to scrap model. It is okay i did that. But except one variable, "Many2one".
So I'm getting this error, when i click the button: "psycopg2.ProgrammingError: can't adapt type 'ware.houses' odoo".
This is my Inventory Module.
class InventoryMenu(models.Model):
_name = "inventory.menu"
_description = "Inventory Menü"
ref_code = fields.Char(string="Referans Numarası: ", required=True, tracking=True, default="000000")
product_name = fields.Char(string="Ürün Adı: ", required=True, tracking=True,)
product_description = fields.Char(string="Ürün Tanımı: ", required=True, tracking=True,)
teslim_alan = fields.Char(string="Teslim Alan: ", required=True, tracking=True,)
teslim_eden = fields.Char(string="Teslim Eden: ", required=True, tracking=True,)
quantity = fields.Float(string="Miktar: ", required=True, tracking=True,)
price = fields.Float(string="Fiyat: ", required=True, tracking=True,)
unit_price = fields.Float(string="Birim Fiyat: ", compute="_unitPriceCalcuteFunc")
warehouse_id = fields.Many2one('ware.houses', string='Depo Adı: ')
#api.depends('quantity', 'price')
def _unitPriceCalcuteFunc(self):
for record in self:
record.unit_price = record.price * record.quantity
def action_delete(self):
vals = {
'ref_code': self.ref_code,
'product_name': self.product_name,
'product_description': self.product_description,
'teslim_alan': self.teslim_alan,
'teslim_eden': self.teslim_eden,
'quantity': self.quantity,
'price': self.price,
'unit_price': self.unit_price,
'warehouse_id': self.warehouse_id
}
self.env['scrap'].create(vals)
return super(InventoryMenu, self).unlink()
This is my Scrap module:
class Scrap(models.Model):
_name = "scrap"
_description = "Scrap"
ref_code = fields.Char(string="Referans Numarası: ", required=True, tracking=True, default="000000")
product_name = fields.Char(string="Ürün Adı: ", required=True, tracking=True, )
product_description = fields.Char(string="Ürün Tanımı: ", required=True, tracking=True, )
teslim_alan = fields.Char(string="Teslim Alan: ", required=True, tracking=True, )
teslim_eden = fields.Char(string="Teslim Eden: ", required=True, tracking=True, )
quantity = fields.Float(string="Miktar: ", required=True, tracking=True, )
price = fields.Float(string="Fiyat: ", required=True, tracking=True, )
unit_price = fields.Float(string="Birim Fiyat: ", compute="_unitPriceCalcuteFunc")
warehouse_id = fields.Many2one('ware.houses', string='Depo Adı: ')
#api.depends('quantity', 'price')
def _unitPriceCalcuteFunc(self):
for record in self:
record.unit_price = record.price * record.quantity
def action_getback(self):
vals = {
'ref_code': self.ref_code,
'product_name': self.product_name,
'product_description': self.product_description,
'teslim_alan': self.teslim_alan,
'teslim_eden': self.teslim_eden,
'quantity': self.quantity,
'price': self.price,
'unit_price': self.unit_price,
'warehouse_id': self.warehouse_id
}
self.env['inventory.menu'].create(vals)
return super(Scrap, self).unlink()
Here is the solution for above code:
'warehouse_id': self.warehouse_id
Please change this line to:
'warehouse_id': self.warehouse_id.id
While creating your vals in action_delete and action_getback methods.
Root Cause: When you pass dictionary of values which you want to create in your model, make sure that every field have correct value.
For EX: If field is Many2one than you need to pass the record_id (type=int), because odoo will directly browse the id to the related model and place the record to that field.
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)]
I am trying to create a sample order in sales order.In the sample order form, products are sold to customers as complimentary copy(books in my case) without charging any money so I have created a separate sub-menu in sales menu.Here I take only product and quantity as input. Sample order number will be the next number from the sales order(like SO360).So I am fetching sales order number as parent_id in my inherited module.I am not able to create sale order line(data in order lines tab)
class SaleOrder(models.Model):
_inherit = 'sale.order'
# Fields
is_sample = fields.Boolean(string="Sample Order", default=False)
parent_id = fields.Many2one('sale.order', string="Parent Sales Order")
sample_ids = fields.One2many('sale.order', 'parent_id',
string="Sample Orders")
# Methods
#api.model
#api.returns('sale.order')
def create(self, vals):
if vals.get('is_sample', False) and vals.get('name', '/') == '/':
IrSeq = self.env['ir.sequence']
ref = IrSeq.next_by_code('sale.order.sample.ref') or '/'
parent = self.search([('id', '=', vals.get('parent_id'))])
vals['name'] = parent.name + ref
vals['user_id'] = parent.user_id.id
return super(SaleOrder, self).create(vals)
class SampleOrderWizard(models.TransientModel):
_name = 'sale.order.sample.wizard'
_description = 'Sample Sale Order Wizard'
# Field default values
#
def _get_parent(self):
res = False
if self.env.context \
and 'active_id' in list(self.env.context.iterkeys()):
res = self.env.context['active_id']
return res
def _get_new_sale_line(self, orig_sale, orig_sale_line, wizard_line):
"""Internal function to get the fields of the sale order line. Modules
enhancing this one should add their own fields to the return value."""
res = {
'order_id': orig_sale.id,
'product_id': orig_sale_line.product_id.id,
'name': orig_sale_line.name,
'sequence': orig_sale_line.sequence,
'price_unit': orig_sale_line.price_unit,
'product_uom': orig_sale_line.product_uom.id,
'product_uom_qty': wizard_line and wizard_line.qty or 0,
'product_uos_qty': wizard_line and wizard_line.qty or 0,
}
# Simple check for installation of sale_line_code module
if hasattr(orig_sale_line, 'order_line_ref'):
res.update({'order_line_ref': orig_sale_line.order_line_ref})
return res
def _get_order_lines(self, sale):
res = []
for line in sale.order_line:
wizard_line = False
for wzline in self.wizard_lines:
if wzline.product == line.product_id:
wizard_line = wzline
break
if wizard_line:
res.append(
(0, 0, self._get_new_sale_line(sale, line, wizard_line))
)
return res
def _get_wizard_lines(self):
res = []
if self._get_parent():
SaleOrder = self.env['sale.order']
parent = SaleOrder.search([('id', '=', self._get_parent())])
for line in parent.order_line:
res.append((0, 0,
{
'product': line.product_id,
'qty': 1,
}))
return res
# Fields
#
order = fields.Many2one('sale.order', default=_get_parent, readonly=True)
wizard_lines = fields.One2many('sale.order.sample.wizard.line', 'wizard',
default=_get_wizard_lines)
order_date = fields.Datetime(default=fields.Datetime.now())
# Methods
#
#api.one
def create_order(self):
sale_vals = {
'user_id': self.order.user_id.id,
'partner_id': self.order.partner_id.id,
'parent_id': self.order.id,
'date_order': self.order_date,
'client_order_ref': self.order.client_order_ref,
'company_id': self.order.company_id.id,
'is_sample': True,
'order_line': self._get_order_lines(self.order)
}
self.env['sale.order'].create(sale_vals)
return {'type': 'ir.actions.act_window_close'}
class SampleOrderWizardLine(models.TransientModel):
_name = 'sale.order.sample.wizard.line'
_description = 'Sample Order Wizard Line'
wizard = fields.Many2one('sale.order.sample.wizard')
product = fields.Many2one('product.product',
domain=[('sale_ok', '=', True)])
qty = fields.Float(string="Quantity", default=1.0,
digits_compute=dp.get_precision('Product UoS'))