[MERGE] forward port of branch 9.0 up to 47bb1bd

This commit is contained in:
Denis Ledoux
2016-02-10 15:55:48 +01:00
28 changed files with 108 additions and 78 deletions
+1 -2
View File
@@ -1561,7 +1561,6 @@ msgstr ""
#: model:ir.model.fields,help:account.field_account_config_settings_module_account_asset
msgid "Asset management: This allows you to manage the assets owned by a company or a person. It keeps track of the depreciation occurred on those assets, and creates account move for those depreciation lines.\n"
"\n"
"Revenue recognition: This allows you to manage the Revenue recognition on selling product. It keeps track of the installment occurred on those revenue recognition, and creates account move for those installment lines.\n"
"-This installs the module account_asset. If you do not check this box, you will be able to do invoicing & payments, but not accounting (Journal Items, Chart of Accounts, ...)"
msgstr ""
@@ -1572,7 +1571,7 @@ msgstr ""
#. module: account
#: model:ir.model.fields,field_description:account.field_account_config_settings_module_account_asset
msgid "Assets management & Revenue recognition"
msgid "Assets management"
msgstr ""
#. module: account
+1 -1
View File
@@ -960,7 +960,7 @@ class AccountInvoice(models.Model):
recs = self.browse(cr, uid, ids, context)
pay_journal = self.pool.get('account.journal').browse(cr, uid, pay_journal_id, context=context)
writeoff_acc = self.pool.get('account.account').browse(cr, uid, writeoff_acc_id, context=context)
return recs.pay_and_reconcile(pay_journal, pay_amount, date, writeoff_acc)
return AccountInvoice.pay_and_reconcile(recs, pay_journal, pay_amount, date, writeoff_acc)
@api.multi
def _track_subtype(self, init_values):
+3 -6
View File
@@ -599,8 +599,9 @@ class AccountMoveLine(models.Model):
@api.v7
def prepare_move_lines_for_reconciliation_widget(self, cr, uid, line_ids, target_currency_id=False, context=None):
recs = self.browse(cr, uid, line_ids, context)
target_currency = target_currency_id and self.pool.get('res.currency').browse(cr, uid, target_currency_id, context=context) or False
return self.browse(cr, uid, line_ids, context).prepare_move_lines_for_reconciliation_widget(target_currency=target_currency)
return AccountMoveLine.prepare_move_lines_for_reconciliation_widget(recs, target_currency=target_currency)
@api.v8
def prepare_move_lines_for_reconciliation_widget(self, target_currency=False, target_date=False):
@@ -695,11 +696,7 @@ class AccountMoveLine(models.Model):
accounts = self.pool['account.account'].browse(cr, uid, datum['id'], context=context)
self.pool['account.account'].mark_as_reconciled(cr, uid, accounts.ids, context=context)
@api.v7
def process_reconciliation(self, cr, uid, mv_line_ids, new_mv_line_dicts, context=None):
return self.browse(cr, uid, mv_line_ids, context).process_reconciliation(new_mv_line_dicts)
@api.v8
@api.multi
def process_reconciliation(self, new_mv_line_dicts):
""" Create new move lines from new_mv_line_dicts (if not empty) then call reconcile_partial on self and new move lines
+1 -3
View File
@@ -82,11 +82,9 @@ class AccountConfigSettings(models.TransientModel):
currency_exchange_journal_id = fields.Many2one('account.journal',
related='company_id.currency_exchange_journal_id',
string="Rate Difference Journal",)
module_account_asset = fields.Boolean(string='Assets management & Revenue recognition',
module_account_asset = fields.Boolean(string='Assets management',
help='Asset management: This allows you to manage the assets owned by a company or a person. '
'It keeps track of the depreciation occurred on those assets, and creates account move for those depreciation lines.\n\n'
'Revenue recognition: This allows you to manage the Revenue recognition on selling product. '
'It keeps track of the installment occurred on those revenue recognition, and creates account move for those installment lines.\n'
'-This installs the module account_asset. If you do not check this box, you will be able to do invoicing & payments, '
'but not accounting (Journal Items, Chart of Accounts, ...)')
module_account_budget = fields.Boolean(string='Budget management',
@@ -158,23 +158,16 @@ class AccountInvoiceReport(models.Model):
# self._table = account_invoice_report
tools.drop_view_if_exists(cr, self._table)
cr.execute("""CREATE or REPLACE VIEW %s as (
WITH currency_rate (currency_id, rate, date_start, date_end) AS (
SELECT r.currency_id, r.rate, r.name AS date_start,
(SELECT name FROM res_currency_rate r2
WHERE r2.name > r.name AND
r2.currency_id = r.currency_id
ORDER BY r2.name ASC
LIMIT 1) AS date_end
FROM res_currency_rate r
)
WITH currency_rate AS (%s)
%s
FROM (
%s %s %s
) AS sub
LEFT JOIN currency_rate cr ON
(cr.currency_id = sub.currency_id AND
cr.company_id = sub.company_id AND
cr.date_start <= COALESCE(sub.date, NOW()) AND
(cr.date_end IS NULL OR cr.date_end > COALESCE(sub.date, NOW())))
)""" % (
self._table,
self._table, self.pool['res.currency']._select_companies_rates(),
self._select(), self._sub_select(), self._from(), self._group_by()))
@@ -52,7 +52,7 @@ class AccountTaxPython(models.Model):
partner = partner_id and self.pool.get('res.partner').browse(cr, uid, partner_id, context=context) or None
ids = isinstance(ids, (int, long)) and [ids] or ids
recs = self.browse(cr, uid, ids, context=context)
return recs.compute_all(price_unit, currency, quantity, product, partner)
return AccountTaxPython.compute_all(recs, price_unit, currency, quantity, product, partner)
class AccountTaxTemplatePython(models.Model):
_inherit = 'account.tax.template'
+6
View File
@@ -1074,6 +1074,12 @@ msgstr ""
msgid "Shipment sent to carrier %s for expedition with tracking number %s"
msgstr ""
#. module: delivery
#: code:addons/delivery/models/stock_picking.py:106
#, python-format
msgid "Your delivery method has no redirect on courier provider's website to track this order."
msgstr ""
#. module: delivery
#: model:ir.model.fields,field_description:delivery.field_stock_picking_carrier_price
msgid "Shipping Cost"
+5 -1
View File
@@ -100,11 +100,15 @@ class StockPicking(models.Model):
@api.multi
def open_website_url(self):
self.ensure_one()
if self.carrier_id.get_tracking_link(self):
url = self.carrier_id.get_tracking_link(self)[0]
else:
raise UserError(_("Your delivery method has no redirect on courier provider's website to track this order."))
client_action = {'type': 'ir.actions.act_url',
'name': "Shipment Tracking Page",
'target': 'new',
'url': self.carrier_id.get_tracking_link(self)[0]
'url': url,
}
return client_action
@@ -200,6 +200,10 @@ class ImLivechatChannel(models.Model):
info['options']["default_username"] = username
return info
# FIXME: to remove in master
@api.model
def match_rules(self, request, channel_id, username='Visitor'):
pass
class ImLivechatChannelRule(models.Model):
""" Channel Rules
@@ -1,4 +1,4 @@
.openerp .annoucement_bar {
.openerp .announcement_bar {
display: none;
}
+2 -1
View File
@@ -7,6 +7,7 @@ from lxml import etree, objectify
from openerp.tools.translate import _
from pprint import pformat
import time
from unicodedata import normalize
from urllib import urlencode
import urllib2
import urlparse
@@ -478,7 +479,7 @@ class PaymentMethod(osv.Model):
'TRANSACTION_CODE': 'ATR',
'OPERATION': 'SAL',
'NB_PAYMENTS': 1, # even if we do not actually have any payment, ogone want it to not be 0
'FILE': line,
'FILE': normalize('NFKD', line).encode('ascii','ignore'), # Ogone Batch must be ASCII only
'REPLY_TYPE': 'XML',
'PSPID': acquirer.ogone_pspid,
'USERID': acquirer.ogone_userid,
@@ -8,6 +8,7 @@ access_account_journal,account.journal,account.model_account_journal,base.group_
access_product_list,product.pricelist,product.model_product_pricelist,base.group_portal,1,0,0,0
access_res_partner,res.partner,base.model_res_partner,base.group_portal,1,0,0,0
access_account_tax,account.tax,account.model_account_tax,base.group_portal,1,0,0,0
access_account_tax_group,account.tax.group,account.model_account_tax_group,base.group_portal,1,0,0,0
access_res_partner_category,res.partner.category,base.model_res_partner_category,base.group_portal,1,0,0,0
access_product_attribute_portal,product.attribute portal,product.model_product_attribute,base.group_portal,1,0,0,0
access_product_attribute_value_portal,product.attribute value portal,product.model_product_attribute_value,base.group_portal,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
8 access_product_list product.pricelist product.model_product_pricelist base.group_portal 1 0 0 0
9 access_res_partner res.partner base.model_res_partner base.group_portal 1 0 0 0
10 access_account_tax account.tax account.model_account_tax base.group_portal 1 0 0 0
11 access_account_tax_group account.tax.group account.model_account_tax_group base.group_portal 1 0 0 0
12 access_res_partner_category res.partner.category base.model_res_partner_category base.group_portal 1 0 0 0
13 access_product_attribute_portal product.attribute portal product.model_product_attribute base.group_portal 1 0 0 0
14 access_product_attribute_value_portal product.attribute value portal product.model_product_attribute_value base.group_portal 1 0 0 0
-5
View File
@@ -182,11 +182,6 @@ class procurement_order(osv.osv):
def reset_to_confirmed(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'confirmed'}, context=context)
@api.v8
def run(self, autocommit=False):
return self._model.run(self._cr, self._uid, self.ids, autocommit=False, context=self._context)
@api.v7
def run(self, cr, uid, ids, autocommit=False, context=None):
for procurement_id in ids:
#we intentionnaly do the browse under the for loop to avoid caching all ids which would be resource greedy
+3 -10
View File
@@ -49,15 +49,7 @@ class purchase_report(osv.osv):
tools.sql.drop_view_if_exists(cr, 'purchase_report')
cr.execute("""
create or replace view purchase_report as (
WITH currency_rate (currency_id, rate, date_start, date_end) AS (
SELECT r.currency_id, r.rate, r.name AS date_start,
(SELECT name FROM res_currency_rate r2
WHERE r2.name > r.name AND
r2.currency_id = r.currency_id
ORDER BY r2.name ASC
LIMIT 1) AS date_end
FROM res_currency_rate r
)
WITH currency_rate as (%s)
select
min(l.id) as id,
s.date_order as date,
@@ -96,6 +88,7 @@ class purchase_report(osv.osv):
left join stock_picking_type spt on (spt.id=s.picking_type_id)
left join account_analytic_account analytic_account on (l.account_analytic_id = analytic_account.id)
left join currency_rate cr on (cr.currency_id = s.currency_id and
cr.company_id = s.company_id and
cr.date_start <= coalesce(s.date_order, now()) and
(cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
group by
@@ -125,4 +118,4 @@ class purchase_report(osv.osv):
partner.commercial_partner_id,
analytic_account.id
)
""")
""" % self.pool['res.currency']._select_companies_rates())
+6
View File
@@ -1093,6 +1093,12 @@ msgstr ""
msgid "Please define an accounting sale journal for this company."
msgstr ""
#. module: sale
#: code:addons/sale/sale.py:316
#, python-format
msgid "There is no invoicable line."
msgstr ""
#. module: sale
#: code:addons/sale/sale.py:654
#, python-format
+3 -10
View File
@@ -43,15 +43,7 @@ class sale_report(osv.osv):
def _select(self):
select_str = """
WITH currency_rate (currency_id, rate, date_start, date_end) AS (
SELECT r.currency_id, r.rate, r.name AS date_start,
(SELECT name FROM res_currency_rate r2
WHERE r2.name > r.name AND
r2.currency_id = r.currency_id
ORDER BY r2.name ASC
LIMIT 1) AS date_end
FROM res_currency_rate r
)
WITH currency_rate as (%s)
SELECT min(l.id) as id,
l.product_id as product_id,
t.uom_id as product_uom,
@@ -75,7 +67,7 @@ class sale_report(osv.osv):
p.product_tmpl_id,
partner.country_id as country_id,
partner.commercial_partner_id as commercial_partner_id
"""
""" % self.pool['res.currency']._select_companies_rates()
return select_str
def _from(self):
@@ -89,6 +81,7 @@ class sale_report(osv.osv):
left join product_uom u2 on (u2.id=t.uom_id)
left join product_pricelist pp on (s.pricelist_id = pp.id)
left join currency_rate cr on (cr.currency_id = pp.currency_id and
cr.company_id = s.company_id and
cr.date_start <= coalesce(s.date_order, now()) and
(cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
"""
+2
View File
@@ -311,6 +311,8 @@ class SaleOrder(models.Model):
line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice)
for invoice in invoices.values():
if not invoice.invoice_line_ids:
raise UserError(_('There is no invoicable line.'))
# If invoice is negative, do a refund invoice instead
if invoice.amount_untaxed < 0:
invoice.type = 'out_refund'
+1 -1
View File
@@ -3149,7 +3149,7 @@ msgstr ""
#. module: website
#: model:ir.ui.view,arch_db:website.view_website_config_settings
msgid "Speed"
msgid "Optimization"
msgstr ""
#. module: website
+1
View File
@@ -158,6 +158,7 @@ class ir_http(orm.AbstractModel):
redirect.set_cookie('website_lang', request.lang)
return redirect
elif url_lang:
request.uid = None
path.pop(1)
return self.reroute('/'.join(path) or '/')
if path[1] == request.website.default_lang_code:
+1 -1
View File
@@ -187,7 +187,7 @@ class website(osv.osv):
'company_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID,'base.main_company'),
'compress_html': False,
'cdn_activated': False,
'cdn_url': '//localhost:8069/',
'cdn_url': '',
'cdn_filters': '\n'.join(DEFAULT_CDN_FILTERS),
'language_ids': _active_languages,
'default_lang_id': _default_language,
+10 -5
View File
@@ -100,8 +100,8 @@
<label for="module_website_version"/>
</div>
</div>
<label for="id" string="Speed"/>
<div>
<label for="id" string="Optimization" groups="base.group_no_one"/>
<div groups="base.group_no_one">
<div>
<field name="compress_html"/>
<label for="compress_html"/>
@@ -109,11 +109,16 @@
<div>
<field name="cdn_activated"/>
<label for="cdn_activated"/>
</div><div>
</div>
<div attrs="{'invisible': [('cdn_activated', '=', False)]}">
<label for="cdn_url"/>
<field name="cdn_url" attrs="{'invisible': [('cdn_activated', '=', False)] }"/>
<field name="cdn_url"
attrs="{'required': [('cdn_activated', '=', True)]}"
placeholder="//mycompany.mycdn.com/"
t-translation="off"/>
<label for="cdn_filters"/>
<field name="cdn_filters" attrs="{'invisible': [('cdn_activated', '=', False)] }"/>
<field name="cdn_filters"
attrs="{'required': [('cdn_activated', '=', True)]}"/>
</div>
</div>
+5 -1
View File
@@ -4,5 +4,9 @@ class Lead(models.Model):
_inherit = 'crm.lead'
def website_form_input_filter(self, request, values):
values.setdefault('medium_id', request.registry['ir.model.data'].xmlid_to_res_id(request.cr, SUPERUSER_ID, 'crm.crm_medium_website'))
values['medium_id'] = (
values.get('medium_id') or
self.default_get(['medium_id']).get('medium_id') or
self.sudo().env['ir.model.data'].xmlid_to_res_id('utm.utm_medium_website')
)
return values
+8 -6
View File
@@ -775,7 +775,7 @@ method should simply set the value of the field to compute on every record in
.. code-block:: python
import random
from openerp import models, fields
from openerp import models, fields, api
class ComputedModel(models.Model):
_name = 'test.computed'
@@ -808,7 +808,7 @@ field whenever some of its dependencies have been modified::
@api.depends('value')
def _compute_name(self):
for record in self:
self.name = "Record with value %s" % self.value
record.name = "Record with value %s" % record.value
.. exercise:: Computed fields
@@ -1153,13 +1153,15 @@ Graph views
Graph views allow aggregated overview and analysis of models, their root
element is ``<graph>``.
.. note::
Pivot views (element ``<pivot>``) a multidimensional table, allows the
selection of filers and dimensions to get the right aggregated dataset
before moving to a more graphical overview. The pivot view shares the same
content definition as graph views.
Graph views have 4 display modes, the default mode is selected using the
``@type`` attribute.
Pivot
a multidimensional table, allows the selection of filers and dimensions
to get the right aggregated dataset before moving to a more graphical
overview
Bar (default)
a bar chart, the first dimension is used to define groups on the
horizontal axis, other dimensions define aggregated bars within each group.
@@ -10,7 +10,7 @@ Index: addons/openacademy/views/openacademy.xml
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
- <tree string="Session Tree">
+ <tree string="Session Tree" colors="#0000ff:duration&lt;5;red:duration&gt;15">
+ <tree string="Session Tree" decoration-info="duration&lt;5" decoration-danger="duration&gt;15">
<field name="name"/>
<field name="course_id"/>
+ <field name="duration" invisible="1"/>
+18 -11
View File
@@ -971,6 +971,9 @@ calendar view are:
``all_day``
name of a boolean field on the record indicating whether the corresponding
event is flagged as day-long (and duration is irrelevant)
``mode``
Default display mode when loading the calendar.
Possible attributes are: ``day``, ``week``, ``month``
.. todo::
@@ -1015,17 +1018,21 @@ take the following attributes:
between 0 and 100
``default_group_by``
name of a field to group tasks by
.. previously documented content which don't seem to be used anymore:
* string
* day_length
* color
* mode
* date_string
* <level>
* <field>
* <html>
``fold_last_level``
If a value is set, the last grouping level is folded
``round_dnd_dates``
enables rounding the task's start and end dates to the nearest scale marks
``consolidation``
field name to display consolidation value in record cell
``consolidation_max``
dictionary with the "group by" field as key and the maximum consolidation
value that can be reached before displaying the cell in red
.. consolidation_exclude
.. consolidation_color
.. ``type``
``gantt`` classic gantt view (default)
``consolidate`` values of the first children are consolidated in the gantt's task
``planning`` children are displayed in the gantt's task
.. _reference/views/diagram:
+18
View File
@@ -236,6 +236,24 @@ class res_currency(osv.osv):
function = "if (arguments[1] === false || arguments[1] === undefined) {" + company_currency_format + " }" + function
return function
def _select_companies_rates(self):
return """
SELECT
r.currency_id,
COALESCE(r.company_id, c.id) as company_id,
r.rate,
r.name AS date_start,
(SELECT name FROM res_currency_rate r2
WHERE r2.name > r.name AND
r2.currency_id = r.currency_id AND
(r2.company_id is null or r2.company_id = r.company_id)
ORDER BY r2.name ASC
LIMIT 1) AS date_end
FROM res_currency_rate r
JOIN res_company c ON (r.company_id is null or r.company_id = c.id)
"""
class res_currency_rate(osv.osv):
_name = "res.currency.rate"
_description = "Currency Rate"
+1
View File
@@ -336,6 +336,7 @@ class res_users(osv.osv):
def create(self, cr, uid, vals, context=None):
user_id = super(res_users, self).create(cr, uid, vals, context=context)
user = self.browse(cr, uid, user_id, context=context)
user.partner_id.active = user.active
if user.partner_id.company_id:
user.partner_id.write({'company_id': user.company_id.id})
return user_id
@@ -425,7 +425,7 @@
assert [p1,p2] == res_partner.search(cr, uid, [('user_ids', 'in', [u1a,u2])]), "o2m IN matches any on the right side"
all_partners = res_partner.search(cr, uid, [])
assert (set(all_partners) - set([p1])) == set(res_partner.search(cr, uid, [('user_ids', 'not in', u1a)])), "o2m NOT IN matches none on the right side"
# For 9.0: assert (set(all_partners) - set([p1])) == set(res_partner.search(cr, uid, [('user_ids', '!=', 'Dédé Boitaclou')])), "o2m NOT IN matches none on the right side"
assert (set(all_partners) - set([p1])) == set(res_partner.search(cr, uid, [('user_ids', '!=', 'Dédé Boitaclou')])), "o2m NOT IN matches none on the right side"
assert (set(all_partners) - set([p1,p2])) == set(res_partner.search(cr, uid, [('user_ids', 'not in', [u1b, u2])])), "o2m NOT IN matches none on the right side"