[MERGE] forward port of branch saas-3 up to revid 9409 dle@openerp.com-20140415101427-a6r7lgy50x9bdah3
bzr revid: chs@openerp.com-20140415142934-rlka4vkxd34fkil8
This commit is contained in:
commit
61da3f4aba
|
@ -840,16 +840,11 @@ class account_journal(osv.osv):
|
||||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
||||||
if not args:
|
if not args:
|
||||||
args = []
|
args = []
|
||||||
if context is None:
|
if operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
context = {}
|
domain = [('code', operator, name), ('name', operator, name)]
|
||||||
ids = []
|
else:
|
||||||
if context.get('journal_type', False):
|
domain = ['|', ('code', operator, name), ('name', operator, name)]
|
||||||
args += [('type','=',context.get('journal_type'))]
|
ids = self.search(cr, user, expression.AND([domain, args]), limit=limit, context=context)
|
||||||
if name:
|
|
||||||
ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit, context=context)
|
|
||||||
if not ids:
|
|
||||||
ids = self.search(cr, user, [('name', 'ilike', name)]+ args, limit=limit, context=context)#fix it ilike should be replace with operator
|
|
||||||
|
|
||||||
return self.name_get(cr, user, ids, context=context)
|
return self.name_get(cr, user, ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -938,13 +933,11 @@ class account_fiscalyear(osv.osv):
|
||||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
|
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
|
||||||
if args is None:
|
if args is None:
|
||||||
args = []
|
args = []
|
||||||
if context is None:
|
if operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
context = {}
|
domain = [('code', operator, name), ('name', operator, name)]
|
||||||
ids = []
|
else:
|
||||||
if name:
|
domain = ['|', ('code', operator, name), ('name', operator, name)]
|
||||||
ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit)
|
ids = self.search(cr, user, expression.AND([domain, args]), limit=limit, context=context)
|
||||||
if not ids:
|
|
||||||
ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
|
|
||||||
return self.name_get(cr, user, ids, context=context)
|
return self.name_get(cr, user, ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1040,19 +1033,11 @@ class account_period(osv.osv):
|
||||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
||||||
if args is None:
|
if args is None:
|
||||||
args = []
|
args = []
|
||||||
if context is None:
|
if operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
context = {}
|
domain = [('code', operator, name), ('name', operator, name)]
|
||||||
ids = []
|
else:
|
||||||
if name:
|
domain = ['|', ('code', operator, name), ('name', operator, name)]
|
||||||
ids = self.search(cr, user,
|
ids = self.search(cr, user, expression.AND([domain, args]), limit=limit, context=context)
|
||||||
[('code', 'ilike', name)] + args,
|
|
||||||
limit=limit,
|
|
||||||
context=context)
|
|
||||||
if not ids:
|
|
||||||
ids = self.search(cr, user,
|
|
||||||
[('name', operator, name)] + args,
|
|
||||||
limit=limit,
|
|
||||||
context=context)
|
|
||||||
return self.name_get(cr, user, ids, context=context)
|
return self.name_get(cr, user, ids, context=context)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
|
@ -1187,36 +1172,6 @@ class account_move(osv.osv):
|
||||||
'company_id': company_id,
|
'company_id': company_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
|
|
||||||
"""
|
|
||||||
Returns a list of tupples containing id, name, as internally it is called {def name_get}
|
|
||||||
result format: {[(id, name), (id, name), ...]}
|
|
||||||
|
|
||||||
@param cr: A database cursor
|
|
||||||
@param user: ID of the user currently logged in
|
|
||||||
@param name: name to search
|
|
||||||
@param args: other arguments
|
|
||||||
@param operator: default operator is 'ilike', it can be changed
|
|
||||||
@param context: context arguments, like lang, time zone
|
|
||||||
@param limit: Returns first 'n' ids of complete result, default is 80.
|
|
||||||
|
|
||||||
@return: Returns a list of tuples containing id and name
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not args:
|
|
||||||
args = []
|
|
||||||
ids = []
|
|
||||||
if name:
|
|
||||||
ids += self.search(cr, user, [('name','ilike',name)]+args, limit=limit, context=context)
|
|
||||||
|
|
||||||
if not ids and name and type(name) == int:
|
|
||||||
ids += self.search(cr, user, [('id','=',name)]+args, limit=limit, context=context)
|
|
||||||
|
|
||||||
if not ids:
|
|
||||||
ids += self.search(cr, user, args, limit=limit, context=context)
|
|
||||||
|
|
||||||
return self.name_get(cr, user, ids, context=context)
|
|
||||||
|
|
||||||
def name_get(self, cursor, user, ids, context=None):
|
def name_get(self, cursor, user, ids, context=None):
|
||||||
if isinstance(ids, (int, long)):
|
if isinstance(ids, (int, long)):
|
||||||
ids = [ids]
|
ids = [ids]
|
||||||
|
@ -1842,10 +1797,12 @@ class account_tax_code(osv.osv):
|
||||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
|
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
|
||||||
if not args:
|
if not args:
|
||||||
args = []
|
args = []
|
||||||
if context is None:
|
if operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
context = {}
|
domain = [('code', operator, name), ('name', operator, name)]
|
||||||
ids = self.search(cr, user, ['|',('name',operator,name),('code',operator,name)] + args, limit=limit, context=context)
|
else:
|
||||||
return self.name_get(cr, user, ids, context)
|
domain = ['|', ('code', operator, name), ('name', operator, name)]
|
||||||
|
ids = self.search(cr, user, expression.AND([domain, args]), limit=limit, context=context)
|
||||||
|
return self.name_get(cr, user, ids, context=context)
|
||||||
|
|
||||||
def name_get(self, cr, uid, ids, context=None):
|
def name_get(self, cr, uid, ids, context=None):
|
||||||
if isinstance(ids, (int, long)):
|
if isinstance(ids, (int, long)):
|
||||||
|
@ -1974,15 +1931,11 @@ class account_tax(osv.osv):
|
||||||
"""
|
"""
|
||||||
if not args:
|
if not args:
|
||||||
args = []
|
args = []
|
||||||
if context is None:
|
if operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
context = {}
|
domain = [('description', operator, name), ('name', operator, name)]
|
||||||
ids = []
|
|
||||||
if name:
|
|
||||||
ids = self.search(cr, user, [('description', '=', name)] + args, limit=limit, context=context)
|
|
||||||
if not ids:
|
|
||||||
ids = self.search(cr, user, [('name', operator, name)] + args, limit=limit, context=context)
|
|
||||||
else:
|
else:
|
||||||
ids = self.search(cr, user, args, limit=limit, context=context or {})
|
domain = ['|', ('description', operator, name), ('name', operator, name)]
|
||||||
|
ids = self.search(cr, user, expression.AND([domain, args]), limit=limit, context=context)
|
||||||
return self.name_get(cr, user, ids, context=context)
|
return self.name_get(cr, user, ids, context=context)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
|
|
|
@ -165,7 +165,7 @@ class account_invoice_refund(osv.osv_memory):
|
||||||
to_reconcile_ids = {}
|
to_reconcile_ids = {}
|
||||||
for line in movelines:
|
for line in movelines:
|
||||||
if line.account_id.id == inv.account_id.id:
|
if line.account_id.id == inv.account_id.id:
|
||||||
to_reconcile_ids[line.account_id.id] = [line.id]
|
to_reconcile_ids.setdefault(line.account_id.id, []).append(line.id)
|
||||||
if line.reconcile_id:
|
if line.reconcile_id:
|
||||||
line.reconcile_id.unlink()
|
line.reconcile_id.unlink()
|
||||||
inv_obj.signal_invoice_open(cr, uid, [refund.id])
|
inv_obj.signal_invoice_open(cr, uid, [refund.id])
|
||||||
|
|
|
@ -162,7 +162,7 @@ class crossovered_budget_lines(osv.osv):
|
||||||
elapsed = strToDate(date_to) - strToDate(date_to)
|
elapsed = strToDate(date_to) - strToDate(date_to)
|
||||||
|
|
||||||
if total.days:
|
if total.days:
|
||||||
theo_amt = float(elapsed.days / float(total.days)) * line.planned_amount
|
theo_amt = float((elapsed.days + 1) / float(total.days + 1)) * line.planned_amount
|
||||||
else:
|
else:
|
||||||
theo_amt = line.planned_amount
|
theo_amt = line.planned_amount
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,10 @@ class calendar_attendee(osv.Model):
|
||||||
@param email_from: email address for user sending the mail
|
@param email_from: email address for user sending the mail
|
||||||
"""
|
"""
|
||||||
res = False
|
res = False
|
||||||
|
|
||||||
|
if self.pool['ir.config_parameter'].get_param(cr, uid, 'calendar.block_mail', default=False):
|
||||||
|
return res
|
||||||
|
|
||||||
mail_ids = []
|
mail_ids = []
|
||||||
data_pool = self.pool['ir.model.data']
|
data_pool = self.pool['ir.model.data']
|
||||||
mailmess_pool = self.pool['mail.message']
|
mailmess_pool = self.pool['mail.message']
|
||||||
|
@ -431,7 +435,7 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||||
if cron and len(cron) == 1:
|
if cron and len(cron) == 1:
|
||||||
cron = self.pool.get('ir.cron').browse(cr, uid, cron[0], context=context)
|
cron = self.pool.get('ir.cron').browse(cr, uid, cron[0], context=context)
|
||||||
else:
|
else:
|
||||||
raise ("Cron for " + self._name + " not identified :( !")
|
_logger.exception("Cron for " + self._name + " can not be identified !")
|
||||||
|
|
||||||
if cron.interval_type == "weeks":
|
if cron.interval_type == "weeks":
|
||||||
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
||||||
|
@ -445,7 +449,7 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||||
cron_interval = cron.interval_number
|
cron_interval = cron.interval_number
|
||||||
|
|
||||||
if not cron_interval:
|
if not cron_interval:
|
||||||
raise ("Cron delay for " + self._name + " can not be calculated :( !")
|
_logger.exception("Cron delay can not be computed !")
|
||||||
|
|
||||||
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
|
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
|
||||||
|
|
||||||
|
@ -649,7 +653,7 @@ class calendar_event(osv.Model):
|
||||||
_inherit = ["mail.thread", "ir.needaction_mixin"]
|
_inherit = ["mail.thread", "ir.needaction_mixin"]
|
||||||
|
|
||||||
def do_run_scheduler(self, cr, uid, id, context=None):
|
def do_run_scheduler(self, cr, uid, id, context=None):
|
||||||
self.pool['calendar.alarm_manager'].do_run_scheduler(cr, uid, context=context)
|
self.pool['calendar.alarm_manager'].get_next_mail(cr, uid, context=context)
|
||||||
|
|
||||||
def get_recurrent_date_by_event(self, cr, uid, event, context=None):
|
def get_recurrent_date_by_event(self, cr, uid, event, context=None):
|
||||||
"""Get recurrent dates based on Rule string and all event where recurrent_id is child
|
"""Get recurrent dates based on Rule string and all event where recurrent_id is child
|
||||||
|
|
|
@ -31,6 +31,7 @@ except ImportError:
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
import logging
|
import logging
|
||||||
import pytz
|
import pytz
|
||||||
|
import socket
|
||||||
import time
|
import time
|
||||||
import xmlrpclib
|
import xmlrpclib
|
||||||
from email.message import Message
|
from email.message import Message
|
||||||
|
@ -880,25 +881,30 @@ class mail_thread(osv.AbstractModel):
|
||||||
# 2. message is a reply to an existign thread (6.1 compatibility)
|
# 2. message is a reply to an existign thread (6.1 compatibility)
|
||||||
ref_match = thread_references and tools.reference_re.search(thread_references)
|
ref_match = thread_references and tools.reference_re.search(thread_references)
|
||||||
if ref_match:
|
if ref_match:
|
||||||
thread_id = int(ref_match.group(1))
|
reply_thread_id = int(ref_match.group(1))
|
||||||
model = ref_match.group(2) or fallback_model
|
reply_model = ref_match.group(2) or fallback_model
|
||||||
if thread_id and model in self.pool:
|
reply_hostname = ref_match.group(3)
|
||||||
model_obj = self.pool[model]
|
local_hostname = socket.gethostname()
|
||||||
compat_mail_msg_ids = mail_msg_obj.search(
|
# do not match forwarded emails from another OpenERP system (thread_id collision!)
|
||||||
cr, uid, [
|
if local_hostname == reply_hostname:
|
||||||
('message_id', '=', False),
|
thread_id, model = reply_thread_id, reply_model
|
||||||
('model', '=', model),
|
if thread_id and model in self.pool:
|
||||||
('res_id', '=', thread_id),
|
model_obj = self.pool[model]
|
||||||
], context=context)
|
compat_mail_msg_ids = mail_msg_obj.search(
|
||||||
if compat_mail_msg_ids and model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
|
cr, uid, [
|
||||||
_logger.info(
|
('message_id', '=', False),
|
||||||
'Routing mail from %s to %s with Message-Id %s: direct thread reply (compat-mode) to model: %s, thread_id: %s, custom_values: %s, uid: %s',
|
('model', '=', model),
|
||||||
email_from, email_to, message_id, model, thread_id, custom_values, uid)
|
('res_id', '=', thread_id),
|
||||||
route = self.message_route_verify(
|
], context=context)
|
||||||
cr, uid, message, message_dict,
|
if compat_mail_msg_ids and model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
|
||||||
(model, thread_id, custom_values, uid, None),
|
_logger.info(
|
||||||
update_author=True, assert_model=True, create_fallback=True, context=context)
|
'Routing mail from %s to %s with Message-Id %s: direct thread reply (compat-mode) to model: %s, thread_id: %s, custom_values: %s, uid: %s',
|
||||||
return route and [route] or []
|
email_from, email_to, message_id, model, thread_id, custom_values, uid)
|
||||||
|
route = self.message_route_verify(
|
||||||
|
cr, uid, message, message_dict,
|
||||||
|
(model, thread_id, custom_values, uid, None),
|
||||||
|
update_author=True, assert_model=True, create_fallback=True, context=context)
|
||||||
|
return route and [route] or []
|
||||||
|
|
||||||
# 2. Reply to a private message
|
# 2. Reply to a private message
|
||||||
if in_reply_to:
|
if in_reply_to:
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
from openerp.addons.mail.tests.common import TestMail
|
from openerp.addons.mail.tests.common import TestMail
|
||||||
from openerp.tools import mute_logger
|
from openerp.tools import mute_logger
|
||||||
|
import socket
|
||||||
|
|
||||||
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
||||||
To: {to}
|
To: {to}
|
||||||
|
@ -400,13 +401,15 @@ class TestMailgateway(TestMail):
|
||||||
to='noone@example.com', subject='spam',
|
to='noone@example.com', subject='spam',
|
||||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id,
|
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id,
|
||||||
msg_id='<1.1.JavaMail.new@agrolait.com>')
|
msg_id='<1.1.JavaMail.new@agrolait.com>')
|
||||||
# There are 6.1 messages, activate compat mode
|
|
||||||
|
# When 6.1 messages are present, compat mode is available
|
||||||
|
# Create a fake 6.1 message
|
||||||
tmp_msg_id = self.mail_message.create(cr, uid, {'message_id': False, 'model': 'mail.group', 'res_id': frog_group.id})
|
tmp_msg_id = self.mail_message.create(cr, uid, {'message_id': False, 'model': 'mail.group', 'res_id': frog_group.id})
|
||||||
# Do: compat mode accepts partial-matching emails
|
# Do: compat mode accepts partial-matching emails
|
||||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other5@gmail.com',
|
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||||
msg_id='<1.2.JavaMail.new@agrolait.com>',
|
msg_id='<1.2.JavaMail.new@agrolait.com>',
|
||||||
to='noone@example.com>', subject='spam',
|
to='noone@example.com>', subject='spam',
|
||||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id)
|
extra='In-Reply-To: <12321321-openerp-%d-mail.group@%s>' % (frog_group.id, socket.gethostname()))
|
||||||
self.mail_message.unlink(cr, uid, [tmp_msg_id])
|
self.mail_message.unlink(cr, uid, [tmp_msg_id])
|
||||||
# Test: no group 'Re: news' created, still only 1 Frogs group
|
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||||
self.assertEqual(len(frog_groups), 0,
|
self.assertEqual(len(frog_groups), 0,
|
||||||
|
@ -418,6 +421,17 @@ class TestMailgateway(TestMail):
|
||||||
# Test: one new message
|
# Test: one new message
|
||||||
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: group should contain 4 messages after reply')
|
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: group should contain 4 messages after reply')
|
||||||
|
|
||||||
|
# 6.1 compat mode should not work if hostname does not match!
|
||||||
|
tmp_msg_id = self.mail_message.create(cr, uid, {'message_id': False, 'model': 'mail.group', 'res_id': frog_group.id})
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
format_and_process,
|
||||||
|
MAIL_TEMPLATE, email_from='other5@gmail.com',
|
||||||
|
msg_id='<1.3.JavaMail.new@agrolait.com>',
|
||||||
|
to='noone@example.com>', subject='spam',
|
||||||
|
extra='In-Reply-To: <12321321-openerp-%d-mail.group@neighbor.com>' % frog_group.id)
|
||||||
|
self.mail_message.unlink(cr, uid, [tmp_msg_id])
|
||||||
|
|
||||||
|
|
||||||
# Do: due to some issue, same email goes back into the mailgateway
|
# Do: due to some issue, same email goes back into the mailgateway
|
||||||
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
|
||||||
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
|
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
|
||||||
|
@ -445,7 +459,7 @@ class TestMailgateway(TestMail):
|
||||||
|
|
||||||
# Do: post a new message, with a known partner -> duplicate emails -> partner
|
# Do: post a new message, with a known partner -> duplicate emails -> partner
|
||||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||||
to='erroneous@example.com>', subject='Re: news (2)',
|
subject='Re: news (2)',
|
||||||
msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
|
msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
|
||||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||||
|
@ -456,10 +470,9 @@ class TestMailgateway(TestMail):
|
||||||
|
|
||||||
# Do: post a new message, with a known partner -> duplicate emails -> user
|
# Do: post a new message, with a known partner -> duplicate emails -> user
|
||||||
frog_group.message_unsubscribe([extra_partner_id])
|
frog_group.message_unsubscribe([extra_partner_id])
|
||||||
raoul_email = self.user_raoul.email
|
|
||||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||||
to='erroneous@example.com>', subject='Re: news (3)',
|
to='groups@example.com', subject='Re: news (3)',
|
||||||
msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
|
msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
|
||||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||||
|
@ -474,7 +487,7 @@ class TestMailgateway(TestMail):
|
||||||
raoul_email = self.user_raoul.email
|
raoul_email = self.user_raoul.email
|
||||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||||
to='erroneous@example.com>', subject='Re: news (3)',
|
to='groups@example.com', subject='Re: news (3)',
|
||||||
msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
|
msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
|
||||||
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
|
||||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||||
|
|
|
@ -29,7 +29,7 @@ from openerp.osv import osv
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MailThread(osv.Model):
|
class MailThread(osv.AbstractModel):
|
||||||
""" Update MailThread to add the feature of bounced emails and replied emails
|
""" Update MailThread to add the feature of bounced emails and replied emails
|
||||||
in message_process. """
|
in message_process. """
|
||||||
_name = 'mail.thread'
|
_name = 'mail.thread'
|
||||||
|
|
|
@ -133,10 +133,7 @@ class purchase_order(osv.osv):
|
||||||
def _invoiced(self, cursor, user, ids, name, arg, context=None):
|
def _invoiced(self, cursor, user, ids, name, arg, context=None):
|
||||||
res = {}
|
res = {}
|
||||||
for purchase in self.browse(cursor, user, ids, context=context):
|
for purchase in self.browse(cursor, user, ids, context=context):
|
||||||
invoiced = False
|
res[purchase.id] = all(line.invoiced for line in purchase.order_line)
|
||||||
if purchase.invoiced_rate == 100.00:
|
|
||||||
invoiced = True
|
|
||||||
res[purchase.id] = invoiced
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_journal(self, cr, uid, context=None):
|
def _get_journal(self, cr, uid, context=None):
|
||||||
|
@ -542,7 +539,7 @@ class purchase_order(osv.osv):
|
||||||
inv_line_id = inv_line_obj.create(cr, uid, inv_line_data, context=context)
|
inv_line_id = inv_line_obj.create(cr, uid, inv_line_data, context=context)
|
||||||
inv_lines.append(inv_line_id)
|
inv_lines.append(inv_line_id)
|
||||||
|
|
||||||
po_line.write({'invoiced': True, 'invoice_lines': [(4, inv_line_id)]}, context=context)
|
po_line.write({'invoice_lines': [(4, inv_line_id)]}, context=context)
|
||||||
|
|
||||||
# get invoice data and create invoice
|
# get invoice data and create invoice
|
||||||
inv_data = {
|
inv_data = {
|
||||||
|
@ -1290,9 +1287,15 @@ class account_invoice(osv.Model):
|
||||||
else:
|
else:
|
||||||
user_id = uid
|
user_id = uid
|
||||||
po_ids = purchase_order_obj.search(cr, user_id, [('invoice_ids', 'in', ids)], context=context)
|
po_ids = purchase_order_obj.search(cr, user_id, [('invoice_ids', 'in', ids)], context=context)
|
||||||
for po_id in po_ids:
|
for order in purchase_order_obj.browse(cr, uid, po_ids, context=context):
|
||||||
purchase_order_obj.message_post(cr, user_id, po_id, body=_("Invoice received"), context=context)
|
purchase_order_obj.message_post(cr, user_id, order.id, body=_("Invoice received"), context=context)
|
||||||
workflow.trg_write(uid, 'purchase.order', po_id, cr)
|
invoiced = []
|
||||||
|
for po_line in order.order_line:
|
||||||
|
if any(line.invoice_id.state not in ['draft', 'cancel'] for line in po_line.invoice_lines):
|
||||||
|
invoiced.append(po_line.id)
|
||||||
|
if invoiced:
|
||||||
|
self.pool['purchase.order.line'].write(cr, uid, invoiced, {'invoiced': True})
|
||||||
|
workflow.trg_write(uid, 'purchase.order', order.id, cr)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def confirm_paid(self, cr, uid, ids, context=None):
|
def confirm_paid(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -110,7 +110,6 @@ class stock_picking(osv.osv):
|
||||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||||
purchase_line_obj = self.pool.get('purchase.order.line')
|
purchase_line_obj = self.pool.get('purchase.order.line')
|
||||||
purchase_line_obj.write(cursor, user, [move_line.purchase_line_id.id], {
|
purchase_line_obj.write(cursor, user, [move_line.purchase_line_id.id], {
|
||||||
'invoiced': True,
|
|
||||||
'invoice_lines': [(4, invoice_line_id)],
|
'invoice_lines': [(4, invoice_line_id)],
|
||||||
})
|
})
|
||||||
return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
|
return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
|
||||||
|
|
|
@ -906,6 +906,7 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
var bg = self.$target.css("background-image");
|
var bg = self.$target.css("background-image");
|
||||||
this.$el.find('li').removeClass("active");
|
this.$el.find('li').removeClass("active");
|
||||||
|
this.$el.find('li').removeClass("btn-primary");
|
||||||
var $active = this.$el.find('li[data-value]')
|
var $active = this.$el.find('li[data-value]')
|
||||||
.filter(function () {
|
.filter(function () {
|
||||||
var $li = $(this);
|
var $li = $(this);
|
||||||
|
@ -918,8 +919,13 @@
|
||||||
this.$el.find('li[data-value].oe_custom_bg') :
|
this.$el.find('li[data-value].oe_custom_bg') :
|
||||||
this.$el.find('li[data-value=""]');
|
this.$el.find('li[data-value=""]');
|
||||||
}
|
}
|
||||||
$active.addClass("active");
|
|
||||||
this.$el.find('li:has(li[data-value].active)').addClass("active");
|
//don't set active on an OpenDialog link, else it not possible to click on it again after.
|
||||||
|
// TODO in Saas-4 - Once bootstrap is in less
|
||||||
|
// - add a class active-style to get the same display but without the active behaviour used by bootstrap in JS.
|
||||||
|
var classStr = _.string.contains($active[0].className, "oe_custom_bg") ? "btn-primary" : "active";
|
||||||
|
$active.addClass(classStr);
|
||||||
|
this.$el.find('li:has(li[data-value].active)').addClass(classStr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
t-att-data-view-xmlid="xmlid if editable else None"
|
t-att-data-view-xmlid="xmlid if editable else None"
|
||||||
t-att-data-main-object="repr(main_object) if editable else None">
|
t-att-data-main-object="repr(main_object) if editable else None">
|
||||||
<head>
|
<head>
|
||||||
|
<script type="text/javascript" src="/web/static/js/watch.js"></script>
|
||||||
<t t-if="main_object and 'website_meta_title' in main_object">
|
<t t-if="main_object and 'website_meta_title' in main_object">
|
||||||
<t t-set="title" t-value="main_object.website_meta_title"/>
|
<t t-set="title" t-value="main_object.website_meta_title"/>
|
||||||
</t>
|
</t>
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
// Bootstrap and jQuery UI conflicts
|
// Bootstrap and jQuery UI conflicts
|
||||||
$.fn.bstooltip = $.fn.tooltip;
|
$.fn.bstooltip = $.fn.tooltip;
|
||||||
$.fn.bsbutton = $.fn.button;
|
$.fn.bsbutton = $.fn.button;
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
|
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
|
||||||
|
|
|
@ -129,7 +129,7 @@ class sale_quote(http.Controller):
|
||||||
order_line_obj.write(request.cr, SUPERUSER_ID, [line_id], {'product_uom_qty': (quantity)}, context=request.context)
|
order_line_obj.write(request.cr, SUPERUSER_ID, [line_id], {'product_uom_qty': (quantity)}, context=request.context)
|
||||||
return [str(quantity), str(order.amount_total)]
|
return [str(quantity), str(order.amount_total)]
|
||||||
|
|
||||||
@http.route(["/quote/template/<model('sale.quote.template'):quote>"], type='http', auth="user", website=True)
|
@http.route(["/quote/template/<model('sale.quote.template'):quote>"], type='http', auth="user", website=True, multilang=True)
|
||||||
def template_view(self, quote, **post):
|
def template_view(self, quote, **post):
|
||||||
values = { 'template': quote }
|
values = { 'template': quote }
|
||||||
return request.website.render('website_quote.so_template', values)
|
return request.website.render('website_quote.so_template', values)
|
||||||
|
|
|
@ -133,7 +133,12 @@ class sale_order(osv.osv):
|
||||||
def onchange_template_id(self, cr, uid, ids, template_id, partner=False, fiscal_position=False, context=None):
|
def onchange_template_id(self, cr, uid, ids, template_id, partner=False, fiscal_position=False, context=None):
|
||||||
if not template_id:
|
if not template_id:
|
||||||
return True
|
return True
|
||||||
lines = []
|
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
context = dict(context, lang=self.pool.get('res.partner').browse(cr, uid, partner, context).lang)
|
||||||
|
|
||||||
|
lines = [(5,)]
|
||||||
quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context)
|
quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context)
|
||||||
for line in quote_template.quote_line:
|
for line in quote_template.quote_line:
|
||||||
res = self.pool.get('sale.order.line').product_id_change(cr, uid, False,
|
res = self.pool.get('sale.order.line').product_id_change(cr, uid, False,
|
||||||
|
|
|
@ -411,7 +411,9 @@ class Ecommerce(http.Controller):
|
||||||
quantity = request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid,
|
quantity = request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid,
|
||||||
product_id=product_id, order_line_id=order_line_id, set_number=set_number,
|
product_id=product_id, order_line_id=order_line_id, set_number=set_number,
|
||||||
context=request.context)
|
context=request.context)
|
||||||
return quantity
|
order = self.get_order()
|
||||||
|
return [quantity,
|
||||||
|
order.get_number_of_products()]
|
||||||
|
|
||||||
@http.route(['/shop/checkout'], type='http', auth="public", website=True, multilang=True)
|
@http.route(['/shop/checkout'], type='http', auth="public", website=True, multilang=True)
|
||||||
def checkout(self, **post):
|
def checkout(self, **post):
|
||||||
|
@ -514,14 +516,7 @@ class Ecommerce(http.Controller):
|
||||||
if error:
|
if error:
|
||||||
return request.website.render("website_sale.checkout", values)
|
return request.website.render("website_sale.checkout", values)
|
||||||
|
|
||||||
company_name = checkout['company']
|
|
||||||
company_id = None
|
|
||||||
if post['company']:
|
|
||||||
company_ids = orm_partner.search(cr, SUPERUSER_ID, [("name", "ilike", company_name), ('is_company', '=', True)], context=context)
|
|
||||||
company_id = (company_ids and company_ids[0]) or orm_partner.create(cr, SUPERUSER_ID, {'name': company_name, 'is_company': True}, context)
|
|
||||||
|
|
||||||
billing_info = dict((k, v) for k,v in checkout.items() if "shipping_" not in k and k != "company")
|
billing_info = dict((k, v) for k,v in checkout.items() if "shipping_" not in k and k != "company")
|
||||||
billing_info['parent_id'] = company_id
|
|
||||||
|
|
||||||
partner_id = None
|
partner_id = None
|
||||||
public_id = request.registry['website'].get_public_user(cr, uid, context)
|
public_id = request.registry['website'].get_public_user(cr, uid, context)
|
||||||
|
@ -542,7 +537,8 @@ class Ecommerce(http.Controller):
|
||||||
shipping_info = {
|
shipping_info = {
|
||||||
'phone': post['shipping_phone'],
|
'phone': post['shipping_phone'],
|
||||||
'zip': post['shipping_zip'],
|
'zip': post['shipping_zip'],
|
||||||
'street': post['shipping_street'],
|
'street': checkout['company'],
|
||||||
|
'street2': post['shipping_street'],
|
||||||
'city': post['shipping_city'],
|
'city': post['shipping_city'],
|
||||||
'name': post['shipping_name'],
|
'name': post['shipping_name'],
|
||||||
'email': post['email'],
|
'email': post['email'],
|
||||||
|
|
Loading…
Reference in New Issue