[MERGE] forward port of branch 8.0 up to d4f41a1
This commit is contained in:
@@ -539,7 +539,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
|
||||
data = pickle.loads(base64.decodestring(wizard.file_import))
|
||||
|
||||
migration_fix_obj = self.pool.get('ir.model.fields.anonymization.migration.fix')
|
||||
fix_ids = migration_fix_obj.search(cr, uid, [('target_version', '=', '7.0')])
|
||||
fix_ids = migration_fix_obj.search(cr, uid, [('target_version', '=', '8.0')])
|
||||
fixes = migration_fix_obj.read(cr, uid, fix_ids, ['model_name', 'field_name', 'query', 'query_type', 'sequence'])
|
||||
fixes = group(fixes, ('model_name', 'field_name'))
|
||||
|
||||
|
||||
@@ -209,9 +209,9 @@
|
||||
(e.g. a customer that has multiple tags)?</a></dt>
|
||||
<dd>
|
||||
<p>The tags should be separated by a comma without any
|
||||
spacing. For example, if you want you customer to be
|
||||
lined to both tags 'Manufacturer' and 'Retailer'
|
||||
then you will encode it as follow "Manufacturer,
|
||||
spacing. For example, if you want your customer to be
|
||||
linked to both tags 'Manufacturer' and 'Retailer'
|
||||
then you will encode "Manufacturer,
|
||||
Retailer" in the same column of your CSV file.</p>
|
||||
<a href="/base_import/static/csv/m2m_customers_tags.csv">
|
||||
CSV file for Manufacturer, Retailer</a><br/>
|
||||
|
||||
@@ -502,6 +502,7 @@ class google_calendar(osv.AbstractModel):
|
||||
rrule = [rule for rule in single_event_dict["recurrence"] if rule.startswith("RRULE:")][0][6:]
|
||||
result['rrule'] = rrule
|
||||
|
||||
context = dict(context or {}, no_mail_to_attendees=True)
|
||||
if type == "write":
|
||||
res = calendar_event.write(cr, uid, event['id'], result, context=context)
|
||||
elif type == "copy":
|
||||
|
||||
@@ -265,6 +265,14 @@ class hr_timesheet_sheet(osv.osv):
|
||||
raise UserError(_('You cannot delete a timesheet which is already confirmed.'))
|
||||
elif sheet['total_attendance'] <> 0.00:
|
||||
raise UserError(_('You cannot delete a timesheet which have attendance entries.'))
|
||||
|
||||
toremove = []
|
||||
analytic_timesheet = self.pool.get('hr.analytic.timesheet')
|
||||
for sheet in self.browse(cr, uid, ids, context=context):
|
||||
for timesheet in sheet.timesheet_ids:
|
||||
toremove.append(timesheet.id)
|
||||
analytic_timesheet.unlink(cr, uid, toremove, context=context)
|
||||
|
||||
return super(hr_timesheet_sheet, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
import math
|
||||
import re
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from _common import ceiling
|
||||
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp import tools
|
||||
from openerp.osv import osv, fields, expression
|
||||
@@ -796,9 +798,16 @@ class product_template(osv.osv):
|
||||
pass
|
||||
return super(product_template, self).name_get(cr, user, ids, context)
|
||||
|
||||
|
||||
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):
|
||||
product_product = self.pool['product.product']
|
||||
results = product_product.name_search(
|
||||
cr, user, name, args, operator=operator, context=context, limit=limit)
|
||||
product_ids = [p[0] for p in results]
|
||||
template_ids = [p.product_tmpl_id.id
|
||||
for p in product_product.browse(
|
||||
cr, user, product_ids, context=context)]
|
||||
uniq_ids = OrderedDict.fromkeys(template_ids).keys()
|
||||
return self.name_get(cr, user, uniq_ids, context=context)
|
||||
|
||||
class product_product(osv.osv):
|
||||
_name = "product.product"
|
||||
@@ -1068,12 +1077,11 @@ class product_product(osv.osv):
|
||||
# on a database with thousands of matching products, due to the huge merge+unique needed for the
|
||||
# OR operator (and given the fact that the 'name' lookup results come from the ir.translation table
|
||||
# Performing a quick memory merge of ids in Python will give much better performance
|
||||
ids = set(self.search(cr, user, args + [('default_code', operator, name)], limit=limit, context=context))
|
||||
ids = self.search(cr, user, args + [('default_code', operator, name)], limit=limit, context=context)
|
||||
if not limit or len(ids) < limit:
|
||||
# we may underrun the limit because of dupes in the results, that's fine
|
||||
limit2 = (limit - len(ids)) if limit else False
|
||||
ids.update(self.search(cr, user, args + [('name', operator, name), ('id', 'not in', list(ids))], limit=limit2, context=context))
|
||||
ids = list(ids)
|
||||
ids += self.search(cr, user, args + [('name', operator, name), ('id', 'not in', ids)], limit=limit2, context=context)
|
||||
elif not ids and operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||
ids = self.search(cr, user, args + ['&', ('default_code', operator, name), ('name', operator, name)], limit=limit, context=context)
|
||||
if not ids and operator in positive_operators:
|
||||
|
||||
@@ -115,9 +115,12 @@ class project_work(osv.osv):
|
||||
vals_line['user_id'] = vals['user_id']
|
||||
vals_line['product_id'] = result['product_id']
|
||||
if vals.get('date'):
|
||||
timestamp = datetime.datetime.strptime(vals['date'], tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
ts = fields.datetime.context_timestamp(cr, uid, timestamp, context)
|
||||
vals_line['date'] = ts.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
if len(vals['date']) > 10:
|
||||
timestamp = datetime.datetime.strptime(vals['date'], tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
ts = fields.datetime.context_timestamp(cr, uid, timestamp, context)
|
||||
vals_line['date'] = ts.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
else:
|
||||
vals_line['date'] = vals['date']
|
||||
|
||||
# Calculate quantity based on employee's product's uom
|
||||
vals_line['unit_amount'] = vals['hours']
|
||||
@@ -260,7 +263,7 @@ class task(osv.osv):
|
||||
missing_analytic_entries[task_work.id] = {
|
||||
'name' : task_work.name,
|
||||
'user_id' : task_work.user_id.id,
|
||||
'date' : task_work.date and task_work.date[:10] or False,
|
||||
'date' : task_work.date,
|
||||
'account_id': acc_id,
|
||||
'hours' : task_work.hours,
|
||||
'task_id' : task_obj.id
|
||||
|
||||
+21
-13
@@ -70,13 +70,33 @@ class stock_move(osv.osv):
|
||||
self.pool.get('purchase.order').write(cr, uid, [purchase_line.order_id.id], {
|
||||
'invoice_ids': [(4, invoice_line_vals['invoice_id'])],
|
||||
})
|
||||
purchase_line_obj = self.pool.get('purchase.order.line')
|
||||
purchase_obj = self.pool.get('purchase.order')
|
||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||
purchase_id = move.purchase_line_id.order_id.id
|
||||
purchase_line_ids = purchase_line_obj.search(cr, uid, [('order_id', '=', purchase_id), ('product_id.type', '=', 'service'), ('invoice_lines', '=', False)], context=context)
|
||||
if purchase_line_ids:
|
||||
inv_lines = []
|
||||
for po_line in purchase_line_obj.browse(cr, uid, purchase_line_ids, context=context):
|
||||
acc_id = purchase_obj._choose_account_from_po_line(cr, uid, po_line, context=context)
|
||||
inv_line_data = purchase_obj._prepare_inv_line(cr, uid, acc_id, po_line, context=context)
|
||||
inv_line_id = invoice_line_obj.create(cr, uid, inv_line_data, context=context)
|
||||
inv_lines.append(inv_line_id)
|
||||
po_line.write({'invoice_lines': [(4, inv_line_id)]})
|
||||
invoice_line_obj.write(cr, uid, inv_lines, {'invoice_id': invoice_line_vals['invoice_id']}, context=context)
|
||||
return invoice_line_id
|
||||
|
||||
def _get_master_data(self, cr, uid, move, company, context=None):
|
||||
if move.purchase_line_id:
|
||||
purchase_order = move.purchase_line_id.order_id
|
||||
return purchase_order.partner_id, purchase_order.create_uid.id, purchase_order.currency_id.id
|
||||
else:
|
||||
elif move.picking_id:
|
||||
# In case of an extra move, it is better to use the data from the original moves
|
||||
for purchase_move in move.picking_id.move_lines:
|
||||
if purchase_move.purchase_line_id:
|
||||
purchase_order = purchase_move.purchase_line_id.order_id
|
||||
return purchase_order.partner_id, purchase_order.create_uid.id, purchase_order.currency_id.id
|
||||
|
||||
partner = move.picking_id and move.picking_id.partner_id or False
|
||||
code = self.get_code_from_locs(cr, uid, move, context=context)
|
||||
if partner and partner.property_product_pricelist_purchase and code == 'incoming':
|
||||
@@ -149,18 +169,6 @@ class stock_picking(osv.osv):
|
||||
purchase_line_obj = self.pool.get('purchase.order.line')
|
||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||
invoice_id = super(stock_picking, self)._create_invoice_from_picking(cr, uid, picking, vals, context=context)
|
||||
if picking.move_lines and picking.move_lines[0].purchase_line_id:
|
||||
purchase_id = picking.move_lines[0].purchase_line_id.order_id.id
|
||||
purchase_line_ids = purchase_line_obj.search(cr, uid, [('order_id', '=', purchase_id), ('product_id.type', '=', 'service'), ('invoiced', '=', False)], context=context)
|
||||
if purchase_line_ids:
|
||||
inv_lines = []
|
||||
for po_line in purchase_line_obj.browse(cr, uid, purchase_line_ids, context=context):
|
||||
acc_id = purchase_obj._choose_account_from_po_line(cr, uid, po_line, context=context)
|
||||
inv_line_data = purchase_obj._prepare_inv_line(cr, uid, acc_id, po_line, context=context)
|
||||
inv_line_id = invoice_line_obj.create(cr, uid, inv_line_data, context=context)
|
||||
inv_lines.append(inv_line_id)
|
||||
po_line.write({'invoice_lines': [(4, inv_line_id)]})
|
||||
invoice_line_obj.write(cr, uid, inv_lines, {'invoice_id': invoice_id}, context=context)
|
||||
return invoice_id
|
||||
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, move, context=None):
|
||||
|
||||
@@ -54,7 +54,9 @@ class AbstractReport(osv.AbstractModel):
|
||||
|
||||
# Rendering self._template with the wrapped report instance localcontext as
|
||||
# rendering environment
|
||||
docargs = wrapped_report.localcontext
|
||||
docargs = dict(wrapped_report.localcontext)
|
||||
if not docargs.get('lang'):
|
||||
docargs.pop('lang', False)
|
||||
docargs['docs'] = docargs.get('objects')
|
||||
|
||||
# Used in template translation (see translate_doc method from report model)
|
||||
|
||||
@@ -517,7 +517,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_sales"
|
||||
type="action" icon="fa-strikethrough">
|
||||
type="object" icon="fa-strikethrough">
|
||||
<field string="Sales" name="sales_count" widget="statinfo" />
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
@@ -374,12 +374,23 @@ class stock_move(osv.osv):
|
||||
self.pool.get('sale.order').write(cr, uid, [sale_line.order_id.id], {
|
||||
'invoice_ids': [(4, invoice_line_vals['invoice_id'])],
|
||||
})
|
||||
sale_line_obj = self.pool.get('sale.order.line')
|
||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||
sale_line_ids = sale_line_obj.search(cr, uid, [('order_id', '=', move.procurement_id.sale_line_id.order_id.id), ('product_id.type', '=', 'service'), ('invoiced', '=', False)], context=context)
|
||||
if sale_line_ids:
|
||||
created_lines = sale_line_obj.invoice_line_create(cr, uid, sale_line_ids, context=context)
|
||||
invoice_line_obj.write(cr, uid, created_lines, {'invoice_id': invoice_line_vals['invoice_id']}, context=context)
|
||||
|
||||
return invoice_line_id
|
||||
|
||||
def _get_master_data(self, cr, uid, move, company, context=None):
|
||||
if move.procurement_id and move.procurement_id.sale_line_id and move.procurement_id.sale_line_id.order_id.order_policy == 'picking':
|
||||
sale_order = move.procurement_id.sale_line_id.order_id
|
||||
return sale_order.partner_invoice_id, sale_order.user_id.id, sale_order.pricelist_id.currency_id.id
|
||||
elif move.picking_id.sale_id:
|
||||
# In case of extra move, it is better to use the same data as the original moves
|
||||
sale_order = move.picking_id.sale_id
|
||||
return sale_order.partner_invoice_id, sale_order.user_id.id, sale_order.pricelist_id.currency_id.id
|
||||
return super(stock_move, self)._get_master_data(cr, uid, move, company, context=context)
|
||||
|
||||
def _get_invoice_line_vals(self, cr, uid, move, partner, inv_type, context=None):
|
||||
@@ -442,13 +453,6 @@ class stock_picking(osv.osv):
|
||||
sale_line_obj = self.pool.get('sale.order.line')
|
||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||
invoice_id = super(stock_picking, self)._create_invoice_from_picking(cr, uid, picking, vals, context=context)
|
||||
if picking.group_id:
|
||||
sale_ids = sale_obj.search(cr, uid, [('procurement_group_id', '=', picking.group_id.id)], context=context)
|
||||
if sale_ids:
|
||||
sale_line_ids = sale_line_obj.search(cr, uid, [('order_id', 'in', sale_ids), ('product_id.type', '=', 'service'), ('invoiced', '=', False)], context=context)
|
||||
if sale_line_ids:
|
||||
created_lines = sale_line_obj.invoice_line_create(cr, uid, sale_line_ids, context=context)
|
||||
invoice_line_obj.write(cr, uid, created_lines, {'invoice_id': invoice_id}, context=context)
|
||||
return invoice_id
|
||||
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, move, context=None):
|
||||
|
||||
@@ -2530,6 +2530,7 @@ class stock_move(osv.osv):
|
||||
'split_from': move.id,
|
||||
'procurement_id': move.procurement_id.id,
|
||||
'move_dest_id': move.move_dest_id.id,
|
||||
'origin_returned_move_id': move.origin_returned_move_id.id,
|
||||
}
|
||||
if context.get('source_location_id'):
|
||||
defaults['location_id'] = context['source_location_id']
|
||||
|
||||
@@ -133,6 +133,12 @@ class stock_return_picking(osv.osv_memory):
|
||||
raise UserError(_("You have manually created product lines, please delete them to proceed"))
|
||||
new_qty = data_get.quantity
|
||||
if new_qty:
|
||||
# The return of a return should be linked with the original's destination move if it was not cancelled
|
||||
if move.origin_returned_move_id.move_dest_id.id and move.origin_returned_move_id.move_dest_id.state != 'cancel':
|
||||
move_dest_id = move.origin_returned_move_id.move_dest_id.id
|
||||
else:
|
||||
move_dest_id = False
|
||||
|
||||
returned_lines += 1
|
||||
move_obj.copy(cr, uid, move.id, {
|
||||
'product_id': data_get.product_id.id,
|
||||
@@ -145,6 +151,7 @@ class stock_return_picking(osv.osv_memory):
|
||||
'origin_returned_move_id': move.id,
|
||||
'procure_method': 'make_to_stock',
|
||||
'restrict_lot_id': data_get.lot_id.id,
|
||||
'move_dest_id': move_dest_id,
|
||||
})
|
||||
|
||||
if not returned_lines:
|
||||
|
||||
@@ -2501,7 +2501,9 @@ instance.web.form.Priority = instance.web.form.FieldChar.extend({
|
||||
this.record_id = this.view.datarecord.id;
|
||||
this.priorities = this.prepare_priority();
|
||||
this.$el.html(QWeb.render("Priority", {'widget': this}));
|
||||
this.$el.find('li').on('click', this.set_priority.bind(this));
|
||||
if (!this.get('readonly')){
|
||||
this.$el.find('li').on('click', this.set_priority.bind(this));
|
||||
}
|
||||
},
|
||||
/* setting the value: in view mode, perform an asynchronous call and reload
|
||||
the form view; in edit mode, use set_value to save the new value that will
|
||||
|
||||
@@ -1118,9 +1118,10 @@
|
||||
<ul style="list-style: none; padding-left: 2px; display: inline-block;">
|
||||
<t t-foreach="widget.priorities" t-as="rec" >
|
||||
<li t-att-data-value="rec.click_value" style="display: inline-block;">
|
||||
<a href="#" t-att-title="rec.name">
|
||||
<a t-if="!widget.get('readonly')" href="#" t-att-title="rec.name">
|
||||
<i t-att-class="widget.get('value') gte rec.value and 'fa fa-star oe_star_on' or 'fa fa-star oe_star_off'"/>
|
||||
</a>
|
||||
<span t-if="widget.get('readonly')" t-att-title="rec.name" t-att-class="widget.get('value') gte rec.value and 'oe_e oe_star_on' or 'oe_e oe_star_off'">7</span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
||||
@@ -1332,8 +1332,14 @@ instance.web_kanban.Priority = instance.web_kanban.AbstractField.extend({
|
||||
var self = this;
|
||||
this.record_id = self.parent.id;
|
||||
this.priorities = self.prepare_priority();
|
||||
var readonly = this.field && this.field.readonly;
|
||||
if (readonly){
|
||||
this.set('readonly', true);
|
||||
}
|
||||
this.$el = $(QWeb.render("Priority", {'widget': this}));
|
||||
this.$el.find('li').click(self.do_action.bind(self));
|
||||
if (!readonly){
|
||||
this.$el.find('li').click(self.do_action.bind(self));
|
||||
}
|
||||
},
|
||||
do_action: function(e) {
|
||||
var self = this;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Load helper
|
||||
phantom.injectJs(phantom.args[0]);
|
||||
var system = require('system');
|
||||
phantom.injectJs(system.args[1]);
|
||||
pt = new PhantomTest();
|
||||
pt.run("/", "console.log('ok')", "console");
|
||||
|
||||
Vendored
+4
-2
@@ -106,8 +106,10 @@ $(function () {
|
||||
// programming language switcher
|
||||
function findSheet(pattern, fromSheet) {
|
||||
if (fromSheet) {
|
||||
for(var i=0; i<fromSheet.cssRules.length; ++i) {
|
||||
var rule = fromSheet.cssRules[i];
|
||||
// cssRules may be `null` in iOS safari (?)
|
||||
var rules = fromSheet.cssRules || [];
|
||||
for(var i=0; i<rules.length; ++i) {
|
||||
var rule = rules[i];
|
||||
if (rule.type !== CSSRule.IMPORT_RULE) { continue; }
|
||||
if (pattern.test(rule.href)) {
|
||||
return rule.styleSheet;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
Germany, 2015-02-23
|
||||
|
||||
D9T GmbH agrees to the terms of the Odoo Corporate Contributor License
|
||||
Agreement v1.0.
|
||||
|
||||
I declare that I am authorized and able to make this agreement and sign this
|
||||
declaration.
|
||||
|
||||
Signed,
|
||||
|
||||
Daniel Kraft, daniel.kraft@d9t.de https://github.com/wamdam
|
||||
|
||||
List of contributors:
|
||||
|
||||
Daniel Kraft, daniel.kraft@d9t.de https://github.com/wamdam
|
||||
Oliver Roch, oliver.roch@d9t.de https://github.com/veroc
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import models
|
||||
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'test-inherits',
|
||||
'version': '0.1',
|
||||
'category': 'Tests',
|
||||
'description': """A module to verify the inheritance using _inherits.""",
|
||||
'author': 'Camptocamp',
|
||||
'website': 'http://www.camptocamp.com',
|
||||
'depends': ['base'],
|
||||
'data': [
|
||||
'ir.model.access.csv',
|
||||
'demo_data.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="unit_a" model="test.unit">
|
||||
<field name="name">Unit A</field>
|
||||
<field name="state">a</field>
|
||||
</record>
|
||||
|
||||
<record id="box_a" model="test.box">
|
||||
<field name="unit_id" ref="unit_a"/>
|
||||
<field name="field_in_box">A</field>
|
||||
</record>
|
||||
|
||||
<record id="pallet_a" model="test.pallet">
|
||||
<field name="box_id" ref="box_a"/>
|
||||
<field name="field_in_pallet">A</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,4 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_test_unit,access_test_unit,model_test_unit,,1,1,1,1
|
||||
access_test_box,access_test_box,model_test_box,,1,1,1,1
|
||||
access_test_pallet,access_test_pallet,model_test_pallet,,1,1,1,1
|
||||
|
@@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp import models, fields, api, osv
|
||||
|
||||
|
||||
# We just create a new model
|
||||
class Unit(models.Model):
|
||||
_name = 'test.unit'
|
||||
|
||||
_columns = {
|
||||
'name': osv.fields.char('Name', required=True),
|
||||
'state': osv.fields.selection([('a', 'A'), ('b', 'B')],
|
||||
string='State'),
|
||||
}
|
||||
|
||||
surname = fields.Char(compute='_compute_surname')
|
||||
|
||||
@api.one
|
||||
@api.depends('name')
|
||||
def _compute_surname(self):
|
||||
self.surname = self.name or ''
|
||||
|
||||
|
||||
# We want to _inherits from the parent model and we add some fields
|
||||
# in the child object
|
||||
class Box(models.Model):
|
||||
_name = 'test.box'
|
||||
_inherits = {'test.unit': 'unit_id'}
|
||||
|
||||
unit_id = fields.Many2one('test.unit', 'Unit', required=True,
|
||||
ondelete='cascade')
|
||||
field_in_box = fields.Char('Field1')
|
||||
|
||||
|
||||
# We add a third level of _inherits
|
||||
class Pallet(models.Model):
|
||||
_name = 'test.pallet'
|
||||
_inherits = {'test.box': 'box_id'}
|
||||
|
||||
box_id = fields.Many2one('test.box', 'Box', required=True,
|
||||
ondelete='cascade')
|
||||
field_in_pallet = fields.Char('Field2')
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_inherits
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class test_inherits(common.TransactionCase):
|
||||
|
||||
def test_create_3_levels_inherits(self):
|
||||
""" Check that we can create an inherits on 3 levels """
|
||||
pallet = self.env['test.pallet'].create({
|
||||
'name': 'B',
|
||||
'field_in_box': 'box',
|
||||
'field_in_pallet': 'pallet',
|
||||
})
|
||||
self.assertTrue(pallet)
|
||||
self.assertEqual(pallet.name, 'B')
|
||||
self.assertEqual(pallet.field_in_box, 'box')
|
||||
self.assertEqual(pallet.field_in_pallet, 'pallet')
|
||||
|
||||
def test_write_3_levels_inherits(self):
|
||||
""" Check that we can create an inherits on 3 levels """
|
||||
pallet = self.env.ref('test_inherits.pallet_a')
|
||||
pallet.write({'name': 'C'})
|
||||
self.assertEqual(pallet.name, 'C')
|
||||
@@ -2907,6 +2907,7 @@ class BaseModel(object):
|
||||
cls._inherit_fields = struct = {}
|
||||
for parent_model, parent_field in cls._inherits.iteritems():
|
||||
parent = cls.pool[parent_model]
|
||||
parent._inherits_reload()
|
||||
for name, column in parent._columns.iteritems():
|
||||
struct[name] = (parent_model, parent_field, column, parent_model)
|
||||
for name, source in parent._inherit_fields.iteritems():
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Phantomjs odoo helper
|
||||
// jshint evil: true, loopfunc: true
|
||||
|
||||
var system = require('system');
|
||||
|
||||
function waitFor (condition, callback, timeout, timeoutMessageCallback) {
|
||||
timeout = timeout || 10000;
|
||||
var start = new Date();
|
||||
@@ -19,7 +21,7 @@ function waitFor (condition, callback, timeout, timeoutMessageCallback) {
|
||||
|
||||
function PhantomTest() {
|
||||
var self = this;
|
||||
this.options = JSON.parse(phantom.args[phantom.args.length-1]);
|
||||
this.options = JSON.parse(system.args[system.args.length-1]);
|
||||
this.inject = this.options.inject || [];
|
||||
this.timeout = this.options.timeout ? Math.round(parseFloat(this.options.timeout)*1000 - 5000) : 10000;
|
||||
this.origin = 'http://localhost';
|
||||
@@ -143,7 +145,7 @@ function PhantomTest() {
|
||||
}
|
||||
|
||||
// js mode or jsfile mode
|
||||
if(phantom.args.length === 1) {
|
||||
if(system.args.length === 2) {
|
||||
pt = new PhantomTest();
|
||||
pt.run(pt.options.url_path, pt.options.code, pt.options.ready);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user