Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions addons/account/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,19 @@ class account_move(osv.osv):
_description = "Account Entry"
_order = 'id desc'

def account_assert_balanced(self, cr, uid, context=None):
cr.execute("""\
SELECT move_id
FROM account_move_line
WHERE state = 'valid'
GROUP BY move_id
HAVING abs(sum(debit) - sum(credit)) > 0.00001
""")
assert len(cr.fetchall()) == 0, \
"For all Journal Items, the state is valid implies that the sum " \
"of credits equals the sum of debits"
return True

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}
Expand Down
4 changes: 1 addition & 3 deletions addons/account/account_assert_test.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<assert model="account.move" search="[]" string="For all Journal Items, the state is valid implies that the sum of credits equals the sum of debits">
<test expr="not len(line_id) or line_id[0].state != 'valid' or (sum([l.debit - l.credit for l in line_id]) &lt;= 0.00001)"/>
</assert>
<function name="account_assert_balanced" model="account.move"/>
</data>
</openerp>
4 changes: 2 additions & 2 deletions addons/account/account_invoice_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
<field name="uos_id" on_change="uos_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.address_invoice_id, parent.currency_id, context, parent.company_id)" nolabel="1"/>
</group>
<field name="price_unit"/>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(parent.fiscal_position,account_id)"/>
<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)"/>
<field name="discount" groups="base.group_extended"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
Expand Down Expand Up @@ -171,7 +171,7 @@
<field colspan="4" context="{'address_invoice_id': address_invoice_id, 'partner_id': partner_id, 'price_type': 'price_type' in dir() and price_type or False, 'type': type}" name="invoice_line" nolabel="1">
<tree string="Invoice lines">
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.address_invoice_id, parent.currency_id, context, parent.company_id)"/>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(parent.fiscal_position,account_id)"/>
<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)"/>
<field name="invoice_line_tax_id" view_mode="2" context="{'type':parent.type}" domain="[('parent_id','=',False)]"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="quantity"/>
Expand Down
8 changes: 4 additions & 4 deletions addons/account_followup/account_followup_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
<openerp>
<data noupdate="1">

<record id="demo_followup1" model="account_followup.followup">
<record id="demo_followup1" model="account_followup.followup" forcecreate="False">
<field name="name">Default Follow-Up</field>
<field name="company_id" ref="base.main_company"/>
<field name="description">First letter after 15 net days, 30 net days and 45 days end of month levels.</field>
</record>

<record id="demo_followup_line1" model="account_followup.followup.line">
<record id="demo_followup_line1" model="account_followup.followup.line" forcecreate="False">
<field name="name">Level 0 : 15 net days</field>
<field name="sequence">0</field>
<field name="start">days</field>
Expand All @@ -25,7 +25,7 @@ Best Regards,
</field>
</record>

<record id="demo_followup_line2" model="account_followup.followup.line">
<record id="demo_followup_line2" model="account_followup.followup.line" forcecreate="False">
<field name="name">Level 1 : 30 net days</field>
<field name="sequence">1</field>
<field name="start">days</field>
Expand All @@ -47,7 +47,7 @@ Best Regards,
</field>
</record>

