[MERGE] forward port of branch saas-6 up to 19fe77b
This commit is contained in:
@@ -131,3 +131,17 @@ class product_template(osv.Model):
|
||||
# Remove context so it is not going to filter on product_id with active_id of template
|
||||
result['context'] = "{}"
|
||||
return result
|
||||
|
||||
|
||||
class stock_move(osv.Model):
|
||||
_inherit = 'stock.move'
|
||||
|
||||
def _create_invoice_line_from_vals(self, cr, uid, move, invoice_line_vals, context=None):
|
||||
# It will set the default analtyic account on the invoice line
|
||||
partner_id = self.pool['account.invoice'].browse(cr, uid, invoice_line_vals.get('invoice_id'), context=context).partner_id.id
|
||||
if 'account_analytic_id' not in invoice_line_vals or not invoice_line_vals.get('account_analytic_id'):
|
||||
rec = self.pool['account.analytic.default'].account_get(cr, uid, move.product_id.id, partner_id, uid, time.strftime('%Y-%m-%d'), company_id=move.company_id.id, context=context)
|
||||
if rec:
|
||||
invoice_line_vals.update({'account_analytic_id': rec.analytic_id.id})
|
||||
res = super(stock_move, self)._create_invoice_line_from_vals(cr, uid, move, invoice_line_vals, context=context)
|
||||
return res
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'version': '1.1',
|
||||
'website' : 'https://www.odoo.com/page/accounting',
|
||||
'category': 'Hidden/Dependency',
|
||||
'depends' : ['base', 'decimal_precision', 'mail'],
|
||||
'depends' : ['base', 'decimal_precision', 'mail', 'report'],
|
||||
'description': """
|
||||
Module for defining analytic accounting object.
|
||||
===============================================
|
||||
|
||||
@@ -265,8 +265,7 @@ class res_users(osv.Model):
|
||||
|
||||
res_partner.signup_prepare(cr, uid, partner_ids, signup_type="reset", expiration=expiration, context=context)
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
context = dict(context or {})
|
||||
|
||||
# send email to users with their signup url
|
||||
template = False
|
||||
@@ -283,6 +282,7 @@ class res_users(osv.Model):
|
||||
for user in self.browse(cr, uid, ids, context):
|
||||
if not user.email:
|
||||
raise UserError(_("Cannot send email: user %s has no email address.") % user.name)
|
||||
context['lang'] = user.lang
|
||||
self.pool.get('mail.template').send_mail(cr, uid, template.id, user.id, force_send=True, raise_exception=True, context=context)
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
|
||||
@@ -290,7 +290,15 @@ class crm_lead(format_address, osv.osv):
|
||||
def on_change_user(self, cr, uid, ids, user_id, context=None):
|
||||
""" When changing the user, also set a team_id or restrict team id
|
||||
to the ones user_id is member of. """
|
||||
if user_id and context.get('team_id'):
|
||||
team = self.pool['crm.team'].browse(cr, uid, context['team_id'], context=context)
|
||||
if user_id in team.member_ids.ids:
|
||||
return {}
|
||||
team_id = self.pool['crm.team']._get_default_team_id(cr, uid, context=context, user_id=user_id)
|
||||
if user_id and not team_id and self.pool['res.users'].has_group(cr, uid, 'base.group_multi_salesteams'):
|
||||
team_ids = self.pool.get('crm.team').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
|
||||
if team_ids:
|
||||
team_id = team_ids[0]
|
||||
return {'value': {'team_id': team_id}}
|
||||
|
||||
def stage_find(self, cr, uid, cases, team_id, domain=None, order='sequence', context=None):
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id" on_change="on_change_user(user_id, context)"
|
||||
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads'] }" widget="selection"/>
|
||||
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads'], 'team_id': team_id}"/>
|
||||
<field name="team_id" widget="selection" domain="[('use_leads','=',True)]"/>
|
||||
<field name="type" invisible="1"/>
|
||||
</group>
|
||||
@@ -496,7 +496,7 @@
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<field name="user_id" on_change="on_change_user(user_id, context)" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}" widget="selection"/>
|
||||
<field name="user_id" on_change="on_change_user(user_id, context)" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads'], 'team_id': team_id}"/>
|
||||
<field name="team_id" widget="selection"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
<record id="open_l10n_eu_service" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_eu_service"/>
|
||||
<field name="type">automatic</field>
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_config_settings_inherit" model="ir.ui.view">
|
||||
|
||||
@@ -6,6 +6,7 @@ var PosDB = require('point_of_sale.DB');
|
||||
var devices = require('point_of_sale.devices');
|
||||
var core = require('web.core');
|
||||
var Model = require('web.DataModel');
|
||||
var formats = require('web.formats');
|
||||
var session = require('web.session');
|
||||
var time = require('web.time');
|
||||
var utils = require('web.utils');
|
||||
@@ -1070,8 +1071,7 @@ exports.Orderline = Backbone.Model.extend({
|
||||
}
|
||||
this.product = options.product;
|
||||
this.price = options.product.price;
|
||||
this.quantity = 1;
|
||||
this.quantityStr = '1';
|
||||
this.set_quantity(1);
|
||||
this.discount = 0;
|
||||
this.discountStr = '0';
|
||||
this.type = 'unit';
|
||||
@@ -1134,7 +1134,8 @@ exports.Orderline = Backbone.Model.extend({
|
||||
if(unit){
|
||||
if (unit.rounding) {
|
||||
this.quantity = round_pr(quant, unit.rounding);
|
||||
this.quantityStr = this.quantity.toFixed(Math.ceil(Math.log(1.0 / unit.rounding) / Math.log(10)));
|
||||
var decimals = Math.ceil(Math.log(1.0 / unit.rounding) / Math.log(10));
|
||||
this.quantityStr = formats.format_value(round_di(this.quantity, decimals), { type: 'float', digits: [69, decimals]});
|
||||
} else {
|
||||
this.quantity = round_pr(quant, 1);
|
||||
this.quantityStr = this.quantity.toFixed(0);
|
||||
|
||||
@@ -894,7 +894,12 @@ class product_product(osv.osv):
|
||||
def _get_image_variant(self, cr, uid, ids, name, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
result[obj.id] = obj.image_variant or getattr(obj.product_tmpl_id, name)
|
||||
if context.get('bin_size'):
|
||||
result[obj.id] = obj.image_variant
|
||||
else:
|
||||
result[obj.id] = tools.image_get_resized_images(obj.image_variant, return_big=True, avoid_resize_medium=True)[name]
|
||||
if not result[obj.id]:
|
||||
result[obj.id] = getattr(obj.product_tmpl_id, name)
|
||||
return result
|
||||
|
||||
def _set_image_variant(self, cr, uid, id, name, value, args, context=None):
|
||||
|
||||
@@ -67,10 +67,6 @@ class AccountInvoiceLine(osv.Model):
|
||||
sale_layout_cat_id = openerp.fields.Many2one('sale_layout.category', string='Section')
|
||||
categ_sequence = openerp.fields.Integer(related='sale_layout_cat_id.sequence',
|
||||
string='Layout Sequence', store=True)
|
||||
_defaults = {
|
||||
'categ_sequence': 0
|
||||
}
|
||||
|
||||
|
||||
class SaleOrder(osv.Model):
|
||||
_inherit = 'sale.order'
|
||||
@@ -100,10 +96,6 @@ class SaleOrderLine(osv.Model):
|
||||
# Store is intentionally set in order to keep the "historic" order.
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'categ_sequence': 0
|
||||
}
|
||||
|
||||
_order = 'order_id, categ_sequence, sale_layout_cat_id, sequence, id'
|
||||
|
||||
def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None):
|
||||
|
||||
@@ -1032,7 +1032,7 @@ var ViewEditor = Widget.extend({
|
||||
render_new_field :function( result ) {
|
||||
var self = this;
|
||||
var action = {
|
||||
context: {'default_model_id': result.id, 'manual': true, 'module' : result.model},
|
||||
context: {'default_model_id': result.id, 'module' : result.model},
|
||||
res_model: "ir.model.fields",
|
||||
views: [[false, 'form']],
|
||||
type: 'ir.actions.act_window',
|
||||
|
||||
@@ -38,9 +38,9 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||
else:
|
||||
first_menu = main_menu.child_id and main_menu.child_id[0]
|
||||
if first_menu:
|
||||
if not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url=='/')):
|
||||
if first_menu.url and (not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url == '/'))):
|
||||
return request.redirect(first_menu.url)
|
||||
if first_menu.url.startswith('/page/'):
|
||||
if first_menu.url and first_menu.url.startswith('/page/'):
|
||||
return request.registry['ir.http'].reroute(first_menu.url)
|
||||
return self.page(page)
|
||||
|
||||
|
||||
@@ -384,7 +384,7 @@ class WebsiteForum(http.Controller):
|
||||
def post_save(self, forum, post, **kwargs):
|
||||
if 'post_name' in kwargs and not kwargs.get('post_name').strip():
|
||||
return request.website.render('website.http_error', {'status_code': _('Bad Request'), 'status_message': _('Title should not be empty.')})
|
||||
post_tags = forum._tag_to_write_vals(kwargs.get('post_tag', ''))
|
||||
post_tags = forum._tag_to_write_vals(kwargs.get('post_tags', ''))
|
||||
vals = {
|
||||
'tag_ids': post_tags,
|
||||
'name': kwargs.get('post_name'),
|
||||
|
||||
@@ -53,7 +53,7 @@ if(!$('.o_website_quote').length) {
|
||||
'submit #accept': 'submitForm',
|
||||
},
|
||||
initSignature: function(ev){
|
||||
this.$("#signature").empty().jSignature({'decor-color' : '#D1D0CE'});
|
||||
this.$("#signature").empty().jSignature({'decor-color' : '#D1D0CE', 'color': '#000', 'background-color': '#fff'});
|
||||
this.empty_sign = this.$("#signature").jSignature("getData",'image');
|
||||
},
|
||||
clearSignature: function(ev){
|
||||
|
||||
@@ -146,9 +146,9 @@ $('.oe_website_sale').each(function () {
|
||||
clickwatch(function(){
|
||||
|
||||
$dom_optional.each(function(){
|
||||
$(this).find('.js_quantity').text(value);
|
||||
product_ids.push($(this).find('span[data-product-id]').data('product-id'));
|
||||
});
|
||||
if (isNaN(value)) value = 0;
|
||||
$input.data('update_change', true);
|
||||
|
||||
ajax.jsonRpc("/shop/cart/update_json", 'call', {
|
||||
|
||||
@@ -31,4 +31,9 @@
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="report_picking_portal" inherit_id="stock.report_picking" groups="base.group_portal">
|
||||
<xpath expr="//tr[@t-foreach='o.move_lines']" position="attributes">
|
||||
<attribute name="t-foreach">o.move_lines.sudo()</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,15 @@
|
||||
French Polynesia (Tahiti), 2015-10-22
|
||||
|
||||
Invitu 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,
|
||||
|
||||
Cyril Vinh-Tung contact@invitu.com https://github.com/invitu
|
||||
|
||||
List of contributors:
|
||||
Cyril Vinh-Tung contact@invitu.com https://github.com/invitu
|
||||
|
||||
@@ -89,7 +89,7 @@ class ir_model(osv.osv):
|
||||
|
||||
_defaults = {
|
||||
'model': 'x_',
|
||||
'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
|
||||
'state': 'manual',
|
||||
}
|
||||
|
||||
def _check_model_name(self, cr, uid, ids, context=None):
|
||||
@@ -173,10 +173,8 @@ class ir_model(osv.osv):
|
||||
def create(self, cr, user, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if context and context.get('manual'):
|
||||
vals['state']='manual'
|
||||
res = super(ir_model,self).create(cr, user, vals, context)
|
||||
if vals.get('state','base')=='manual':
|
||||
if vals.get('state','manual')=='manual':
|
||||
# setup models; this automatically adds model in registry
|
||||
self.pool.setup_models(cr, partial=(not self.pool.ready))
|
||||
# update database schema
|
||||
@@ -259,7 +257,7 @@ class ir_model_fields(osv.osv):
|
||||
'selection': "",
|
||||
'domain': "[]",
|
||||
'name': 'x_',
|
||||
'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
|
||||
'state': 'manual',
|
||||
'on_delete': 'set null',
|
||||
'field_description': '',
|
||||
'selectable': 1,
|
||||
@@ -439,14 +437,12 @@ class ir_model_fields(osv.osv):
|
||||
vals['model'] = model_data.model
|
||||
if context is None:
|
||||
context = {}
|
||||
if context and context.get('manual',False):
|
||||
vals['state'] = 'manual'
|
||||
if vals.get('ttype', False) == 'selection':
|
||||
if not vals.get('selection',False):
|
||||
raise UserError(_('For selection fields, the Selection Options must be given!'))
|
||||
self._check_selection(cr, user, vals['selection'], context=context)
|
||||
res = super(ir_model_fields,self).create(cr, user, vals, context)
|
||||
if vals.get('state','base') == 'manual':
|
||||
if vals.get('state','manual') == 'manual':
|
||||
if not vals['name'].startswith('x_'):
|
||||
raise UserError(_("Custom fields must have a name that starts with 'x_' !"))
|
||||
|
||||
@@ -474,8 +470,6 @@ class ir_model_fields(osv.osv):
|
||||
def write(self, cr, user, ids, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if context and context.get('manual',False):
|
||||
vals['state'] = 'manual'
|
||||
|
||||
#For the moment renaming a sparse field or changing the storing system is not allowed. This may be done later
|
||||
if 'serialization_field_id' in vals or 'name' in vals:
|
||||
@@ -518,7 +512,7 @@ class ir_model_fields(osv.osv):
|
||||
raise UserError(_('Can only rename one field at a time!'))
|
||||
if vals['name'] in obj._fields:
|
||||
raise UserError(_('Cannot rename field to %s, because that field already exists!') % vals['name'])
|
||||
if vals.get('state', 'base') == 'manual' and not vals['name'].startswith('x_'):
|
||||
if vals.get('state', 'manual') == 'manual' and not vals['name'].startswith('x_'):
|
||||
raise UserError(_('New field name must still start with x_ , because it is a custom field!'))
|
||||
if '\'' in vals['name'] or '"' in vals['name'] or ';' in vals['name']:
|
||||
raise ValueError('Invalid character in column name')
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Fields">
|
||||
<field context="{'manual':True}" name="field_id">
|
||||
<field name="field_id">
|
||||
<tree string="Fields Description">
|
||||
<field name="name"/>
|
||||
<field name="field_description"/>
|
||||
@@ -203,7 +203,7 @@
|
||||
<field name="name">Models</field>
|
||||
<field name="res_model">ir.model</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{'manual':True}</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="view_id" ref="view_model_tree"/>
|
||||
</record>
|
||||
<menuitem action="action_model_model" id="ir_model_model_menu" parent="next_id_9"/>
|
||||
@@ -351,7 +351,7 @@
|
||||
<field name="name">Fields</field>
|
||||
<field name="res_model">ir.model.fields</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{'manual':True}</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="view_id" ref="view_model_fields_tree"/>
|
||||
</record>
|
||||
<menuitem action="action_model_fields" id="ir_model_model_fields" parent="base.next_id_9"/>
|
||||
|
||||
@@ -130,11 +130,13 @@ class ir_translation_import_cursor(object):
|
||||
AND irt.type = ti.type
|
||||
AND irt.module = ti.module
|
||||
AND irt.name = ti.name
|
||||
AND (ti.type IN ('field', 'help') OR irt.src = ti.src)
|
||||
AND ( ti.type NOT IN ('model', 'view')
|
||||
OR (ti.type = 'model' AND ti.res_id = irt.res_id)
|
||||
OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id))
|
||||
)
|
||||
AND (
|
||||
(ti.type = 'model' AND ti.res_id = irt.res_id AND irt.src = ti.src)
|
||||
OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id) AND irt.src = ti.src)
|
||||
OR (ti.type = 'field')
|
||||
OR (ti.type = 'help')
|
||||
OR (ti.type NOT IN ('model', 'view', 'field', 'help') AND irt.src = ti.src)
|
||||
)
|
||||
"""
|
||||
|
||||
# Step 2: update existing (matching) translations
|
||||
|
||||
@@ -61,9 +61,9 @@ def report_configuration():
|
||||
user = config['db_user'] or os.environ.get('PGUSER', 'default')
|
||||
_logger.info('database: %s@%s:%s', user, host, port)
|
||||
|
||||
def rm_pid_file():
|
||||
def rm_pid_file(main_pid):
|
||||
config = openerp.tools.config
|
||||
if not openerp.evented and config['pidfile']:
|
||||
if config['pidfile'] and main_pid == os.getpid():
|
||||
try:
|
||||
os.unlink(config['pidfile'])
|
||||
except OSError:
|
||||
@@ -76,10 +76,10 @@ def setup_pid_file():
|
||||
"""
|
||||
config = openerp.tools.config
|
||||
if not openerp.evented and config['pidfile']:
|
||||
pid = os.getpid()
|
||||
with open(config['pidfile'], 'w') as fd:
|
||||
pidtext = "%d" % (os.getpid())
|
||||
fd.write(pidtext)
|
||||
atexit.register(rm_pid_file)
|
||||
fd.write(str(pid))
|
||||
atexit.register(rm_pid_file, pid)
|
||||
|
||||
def export_translation():
|
||||
config = openerp.tools.config
|
||||
|
||||
Reference in New Issue
Block a user