[MERGE] forward port of branch 8.0 up to 9c8b99a

This commit is contained in:
Christophe Simonis
2015-09-04 18:30:48 +02:00
20 changed files with 148 additions and 73 deletions
+1 -1
View File
@@ -73,7 +73,7 @@
<group>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id, parent.date_invoice)" groups="account.group_account_user"/>
<field name="invoice_line_tax_id" context="{'type':parent.get('type')}" domain="[('parent_id','=',False),('company_id', '=', parent.company_id)]" widget="many2many_tags"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id)], ('state','not in',('close','cancelled'))]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('state','not in',('close','cancelled'))]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
</group>
+1 -1
View File
@@ -40,7 +40,7 @@ class CashBox(osv.osv_memory):
def _create_bank_statement_line(self, cr, uid, box, record, context=None):
values = self._compute_values_for_statement_line(cr, uid, box, record, context=context)
return self.pool.get('account.bank.statement.line').create(cr, uid, values, context=context)
return self.pool.get('account.bank.statement').write(cr, uid, [record.id], {'line_ids': [(0, False, values)]}, context=context)
class CashBoxIn(CashBox):
@@ -39,9 +39,8 @@ class account_bank_statement(osv.osv):
res = super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
return res
def button_confirm_bank(self, cr, uid, ids, context=None):
def confirm_statement_lines(self, cr, uid, ids, context=None):
bank_statement_line_obj = self.pool.get('account.bank.statement.line')
super(account_bank_statement, self).button_confirm_bank(cr, uid, ids, context=context)
for st in self.browse(cr, uid, ids, context=context):
if st.line_ids:
line_ids = [l.id for l in st.line_ids]
@@ -51,6 +50,16 @@ class account_bank_statement(osv.osv):
bank_statement_line_obj.invalidate_cache(cr, uid, ['state'], line_ids, context=context)
return True
def button_confirm_bank(self, cr, uid, ids, context=None):
res = super(account_bank_statement, self).button_confirm_bank(cr, uid, ids, context=context)
self.confirm_statement_lines(cr, uid, ids, context=context)
return res
def button_confirm_cash(self, cr, uid, ids, context=None):
res = super(account_bank_statement, self).button_confirm_cash(cr, uid, ids, context=context)
self.confirm_statement_lines(cr, uid, ids, context=context)
return res
def button_cancel(self, cr, uid, ids, context=None):
bank_statement_line_obj = self.pool.get('account.bank.statement.line')
super(account_bank_statement, self).button_cancel(cr, uid, ids, context=context)
+1 -1
View File
@@ -252,7 +252,7 @@ class account_analytic_account(osv.osv):
_defaults = {
'type': 'normal',
'company_id': _default_company,
'code' : lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(cr, uid, 'account.analytic.account'),
'code' : lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(cr, uid, 'account.analytic.account', context=context),
'state': 'open',
'user_id': lambda self, cr, uid, ctx: uid,
'partner_id': lambda self, cr, uid, ctx: ctx.get('partner_id', False),
+3
View File
@@ -210,6 +210,9 @@ class delivery_grid(osv.osv):
quantity += q
total = (order.amount_total or 0.0) - total_delivery
ctx = context.copy()
ctx['date'] = order.date_order
total = self.pool['res.currency'].compute(cr, uid, order.currency_id.id, order.company_id.currency_id.id, total, context=ctx)
return self.get_price_from_picking(cr, uid, id, total,weight, volume, quantity, context=context)
def get_price_from_picking(self, cr, uid, id, total, weight, volume, quantity, context=None):
@@ -389,7 +389,7 @@
</div>
<label for="address_id"/>
<div>
<field name="address_id" context="{'show_address': 1}" domain= "[('is_company', '=', True )]"/>
<field name="address_id" context="{'show_address': 1}" domain= "[('is_company', '=', True )]" options="{'always_reload': True}"/>
</div>
</group>
<xpath expr="//field[@name='department_id']" position="after">
@@ -201,7 +201,7 @@ class hr_timesheet_sheet(osv.osv):
return (datetime.today() + relativedelta(weekday=0, days=-6)).strftime('%Y-%m-%d')
elif r=='year':
return time.strftime('%Y-01-01')
return time.strftime('%Y-%m-%d')
return fields.date.context_today(self, cr, uid, context)
def _default_date_to(self, cr, uid, context=None):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@@ -212,7 +212,7 @@ class hr_timesheet_sheet(osv.osv):
return (datetime.today() + relativedelta(weekday=6)).strftime('%Y-%m-%d')
elif r=='year':
return time.strftime('%Y-12-31')
return time.strftime('%Y-%m-%d')
return fields.date.context_today(self, cr, uid, context)
def _default_employee(self, cr, uid, context=None):
emp_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)], context=context)
@@ -418,8 +418,12 @@ class hr_attendance(osv.osv):
INNER JOIN resource_resource r
ON (e.resource_id = r.id)
ON (a.employee_id = e.id)
WHERE %(date_to)s >= date_trunc('day', a.name)
AND %(date_from)s <= a.name
LEFT JOIN res_users u
ON r.user_id = u.id
LEFT JOIN res_partner p
ON u.partner_id = p.id
WHERE %(date_to)s >= date_trunc('day', a.name AT TIME ZONE 'UTC' AT TIME ZONE coalesce(p.tz, 'UTC'))
AND %(date_from)s <= date_trunc('day', a.name AT TIME ZONE 'UTC' AT TIME ZONE coalesce(p.tz, 'UTC'))
AND %(user_id)s = r.user_id
GROUP BY a.id""", {'date_from': ts.date_from,
'date_to': ts.date_to,
+1 -1
View File
@@ -1408,7 +1408,7 @@ class pos_order_line(osv.osv):
}
_defaults = {
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(cr, uid, 'pos.order.line'),
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(cr, uid, 'pos.order.line', context=context),
'qty': lambda *a: 1,
'discount': lambda *a: 0.0,
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
+2 -2
View File
@@ -346,7 +346,7 @@ class purchase_order(osv.osv):
def create(self, cr, uid, vals, context=None):
if vals.get('name','/')=='/':
vals['name'] = self.pool.get('ir.sequence').next_by_code(cr, uid, 'purchase.order') or '/'
vals['name'] = self.pool.get('ir.sequence').next_by_code(cr, uid, 'purchase.order', context=context) or '/'
context = dict(context or {}, mail_create_nolog=True)
order = super(purchase_order, self).create(cr, uid, vals, context=context)
self.message_post(cr, uid, [order], body=_("RFQ created"), context=context)
@@ -1642,7 +1642,7 @@ class procurement_order(osv.osv):
value_lines = self._get_po_line_values_from_procs(cr, uid, procurements, partner, schedule_date, context=context)
line_values += [(0, 0, value_lines[x]) for x in value_lines.keys()]
name = seq_obj.next_by_code(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
name = seq_obj.next_by_code(cr, uid, 'purchase.order', context=context) or _('PO: %s') % procurement.name
gpo = procurement.rule_id.group_propagation_option
group = (gpo == 'fixed' and procurement.rule_id.group_id.id) or (gpo == 'propagate' and procurement.group_id.id) or False
fp = acc_pos_obj.get_fiscal_position(cr, uid, None, partner.id, context=context)
+13 -11
View File
@@ -30,6 +30,7 @@ from openerp.osv import fields, osv
from openerp.tools.float_utils import float_compare
from openerp.tools.translate import _
from openerp.exceptions import UserError
import pytz
class resource_calendar(osv.osv):
""" Calendar model for a resource. It has
@@ -345,22 +346,23 @@ class resource_calendar(osv.osv):
return intervals
working_intervals = []
tz_info = fields.datetime.context_timestamp(cr, uid, work_dt, context=context).tzinfo
for calendar_working_day in self.get_attendances_for_weekday(cr, uid, id, start_dt, context=context):
if context and context.get('no_round_hours'):
min_from = int((calendar_working_day.hour_from - int(calendar_working_day.hour_from)) * 60)
min_to = int((calendar_working_day.hour_to - int(calendar_working_day.hour_to)) * 60)
working_interval = (
work_dt.replace(hour=int(calendar_working_day.hour_from), minute=min_from),
work_dt.replace(hour=int(calendar_working_day.hour_to), minute=min_to),
calendar_working_day.id,
)
dt_f = work_dt.replace(hour=int(calendar_working_day.hour_from), minute=min_from)
dt_t = work_dt.replace(hour=int(calendar_working_day.hour_to), minute=min_to)
else:
working_interval = (
work_dt.replace(hour=int(calendar_working_day.hour_from)),
work_dt.replace(hour=int(calendar_working_day.hour_to)),
calendar_working_day.id,
)
dt_f = work_dt.replace(hour=int(calendar_working_day.hour_from))
dt_t = work_dt.replace(hour=int(calendar_working_day.hour_to))
# adapt tz
working_interval = (
dt_f.replace(tzinfo=tz_info).astimezone(pytz.UTC).replace(tzinfo=None),
dt_t.replace(tzinfo=tz_info).astimezone(pytz.UTC).replace(tzinfo=None),
calendar_working_day.id
)
working_intervals += self.interval_remove_leaves(cr, uid, working_interval, work_limits, context=context)
# find leave intervals
@@ -620,7 +622,7 @@ class resource_calendar(osv.osv):
for dt_str, hours, calendar_id in date_and_hours_by_cal:
result = self.schedule_hours(
cr, uid, calendar_id, hours,
day_dt=datetime.datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S').replace(minute=0, second=0),
day_dt=datetime.datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S').replace(second=0),
compute_leaves=True, resource_id=resource,
default_interval=(8, 16)
)
+23 -22
View File
@@ -154,13 +154,13 @@ class TestResource(TestResourceCommon):
_format = '%Y-%m-%d %H:%M:%S'
# Test: day0 without leaves: 1 interval
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1)
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1, context={'tz': 'UTC'})
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 09:08:07', _format), 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working intervals')
# Test: day3 without leaves: 2 interval
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date2)
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date2, context={'tz': 'UTC'})
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][0], datetime.strptime('2013-02-15 10:11:12', _format), 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][1], datetime.strptime('2013-02-15 13:00:00', _format), 'resource_calendar: wrong working intervals')
@@ -168,7 +168,7 @@ class TestResource(TestResourceCommon):
self.assertEqual(intervals[1][1], datetime.strptime('2013-02-15 23:00:00', _format), 'resource_calendar: wrong working intervals')
# Test: day0 with leaves outside range: 1 interval
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=0), compute_leaves=True)
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=0), compute_leaves=True, context={'tz': 'UTC'})
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 08:00:00', _format), 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working intervals')
@@ -177,7 +177,7 @@ class TestResource(TestResourceCommon):
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id,
start_dt=self.date1.replace(hour=8) + relativedelta(days=7),
end_dt=self.date1.replace(hour=15, minute=45, second=30) + relativedelta(days=7),
compute_leaves=True)
compute_leaves=True, context={'tz': 'UTC'})
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][0], datetime.strptime('2013-02-19 08:08:07', _format), 'resource_calendar: wrong working intervals')
self.assertEqual(intervals[0][1], datetime.strptime('2013-02-19 09:00:00', _format), 'resource_calendar: wrong working intervals')
@@ -190,18 +190,18 @@ class TestResource(TestResourceCommon):
_format = '%Y-%m-%d %H:%M:%S'
# Test: day1, beginning at 10:30 -> work from 10:30 (arrival) until 16:00
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0))
intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0), context={'tz': 'UTC'})
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval / day computing')
self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 10:30:00', _format), 'resource_calendar: wrong working interval / day computing')
self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working interval / day computing')
# Test: hour computation for same interval, should give 5.5
wh = self.resource_calendar.get_working_hours_of_date(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0))
wh = self.resource_calendar.get_working_hours_of_date(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0), context={'tz': 'UTC'})
self.assertEqual(wh, 5.5, 'resource_calendar: wrong working interval / day time computing')
# Test: day1+7 on leave, without leave computation
intervals = self.resource_calendar.get_working_intervals_of_day(
cr, uid, self.calendar_id,
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7)
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7), context={'tz': 'UTC'}
)
# Result: day1 (08->16)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
@@ -212,7 +212,7 @@ class TestResource(TestResourceCommon):
intervals = self.resource_calendar.get_working_intervals_of_day(
cr, uid, self.calendar_id,
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7),
compute_leaves=True
compute_leaves=True, context={'tz': 'UTC'}
)
# Result: day1 (08->09 + 12->16)
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working interval/day computing')
@@ -225,7 +225,7 @@ class TestResource(TestResourceCommon):
intervals = self.resource_calendar.get_working_intervals_of_day(
cr, uid, self.calendar_id,
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
compute_leaves=True
compute_leaves=True, context={'tz': 'UTC'}
)
# Result: day1 (08->16)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
@@ -237,7 +237,7 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id,
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
compute_leaves=True,
resource_id=self.resource1_id
resource_id=self.resource1_id, context={'tz': 'UTC'}
)
# Result: nothing, because on leave
self.assertEqual(len(intervals), 0, 'resource_calendar: wrong working interval/day computing')
@@ -269,7 +269,7 @@ class TestResource(TestResourceCommon):
# (datetime.datetime(2013, 2, 8, 16, 0), datetime.datetime(2013, 2, 8, 23, 0))
# (datetime.datetime(2013, 2, 12, 8, 0), datetime.datetime(2013, 2, 12, 9, 0))
res = self.resource_calendar.schedule_hours(cr, uid, self.calendar_id, -40, day_dt=self.date1.replace(minute=0, second=0))
res = self.resource_calendar.schedule_hours(cr, uid, self.calendar_id, -40, day_dt=self.date1.replace(minute=0, second=0), context={'tz': 'UTC'})
# current day, limited at 09:00 because of day_dt specified -> 1 hour
self.assertEqual(res[-1][0], datetime.strptime('2013-02-12 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
self.assertEqual(res[-1][1], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
@@ -308,7 +308,7 @@ class TestResource(TestResourceCommon):
res = self.resource_calendar.schedule_hours(
cr, uid, self.calendar_id, 40,
day_dt=self.date1.replace(minute=0, second=0)
day_dt=self.date1.replace(minute=0, second=0), context={'tz': 'UTC'}
)
self.assertEqual(res[0][0], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
self.assertEqual(res[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
@@ -342,7 +342,8 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id, 40,
day_dt=self.date1.replace(minute=0, second=0),
compute_leaves=True,
resource_id=self.resource1_id
resource_id=self.resource1_id,
context={'tz': 'UTC'}
)
self.assertEqual(res[0][0], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
self.assertEqual(res[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
@@ -377,7 +378,7 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id,
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
resource_id=self.resource1_id, exclude_leaves=True)
resource_id=self.resource1_id, exclude_leaves=True, context={'tz': 'UTC'})
self.assertEqual(res, 40.0, 'resource_calendar: wrong _interval_hours_get compatibility computation')
# new API: resource without leaves
@@ -386,7 +387,7 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id,
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
compute_leaves=False, resource_id=self.resource1_id)
compute_leaves=False, resource_id=self.resource1_id, context={'tz': 'UTC'})
self.assertEqual(res, 40.0, 'resource_calendar: wrong get_working_hours computation')
# old API: resource and leaves
@@ -395,7 +396,7 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id,
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
resource_id=self.resource1_id, exclude_leaves=False)
resource_id=self.resource1_id, exclude_leaves=False, context={'tz': 'UTC'})
self.assertEqual(res, 33.0, 'resource_calendar: wrong _interval_hours_get compatibility computation')
# new API: resource and leaves
@@ -404,7 +405,7 @@ class TestResource(TestResourceCommon):
cr, uid, self.calendar_id,
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
compute_leaves=True, resource_id=self.resource1_id)
compute_leaves=True, resource_id=self.resource1_id, context={'tz': 'UTC'})
self.assertEqual(res, 33.0, 'resource_calendar: wrong get_working_hours computation')
# --------------------------------------------------
@@ -417,7 +418,7 @@ class TestResource(TestResourceCommon):
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0),
compute_leaves=True, resource_id=self.resource1_id,
default_interval=(8, 16))
default_interval=(8, 16), context={'tz': 'UTC'})
self.assertEqual(res, 32.0, 'resource_calendar: wrong get_working_hours computation')
def test_50_calendar_schedule_days(self):
@@ -429,14 +430,14 @@ class TestResource(TestResourceCommon):
# Test1: with calendar
# --------------------------------------------------
res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, 5, day_date=self.date1)
res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, 5, day_date=self.date1, context={'tz': 'UTC'})
self.assertEqual(res.date(), datetime.strptime('2013-02-26 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, -2, day_date=self.date1)
res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, -2, day_date=self.date1, context={'tz': 'UTC'})
self.assertEqual(res.date(), datetime.strptime('2013-02-08 00:00:00', _format).date(), 'resource_calendar: wrong days scheduling')
res = self.resource_calendar.schedule_days_get_date(
cr, uid, self.calendar_id, 5, day_date=self.date1,
compute_leaves=True, resource_id=self.resource1_id)
compute_leaves=True, resource_id=self.resource1_id, context={'tz': 'UTC'})
self.assertEqual(res.date(), datetime.strptime('2013-03-01 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
# --------------------------------------------------
@@ -444,7 +445,7 @@ class TestResource(TestResourceCommon):
# --------------------------------------------------
# Without calendar, should only count days -> 12 -> 16, 5 days with default intervals
res = self.resource_calendar.schedule_days_get_date(cr, uid, None, 5, day_date=self.date1, default_interval=(8, 16))
res = self.resource_calendar.schedule_days_get_date(cr, uid, None, 5, day_date=self.date1, default_interval=(8, 16), context={'tz': 'UTC'})
self.assertEqual(res, datetime.strptime('2013-02-16 16:00:00', _format), 'resource_calendar: wrong days scheduling')
def seconds(td):
+2 -2
View File
@@ -2702,9 +2702,9 @@ class stock_inventory(osv.osv):
if stock_settings.group_stock_tracking_owner:
res_filter.append(('owner', _('One owner only')))
res_filter.append(('product_owner', _('One product for a specific owner')))
if stock_settings.group_stock_tracking_lot:
if stock_settings.group_stock_production_lot:
res_filter.append(('lot', _('One Lot/Serial Number')))
if stock_settings.group_stock_packaging:
if stock_settings.group_stock_tracking_lot:
res_filter.append(('pack', _('A Pack')))
return res_filter
+5 -1
View File
@@ -33,6 +33,7 @@ import openerp
import openerp.modules.registry
from openerp.addons.base.ir.ir_qweb import AssetsBundle, QWebTemplateNotFound
from openerp.modules import get_module_resource
from openerp.service import model as service_model
from openerp.tools import topological_sort
from openerp.tools.translate import _
from openerp.tools import ustr
@@ -953,7 +954,10 @@ class DataSet(http.Controller):
if method.startswith('_'):
raise AccessError(_("Underscore prefixed methods cannot be remotely called"))
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
@service_model.check
def checked_call(__dbname, *args, **kwargs):
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
return checked_call(request.db, *args, **kwargs)
@http.route('/web/dataset/call', type='json', auth="user")
def call(self, model, method, args, domain_id=None, context_id=None):
@@ -1121,9 +1121,11 @@ define(['summernote/summernote'], function () {
saveElement: function ($el) {
// escape text nodes for xml saving
var escaped_el = $el.clone();
escaped_el.find('*').addBack().not('script,style').contents().each(function(){
var to_escape = escaped_el.find('*').addBack();
to_escape = to_escape.not(to_escape.filter('script,style,[data-oe-model][data-oe-model!="ir.ui.view"]').find('*').addBack());
to_escape.contents().each(function(){
if(this.nodeType == 3) {
this.nodeValue = _.escape(this.nodeValue);
this.nodeValue = $('<div />').text(this.nodeValue).html();
}
});
var markup = escaped_el.prop('outerHTML');
@@ -90,6 +90,12 @@ class website_hr_recruitment(http.Controller):
'default': default,
})
def _get_applicant_char_fields(self):
return ['email_from', 'partner_name', 'description']
def _get_applicant_relational_fields(self):
return ['department_id', 'job_id']
@http.route('/jobs/thankyou', methods=['POST'], type='http', auth="public", website=True)
def jobs_thankyou(self, **post):
error = {}
@@ -109,9 +115,9 @@ class website_hr_recruitment(http.Controller):
value = {
'name': '%s\'s Application' % post.get('partner_name'),
}
for f in ['email_from', 'partner_name', 'description']:
for f in self._get_applicant_char_fields():
value[f] = post.get(f)
for f in ['department_id', 'job_id']:
for f in self._get_applicant_relational_fields():
value[f] = int(post.get(f) or 0)
# Retro-compatibility for saas-3. "phone" field should be replace by "partner_phone" in the template in trunk.
value['partner_phone'] = post.pop('phone', False)
+22 -12
View File
@@ -138,24 +138,17 @@ class website_sale(http.Controller):
return attribute_value_ids
@http.route(['/shop',
'/shop/page/<int:page>',
'/shop/category/<model("product.public.category"):category>',
'/shop/category/<model("product.public.category"):category>/page/<int:page>'
], type='http', auth="public", website=True)
def shop(self, page=0, category=None, search='', **post):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
def _get_search_domain(self, search, category, attrib_values):
domain = request.website.sale_product_domain()
if search:
for srch in search.split(" "):
domain += ['|', '|', '|', ('name', 'ilike', srch), ('description', 'ilike', srch),
domain += [
'|', '|', '|', ('name', 'ilike', srch), ('description', 'ilike', srch),
('description_sale', 'ilike', srch), ('product_variant_ids.default_code', 'ilike', srch)]
if category:
domain += [('public_categ_ids', 'child_of', int(category))]
attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [map(int,v.split("-")) for v in attrib_list if v]
attrib_set = set([v[1] for v in attrib_values])
if attrib_values:
attrib = None
@@ -173,6 +166,23 @@ class website_sale(http.Controller):
if attrib:
domain += [('attribute_line_ids.value_ids', 'in', ids)]
return domain
@http.route([
'/shop',
'/shop/page/<int:page>',
'/shop/category/<model("product.public.category"):category>',
'/shop/category/<model("product.public.category"):category>/page/<int:page>'
], type='http', auth="public", website=True)
def shop(self, page=0, category=None, search='', **post):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [map(int, v.split("-")) for v in attrib_list if v]
attrib_set = set([v[1] for v in attrib_values])
domain = self._get_search_domain(search, category, attrib_values)
keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list)
if not context.get('pricelist'):
+8
View File
@@ -38,6 +38,7 @@ class mother(models.Model):
_inherit = 'test.inherit.mother'
field_in_mother = fields.Char()
partner_id = fields.Many2one('res.partner')
# extend the name field: make it required and change its default value
name = fields.Char(required=True, default='Bar')
@@ -70,3 +71,10 @@ class daughter(models.Model):
# change the default value of an inherited field
name = fields.Char(default='Baz')
class res_partner(models.Model):
_inherit = 'res.partner'
# define a one2many field based on the inherited field partner_id
daughter_ids = fields.One2many('test.inherit.daughter', 'partner_id')
@@ -64,3 +64,15 @@ class test_inherits(common.TransactionCase):
[('a', 'A'), ('b', 'B'), ('c', 'C'), ('d', 'D')])
self.assertEqual(mother._columns['state'].selection,
[('a', 'A'), ('b', 'B'), ('c', 'C'), ('d', 'D')])
def test_50_search_one2many(self):
""" check search on one2many field based on inherited many2one field. """
# create a daughter record attached to partner Demo
partner_demo = self.env.ref('base.partner_demo')
daughter = self.env['test.inherit.daughter'].create({'partner_id': partner_demo.id})
self.assertEqual(daughter.partner_id, partner_demo)
self.assertIn(daughter, partner_demo.daughter_ids)
# search the partner from the daughter record
partners = self.env['res.partner'].search([('daughter_ids', 'in', daughter.ids)])
self.assertIn(partner_demo, partners)
+13 -5
View File
@@ -4728,8 +4728,10 @@ class BaseModel(object):
context = {}
# avoid recursion through already copied records in case of circular relationship
seen_map = context.setdefault('__copy_data_seen', {})
if id in seen_map.setdefault(self._name, []):
if '__copy_data_seen' not in context:
context = dict(context, __copy_data_seen=defaultdict(list))
seen_map = context['__copy_data_seen']
if id in seen_map[self._name]:
return
seen_map[self._name].append(id)
@@ -4799,8 +4801,10 @@ class BaseModel(object):
context = {}
# avoid recursion through already copied records in case of circular relationship
seen_map = context.setdefault('__copy_translations_seen',{})
if old_id in seen_map.setdefault(self._name,[]):
if '__copy_translations_seen' not in context:
context = dict(context, __copy_translations_seen=defaultdict(list))
seen_map = context['__copy_translations_seen']
if old_id in seen_map[self._name]:
return
seen_map[self._name].append(old_id)
@@ -5369,7 +5373,11 @@ class BaseModel(object):
"""
if self:
vals = [func(rec) for rec in self]
return reduce(operator.or_, vals) if isinstance(vals[0], BaseModel) else vals
if isinstance(vals[0], BaseModel):
# return the union of all recordsets in O(n)
ids = set(itertools.chain(*[rec._ids for rec in vals]))
return vals[0].browse(ids)
return vals
else:
vals = func(self)
return vals if isinstance(vals, BaseModel) else []
+9 -3
View File
@@ -138,6 +138,7 @@ import traceback
import openerp.modules
from . import fields
from .. import SUPERUSER_ID
from ..models import MAGIC_COLUMNS, BaseModel
import openerp.tools as tools
@@ -942,11 +943,16 @@ class expression(object):
call_null = False
push(create_substitution_leaf(leaf, FALSE_LEAF, model))
else:
ids2 = select_from_where(cr, column._fields_id, comodel._table, 'id', ids2, operator)
if ids2:
# determine ids1 <-- column._fields_id --- ids2
if comodel._fields[column._fields_id].store:
ids1 = select_from_where(cr, column._fields_id, comodel._table, 'id', ids2, operator)
else:
recs = comodel.browse(cr, SUPERUSER_ID, ids2, {'prefetch_fields': False})
ids1 = recs.mapped(column._fields_id).ids
if ids1:
call_null = False
o2m_op = 'not in' if operator in NEGATIVE_TERM_OPERATORS else 'in'
push(create_substitution_leaf(leaf, ('id', o2m_op, ids2), model))
push(create_substitution_leaf(leaf, ('id', o2m_op, ids1), model))
if call_null:
o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'