<record id="demo_followup_line3" model="account_followup.followup.line">
<record id="demo_followup_line3" model="account_followup.followup.line" forcecreate="False">
<field name="name">Level 2 : 45 days end of month</field>
<field name="sequence">2</field>
<field name="start">end_of_month</field>
Expand Down
2 changes: 1 addition & 1 deletion addons/product/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ def _calc_qty(self, cr, uid, ids, fields, arg, context=None):
'company_id':fields.many2one('res.company','Company',select=1),
}
_defaults = {
'qty': lambda *a: 0.0,
'min_qty': lambda *a: 0.0,
'sequence': lambda *a: 1,
'delay': lambda *a: 1,
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'product.supplierinfo', context=c),
Expand Down
Binary file removed addons/thunderbird/plugin/openerp_plugin.xpi.THIS
Binary file not shown.
Binary file not shown.
4 changes: 2 additions & 2 deletions addons/web/static/src/js/views.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ session.web.ViewManager = session.web.OldWidget.extend(/** @lends session.web.V
var container = $("#" + this.element_id + '_view_' + view_type);
view_promise = controller.appendTo(container);
this.views[view_type].controller = controller;
this.views[view_type].deferred.resolve(view_type);
$.when(view_promise).then(function() {
self.views[view_type].deferred.resolve(view_type);
self.on_controller_inited(view_type, controller);
if (self.searchview
&& self.flags.auto_search
Expand Down Expand Up @@ -701,7 +701,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
);
}

$.when(defs).then(function() {
$.when(this.views[this.active_view] ? this.views[this.active_view].deferred : $.when(), defs).then(function() {
self.views[self.active_view].controller.do_load_state(state, warm);
});
},
Expand Down
13 changes: 8 additions & 5 deletions openerp/addons/base/ir/ir_cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
import psycopg2
from datetime import datetime
from dateutil.relativedelta import relativedelta
import pytz

import netsvc
import openerp
import pooler
import tools
from openerp import SUPERUSER_ID
from openerp.cron import WAKE_UP_NOW
from osv import fields, osv
from tools import DEFAULT_SERVER_DATETIME_FORMAT
Expand Down Expand Up @@ -161,7 +163,8 @@ def _run_job(self, cr, job, now):

"""
try:
nextcall = datetime.strptime(job['nextcall'], DEFAULT_SERVER_DATETIME_FORMAT)
now = fields.datetime.context_timestamp(cr, job['user_id'], now)
nextcall = fields.datetime.context_timestamp(cr, job['user_id'], datetime.strptime(job['nextcall'], DEFAULT_SERVER_DATETIME_FORMAT))
numbercall = job['numbercall']

ok = False
Expand All @@ -177,7 +180,7 @@ def _run_job(self, cr, job, now):
if not numbercall:
addsql = ', active=False'
cr.execute("UPDATE ir_cron SET nextcall=%s, numbercall=%s"+addsql+" WHERE id=%s",
(nextcall.strftime(DEFAULT_SERVER_DATETIME_FORMAT), numbercall, job['id']))
(nextcall.astimezone(pytz.UTC).strftime(DEFAULT_SERVER_DATETIME_FORMAT), numbercall, job['id']))

if numbercall:
# Reschedule our own main cron thread if necessary.
Expand Down Expand Up @@ -287,8 +290,8 @@ def _process_job(self, cr, job):
:param job: job to be run (as a dictionary).
"""
try:
now = datetime.now()
nextcall = datetime.strptime(job['nextcall'], DEFAULT_SERVER_DATETIME_FORMAT)
now = fields.datetime.context_timestamp(cr, job['user_id'], datetime.now())
nextcall = fields.datetime.context_timestamp(cr, job['user_id'], datetime.strptime(job['nextcall'], DEFAULT_SERVER_DATETIME_FORMAT))
numbercall = job['numbercall']

ok = False
Expand All @@ -304,7 +307,7 @@ def _process_job(self, cr, job):
if not numbercall:
addsql = ', active=False'
cr.execute("UPDATE ir_cron SET nextcall=%s, numbercall=%s"+addsql+" WHERE id=%s",
(nextcall.strftime(DEFAULT_SERVER_DATETIME_FORMAT), numbercall, job['id']))
(nextcall.astimezone(pytz.UTC).strftime(DEFAULT_SERVER_DATETIME_FORMAT), numbercall, job['id']))

finally:
cr.commit()
Expand Down
25 changes: 18 additions & 7 deletions openerp/osv/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import openerp.tools as tools
from openerp.tools.translate import _
from openerp.tools import float_round, float_repr
from openerp import SUPERUSER_ID
import simplejson

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -279,8 +280,8 @@ def context_today(model, cr, uid, context=None, timestamp=None):
This method may be passed as value to initialize _defaults.

:param Model model: model (osv) for which the date value is being
computed - technical field, currently ignored,
automatically passed when used in _defaults.
computed - automatically passed when used in
_defaults.
:param datetime timestamp: optional datetime value to use instead of
the current date and time (must be a
datetime, regular dates can't be converted
Expand All @@ -293,9 +294,14 @@ def context_today(model, cr, uid, context=None, timestamp=None):
today = timestamp or DT.datetime.now()
context_today = None
if context and context.get('tz'):
tz_name = context['tz']
else:
tz_name = model.pool.get('res.users').read(cr, SUPERUSER_ID, uid,
['context_tz'])['context_tz']
if tz_name:
try:
utc = pytz.timezone('UTC')
context_tz = pytz.timezone(context['tz'])
context_tz = pytz.timezone(tz_name)
utc_today = utc.localize(today, is_dst=False) # UTC = no DST
context_today = utc_today.astimezone(context_tz)
except Exception:
Expand Down Expand Up @@ -336,16 +342,21 @@ def context_timestamp(cr, uid, timestamp, context=None):
"""
assert isinstance(timestamp, DT.datetime), 'Datetime instance expected'
if context and context.get('tz'):
tz_name = context['tz']
else:
registry = openerp.modules.registry.RegistryManager.get(cr.dbname)
tz_name = registry.get('res.users').read(cr, SUPERUSER_ID, uid,
['context_tz'])['context_tz']
utc_timestamp = pytz.utc.localize(timestamp, is_dst=False) # UTC = no DST
if tz_name:
try:
utc = pytz.timezone('UTC')
context_tz = pytz.timezone(context['tz'])
utc_timestamp = utc.localize(timestamp, is_dst=False) # UTC = no DST
context_tz = pytz.timezone(tz_name)
return utc_timestamp.astimezone(context_tz)
except Exception:
_logger.debug("failed to compute context/client-specific timestamp, "
"using the UTC value",
exc_info=True)
return timestamp
return utc_timestamp

class time(_column):
_type = 'time'
Expand Down
6 changes: 3 additions & 3 deletions openerp/tools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,9 @@ def die(cond, msg):
"the i18n-export option cannot be used without the database (-d) option")

# Check if the config file exists (-c used, but not -s)
die(not opt.save and opt.config and not os.path.exists(opt.config),
"The config file '%s' selected with -c/--config doesn't exist, "\
"use -s/--save if you want to generate it"%(opt.config))
die(not opt.save and opt.config and not os.access(opt.config, os.R_OK),
"The config file '%s' selected with -c/--config doesn't exist or is not readable, "\
"use -s/--save if you want to generate it"% opt.config)

# place/search the config file on Win32 near the server installation
# (../etc from the server)
Expand Down
7 changes: 4 additions & 3 deletions openerp/tools/safe_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
# lp:703841), does import time.
_ALLOWED_MODULES = ['_strptime', 'time']

_UNSAFE_ATTRIBUTES = ['f_builtins', 'f_globals', 'f_locals', 'gi_frame',
'co_code', 'func_globals']

_CONST_OPCODES = set(opmap[x] for x in [
'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'ROT_FOUR', 'DUP_TOP', 'DUP_TOPX',
'POP_BLOCK','SETUP_LOOP', 'BUILD_LIST', 'BUILD_MAP', 'BUILD_TUPLE',
Expand Down Expand Up @@ -113,7 +116,7 @@ def assert_no_dunder_name(code_obj, expr):
.. note:: actually forbids every name containing 2 underscores
"""
for name in code_obj.co_names:
if "__" in name:
if "__" in name or name in _UNSAFE_ATTRIBUTES:
raise NameError('Access to forbidden name %r (%r)' % (name, expr))

def assert_valid_codeobj(allowed_codes, code_obj, expr):
Expand Down Expand Up @@ -264,8 +267,6 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal
'False': False,
'None': None,
'str': str,
'globals': locals,
'locals': locals,
'bool': bool,
'dict': dict,
'list': list,
Expand Down