[MERGE] forward port of branch 8.0 up to a6a1764
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user