[MERGE] forward port of branch 8.0 up to a6a1764

This commit is contained in:
Christophe Simonis
2015-02-23 19:04:39 +01:00
11 changed files with 69 additions and 29 deletions
+10
View File
@@ -860,6 +860,16 @@ class account_bank_statement_line(osv.osv):
mv_line_dict['credit'] = credit_at_old_rate
to_create.append(mv_line_dict)
# If the reconciliation is performed in another currency than the company currency, the amounts are converted to get the right debit/credit.
# If there is more than 1 debit and 1 credit, this can induce a rounding error, which we put in the foreign exchane gain/loss account.
if st_line_currency.id != company_currency.id:
diff_amount = bank_st_move_vals['debit'] - bank_st_move_vals['credit'] \
+ sum(aml['debit'] for aml in to_create) - sum(aml['credit'] for aml in to_create)
if not company_currency.is_zero(diff_amount):
diff_aml = self.get_currency_rate_line(cr, uid, st_line, diff_amount, move_id, context=context)
diff_aml['name'] = _('Rounding error from currency conversion')
to_create.append(diff_aml)
# Create move lines
move_line_pairs_to_reconcile = []
for mv_line_dict in to_create:
+1
View File
@@ -1096,6 +1096,7 @@ class account_invoice(models.Model):
values['date_invoice'] = date or fields.Date.context_today(invoice)
values['state'] = 'draft'
values['number'] = False
values['origin'] = invoice.number
if period_id:
values['period_id'] = period_id
+28 -3
View File
@@ -70,6 +70,7 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="20"/>
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button type="action"
@@ -78,14 +79,38 @@
icon="fa-pencil-square-o"
name="%(account.action_invoice_tree)d"
attrs="{'invisible': [('customer', '=', False)]}"
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}" groups="account.group_account_invoice">
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}">
<div><strong><field name="total_invoiced" widget="monetary"/></strong><br/>Invoiced</div>
</button>
<button type="action" class="oe_stat_button" name="%(account.action_account_moves_all_tree)d" groups="account.group_account_user" icon="fa-list">
</xpath>
</field>
</record>
<record model="ir.ui.view" id="partner_view_button_journal_item_count">
<field name="name">partner.view.button.journal_item_count</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="21"/>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button type="action" class="oe_stat_button" name="%(account.action_account_moves_all_tree)d" icon="fa-list">
<field string="Journal Items" name="journal_item_count" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="partner_view_button_contracts_count">
<field name="name">partner.view.button.contracts_count</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="22"/>
<field name="groups_id" eval="[(4, ref('analytic.group_analytic_accounting'))]"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button class="oe_inline oe_stat_button" type="action" name="%(account.action_open_partner_analytic_accounts)d"
icon="fa-book" groups="analytic.group_analytic_accounting">
icon="fa-book">
<field string="Contracts" name="contracts_count" widget="statinfo"/>
</button>
</xpath>
+6 -1
View File
@@ -1417,6 +1417,12 @@ class calendar_event(osv.Model):
del context['default_date']
return super(calendar_event, self).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, **kwargs)
def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
return super(calendar_event, self).message_subscribe(cr, uid, get_real_ids(ids), partner_ids, subtype_ids=subtype_ids, context=context)
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
return super(calendar_event, self).message_unsubscribe(cr, uid, get_real_ids(ids), partner_ids, context=context)
def do_sendmail(self, cr, uid, ids, context=None):
for event in self.browse(cr, uid, ids, context):
current_user = self.pool['res.users'].browse(cr, uid, uid, context=context)
@@ -1748,7 +1754,6 @@ class calendar_event(osv.Model):
return res
class mail_message(osv.Model):
_inherit = "mail.message"
+2 -1
View File
@@ -26,6 +26,7 @@ import sets
from openerp import tools, models
from openerp.osv import fields, osv
from openerp.tools import float_is_zero
from openerp.tools.translate import _
from openerp.exceptions import UserError
@@ -602,7 +603,7 @@ class pos_order(osv.osv):
session.write({'sequence_number': order['sequence_number'] + 1})
session.refresh()
if order['amount_return']:
if not float_is_zero(order['amount_return'], self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')):
cash_journal = session.cash_journal_id
if not cash_journal:
cash_journal_ids = filter(lambda st: st.journal_id.type=='cash', session.statement_ids)
+1 -1
View File
@@ -206,7 +206,7 @@ class project(osv.osv):
return res
def _task_count(self, cr, uid, ids, field_name, arg, context=None):
res={}
for tasks in self.browse(cr, uid, ids, context):
for tasks in self.browse(cr, uid, ids, dict(context, active_test=False)):
res[tasks.id] = len(tasks.task_ids)
return res
def _get_alias_models(self, cr, uid, context=None):
+1 -1
View File
@@ -281,7 +281,7 @@
<div class="row oe_margin_top_8 oe_kanban_project_list">
<div class="col-md-6">
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action">
<t t-raw="record.task_ids.raw_value.length" />
<t t-raw="record.task_count.raw_value" />
<field name="label_tasks"/>
</a>
</div>
+2 -1
View File
@@ -399,12 +399,13 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="50"/>
<field name="groups_id" eval="[(4, ref('project.group_project_user'))]"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button class="oe_inline oe_stat_button" type="action" name="%(action_view_issues)d"
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
attrs="{'invisible': [('customer', '=', False)]}"
icon="fa-bug" groups="project.group_project_user">
icon="fa-bug">
<field string="Issues" name="issue_count" widget="statinfo"/>
</button>
+1 -2
View File
@@ -658,7 +658,7 @@ class Field(object):
self.column = fields.property(**args)
elif self.column:
# let the column provide a valid column for the given parameters
self.column = self.column.new(**args)
self.column = self.column.new(_computed_field=bool(self.compute), **args)
else:
# create a fresh new column of the right type
self.column = getattr(fields, self.type)(**args)
@@ -677,7 +677,6 @@ class Field(object):
_column_groups = property(attrgetter('groups'))
_column_change_default = property(attrgetter('change_default'))
_column_deprecated = property(attrgetter('deprecated'))
_column_compute = property(lambda self: bool(self.compute))
############################################################################
#
+2 -1
View File
@@ -64,7 +64,7 @@ from .api import Environment
from .exceptions import AccessError, MissingError, ValidationError, UserError
from .osv import fields
from .osv.query import Query
from .tools import lazy_property, ormcache
from .tools import frozendict, lazy_property, ormcache
from .tools.config import config
from .tools.misc import CountingStream, DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from .tools.safe_eval import safe_eval as eval
@@ -633,6 +633,7 @@ class BaseModel(object):
'_register': False,
'_columns': None, # recomputed in _setup_fields()
'_defaults': None, # recomputed in _setup_base()
'_fields': frozendict(), # idem
'_inherits': dict(cls._inherits),
'_depends': dict(cls._depends),
'_constraints': list(cls._constraints),
+15 -18
View File
@@ -115,6 +115,7 @@ class _column(object):
"""
args0 = {
'string': string,
'help': args.pop('help', None),
'required': required,
'readonly': readonly,
'_domain': domain,
@@ -127,6 +128,9 @@ class _column(object):
'translate': translate,
'select': select,
'manual': manual,
'group_operator': args.pop('group_operator', None),
'groups': args.pop('groups', None),
'deprecated': args.pop('deprecated', None),
}
for key, val in args0.iteritems():
if val:
@@ -140,30 +144,23 @@ class _column(object):
if not self._classic_write or self.deprecated or self.manual:
self._prefetch = False
def new(self, **args):
""" return a column like `self` with the given parameters """
def new(self, _computed_field=False, **args):
""" Return a column like `self` with the given parameters; the parameter
`_computed_field` tells whether the corresponding field is computed.
"""
# memory optimization: reuse self whenever possible; you can reduce the
# average memory usage per registry by 10 megabytes!
return self if self.same_parameters(args) else type(self)(**args)
def same_parameters(self, args):
dummy = object()
return all(
# either both are falsy, or they are equal
(not val1 and not val) or (val1 == val)
for key, val in args.iteritems()
for val1 in [getattr(self, key, getattr(self, '_' + key, dummy))]
)
column = type(self)(**args)
return self if self.to_field_args() == column.to_field_args() else column
def to_field(self):
""" convert column `self` to a new-style field """
from openerp.fields import Field
return Field.by_type[self._type](**self.to_field_args())
return Field.by_type[self._type](column=self, **self.to_field_args())
def to_field_args(self):
""" return a dictionary with all the arguments to pass to the field """
base_items = [
('column', self), # field interfaces self
('copy', self.copy),
]
truthy_items = filter(itemgetter(1), [
@@ -349,7 +346,7 @@ class float(_column):
# synopsis: digits_compute(cr) -> (precision, scale)
self.digits_compute = digits_compute
def new(self, **args):
def new(self, _computed_field=False, **args):
# float columns are database-dependent, so always recreate them
return type(self)(**args)
@@ -1292,9 +1289,9 @@ class function(_column):
self._symbol_f = type_class._symbol_f
self._symbol_set = type_class._symbol_set
def new(self, **args):
if args.get('compute'):
# field is computed, we need an instance of the given type
def new(self, _computed_field=False, **args):
if _computed_field:
# field is computed, we need an instance of a non-function column
type_class = globals()[self._type]
return type_class(**args)
else: