[MERGE] trunk
bzr revid: fp@openerp.com-20120815185713-82zylb0yqqgs008y
This commit is contained in:
commit
d820e866ee
|
@ -19,10 +19,10 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import partner
|
||||
import account
|
||||
import installer
|
||||
import project
|
||||
import partner
|
||||
import account_invoice
|
||||
import account_bank_statement
|
||||
import account_bank
|
||||
|
|
|
@ -1351,11 +1351,11 @@ class account_invoice_line(osv.osv):
|
|||
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'),
|
||||
'product_id': fields.many2one('product.product', 'Product', ondelete='set null'),
|
||||
'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Account')),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', type="float",
|
||||
digits_compute= dp.get_precision('Account'), store=True),
|
||||
'quantity': fields.float('Quantity', required=True),
|
||||
'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Account')),
|
||||
'quantity': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True),
|
||||
'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')),
|
||||
'invoice_line_tax_id': fields.many2many('account.tax', 'account_invoice_line_tax', 'invoice_line_id', 'tax_id', 'Taxes', domain=[('parent_id','=',False)]),
|
||||
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||
'company_id': fields.related('invoice_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<!--Email template -->
|
||||
<record id="email_template_edi_invoice" model="email.template">
|
||||
<field name="name">Automated Invoice Notification Mail</field>
|
||||
<field name="email_from">${object.user_id.user_email or object.company_id.email or 'noreply@localhost'}</field>
|
||||
<field name="email_from">${object.user_id.email or object.company_id.email or 'noreply@localhost'}</field>
|
||||
<field name="subject">${object.company_id.name} Invoice (Ref ${object.number or 'n/a' })</field>
|
||||
<field name="email_to">${object.partner_id.email or ''}</field>
|
||||
<field name="model_id" ref="account.model_account_invoice"/>
|
||||
|
@ -58,7 +58,7 @@
|
|||
% if object.origin:
|
||||
Order reference: ${object.origin}<br />
|
||||
% endif
|
||||
Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a>
|
||||
Your contact: <a href="mailto:${object.user_id.email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -133,7 +133,7 @@ A new invoice is available for ${object.partner_id.name}:
|
|||
% if object.origin:
|
||||
| Order reference: ${object.origin}
|
||||
% endif
|
||||
| Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
|
||||
| Your contact: ${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''}
|
||||
|
||||
You can view the invoice document, download it and pay online using the following link:
|
||||
${ctx.get('edi_web_url_view') or 'n/a'}
|
||||
|
@ -160,7 +160,7 @@ Thank you for choosing ${object.company_id.name}!
|
|||
|
||||
|
||||
--
|
||||
${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
|
||||
${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''}
|
||||
${object.company_id.name}
|
||||
% if object.company_id.street:
|
||||
${object.company_id.street or ''}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -53,7 +53,7 @@ class analytic_account(osv.osv):
|
|||
('name', 'not ilike', 'maintenance'),
|
||||
('partner_id', '!=', False),
|
||||
('user_id', '!=', False),
|
||||
('user_id.user_email', '!=', False),
|
||||
('user_id.email', '!=', False),
|
||||
('state', 'in', ('draft', 'open')),
|
||||
'|', ('date', '<', time.strftime('%Y-%m-%d')), ('date', '=', False),
|
||||
]
|
||||
|
@ -70,7 +70,7 @@ class analytic_account(osv.osv):
|
|||
for user, data in users.iteritems():
|
||||
subject = '[OPENERP] Reporting: Analytic Accounts'
|
||||
body = Template(MAKO_TEMPLATE).render_unicode(user=user, partners=data)
|
||||
tools.email_send('noreply@openerp.com', [user.user_email, ], subject, body)
|
||||
tools.email_send('noreply@openerp.com', [user.email, ], subject, body)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ class users(osv.osv):
|
|||
cr, SUPERUSER_ID, conf, login, entry)
|
||||
if user_id:
|
||||
cr.execute("""UPDATE res_users
|
||||
SET date=now() AT TIME ZONE 'UTC'
|
||||
SET login_date=now() AT TIME ZONE 'UTC'
|
||||
WHERE login=%s""",
|
||||
(tools.ustr(login),))
|
||||
cr.commit()
|
||||
|
|
|
@ -66,7 +66,7 @@ class res_users(osv.osv):
|
|||
else:
|
||||
with utils.cursor(db) as cr:
|
||||
cr.execute("""UPDATE res_users
|
||||
SET date=now() AT TIME ZONE 'UTC'
|
||||
SET login_date=now() AT TIME ZONE 'UTC'
|
||||
WHERE login=%s AND openid_key=%s AND active=%s RETURNING id""",
|
||||
(tools.ustr(login), tools.ustr(password), True))
|
||||
res = cr.fetchone()
|
||||
|
|
|
@ -1,2 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version
|
||||
#
|
||||
# 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 Affero General Public License for more details
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import res_config
|
||||
import auth_signup
|
||||
|
|
|
@ -1,22 +1,43 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009-today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version
|
||||
#
|
||||
# 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 Affero General Public License for more details
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Signup',
|
||||
'description': 'Allow users to sign up',
|
||||
'author': 'OpenERP SA',
|
||||
'version': '1.0',
|
||||
'category': 'Authentication',
|
||||
'website': 'http://www.openerp.com',
|
||||
'installable': True,
|
||||
'depends': ['auth_anonymous', 'base_setup'],
|
||||
'data': [
|
||||
'res_config.xml',
|
||||
],
|
||||
'js': [
|
||||
'static/src/js/auth_signup.js',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/auth_signup.css',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/auth_signup.xml',
|
||||
],
|
||||
'name': 'Signup',
|
||||
'description': 'Allow users to sign up',
|
||||
'author': 'OpenERP SA',
|
||||
'version': '1.0',
|
||||
'category': 'Authentication',
|
||||
'website': 'http://www.openerp.com',
|
||||
'installable': True,
|
||||
'depends': ['auth_anonymous', 'base_setup'],
|
||||
'data': [
|
||||
'res_config.xml',
|
||||
],
|
||||
'js': [
|
||||
'static/src/js/auth_signup.js',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/auth_signup.css',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/auth_signup.xml',
|
||||
],
|
||||
}
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version
|
||||
#
|
||||
# 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 Affero General Public License for more details
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
class res_users(osv.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
_sql_constraints = [
|
||||
('email_uniq', 'UNIQUE (user_email)', 'You can not have two users with the same email!')
|
||||
]
|
||||
|
||||
class signup_signup(osv.TransientModel):
|
||||
_name = 'auth.signup'
|
||||
|
||||
|
@ -24,7 +38,7 @@ class signup_signup(osv.TransientModel):
|
|||
new_user = {
|
||||
'name': values['name'],
|
||||
'login': values['email'],
|
||||
'user_email': values['email'],
|
||||
'email': values['email'],
|
||||
'password': values['password'],
|
||||
'active': True,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version
|
||||
#
|
||||
# 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 Affero General Public License for more details
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
class base_config_settings(osv.TransientModel):
|
||||
|
|
|
@ -292,7 +292,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
'object_description': hasattr(obj, 'description') and obj.description or False,
|
||||
'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/',
|
||||
'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \
|
||||
obj.user_id.user_email) or '/',
|
||||
obj.user_id.email) or '/',
|
||||
'object_user_phone': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and \
|
||||
obj.partner_address_id.phone) or '/',
|
||||
'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/',
|
||||
|
@ -319,8 +319,8 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
mail_message = self.pool.get('mail.message')
|
||||
body = self.format_mail(obj, body)
|
||||
if not emailfrom:
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.user_email:
|
||||
emailfrom = obj.user_id.user_email
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email:
|
||||
emailfrom = obj.user_id.email
|
||||
|
||||
name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
|
||||
emailfrom = tools.ustr(emailfrom)
|
||||
|
@ -419,7 +419,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
emails = []
|
||||
if hasattr(obj, 'user_id') and action.act_mail_to_user:
|
||||
if obj.user_id:
|
||||
emails.append(obj.user_id.user_email)
|
||||
emails.append(obj.user_id.email)
|
||||
|
||||
if action.act_mail_to_watchers:
|
||||
emails += (action.act_email_cc or '').split(',')
|
||||
|
|
|
@ -245,7 +245,7 @@ class calendar_attendee(osv.osv):
|
|||
continue
|
||||
else:
|
||||
result[id][name] = self._get_address(attdata.sent_by_uid.name, \
|
||||
attdata.sent_by_uid.user_email)
|
||||
attdata.sent_by_uid.email)
|
||||
|
||||
if name == 'cn':
|
||||
if attdata.user_id:
|
||||
|
@ -289,7 +289,7 @@ class calendar_attendee(osv.osv):
|
|||
|
||||
if name == 'language':
|
||||
user_obj = self.pool.get('res.users')
|
||||
lang = user_obj.read(cr, uid, uid, ['context_lang'], context=context)['context_lang']
|
||||
lang = user_obj.read(cr, uid, uid, ['lang'], context=context)['lang']
|
||||
result[id][name] = lang.replace('_', '-')
|
||||
|
||||
return result
|
||||
|
@ -434,7 +434,7 @@ property or property parameter."),
|
|||
if not organizer:
|
||||
organizer = event_obj.user_id
|
||||
event_org.params['CN'] = [organizer.name]
|
||||
event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name)
|
||||
event_org.value = 'MAILTO:' + (organizer.email or organizer.name)
|
||||
|
||||
if event_obj.alarm_id:
|
||||
# computes alarm data
|
||||
|
@ -535,7 +535,7 @@ property or property parameter."),
|
|||
return {'value': {'email': ''}}
|
||||
usr_obj = self.pool.get('res.users')
|
||||
user = usr_obj.browse(cr, uid, user_id, *args)
|
||||
return {'value': {'email': user.user_email, 'availability':user.availability}}
|
||||
return {'value': {'email': user.email, 'availability':user.availability}}
|
||||
|
||||
def do_tentative(self, cr, uid, ids, context=None, *args):
|
||||
""" Makes event invitation as Tentative
|
||||
|
@ -891,9 +891,9 @@ From:
|
|||
|
||||
""" % (alarm.name, alarm.trigger_date, alarm.description, \
|
||||
alarm.user_id.name, alarm.user_id.signature)
|
||||
mail_to = [alarm.user_id.user_email]
|
||||
mail_to = [alarm.user_id.email]
|
||||
for att in alarm.attendee_ids:
|
||||
mail_to.append(att.user_id.user_email)
|
||||
mail_to.append(att.user_id.email)
|
||||
if mail_to:
|
||||
mail_message.schedule_with_attach(cr, uid,
|
||||
tools.config.get('email_from', False),
|
||||
|
@ -947,7 +947,7 @@ class calendar_event(osv.osv):
|
|||
value['duration'] = duration
|
||||
# change start_date's time to 00:00:00 in the user's timezone
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid)
|
||||
tz = pytz.timezone(user.context_tz) if user.context_tz else pytz.utc
|
||||
tz = pytz.timezone(user.tz) if user.tz else pytz.utc
|
||||
start = pytz.utc.localize(start).astimezone(tz) # convert start in user's timezone
|
||||
start = start.replace(hour=0, minute=0, second=0) # change start's time to 00:00:00
|
||||
start = start.astimezone(pytz.utc) # convert start back to utc
|
||||
|
@ -1097,8 +1097,8 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
user_pool = self.pool.get('res.users')
|
||||
user = user_pool.browse(cr, uid, uid, context=context)
|
||||
res = user.name
|
||||
if user.user_email:
|
||||
res += " <%s>" %(user.user_email)
|
||||
if user.email:
|
||||
res += " <%s>" %(user.email)
|
||||
return res
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -99,12 +99,12 @@ send an Email to Invited Person')
|
|||
user = user_obj.browse(cr, uid, user_id)
|
||||
res = {
|
||||
'user_id': user_id,
|
||||
'email': user.user_email
|
||||
'email': user.email
|
||||
}
|
||||
res.update(ref)
|
||||
vals.append(res)
|
||||
if user.user_email:
|
||||
mail_to.append(user.user_email)
|
||||
if user.email:
|
||||
mail_to.append(user.email)
|
||||
|
||||
elif type == 'external' and datas.get('email'):
|
||||
res = {'email': datas['email']}
|
||||
|
@ -143,7 +143,7 @@ send an Email to Invited Person')
|
|||
self._columns['type'].selection))
|
||||
raise osv.except_osv(_('Error!'), _("%s must have an email address to send mail.") %(name[0]))
|
||||
att_obj._send_mail(cr, uid, attendees, mail_to, \
|
||||
email_from = current_user.user_email or tools.config.get('email_from', False))
|
||||
email_from = current_user.email or tools.config.get('email_from', False))
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ class users(osv.osv):
|
|||
|
||||
# Check if the encrypted password matches against the one in the db.
|
||||
cr.execute("""UPDATE res_users
|
||||
SET date=now() AT TIME ZONE 'UTC'
|
||||
SET login_date=now() AT TIME ZONE 'UTC'
|
||||
WHERE id=%s AND password=%s AND active
|
||||
RETURNING id""",
|
||||
(int(id), encrypted_pw.encode('utf-8')))
|
||||
|
|
|
@ -50,7 +50,7 @@ class specify_partner_terminology(osv.osv_memory):
|
|||
def make_translations(self, cr, uid, ids, name, type, src, value, res_id=0, context=None):
|
||||
trans_obj = self.pool.get('ir.translation')
|
||||
user_obj = self.pool.get('res.users')
|
||||
context_lang = user_obj.browse(cr, uid, uid, context=context).context_lang
|
||||
context_lang = user_obj.browse(cr, uid, uid, context=context).lang
|
||||
existing_trans_ids = trans_obj.search(cr, uid, [('name','=',name), ('lang','=',context_lang), ('type','=',type), ('src','=',src), ('res_id','=',res_id)])
|
||||
if existing_trans_ids:
|
||||
trans_obj.write(cr, uid, existing_trans_ids, {'value': value}, context=context)
|
||||
|
|
|
@ -57,7 +57,7 @@ class base_stage(object):
|
|||
if not context or not context.get('portal'):
|
||||
return False
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
return user.user_email
|
||||
return user.email
|
||||
|
||||
def _get_default_user(self, cr, uid, context=None):
|
||||
""" Gives current user id
|
||||
|
@ -301,15 +301,15 @@ class base_stage(object):
|
|||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if not destination and not case.email_from:
|
||||
return False
|
||||
if not case.user_id.user_email:
|
||||
if not case.user_id.email:
|
||||
return False
|
||||
if destination and case.section_id.user_id:
|
||||
case_email = case.section_id.user_id.user_email
|
||||
case_email = case.section_id.user_id.email
|
||||
else:
|
||||
case_email = case.user_id.user_email
|
||||
case_email = case.user_id.email
|
||||
|
||||
src = case_email
|
||||
dest = case.user_id.user_email or ""
|
||||
dest = case.user_id.email or ""
|
||||
body = case.description or ""
|
||||
for message in case.message_ids:
|
||||
if message.email_from and message.body_text:
|
||||
|
@ -366,8 +366,8 @@ class base_stage(object):
|
|||
l=[]
|
||||
if case.email_cc:
|
||||
l.append(case.email_cc)
|
||||
if case.user_id and case.user_id.user_email:
|
||||
l.append(case.user_id.user_email)
|
||||
if case.user_id and case.user_id.email:
|
||||
l.append(case.user_id.email)
|
||||
res[case.id] = l
|
||||
return res
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class base_state(object):
|
|||
if not context or not context.get('portal'):
|
||||
return False
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
return user.user_email
|
||||
return user.email
|
||||
|
||||
def _get_default_user(self, cr, uid, context=None):
|
||||
""" Gives current user id
|
||||
|
|
|
@ -49,8 +49,8 @@ class base_action_rule(osv.osv):
|
|||
mail_message = self.pool.get('mail.message')
|
||||
body = self.format_mail(obj, body)
|
||||
if not emailfrom:
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.user_email:
|
||||
emailfrom = obj.user_id.user_email
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email:
|
||||
emailfrom = obj.user_id.email
|
||||
|
||||
name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
|
||||
emailfrom = tools.ustr(emailfrom)
|
||||
|
|
|
@ -243,7 +243,7 @@ class crm_lead(base_stage, osv.osv):
|
|||
'partner_address_name': fields.related('partner_id', 'name', type='char', string='Partner Contact Name', readonly=True),
|
||||
'partner_address_email': fields.related('partner_id', 'email', type='char', string='Partner Contact Email', readonly=True),
|
||||
'company_currency': fields.related('company_id', 'currency_id', 'symbol', type='char', string='Company Currency', readonly=True),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
|
||||
'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True),
|
||||
|
||||
# Fields for address, due to separation from crm and res.partner
|
||||
|
@ -692,11 +692,11 @@ class crm_lead(base_stage, osv.osv):
|
|||
"""
|
||||
#TOFIX: mail template should be used here instead of fix subject, body text.
|
||||
message = self.pool.get('mail.message')
|
||||
email_to = lead.user_id and lead.user_id.user_email
|
||||
email_to = lead.user_id and lead.user_id.email
|
||||
if not email_to:
|
||||
return False
|
||||
|
||||
email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
|
||||
email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.email or email_to
|
||||
partner = lead.partner_id and lead.partner_id.name or lead.partner_name
|
||||
subject = "lead %s converted into opportunity" % lead.name
|
||||
body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
|
||||
|
|
|
@ -43,16 +43,13 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
_defaults = {
|
||||
'send_to' : 'email',
|
||||
'history': 'latest',
|
||||
'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid],
|
||||
'email_from': lambda s, cr, uid, c: s.pool.get('res.users').browse(cr, uid, uid, c).email,
|
||||
}
|
||||
|
||||
|
||||
|
||||
def on_change_email(self, cr, uid, ids, user):
|
||||
def on_change_email(self, cr, uid, ids, user, context=None):
|
||||
if not user:
|
||||
return {'value': {'email_to': False}}
|
||||
email = self.pool.get('res.users')._get_email_from(cr, uid, [user])[user]
|
||||
return {'value': {'email_to': email}}
|
||||
return {'value': {'email_to': self.pool.get('res.users').browse(cr, uid, uid, context=context).email}}
|
||||
|
||||
def on_change_history(self, cr, uid, ids, history_type, context=None):
|
||||
"""Gives message body according to type of history selected
|
||||
|
@ -80,7 +77,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
partner = partner_obj.browse(cr, uid, [partner_id])
|
||||
user_id = partner and partner[0].user_id or False
|
||||
data.update({'email_from': partner and partner[0].email or "",
|
||||
'email_cc' : user_id and user_id.user_email or '',
|
||||
'email_cc' : user_id and user_id.user or '',
|
||||
'user_id': user_id and user_id.id or False})
|
||||
return {'value' : data}
|
||||
|
||||
|
@ -185,7 +182,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
if partner_assigned_id:
|
||||
assigned_partner = partner.browse(cr, uid, partner_assigned_id, context=context)
|
||||
user_id = assigned_partner.user_id and assigned_partner.user_id.id or False
|
||||
email_cc = assigned_partner.user_id and assigned_partner.user_id.user_email or ''
|
||||
email_cc = assigned_partner.user_id and assigned_partner.user_id.email or ''
|
||||
email = assigned_partner.email
|
||||
|
||||
res.update({
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
import time
|
||||
from osv import fields,osv
|
||||
from tools.translate import _
|
||||
import decimal_precision as dp
|
||||
|
||||
class delivery_carrier(osv.osv):
|
||||
_name = "delivery.carrier"
|
||||
|
@ -237,8 +238,8 @@ class delivery_grid_line(osv.osv):
|
|||
'max_value': fields.float('Maximum Value', required=True),
|
||||
'price_type': fields.selection([('fixed','Fixed'),('variable','Variable')], 'Price Type', required=True),
|
||||
'variable_factor': fields.selection([('weight','Weight'),('volume','Volume'),('wv','Weight * Volume'), ('price','Price')], 'Variable Factor', required=True),
|
||||
'list_price': fields.float('Sale Price', required=True),
|
||||
'standard_price': fields.float('Cost Price', required=True),
|
||||
'list_price': fields.float('Sale Price', digits_compute= dp.get_precision('Product Price'), required=True),
|
||||
'standard_price': fields.float('Cost Price', digits_compute= dp.get_precision('Product Price'), required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *args: 'weight',
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<record id="confirmation_event" model="email.template">
|
||||
<field name="name">Confirmation of the Event</field>
|
||||
<field name="model_id" ref="event.model_event_registration"/>
|
||||
<field name="email_from" >${object.user_id.user_email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}</field>
|
||||
<field name="email_from" >${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}</field>
|
||||
<field name="email_to" >${object.email}</field>
|
||||
<field name="subject">Your registration at ${object.event_id.name}</field>
|
||||
<field name="body_text">
|
||||
|
@ -24,7 +24,7 @@
|
|||
<record id="confirmation_registration" model="email.template">
|
||||
<field name="name">Confirmation of the Registration</field>
|
||||
<field name="model_id" ref="event.model_event_registration"/>
|
||||
<field name="email_from" >${object.user_id.user_email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}</field>
|
||||
<field name="email_from" >${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'}</field>
|
||||
<field name="email_to" >${object.email}</field>
|
||||
<field name="subject">Your registration at ${object.event_id.name}</field>
|
||||
<field name="body_text">
|
||||
|
|
|
@ -230,7 +230,7 @@ class event_event(osv.osv):
|
|||
curr_reg_ids = register_pool.search(cr, uid, [('user_id', '=', user.id), ('event_id', '=' , ids[0])])
|
||||
#the subscription is done with SUPERUSER_ID because in case we share the kanban view, we want anyone to be able to subscribe
|
||||
if not curr_reg_ids:
|
||||
curr_reg_ids = [register_pool.create(cr, SUPERUSER_ID, {'event_id': ids[0] ,'email': user.user_email, 'name':user.name, 'user_id': user.id, 'nb_register': num_of_seats})]
|
||||
curr_reg_ids = [register_pool.create(cr, SUPERUSER_ID, {'event_id': ids[0] ,'email': user.email, 'name':user.name, 'user_id': user.id, 'nb_register': num_of_seats})]
|
||||
else:
|
||||
register_pool.write(cr, uid, curr_reg_ids, {'nb_register': num_of_seats}, context=context)
|
||||
return register_pool.confirm_registration(cr, SUPERUSER_ID, curr_reg_ids, context=context)
|
||||
|
|
|
@ -252,7 +252,7 @@ class hr_employee(osv.osv):
|
|||
def onchange_user(self, cr, uid, ids, user_id, context=None):
|
||||
work_email = False
|
||||
if user_id:
|
||||
work_email = self.pool.get('res.users').browse(cr, uid, user_id, context=context).user_email
|
||||
work_email = self.pool.get('res.users').browse(cr, uid, user_id, context=context).email
|
||||
return {'value': {'work_email' : work_email}}
|
||||
|
||||
def _get_default_image(self, cr, uid, context=None):
|
||||
|
|
|
@ -72,7 +72,7 @@ class hr_expense_expense(osv.osv):
|
|||
'account_move_id': fields.many2one('account.move', 'Ledger Posting'),
|
||||
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
|
||||
'note': fields.text('Note'),
|
||||
'amount': fields.function(_amount, string='Total Amount'),
|
||||
'amount': fields.function(_amount, string='Total Amount', digits_compute= dp.get_precision('Account')),
|
||||
'invoice_id': fields.many2one('account.invoice', "Employee's Invoice"),
|
||||
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
|
||||
'department_id':fields.many2one('hr.department','Department'),
|
||||
|
@ -258,8 +258,8 @@ class hr_expense_line(osv.osv):
|
|||
'date_value': fields.date('Date', required=True),
|
||||
'expense_id': fields.many2one('hr.expense.expense', 'Expense', ondelete='cascade', select=True),
|
||||
'total_amount': fields.function(_amount, string='Total', digits_compute=dp.get_precision('Account')),
|
||||
'unit_amount': fields.float('Unit Price', digits_compute=dp.get_precision('Account')),
|
||||
'unit_quantity': fields.float('Quantities' ),
|
||||
'unit_amount': fields.float('Unit Price', digits_compute=dp.get_precision('Product Price')),
|
||||
'unit_quantity': fields.float('Quantities', digits_compute= dp.get_precision('Product Unit of Measure')),
|
||||
'product_id': fields.many2one('product.product', 'Product', domain=[('hr_expense_ok','=',True)]),
|
||||
'uom_id': fields.many2one('product.uom', 'Unit of Measure'),
|
||||
'description': fields.text('Description'),
|
||||
|
|
|
@ -228,7 +228,7 @@ class hr_applicant(base_stage, osv.Model):
|
|||
multi='day_close', type="float", store=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
'emp_id': fields.many2one('hr.employee', 'employee'),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -72,7 +72,7 @@ class report_account_analytic_line_to_invoice(osv.osv):
|
|||
'account_id':fields.many2one('account.analytic.account', 'Analytic account', readonly=True),
|
||||
'product_uom_id':fields.many2one('product.uom', 'Unit of Measure', readonly=True),
|
||||
'unit_amount': fields.float('Units', readonly=True),
|
||||
'sale_price': fields.float('Sale price', readonly=True, digits_compute=dp.get_precision('Sale Price')),
|
||||
'sale_price': fields.float('Sale price', readonly=True, digits_compute=dp.get_precision('Product Price')),
|
||||
'amount': fields.float('Amount', readonly=True, digits_compute=dp.get_precision('Account')),
|
||||
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'),
|
||||
('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')],'Month',readonly=True),
|
||||
|
|
|
@ -877,7 +877,7 @@ class sugar_import(import_framework):
|
|||
else:
|
||||
val['password'] = 'sugarcrm' #default password for all user #TODO needed in documentation
|
||||
|
||||
val['context_lang'] = self.context.get('lang','en_US')
|
||||
val['lang'] = self.context.get('lang','en_US')
|
||||
return val
|
||||
|
||||
def get_users_department(self, val):
|
||||
|
@ -895,10 +895,10 @@ class sugar_import(import_framework):
|
|||
'map' : {
|
||||
'name': concat('first_name', 'last_name'),
|
||||
'login': value('user_name', fallback='last_name'),
|
||||
'context_lang' : 'context_lang',
|
||||
'lang' : 'context_lang',
|
||||
'password' : 'password',
|
||||
'.id' : '.id',
|
||||
'user_email' : 'email1',
|
||||
'email' : 'email1',
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -964,7 +964,7 @@ class import_sugarcrm(osv.osv):
|
|||
}
|
||||
|
||||
def _get_email_id(self, cr, uid, context=None):
|
||||
return self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email
|
||||
return self.pool.get('res.users').browse(cr, uid, uid, context=context).email
|
||||
|
||||
def _module_installed(self, cr, uid, model, context=None):
|
||||
module_id = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', model), ('state', "=", "installed")], context=context)
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<td>
|
||||
<para style="terp_default_8">[[ user.name ]] </para>
|
||||
<para style="terp_default_8">[[ user.login ]]</para>
|
||||
<para style="terp_default_8">[[ user.user_email ]]</para>
|
||||
<para style="terp_default_8">[[ user.email ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -25,8 +25,8 @@ import mail_mail
|
|||
import mail_thread
|
||||
import mail_group
|
||||
import mail_subscription
|
||||
import res_users
|
||||
import res_partner
|
||||
import res_users
|
||||
import report
|
||||
import wizard
|
||||
import res_config
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<value>Welcome to OpenERP!</value>
|
||||
<value>Your homepage is a summary of messages you received and key information about documents you follow.
|
||||
|
||||
The top menu bar contains all applications you installed. You can use this <i>Settings</i> menu to intall more applications, activate others features or give access to new users.
|
||||
The top menu bar contains all applications you installed. You can use this <i>Settings</i> menu to install more applications, activate others features or give access to new users.
|
||||
|
||||
To setup your preferences (name, email signature, avatar), click on the top right corner.</value>
|
||||
</function>
|
||||
|
|
|
@ -70,6 +70,9 @@ class mail_message(osv.Model):
|
|||
return result
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
# name_get may receive int id instead of an id list
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
res = []
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
name = ''
|
||||
|
@ -96,11 +99,10 @@ class mail_message(osv.Model):
|
|||
|
||||
# this is redundant with notifications ? Yes
|
||||
'partner_ids': fields.many2many('res.partner',
|
||||
'mail_message_destination_partner_rel',
|
||||
'mail_message_res_partner_rel',
|
||||
'message_id', 'partner_id', 'Destination partners',
|
||||
help="When sending emails through the social network composition wizard"\
|
||||
"you may choose to send a copy of the mail to partners."),
|
||||
|
||||
'attachment_ids': fields.one2many('ir.attachment', 'res_id', 'Attachments'
|
||||
domain=[('res_model','=','mail.message')]),
|
||||
|
||||
|
@ -204,7 +206,6 @@ class mail_message(osv.Model):
|
|||
self.check(cr, uid, ids, 'unlink', context=context)
|
||||
return super(mail_message, self).unlink(cr, uid, ids, context)
|
||||
|
||||
# FP Note: to be simplified, mail.message fields only, not mail.mail
|
||||
def parse_message(self, message, save_original=False, context=None):
|
||||
"""Parses a string or email.message.Message representing an
|
||||
RFC-2822 email, and returns a generic dict holding the
|
||||
|
|
|
@ -741,7 +741,7 @@ class mail_thread(osv.Model):
|
|||
for thread in self.browse(cr, uid, ids, context=context):
|
||||
l = set()
|
||||
for message in thread.message_ids:
|
||||
l.add((message.user_id and message.user_id.user_email) or '')
|
||||
l.add((message.user_id and message.user_id.email) or '')
|
||||
l.add(message.email_from or '')
|
||||
l.add(message.email_cc or '')
|
||||
res[thread.id] = filter(None, l)
|
||||
|
|
|
@ -20,20 +20,28 @@
|
|||
##############################################################################
|
||||
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
|
||||
class res_partner_mail(osv.osv):
|
||||
class res_partner_mail(osv.Model):
|
||||
""" Inherits partner and adds CRM information in the partner form """
|
||||
_name = "res.partner"
|
||||
_inherit = ['res.partner', 'mail.thread']
|
||||
|
||||
def message_search_get_domain(self, cr, uid, ids, context=None):
|
||||
""" Override of message_search_get_domain for partner discussion page.
|
||||
The purpose is to add messages directly sent to the partner.
|
||||
The purpose is to add messages directly sent to the partner. It also
|
||||
adds messages pushed to the related user, if any, using @login.
|
||||
"""
|
||||
initial_domain = super(res_partner_mail, self).message_search_get_domain(cr, uid, ids, context=context)
|
||||
if self._name == 'res.partner': # to avoid models inheriting from res.partner
|
||||
search_domain = ['|'] + initial_domain + ['|', ('partner_id', 'in', ids), ('partner_ids', 'in', ids)]
|
||||
# to avoid models inheriting from res.partner
|
||||
if self._name != 'res.partner':
|
||||
return initial_domain
|
||||
# add message linked to the partner
|
||||
search_domain = ['|'] + initial_domain + ['|', ('partner_id', 'in', ids), ('partner_ids', 'in', ids)]
|
||||
# if partner is linked to a user: find @login
|
||||
res_users_obj = self.pool.get('res.users')
|
||||
user_ids = res_users_obj.search(cr, uid, [('partner_id', 'in', ids)], context=context)
|
||||
for user in res_users_obj.browse(cr, uid, user_ids, context=context):
|
||||
search_domain = ['|'] + search_domain + ['|', ('body_text', 'like', '@%s' % (user.login)), ('body_html', 'like', '@%s' % (user.login))]
|
||||
return search_domain
|
||||
_columns = {
|
||||
'notification_email_pref': fields.selection([
|
||||
|
|
|
@ -28,7 +28,7 @@ from tools.translate import _
|
|||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class res_users(osv.osv):
|
||||
class res_users(osv.Model):
|
||||
""" Update of res.users class
|
||||
- add a preference about sending emails about notifications
|
||||
- make a new user follow itself
|
||||
|
@ -40,8 +40,8 @@ class res_users(osv.osv):
|
|||
|
||||
_columns = {
|
||||
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
|
||||
help="Email address internally associated with this user. Incoming emails will appear "
|
||||
"in the user's notifications."),
|
||||
help="Email address internally associated with this user. Incoming "\
|
||||
"emails will appear in the user's notifications."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -92,25 +92,29 @@ class res_users(osv.osv):
|
|||
|
||||
self._columns['alias_id'].required = True
|
||||
|
||||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
# create default alias same as the login
|
||||
mail_alias = self.pool.get('mail.alias')
|
||||
alias_id = mail_alias.create_unique_alias(cr, uid, {'alias_name': data['login']}, model_name=self._name, context=context)
|
||||
data['alias_id'] = alias_id
|
||||
data.pop('alias_name', None) # prevent errors during copy()
|
||||
# create user that follows its related partner
|
||||
user_id = super(res_users, self).create(cr, uid, data, context=context)
|
||||
mail_alias.write(cr, SUPERUSER_ID, [alias_id], {"alias_force_thread_id": user_id}, context)
|
||||
|
||||
user = self.browse(cr, uid, user_id, context=context)
|
||||
# make user follow itself
|
||||
self.message_subscribe(cr, uid, [user_id], [user_id], context=context)
|
||||
self.pool.get('res.partner').message_subscribe(cr, uid, [user.partner_id.id], [user_id], context=context)
|
||||
# alias
|
||||
mail_alias.write(cr, SUPERUSER_ID, [alias_id], {"alias_force_thread_id": user_id}, context)
|
||||
# create a welcome message
|
||||
company_name = user.company_id.name if user.company_id else _('the company')
|
||||
message = _('%s joined the %s network! Take a moment to welcome %s.') % (user.name, company_name, user.name)
|
||||
self.message_append_note(cr, uid, [user_id], body=message, type='comment', context=context)
|
||||
self.create_welcome_message(cr, uid, user, context=context)
|
||||
return user_id
|
||||
|
||||
def create_welcome_message(self, cr, uid, user, context=None):
|
||||
company_name = user.company_id.name if user.company_id else _('the company')
|
||||
subject = '''%s has joined %s.''' % (user.name, company_name)
|
||||
body = '''Welcome to OpenERP !'''
|
||||
return self.pool.get('res.partner').message_append_note(cr, user.id, [user.partner_id.id],
|
||||
subject=subject, body=body, type='comment', content_subtype='html', context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
# User alias is sync'ed with login
|
||||
if vals.get('login'): vals['alias_name'] = vals['login']
|
||||
|
@ -124,27 +128,55 @@ class res_users(osv.osv):
|
|||
alias_pool.unlink(cr, uid, alias_ids, context=context)
|
||||
return res
|
||||
|
||||
def message_search_get_domain(self, cr, uid, ids, context=None):
|
||||
""" Override of message_search_get_domain for partner discussion page.
|
||||
The purpose is to add messages directly sent to user using
|
||||
@user_login.
|
||||
"""
|
||||
initial_domain = super(res_users, self).message_search_get_domain(cr, uid, ids, context=context)
|
||||
custom_domain = []
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
if custom_domain:
|
||||
custom_domain += ['|']
|
||||
custom_domain += ['|', ('body_text', 'like', '@%s' % (user.login)), ('body_html', 'like', '@%s' % (user.login))]
|
||||
return ['|'] + initial_domain + custom_domain
|
||||
# --------------------------------------------------
|
||||
# Wrappers on partner methods for Chatter
|
||||
# #FIXME: another branch holds a refactoring of mail.thread
|
||||
# that should help cleaning those wrappers
|
||||
# --------------------------------------------------
|
||||
|
||||
class res_users_mail_group(osv.osv):
|
||||
def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None,
|
||||
type='email', email_date=None, parent_id=False,
|
||||
content_subtype='plain', state=None,
|
||||
partner_ids=None, email_from=False, email_to=False,
|
||||
email_cc=None, email_bcc=None, reply_to=None,
|
||||
headers=None, message_id=False, references=None,
|
||||
attachments=None, original=None, context=None):
|
||||
for user in self.browse(cr, uid, threads, context=context):
|
||||
user.partner_id.message_append(subject, body_text, body_html, type, email_date, parent_id,
|
||||
content_subtype, state, partner_ids, email_from, email_to, email_cc, email_bcc, reply_to,
|
||||
headers, message_id, references, attachments, original)
|
||||
|
||||
def message_read(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None,
|
||||
limit=100, offset=0, domain=None, context=None):
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
return user.partner_id.message_read(fetch_ancestors, ancestor_ids, limit, offset, domain)
|
||||
|
||||
def message_read_subscribers(self, cr, uid, ids, fields=['id', 'name', 'image_small'], context=None):
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
return user.partner_id.message_read_subscribers(fields)
|
||||
|
||||
def message_search(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None,
|
||||
limit=100, offset=0, domain=None, count=False, context=None):
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
return user.partner_id.message_search(fetch_ancestors, ancestor_ids, limit, offset, domain, count)
|
||||
|
||||
def message_subscribe(self, cr, uid, ids, user_ids = None, context=None):
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
return user.partner_id.message_subscribe(user_ids)
|
||||
|
||||
def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None):
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
return user.partner_id.message_unsubscribe(user_ids)
|
||||
|
||||
|
||||
class res_users_mail_group(osv.Model):
|
||||
""" Update of res.groups class
|
||||
- if adding/removing users from a group, check mail.groups linked to
|
||||
this user group, and subscribe / unsubscribe them from the discussion
|
||||
group. This is done by overriding the write method.
|
||||
"""
|
||||
_name = 'res.users'
|
||||
_inherit = ['res.users', 'mail.thread']
|
||||
_inherit = ['res.users']
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
write_res = super(res_users_mail_group, self).write(cr, uid, ids, vals, context=context)
|
||||
|
@ -157,8 +189,7 @@ class res_users_mail_group(osv.osv):
|
|||
mail_group_obj.message_subscribe(cr, uid, mail_group_ids, ids, context=context)
|
||||
return write_res
|
||||
|
||||
|
||||
class res_groups_mail_group(osv.osv):
|
||||
class res_groups_mail_group(osv.Model):
|
||||
""" Update of res.groups class
|
||||
- if adding/removing users from a group, check mail.groups linked to
|
||||
this user group, and subscribe / unsubscribe them from the discussion
|
||||
|
@ -176,3 +207,5 @@ class res_groups_mail_group(osv.osv):
|
|||
mail_group_ids = mail_group_obj.search(cr, uid, [('group_ids', 'in', ids)], context=context)
|
||||
mail_group_obj.message_subscribe(cr, uid, mail_group_ids, user_ids, context=context)
|
||||
return super(res_groups_mail_group, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
# vim:et:
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<field name="inherit_id" ref="base.view_users_form_simple_modif"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<field name="user_email" position="before">
|
||||
<field name="email" position="before">
|
||||
<field name="notification_email_pref" readonly="0"/>
|
||||
</field>
|
||||
</data>
|
||||
|
@ -23,15 +23,10 @@
|
|||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<field name="user_email" position="before">
|
||||
<field name="email" position="before">
|
||||
<field name="notification_email_pref"/>
|
||||
</field>
|
||||
<xpath expr="/form/sheet" position="after">
|
||||
<div class="oe_chatter">
|
||||
<field name="message_ids" colspan="4" widget="mail_thread" nolabel="1"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<field name="user_email" position="after">
|
||||
<field name="email" position="after">
|
||||
<field name="alias_domain" invisible="1"/>
|
||||
<field name="alias_id" readonly="1" required="0" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
|
||||
</field>
|
||||
|
|
|
@ -1021,7 +1021,6 @@ openerp.mail = function(session) {
|
|||
if (this.compose_message_widget) {
|
||||
this.compose_message_widget.destroy();
|
||||
}
|
||||
debugger;
|
||||
this.compose_message_widget = new mail.ComposeMessage(this, {
|
||||
'extended_mode': false, 'uid': this.session.uid, 'res_model': this.params.res_model,
|
||||
'res_id': this.params.res_id, 'mode': mode || 'comment', 'msg_id': msg_id });
|
||||
|
|
|
@ -100,7 +100,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
# Try to provide default email_from if not specified yet
|
||||
if not result.get('email_from'):
|
||||
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
result['email_from'] = current_user.user_email or False
|
||||
result['email_from'] = current_user.email or False
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
|
@ -133,7 +133,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
result.update({
|
||||
'model': model,
|
||||
'res_id': res_id,
|
||||
'email_from': user.user_email or tools.config.get('email_from', False),
|
||||
'email_from': user.email or tools.config.get('email_from', False),
|
||||
'body_html': False,
|
||||
'body_text': False,
|
||||
'subject': False,
|
||||
|
@ -223,7 +223,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
'dest_partner_ids': dest_partner_ids,
|
||||
'model': message_data.model or False,
|
||||
'res_id': message_data.res_id or False,
|
||||
'email_from': current_user.user_email or message_data.email_to or False,
|
||||
'email_from': current_user.email or message_data.email_to or False,
|
||||
'email_to': message_data.reply_to or message_data.email_from or False,
|
||||
'email_cc': message_data.email_cc or False,
|
||||
'user_id': uid,
|
||||
|
|
|
@ -120,7 +120,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
'Status',),
|
||||
'activity_ids': fields.one2many('marketing.campaign.activity',
|
||||
'campaign_id', 'Activities'),
|
||||
'fixed_cost': fields.float('Fixed Cost', help="Fixed cost for running this campaign. You may also specify variable cost and revenue on each campaign activity. Cost and Revenue statistics are included in Campaign Reporting.", digits_compute=dp.get_precision('Purchase Price')),
|
||||
'fixed_cost': fields.float('Fixed Cost', help="Fixed cost for running this campaign. You may also specify variable cost and revenue on each campaign activity. Cost and Revenue statistics are included in Campaign Reporting.", digits_compute=dp.get_precision('Product Price')),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -435,8 +435,8 @@ class marketing_campaign_activity(osv.osv):
|
|||
'from_ids': fields.one2many('marketing.campaign.transition',
|
||||
'activity_to_id',
|
||||
'Previous Activities'),
|
||||
'variable_cost': fields.float('Variable Cost', help="Set a variable cost if you consider that every campaign item that has reached this point has entailed a certain cost. You can get cost statistics in the Reporting section", digits_compute=dp.get_precision('Purchase Price')),
|
||||
'revenue': fields.float('Revenue', help="Set an expected revenue if you consider that every campaign item that has reached this point has generated a certain revenue. You can get revenue statistics in the Reporting section", digits_compute=dp.get_precision('Sale Price')),
|
||||
'variable_cost': fields.float('Variable Cost', help="Set a variable cost if you consider that every campaign item that has reached this point has entailed a certain cost. You can get cost statistics in the Reporting section", digits_compute=dp.get_precision('Product Price')),
|
||||
'revenue': fields.float('Revenue', help="Set an expected revenue if you consider that every campaign item that has reached this point has generated a certain revenue. You can get revenue statistics in the Reporting section", digits_compute=dp.get_precision('Account')),
|
||||
'signal': fields.char('Signal', size=128,
|
||||
help='An activity with a signal can be called programmatically. Be careful, the workitem is always created when a signal is sent'),
|
||||
'keep_if_condition_not_met': fields.boolean("Don't Delete Workitems",
|
||||
|
|
|
@ -63,8 +63,8 @@ class campaign_analysis(osv.osv):
|
|||
'country_id': fields.related('partner_id', 'country_id',
|
||||
type='many2one', relation='res.country',string='Country'),
|
||||
'total_cost' : fields.function(_total_cost, string='Cost',
|
||||
type="float", digits_compute=dp.get_precision('Purchase Price')),
|
||||
'revenue': fields.float('Revenue', readonly=True, digits_compute=dp.get_precision('Sale Price')),
|
||||
type="float", digits_compute=dp.get_precision('Account')),
|
||||
'revenue': fields.float('Revenue', readonly=True, digits_compute=dp.get_precision('Account')),
|
||||
'count' : fields.integer('# of Actions', readonly=True),
|
||||
'state': fields.selection([('todo', 'To Do'),
|
||||
('exception', 'Exception'), ('done', 'Done'),
|
||||
|
|
|
@ -146,7 +146,7 @@ class membership_line(osv.osv):
|
|||
'date_to': fields.date('To', readonly=True),
|
||||
'date_cancel': fields.date('Cancel date'),
|
||||
'date': fields.date('Join Date', help="Date on which member has joined the membership"),
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Sale Price'), required=True, help='Amount for the membership'),
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Product Price'), required=True, help='Amount for the membership'),
|
||||
'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line', readonly=True),
|
||||
'account_invoice_id': fields.related('account_invoice_line', 'invoice_id', type='many2one', relation='account.invoice', string='Invoice', readonly=True),
|
||||
'state': fields.function(_state,
|
||||
|
@ -447,7 +447,7 @@ Partner()
|
|||
class product_template(osv.osv):
|
||||
_inherit = 'product.template'
|
||||
_columns = {
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Sale Price')),
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Product Price')),
|
||||
}
|
||||
|
||||
product_template()
|
||||
|
|
|
@ -29,7 +29,7 @@ class membership_invoice(osv.osv_memory):
|
|||
_description = "Membership Invoice"
|
||||
_columns = {
|
||||
'product_id': fields.many2one('product.product','Membership', required=True),
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Sale Price'), required=True),
|
||||
'member_price': fields.float('Member Price', digits_compute= dp.get_precision('Product Price'), required=True),
|
||||
}
|
||||
def onchange_product(self, cr, uid, ids, product_id=False):
|
||||
"""This function returns value of product's member price based on product id.
|
||||
|
|
|
@ -138,7 +138,7 @@ class report_custom(report_rml):
|
|||
</row>
|
||||
""" % (_('Components'), _('Components suppliers'), _('Quantity'),_('Cost Price per Unit of Measure'), _('Supplier Price per Unit of Measure'))
|
||||
|
||||
purchase_price_digits = rml_obj.get_digits(dp='Purchase Price')
|
||||
purchase_price_digits = rml_obj.get_digits(dp='Product Price')
|
||||
|
||||
for product in product_pool.browse(cr, uid, ids, context=context):
|
||||
product_uom_name = to_xml(product.uom_id.name)
|
||||
|
|
|
@ -692,10 +692,10 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
|
|||
'to_invoice': fields.boolean('To Invoice'),
|
||||
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok','=',True)], required=True),
|
||||
'invoiced': fields.boolean('Invoiced',readonly=True),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Sale Price')),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Account')),
|
||||
'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes'),
|
||||
'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product UoS'), required=True),
|
||||
'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||
'prodlot_id': fields.many2one('stock.production.lot', 'Lot Number',domain="[('product_id','=',product_id)]"),
|
||||
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
||||
|
@ -784,10 +784,10 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin):
|
|||
'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', required=True, ondelete='cascade', select=True),
|
||||
'name': fields.char('Description', size=64, select=True,required=True),
|
||||
'product_id': fields.many2one('product.product', 'Product'),
|
||||
'product_uom_qty': fields.float('Quantity', digits=(16,2), required=True),
|
||||
'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True),
|
||||
'price_unit': fields.float('Unit Price', required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Sale Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Account')),
|
||||
'tax_id': fields.many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes'),
|
||||
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
||||
'to_invoice': fields.boolean('To Invoice'),
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
import portal
|
||||
import wizard
|
||||
import res_user
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -43,7 +43,6 @@ very handy when used in combination with the module 'share'.
|
|||
'security/ir.model.access.csv',
|
||||
'portal_view.xml',
|
||||
'portal_data.xml',
|
||||
'res_user_view.xml',
|
||||
'wizard/portal_wizard_view.xml',
|
||||
'wizard/share_wizard_view.xml',
|
||||
],
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
|
||||
|
||||
|
||||
class res_users(osv.osv):
|
||||
_inherit = 'res.users'
|
||||
_columns = {
|
||||
'partner_id': fields.many2one('res.partner',
|
||||
string='Related Partner'),
|
||||
}
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- add partner field in user form -->
|
||||
<record id="view_users_form" model="ir.ui.view">
|
||||
<field name="name">res.portal.users.form</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="active" position="before">
|
||||
<field name="partner_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -26,7 +26,7 @@ from osv import osv, fields
|
|||
from tools.misc import email_re
|
||||
from tools.translate import _
|
||||
|
||||
from base.res.res_users import _lang_get
|
||||
from base.res.res_partner import _lang_get
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -62,9 +62,9 @@ def random_password():
|
|||
random.shuffle(chars)
|
||||
return ''.join(chars)
|
||||
|
||||
def extract_email(user_email):
|
||||
def extract_email(email):
|
||||
""" extract the email address from a user-friendly email address """
|
||||
m = email_re.search(user_email or "")
|
||||
m = email_re.search(email or "")
|
||||
return m and m.group(0) or ""
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ class wizard(osv.osv_memory):
|
|||
|
||||
return{
|
||||
'name': address.name,
|
||||
'user_email': extract_email(address.email),
|
||||
'email': extract_email(address.email),
|
||||
'lang': lang,
|
||||
'partner_id': partner_id,
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class wizard(osv.osv_memory):
|
|||
|
||||
user_obj = self.pool.get('res.users')
|
||||
user = user_obj.browse(cr, ROOT_UID, uid, context0)
|
||||
if not user.user_email:
|
||||
if not user.email:
|
||||
raise osv.except_osv(_('Email required'),
|
||||
_('You must have an email address in your User Preferences'
|
||||
' to send emails.'))
|
||||
|
@ -144,7 +144,7 @@ class wizard(osv.osv_memory):
|
|||
portal_obj = self.pool.get('res.portal')
|
||||
for wiz in self.browse(cr, uid, ids, context):
|
||||
# determine existing users
|
||||
login_cond = [('login', 'in', [u.user_email for u in wiz.user_ids])]
|
||||
login_cond = [('login', 'in', [u.email for u in wiz.user_ids])]
|
||||
existing_uids = user_obj.search(cr, ROOT_UID, login_cond)
|
||||
existing_users = user_obj.browse(cr, ROOT_UID, existing_uids)
|
||||
existing_logins = [u.login for u in existing_users]
|
||||
|
@ -152,15 +152,15 @@ class wizard(osv.osv_memory):
|
|||
# create new users in portal (skip existing logins)
|
||||
new_users_data = [ {
|
||||
'name': u.name,
|
||||
'login': u.user_email,
|
||||
'login': u.email,
|
||||
'password': random_password(),
|
||||
'user_email': u.user_email,
|
||||
'context_lang': u.lang,
|
||||
'email': u.email,
|
||||
'lang': u.lang,
|
||||
'share': True,
|
||||
'action_id': wiz.portal_id.home_action_id and wiz.portal_id.home_action_id.id or False,
|
||||
'partner_id': u.partner_id and u.partner_id.id,
|
||||
'groups_id': [(6, 0, [])],
|
||||
} for u in wiz.user_ids if u.user_email not in existing_logins ]
|
||||
} for u in wiz.user_ids if u.email not in existing_logins ]
|
||||
portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id],
|
||||
{'users': [(0, 0, data) for data in new_users_data]}, context0)
|
||||
|
||||
|
@ -175,13 +175,13 @@ class wizard(osv.osv_memory):
|
|||
dest_uids = user_obj.search(cr, ROOT_UID, login_cond)
|
||||
dest_users = user_obj.browse(cr, ROOT_UID, dest_uids)
|
||||
for dest_user in dest_users:
|
||||
context['lang'] = dest_user.context_lang
|
||||
context['lang'] = dest_user.lang
|
||||
data['login'] = dest_user.login
|
||||
data['password'] = dest_user.password
|
||||
data['name'] = dest_user.name
|
||||
|
||||
email_from = user.user_email
|
||||
email_to = dest_user.user_email
|
||||
email_from = user.email
|
||||
email_to = dest_user.email
|
||||
subject = _(WELCOME_EMAIL_SUBJECT) % data
|
||||
body = _(WELCOME_EMAIL_BODY) % data
|
||||
res = mail_message_obj.schedule_with_attach(cr, uid, email_from , [email_to], subject, body, context=context)
|
||||
|
@ -208,7 +208,7 @@ class wizard_user(osv.osv_memory):
|
|||
'name': fields.char(size=64, required=True,
|
||||
string='User Name',
|
||||
help="The user's real name"),
|
||||
'user_email': fields.char(size=64, required=True,
|
||||
'email': fields.char(size=64, required=True,
|
||||
string='Email',
|
||||
help="Will be used as user login. "
|
||||
"Also necessary to send the account information to new users"),
|
||||
|
@ -222,7 +222,7 @@ class wizard_user(osv.osv_memory):
|
|||
def _check_email(self, cr, uid, ids):
|
||||
""" check syntax of email address """
|
||||
for wuser in self.browse(cr, uid, ids):
|
||||
if not email_re.match(wuser.user_email): return False
|
||||
if not email_re.match(wuser.email): return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
editable in the web client 6.0 -->
|
||||
<tree string="Portal Users" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="user_email"/>
|
||||
<field name="email"/>
|
||||
<field name="partner_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -55,7 +55,7 @@
|
|||
<form string="Portal User" version="7.0">
|
||||
<group colspan="2" col="2">
|
||||
<field name="name"/>
|
||||
<field name="user_email"/>
|
||||
<field name="email"/>
|
||||
<field name="lang"/>
|
||||
<field name="partner_id"/>
|
||||
</group>
|
||||
|
|
|
@ -50,7 +50,7 @@ class crm_contact_us(osv.TransientModel):
|
|||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
|
||||
if (user.login != 'anonymous'):
|
||||
return user.user_email
|
||||
return user.email
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ class procurement_order(osv.osv):
|
|||
|
||||
Exceptions:\n""") % (start_date, end_date, report_total, report_except, report_later)
|
||||
summary += '\n'.join(report)
|
||||
self.pool.get('res.users').message_append_note(cr, uid, [uid], body=summary, context=context)
|
||||
procurement_obj.message_append_note(cr, uid, ids, body=summary, context=context)
|
||||
|
||||
if use_new_cursor:
|
||||
cr.commit()
|
||||
|
@ -234,7 +234,6 @@ class procurement_order(osv.osv):
|
|||
location_obj = self.pool.get('stock.location')
|
||||
procurement_obj = self.pool.get('procurement.order')
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
report = []
|
||||
offset = 0
|
||||
ids = [1]
|
||||
if automatic:
|
||||
|
@ -288,9 +287,6 @@ class procurement_order(osv.osv):
|
|||
offset += len(ids)
|
||||
if use_new_cursor:
|
||||
cr.commit()
|
||||
if user_id and report:
|
||||
# Chatter: old res.request is now a chatter on res.users, id=uid
|
||||
self.pool.get('res.users').message_append_note(cr, uid, [user_id], body='\n'.join(report), subject=_('Orderpoint report'), context=context)
|
||||
if use_new_cursor:
|
||||
cr.commit()
|
||||
cr.close()
|
||||
|
|
|
@ -407,18 +407,18 @@ class product_pricelist_item(osv.osv):
|
|||
'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'),
|
||||
|
||||
'price_surcharge': fields.float('Price Surcharge',
|
||||
digits_compute= dp.get_precision('Sale Price')),
|
||||
digits_compute= dp.get_precision('Product Price')),
|
||||
'price_discount': fields.float('Price Discount', digits=(16,4)),
|
||||
'price_round': fields.float('Price Rounding',
|
||||
digits_compute= dp.get_precision('Sale Price'),
|
||||
digits_compute= dp.get_precision('Product Price'),
|
||||
help="Sets the price so that it is a multiple of this value.\n" \
|
||||
"Rounding is applied after the discount and before the surcharge.\n" \
|
||||
"To have prices that end in 9.99, set rounding 10, surcharge -0.01" \
|
||||
),
|
||||
'price_min_margin': fields.float('Min. Price Margin',
|
||||
digits_compute= dp.get_precision('Sale Price')),
|
||||
digits_compute= dp.get_precision('Product Price')),
|
||||
'price_max_margin': fields.float('Max. Price Margin',
|
||||
digits_compute= dp.get_precision('Sale Price')),
|
||||
digits_compute= dp.get_precision('Product Price')),
|
||||
'company_id': fields.related('price_version_id','company_id',type='many2one',
|
||||
readonly=True, relation='res.company', string='Company', store=True)
|
||||
}
|
||||
|
|
|
@ -272,8 +272,8 @@ class product_template(osv.osv):
|
|||
'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procurement Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until re-supplying. 'Make to Order': When needed, purchase or produce for the procurement request."),
|
||||
'rental': fields.boolean('Can be Rent'),
|
||||
'categ_id': fields.many2one('product.category','Category', required=True, change_default=True, domain="[('type','=','normal')]" ,help="Select category for the current product"),
|
||||
'list_price': fields.float('Sale Price', digits_compute=dp.get_precision('Sale Price'), help="Base price for computing the customer price. Sometimes called the catalog price."),
|
||||
'standard_price': fields.float('Cost Price', required=True, digits_compute=dp.get_precision('Purchase Price'), help="Product's cost for accounting stock valuation. It is the base price for the supplier price.", groups="base.group_user"),
|
||||
'list_price': fields.float('Sale Price', digits_compute=dp.get_precision('Product Price'), help="Base price for computing the customer price. Sometimes called the catalog price."),
|
||||
'standard_price': fields.float('Cost Price', required=True, digits_compute=dp.get_precision('Product Price'), help="Product's cost for accounting stock valuation. It is the base price for the supplier price.", groups="base.group_user"),
|
||||
'volume': fields.float('Volume', help="The volume in m3."),
|
||||
'weight': fields.float('Gross Weight', digits_compute=dp.get_precision('Stock Weight'), help="The gross weight in Kg."),
|
||||
'weight_net': fields.float('Net Weight', digits_compute=dp.get_precision('Stock Weight'), help="The net weight in Kg."),
|
||||
|
@ -518,8 +518,8 @@ class product_product(osv.osv):
|
|||
'virtual_available': fields.function(_product_virtual_available, type='float', string='Quantity Available'),
|
||||
'incoming_qty': fields.function(_product_incoming_qty, type='float', string='Incoming'),
|
||||
'outgoing_qty': fields.function(_product_outgoing_qty, type='float', string='Outgoing'),
|
||||
'price': fields.function(_product_price, type='float', string='Pricelist', digits_compute=dp.get_precision('Sale Price')),
|
||||
'lst_price' : fields.function(_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Sale Price')),
|
||||
'price': fields.function(_product_price, type='float', string='Pricelist', digits_compute=dp.get_precision('Product Price')),
|
||||
'lst_price' : fields.function(_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Product Price')),
|
||||
'code': fields.function(_product_code, type='char', string='Reference'),
|
||||
'partner_ref' : fields.function(_product_partner_ref, type='char', string='Customer ref'),
|
||||
'default_code' : fields.char('Reference', size=64, select=True),
|
||||
|
@ -528,8 +528,8 @@ class product_product(osv.osv):
|
|||
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade"),
|
||||
'ean13': fields.char('EAN13', size=13, help="The numbers encoded in EAN-13 bar codes are product identification numbers."),
|
||||
'packaging' : fields.one2many('product.packaging', 'product_id', 'Logistical Units', help="Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module."),
|
||||
'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Sale Price')),
|
||||
'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Sale Price')),
|
||||
'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price')),
|
||||
'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Product Price')),
|
||||
'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'),
|
||||
'name_template': fields.related('product_tmpl_id', 'name', string="Name", type='char', size=128, store=True, select=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
|
@ -878,7 +878,7 @@ class pricelist_partnerinfo(osv.osv):
|
|||
'name': fields.char('Description', size=64),
|
||||
'suppinfo_id': fields.many2one('product.supplierinfo', 'Partner Information', required=True, ondelete='cascade'),
|
||||
'min_quantity': fields.float('Quantity', required=True, help="The minimal quantity to trigger this rule, expressed in the supplier Unit of Measure if any or in the default Unit of Measure of the product otherrwise."),
|
||||
'price': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Purchase Price'), help="This price will be considered as a price for the supplier Unit of Measure if any or the default Unit of Measure of the product otherwise"),
|
||||
'price': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Product Price'), help="This price will be considered as a price for the supplier Unit of Measure if any or the default Unit of Measure of the product otherwise"),
|
||||
}
|
||||
_order = 'min_quantity asc'
|
||||
pricelist_partnerinfo()
|
||||
|
|
|
@ -157,12 +157,12 @@ parameter) will see those record just disappear.
|
|||
<field eval="'product.pricelist,'+str(ref('list0'))" name="value"/>
|
||||
</record>
|
||||
|
||||
<record forcecreate="True" id="decimal_sale" model="decimal.precision">
|
||||
<field name="name">Sale Price</field>
|
||||
<record forcecreate="True" id="decimal_price" model="decimal.precision">
|
||||
<field name="name">Product Price</field>
|
||||
<field name="digits">2</field>
|
||||
</record>
|
||||
<record forcecreate="True" id="decimal_purchase" model="decimal.precision">
|
||||
<field name="name">Purchase Price</field>
|
||||
<record forcecreate="True" id="decimal_discount" model="decimal.precision">
|
||||
<field name="name">Discount</field>
|
||||
<field name="digits">2</field>
|
||||
</record>
|
||||
<record forcecreate="True" id="decimal_account" model="decimal.precision">
|
||||
|
|
|
@ -112,7 +112,7 @@ class product_pricelist(report_sxw.rml_parse):
|
|||
return res
|
||||
|
||||
def _get_price(self,pricelist_id, product_id,qty):
|
||||
sale_price_digits = self.get_digits(dp='Sale Price')
|
||||
sale_price_digits = self.get_digits(dp='Product Price')
|
||||
pool = pooler.get_pool(self.cr.dbname)
|
||||
price_dict = pool.get('product.pricelist').price_get(self.cr, self.uid, [pricelist_id], product_id, qty, context=self.localcontext)
|
||||
if price_dict[pricelist_id]:
|
||||
|
|
|
@ -797,7 +797,7 @@ class task(base_stage, osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -256,7 +256,7 @@ class project_issue(base_stage, osv.osv):
|
|||
'inactivity_days': fields.function(_compute_day, string='Days since last action', \
|
||||
multi='compute_day', type="integer", help="Difference in days between last action and current date"),
|
||||
'color': fields.integer('Color Index'),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'progress': fields.function(_hours_get, string='Progress (%)', multi='hours', group_operator="avg", help="Computed as: Time Spent / Total Time.",
|
||||
|
|
|
@ -73,7 +73,7 @@ class project_tasks(osv.osv):
|
|||
followers = super(project_tasks,self).message_thread_followers(cr, uid, ids, context=context)
|
||||
for task in self.browse(cr, uid, followers.keys(), context=context):
|
||||
task_followers = set(followers[task.id])
|
||||
task_followers.add(task.user_id.user_email)
|
||||
task_followers.add(task.user_id.email)
|
||||
followers[task.id] = filter(None, task_followers)
|
||||
return followers
|
||||
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
-
|
||||
!record {model: res.users, id: res_users_hrmanager0}:
|
||||
company_id: base.main_company
|
||||
context_lang: en_US
|
||||
login: hr
|
||||
name: HR Manager
|
||||
login: hr
|
||||
password: hr
|
||||
groups_id:
|
||||
- base.group_hr_manager
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<!--Email template -->
|
||||
<record id="email_template_edi_purchase" model="email.template">
|
||||
<field name="name">Automated Purchase Order Notification Mail</field>
|
||||
<field name="email_from">${object.validator.user_email or ''}</field>
|
||||
<field name="email_from">${object.validator.email or ''}</field>
|
||||
<field name="subject">${object.company_id.name} Order (Ref ${object.name or 'n/a' })</field>
|
||||
<field name="email_to">${object.partner_id.email}</field>
|
||||
<field name="model_id" ref="purchase.model_purchase_order"/>
|
||||
|
@ -61,7 +61,7 @@
|
|||
% if object.partner_ref:
|
||||
Your reference: ${object.partner_ref}<br />
|
||||
% endif
|
||||
Your contact: <a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a>
|
||||
Your contact: <a href="mailto:${object.validator.email or ''}?subject=Order%20${object.name}">${object.validator.name}</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -121,7 +121,7 @@ Here is a ${object.state in ('draft', 'sent') and 'request for quotation' or 'pu
|
|||
% if object.partner_ref:
|
||||
| Your reference: ${object.partner_ref}<br />
|
||||
% endif
|
||||
| Your contact: ${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''}
|
||||
| Your contact: ${object.validator.name} ${object.validator.email and '<%s>'%(object.validator.email) or ''}
|
||||
|
||||
You can view the ${object.state in ('draft', 'sent') and 'request for quotation' or 'order confirmation'} and download it using the following link:
|
||||
${ctx.get('edi_web_url_view') or 'n/a'}
|
||||
|
@ -132,7 +132,7 @@ Thank you!
|
|||
|
||||
|
||||
--
|
||||
${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''}
|
||||
${object.validator.name} ${object.validator.email and '<%s>'%(object.validator.email) or ''}
|
||||
${object.company_id.name}
|
||||
% if object.company_id.street:
|
||||
${object.company_id.street or ''}
|
||||
|
|
|
@ -143,7 +143,6 @@ class purchase_order(osv.osv):
|
|||
|
||||
STATE_SELECTION = [
|
||||
('draft', 'Draft PO'),
|
||||
('wait', 'Waiting'),
|
||||
('sent', 'RFQ Sent'),
|
||||
('confirmed', 'Waiting Approval'),
|
||||
('approved', 'Purchase Order'),
|
||||
|
@ -190,15 +189,15 @@ class purchase_order(osv.osv):
|
|||
'purchase.order.line': (_get_order, ['date_planned'], 10),
|
||||
}
|
||||
),
|
||||
'amount_untaxed': fields.function(_amount_all, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount',
|
||||
'amount_untaxed': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Untaxed Amount',
|
||||
store={
|
||||
'purchase.order.line': (_get_order, None, 10),
|
||||
}, multi="sums", help="The amount without tax"),
|
||||
'amount_tax': fields.function(_amount_all, digits_compute= dp.get_precision('Purchase Price'), string='Taxes',
|
||||
'amount_tax': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Taxes',
|
||||
store={
|
||||
'purchase.order.line': (_get_order, None, 10),
|
||||
}, multi="sums", help="The tax amount"),
|
||||
'amount_total': fields.function(_amount_all, digits_compute= dp.get_precision('Purchase Price'), string='Total',
|
||||
'amount_total': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Total',
|
||||
store={
|
||||
'purchase.order.line': (_get_order, None, 10),
|
||||
}, multi="sums",help="The total amount"),
|
||||
|
@ -800,8 +799,8 @@ class purchase_order_line(osv.osv):
|
|||
'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok','=',True)], change_default=True),
|
||||
'move_ids': fields.one2many('stock.move', 'purchase_line_id', 'Reservation', readonly=True, ondelete='set null'),
|
||||
'move_dest_id': fields.many2one('stock.move', 'Reservation Destination', ondelete='set null'),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Purchase Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Purchase Price')),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
|
||||
'order_id': fields.many2one('purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'),
|
||||
'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
|
||||
'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
|
||||
|
|
|
@ -180,16 +180,15 @@
|
|||
<button name="purchase_confirm" states="draft,sent" string="Confirm Quotation" class="oe_highlight"/>
|
||||
<button name="wkf_send_rfq" states="draft" string="Send RFQ" type="object" context="{'send_rfq':True}"/>
|
||||
<button name="wkf_send_rfq" states="confirmed" string="Resend Purchase Order" type="object" class="oe_highlight"/>
|
||||
<button name="action_cancel" states="except_picking,except_invoice,wait" string="Cancel" type="object" />
|
||||
<button name="action_cancel" states="except_picking,except_invoice" string="Cancel" type="object" />
|
||||
<button name="picking_ok" states="except_picking" string="Manually Corrected"/>
|
||||
<button name="invoice_ok" states="except_invoice" string="Manually Corrected"/>
|
||||
<button name="purchase_appbuyer" states="wait_auth" string="Approve Purchase" class="oe_highlight"/>
|
||||
<button name="purchase_approve" states="confirmed" string="Approve Order" class="oe_highlight"/>
|
||||
<button name="view_invoice" string="Receive Invoice" type="object" attrs="{'invisible': ['|', ('invoice_method','=','picking'), '|', ('state','!=', 'approved'), ('invoiced','=',True) ]}" class="oe_highlight"/>
|
||||
<button name="view_picking" string="Receive Products" type="object" attrs="{'invisible': ['|', ('shipped','=',True), ('state','!=', 'approved')]}" class="oe_highlight"/>
|
||||
<button name="action_cancel_draft" states="cancel,sent,confirmed" string="Set to Draft" type="object" />
|
||||
<button name="purchase_cancel" states="draft,confirmed,wait_auth,sent" string="Cancel"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue","wait":"blue"}' readonly="1"/>
|
||||
<button name="purchase_cancel" states="draft,confirmed,sent" string="Cancel"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue"}' readonly="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
|
|
|
@ -274,10 +274,10 @@
|
|||
<para style="terp_default_Right_9">[[ formatLang(line.product_qty ) ]] [[ line.product_uom.name ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_unit, digits=get_digits(dp='Purchase Price') ) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_unit, digits=get_digits(dp='Product Price') ) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_subtotal, digits=get_digits(dp='Purchase Price'), currency_obj=o.pricelist_id.currency_id ) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_subtotal, digits=get_digits(dp='Account'), currency_obj=o.pricelist_id.currency_id ) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -293,7 +293,7 @@
|
|||
<para style="terp_default_9">Net Total :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_untaxed, digits=get_digits(dp='Purchase Price'), currency_obj=o.pricelist_id.currency_id ) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_untaxed, digits=get_digits(dp='Account'), currency_obj=o.pricelist_id.currency_id ) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -306,7 +306,7 @@
|
|||
<para style="terp_default_9">Taxes :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_tax, dp='Purchase Price', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_tax, dp='Account', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -319,7 +319,7 @@
|
|||
<para style="terp_default_Bold_9">Total :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Bold_9_Right">[[ formatLang(o.amount_total, digits=get_digits(dp='Purchase Price') , currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
<para style="terp_default_Bold_9_Right">[[ formatLang(o.amount_total, digits=get_digits(dp='Account') , currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -35,7 +35,6 @@ class purchase_report(osv.osv):
|
|||
'name': fields.char('Year',size=64,required=False, readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'state': fields.selection([('draft', 'Request for Quotation'),
|
||||
('wait', 'Waiting'),
|
||||
('confirmed', 'Waiting Supplier Ack'),
|
||||
('approved', 'Approved'),
|
||||
('except_picking', 'Shipping Exception'),
|
||||
|
|
|
@ -59,21 +59,12 @@ class purchase_config_settings(osv.osv_memory):
|
|||
help="""Purchase Requisitions are used when you want to request quotations from several suppliers for a given set of products.
|
||||
You can configure per product if you directly do a Request for Quotation
|
||||
to one supplier or if you want a purchase requisition to negotiate with several suppliers."""),
|
||||
'decimal_precision': fields.integer('specify decimal precision on price',help="As an example, a decimal precision of 2 will allow prices like: 9.99 EUR, whereas a decimal precision of 4 will allow prices like: 0.0231 EUR per unit."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'default_invoice_method': 'manual',
|
||||
}
|
||||
|
||||
def get_default_dp(self, cr, uid, fields, context=None):
|
||||
dp = self.pool.get('ir.model.data').get_object(cr,uid, 'product','decimal_purchase')
|
||||
return {'decimal_precision': dp.digits}
|
||||
|
||||
def set_default_dp(self, cr, uid, ids, context=None):
|
||||
config = self.browse(cr, uid, ids[0], context)
|
||||
dp = self.pool.get('ir.model.data').get_object(cr,uid, 'product','decimal_purchase')
|
||||
dp.write({'digits': config.decimal_precision})
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,10 +32,6 @@
|
|||
<label for="default_invoice_method"/>
|
||||
<field name="default_invoice_method" class="oe_inline"/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="decimal_precision"/>
|
||||
<field name="decimal_precision" class="oe_inline"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<separator string="Purchase Order"/>
|
||||
|
|
|
@ -69,7 +69,7 @@ class purchase_requisition(osv.osv):
|
|||
purchase_order_obj = self.pool.get('purchase.order')
|
||||
for purchase in self.browse(cr, uid, ids, context=context):
|
||||
for purchase_id in purchase.purchase_ids:
|
||||
if str(purchase_id.state) in('draft','wait'):
|
||||
if str(purchase_id.state) in('draft'):
|
||||
purchase_order_obj.action_cancel(cr,uid,[purchase_id.id])
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
self.cancel_send_note(cr, uid, ids, context=context)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<!--Email template -->
|
||||
<record id="email_template_edi_sale" model="email.template">
|
||||
<field name="name">Automated Sale Order Notification Mail</field>
|
||||
<field name="email_from">${object.user_id.user_email or ''}</field>
|
||||
<field name="email_from">${object.user_id.email or ''}</field>
|
||||
<field name="subject">${object.company_id.name} Order (Ref ${object.name or 'n/a' })</field>
|
||||
<field name="email_to">${object.partner_invoice_id.email}</field>
|
||||
<field name="model_id" ref="sale.model_sale_order"/>
|
||||
|
@ -60,7 +60,7 @@
|
|||
% if object.client_order_ref:
|
||||
Your reference: ${object.client_order_ref}<br />
|
||||
% endif
|
||||
Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a>
|
||||
Your contact: <a href="mailto:${object.user_id.email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -139,7 +139,7 @@ Here is your ${object.state in ('draft', 'sent') and 'quotation' or 'order confi
|
|||
% if object.client_order_ref:
|
||||
| Your reference: ${object.client_order_ref}<br />
|
||||
% endif
|
||||
| Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
|
||||
| Your contact: ${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''}
|
||||
|
||||
You can view the ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'}, download it and even pay online using the following link:
|
||||
${ctx.get('edi_web_url_view') or 'n/a'}
|
||||
|
@ -166,7 +166,7 @@ Thank you for choosing ${object.company_id.name}!
|
|||
|
||||
|
||||
--
|
||||
${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
|
||||
${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''}
|
||||
${object.company_id.name}
|
||||
% if object.company_id.street:
|
||||
${object.company_id.street or ''}
|
||||
|
|
|
@ -266,13 +266,13 @@
|
|||
<para style="terp_default_Right_9">[[ formatLang(line.product_uos and line.product_uos_qty or line.product_uom_qty) ]] [[ line.product_uos and line.product_uos.name or line.product_uom.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_unit ) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_unit , digits=get_digits(dp='Product Price'))]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_9">[[ formatLang(line.discount) ]]</para>
|
||||
<para style="terp_default_Centre_9">[[ formatLang(line.discount, digits=get_digits(dp='Discount'))]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_subtotal, digits=get_digits(dp='Sale Price'), currency_obj=o.pricelist_id.currency_id) ]] </para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.price_subtotal, digits=get_digits(dp='Account'), currency_obj=o.pricelist_id.currency_id) ]] </para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -288,7 +288,7 @@
|
|||
<para style="terp_default_9">Net Total :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_untaxed, dp='Sale Price', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_untaxed, dp='Account', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -301,7 +301,7 @@
|
|||
<para style="terp_default_9">Taxes :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_tax, dp='Sale Price', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_tax, dp='Account', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -314,7 +314,7 @@
|
|||
<para style="terp_default_Bold_9">Total :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(o.amount_total, dp='Sale Price', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(o.amount_total, dp='Account', currency_obj=o.pricelist_id.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -98,17 +98,7 @@ class sale_configuration(osv.osv_memory):
|
|||
'module_project_timesheet': fields.boolean("Project Timesheet"),
|
||||
'module_project_mrp': fields.boolean("Project MRP"),
|
||||
'module_project': fields.boolean("Project"),
|
||||
'decimal_precision': fields.integer("Decimal precision on prices:",help="As an example, a decimal precision of 2 will allow prices like: 9.99 EUR, whereas a decimal precision of 4 will allow prices like: 0.0231 EUR per unit."),
|
||||
}
|
||||
def _check_decimal(self, cr, uid, ids, context=None):
|
||||
for decimal in self.browse(cr, uid, ids, context=context):
|
||||
if decimal.decimal_precision > 20:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_decimal, 'Digits must be between 0 to 20 ', ['decimal_precision']),
|
||||
]
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
ir_model_data = self.pool.get('ir.model.data')
|
||||
|
@ -139,14 +129,6 @@ class sale_configuration(osv.osv_memory):
|
|||
'time_unit': _get_default_time_unit,
|
||||
}
|
||||
|
||||
def get_default_dp(self, cr, uid, fields, context=None):
|
||||
dp = self.pool.get('ir.model.data').get_object(cr, uid, 'product','decimal_sale')
|
||||
return {'decimal_precision': dp.digits}
|
||||
|
||||
def set_default_dp(self, cr, uid, ids, context=None):
|
||||
config = self.browse(cr, uid, ids[0], context)
|
||||
dp = self.pool.get('ir.model.data').get_object(cr, uid, 'product','decimal_sale')
|
||||
dp.write({'digits': config.decimal_precision})
|
||||
|
||||
def set_sale_defaults(self, cr, uid, ids, context=None):
|
||||
ir_values = self.pool.get('ir.values')
|
||||
|
|
|
@ -95,10 +95,6 @@
|
|||
<field name="group_discount_per_so_line" class="oe_inline"/>
|
||||
<label for="group_discount_per_so_line"/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="decimal_precision"/>
|
||||
<field name="decimal_precision" class="oe_inline"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
|
|
|
@ -247,19 +247,19 @@ class sale_order(osv.osv):
|
|||
fnct_search=_invoiced_search, type='boolean', help="It indicates that an invoice has been paid."),
|
||||
'note': fields.text('Terms and conditions'),
|
||||
|
||||
'amount_untaxed': fields.function(_amount_all, digits_compute= dp.get_precision('Sale Price'), string='Untaxed Amount',
|
||||
'amount_untaxed': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Untaxed Amount',
|
||||
store = {
|
||||
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
|
||||
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
|
||||
},
|
||||
multi='sums', help="The amount without tax."),
|
||||
'amount_tax': fields.function(_amount_all, digits_compute= dp.get_precision('Sale Price'), string='Taxes',
|
||||
'amount_tax': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Taxes',
|
||||
store = {
|
||||
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
|
||||
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
|
||||
},
|
||||
multi='sums', help="The tax amount."),
|
||||
'amount_total': fields.function(_amount_all, digits_compute= dp.get_precision('Sale Price'), string='Total',
|
||||
'amount_total': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Total',
|
||||
store = {
|
||||
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
|
||||
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
|
||||
|
@ -1110,8 +1110,8 @@ class sale_order_line(osv.osv):
|
|||
'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
|
||||
'invoiced': fields.boolean('Invoiced', readonly=True),
|
||||
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price'), readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Sale Price')),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price'), readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
|
||||
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
help="If 'on order', it triggers a procurement when the sale order is confirmed to create a task, purchase order or manufacturing order linked to this sale order line."),
|
||||
|
@ -1123,7 +1123,7 @@ class sale_order_line(osv.osv):
|
|||
'product_uos': fields.many2one('product.uom', 'Product UoS'),
|
||||
'product_packaging': fields.many2one('product.packaging', 'Packaging'),
|
||||
'move_ids': fields.one2many('stock.move', 'sale_line_id', 'Inventory Moves', readonly=True),
|
||||
'discount': fields.float('Discount', digits=(16, 2), readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount'), readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'number_packages': fields.function(_number_packages, type='integer', string='Number Packages'),
|
||||
'th_weight': fields.float('Weight', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'state': fields.selection([('cancel', 'Cancelled'),('draft', 'Draft'),('confirmed', 'Confirmed'),('exception', 'Exception'),('done', 'Done')], 'Status', required=True, readonly=True,
|
||||
|
@ -1201,7 +1201,7 @@ class sale_order_line(osv.osv):
|
|||
pu = 0.0
|
||||
if uosqty:
|
||||
pu = round(line.price_unit * line.product_uom_qty / uosqty,
|
||||
self.pool.get('decimal.precision').precision_get(cr, uid, 'Sale Price'))
|
||||
self.pool.get('decimal.precision').precision_get(cr, uid, 'Product Price'))
|
||||
fpos = line.order_id.fiscal_position or False
|
||||
account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, account_id)
|
||||
if not account_id:
|
||||
|
|
|
@ -39,7 +39,7 @@ class sale_advance_payment_inv(osv.osv_memory):
|
|||
'product_id': fields.many2one('product.product', 'Advance Product',
|
||||
help="""Select a product of type service which is called 'Advance Product'.
|
||||
You may have to create it and set it as a default value on this field."""),
|
||||
'amount': fields.float('Advance Amount', digits_compute= dp.get_precision('Sale Price'),
|
||||
'amount': fields.float('Advance Amount', digits_compute= dp.get_precision('Account'),
|
||||
help="The amount to be invoiced in advance."),
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ class share_wizard(osv.TransientModel):
|
|||
}
|
||||
|
||||
def has_email(self, cr, uid, context=None):
|
||||
return bool(self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email)
|
||||
return bool(self.pool.get('res.users').browse(cr, uid, uid, context=context).email)
|
||||
|
||||
def go_step_1(self, cr, uid, ids, context=None):
|
||||
wizard_data = self.browse(cr,uid,ids,context)[0]
|
||||
|
@ -241,7 +241,7 @@ class share_wizard(osv.TransientModel):
|
|||
if not wizard_data.invite:
|
||||
existing = user_obj.search(cr, UID_ROOT, [('login', '=', new_user)])
|
||||
else:
|
||||
existing = user_obj.search(cr, UID_ROOT, [('user_email', '=', new_user)])
|
||||
existing = user_obj.search(cr, UID_ROOT, [('email', '=', new_user)])
|
||||
existing_ids.extend(existing)
|
||||
if existing:
|
||||
new_line = { 'user_id': existing[0],
|
||||
|
@ -253,7 +253,7 @@ class share_wizard(osv.TransientModel):
|
|||
'login': new_user,
|
||||
'password': new_pass,
|
||||
'name': new_user,
|
||||
'user_email': new_user,
|
||||
'email': new_user,
|
||||
'groups_id': [(6,0,[group_id])],
|
||||
'share': True,
|
||||
'message_email_pref': 'all',
|
||||
|
@ -825,12 +825,12 @@ class share_wizard(osv.TransientModel):
|
|||
message_obj = self.pool.get('mail.message')
|
||||
notification_obj = self.pool.get('mail.notification')
|
||||
user = self.pool.get('res.users').browse(cr, UID_ROOT, uid)
|
||||
if not user.user_email:
|
||||
if not user.email:
|
||||
raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.'))
|
||||
|
||||
# TODO: also send an HTML version of this mail
|
||||
for result_line in wizard_data.result_line_ids:
|
||||
email_to = result_line.user_id.user_email
|
||||
email_to = result_line.user_id.email
|
||||
if not email_to:
|
||||
continue
|
||||
subject = _('Invitation to collaborate about %s') % (wizard_data.record_name)
|
||||
|
@ -849,20 +849,20 @@ class share_wizard(osv.TransientModel):
|
|||
body += "--\n"
|
||||
body += _("OpenERP is a powerful and user-friendly suite of Business Applications (CRM, Sales, HR, etc.)\n"
|
||||
"It is open source and can be found on http://www.openerp.com.")
|
||||
msg_id = message_obj.schedule_with_attach(cr, uid, user.user_email, [email_to], subject, body, model='', context=context)
|
||||
msg_id = message_obj.schedule_with_attach(cr, uid, user.email, [email_to], subject, body, model='', context=context)
|
||||
notification_obj.create(cr, uid, {'user_id': result_line.user_id.id, 'message_id': msg_id}, context=context)
|
||||
|
||||
def send_emails(self, cr, uid, wizard_data, context=None):
|
||||
_logger.info('Sending share notifications by email...')
|
||||
mail_message = self.pool.get('mail.message')
|
||||
user = self.pool.get('res.users').browse(cr, UID_ROOT, uid)
|
||||
if not user.user_email:
|
||||
if not user.email:
|
||||
raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.'))
|
||||
|
||||
# TODO: also send an HTML version of this mail
|
||||
msg_ids = []
|
||||
for result_line in wizard_data.result_line_ids:
|
||||
email_to = result_line.user_id.user_email
|
||||
email_to = result_line.user_id.email
|
||||
if not email_to:
|
||||
continue
|
||||
subject = wizard_data.name
|
||||
|
@ -883,7 +883,7 @@ class share_wizard(osv.TransientModel):
|
|||
body += "--\n"
|
||||
body += _("OpenERP is a powerful and user-friendly suite of Business Applications (CRM, Sales, HR, etc.)\n"
|
||||
"It is open source and can be found on http://www.openerp.com.")
|
||||
msg_ids.append(mail_message.schedule_with_attach(cr, uid, user.user_email, [email_to], subject, body, model='share.wizard', context=context))
|
||||
msg_ids.append(mail_message.schedule_with_attach(cr, uid, user.email, [email_to], subject, body, model='share.wizard', context=context))
|
||||
# force direct delivery, as users expect instant notification
|
||||
mail_message.send(cr, uid, msg_ids, context=context)
|
||||
_logger.info('%d share notification(s) sent.', len(msg_ids))
|
||||
|
|
|
@ -740,7 +740,7 @@ class survey_request(osv.osv):
|
|||
if user_id:
|
||||
user_obj = self.pool.get('res.users')
|
||||
user = user_obj.browse(cr, uid, user_id, context=context)
|
||||
return {'value': {'email': user.user_email}}
|
||||
return {'value': {'email': user.email}}
|
||||
return {}
|
||||
|
||||
survey_request()
|
||||
|
|
|
@ -414,8 +414,8 @@ class survey_question_wiz(osv.osv_memory):
|
|||
file.close()
|
||||
os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
|
||||
|
||||
user_email = user_obj.browse(cr, uid, uid, context).user_email
|
||||
resp_email = survey_data.responsible_id and survey_data.responsible_id.user_email or False
|
||||
user_email = user_obj.browse(cr, uid, uid, context).email
|
||||
resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
|
||||
|
||||
if user_email and resp_email:
|
||||
user_name = user_obj.browse(cr, uid, uid, context=context).name
|
||||
|
|
Loading…
Reference in New Issue