summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-05-04 14:42:54 +0200
committerChristophe Simonis <chs@odoo.com>2016-05-04 14:42:54 +0200
commit89873cbed5fb31547843a7a135145d46986431af (patch)
tree0b2eda7a7cc06d98f28d7d573154b1df409e3f6d /addons
parent431ef552b32ad97b74d3204b6ce496da104c034c (diff)
parent3381e7bedf6d2fc7126e171ee8ad06574903bac2 (diff)
[MERGE] forward port of branch 9.0 up to 3381e7b
Diffstat (limited to 'addons')
-rw-r--r--addons/account/models/account_payment.py2
-rw-r--r--addons/base_action_rule/base_action_rule.py2
-rw-r--r--addons/crm_partner_assign/wizard/crm_channel_interested.py2
-rw-r--r--addons/hr_holidays/hr_holidays.py13
-rw-r--r--addons/mail/static/src/js/client_action.js21
-rw-r--r--addons/mail/static/src/js/systray.js4
-rw-r--r--addons/mail/static/src/xml/systray.xml1
-rw-r--r--addons/mrp/mrp.py29
-rw-r--r--addons/point_of_sale/point_of_sale_view.xml1
-rw-r--r--addons/point_of_sale/static/src/js/screens.js4
-rw-r--r--addons/product_expiry/product_expiry.py2
-rw-r--r--addons/sale_mrp/sale_mrp.py4
-rw-r--r--addons/website_project_issue/controllers/main.py10
13 files changed, 54 insertions, 41 deletions
diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py
index b08a17092a9..38ad5ecffc1 100644
--- a/addons/account/models/account_payment.py
+++ b/addons/account/models/account_payment.py
@@ -248,7 +248,7 @@ class account_payment(models.Model):
invoice_defaults = self.resolve_2many_commands('invoice_ids', rec.get('invoice_ids'))
if invoice_defaults and len(invoice_defaults) == 1:
invoice = invoice_defaults[0]
- rec['communication'] = invoice['reference']
+ rec['communication'] = invoice['reference'] or invoice['name'] or invoice['number']
rec['currency_id'] = invoice['currency_id'][0]
rec['payment_type'] = invoice['type'] in ('out_invoice', 'in_refund') and 'inbound' or 'outbound'
rec['partner_type'] = MAP_INVOICE_TYPE_PARTNER_TYPE[invoice['type']]
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 39dd7b1f3e3..76c70e5db11 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -274,7 +274,7 @@ class base_action_rule(osv.osv):
# check conditions, and execute actions on the records that satisfy them
for action in actions:
- action._process(action._filter_post(pre[action]))
+ action._process(action._filter_post(records))
# call original method
return unlink.origin(self, **kwargs)
diff --git a/addons/crm_partner_assign/wizard/crm_channel_interested.py b/addons/crm_partner_assign/wizard/crm_channel_interested.py
index ac9bd931464..ae80f44e375 100644
--- a/addons/crm_partner_assign/wizard/crm_channel_interested.py
+++ b/addons/crm_partner_assign/wizard/crm_channel_interested.py
@@ -41,7 +41,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
if wizard.comment:
message += '<p>%s</p>' % wizard.comment
for active_id in context.get('active_ids', []):
- lead_obj.message_post(cr, uid, active_id, body=message, subtype="mail.mt_comment", context=context)
+ lead_obj.message_post(cr, uid, active_id, body=message, subtype="mail.mt_note", context=context)
if values:
lead_obj.write(cr, SUPERUSER_ID, context.get('active_ids', []), values)
lead_obj.set_tag_assign(cr, SUPERUSER_ID, context.get('active_ids', []), False)
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index bdce2f9de44..b694b882ca9 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -450,6 +450,19 @@ class hr_holidays(osv.osv):
return True
def holidays_confirm(self, cr, uid, ids, context=None):
+ for record in self.browse(cr, uid, ids, context=context):
+ if record.department_id:
+ # Subscribe the followers of the department following the `confirmed` subtype
+ # It's done manually because `message_auto_subscribe` only works on fields for which
+ # the value is passed to the `create` or `write` methods,
+ # it doesn't work for related/computed fields
+ # This can be removed as soon as `department_id` on `hr.holidays` becomes a regular
+ # fields or as soon as `message_auto_subscribe` works with related/computed fields.
+ confirmed_subtype = self.pool['ir.model.data'].xmlid_to_object(cr, uid, 'hr_holidays.mt_department_holidays_confirmed', context=context)
+ self.message_subscribe(cr, uid, [record.id], [
+ follower.partner_id.id for follower in record.department_id.message_follower_ids
+ if confirmed_subtype in follower.subtype_ids
+ ], context=context)
return self.write(cr, uid, ids, {'state': 'confirm'})
def holidays_refuse(self, cr, uid, ids, context=None):
diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js
index 704c3d4064c..04e1ed13ba8 100644
--- a/addons/mail/static/src/js/client_action.js
+++ b/addons/mail/static/src/js/client_action.js
@@ -283,12 +283,13 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
},
unselect_message: function() {
- if (this.channel.type !== 'static' && !this.channel.mass_mailing) {
- this.basic_composer.toggle(true);
- this.basic_composer.focus();
+ this.basic_composer.toggle(this.channel.type !== 'static' && !this.channel.mass_mailing);
+ this.extended_composer.toggle(this.channel.type !== 'static' && this.channel.mass_mailing);
+ if (!config.device.touch) {
+ var composer = this.channel.mass_mailing ? this.extended_composer : this.basic_composer;
+ composer.focus();
}
this.$el.removeClass('o_mail_selection_mode');
- this.extended_composer.toggle(this.channel.mass_mailing);
this.thread.unselect();
this.selected_message = null;
},
@@ -424,10 +425,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
.find('.o_mail_chat_button_unstar_all')
.toggle(channel.id === "channel_starred");
- self.basic_composer.toggle(channel.type !== 'static' && !channel.mass_mailing);
- self.extended_composer.toggle(channel.type !== 'static' && channel.mass_mailing);
- self.$el.removeClass('o_mail_selection_mode');
-
self.$('.o_mail_chat_channel_item')
.removeClass('o_active')
.filter('[data-channel-id=' + channel.id + ']')
@@ -443,14 +440,14 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
// Update control panel before focusing the composer, otherwise focus is on the searchview
self.update_cp();
- if (!config.device.touch) {
- var composer = channel.mass_mailing ? self.extended_composer : self.basic_composer;
- composer.focus();
- }
if (config.device.size_class === config.device.SIZES.XS) {
self.$('.o_mail_chat_sidebar').hide();
}
+ // Display and focus the adequate composer, and unselect possibly selected message
+ // to prevent sending messages as reply to that message
+ self.unselect_message();
+
self.action_manager.do_push_state({
action: self.action.id,
active_id: self.channel.id,
diff --git a/addons/mail/static/src/js/systray.js b/addons/mail/static/src/js/systray.js
index af442f5606e..5e73042a7aa 100644
--- a/addons/mail/static/src/js/systray.js
+++ b/addons/mail/static/src/js/systray.js
@@ -111,9 +111,7 @@ var MessagingMenu = Widget.extend({
// Generate last message preview (inline message body and compute date to display)
_.each(channels_preview, function (channel) {
- channel.last_message_preview =
- channel.last_message.displayed_author + ': ' +
- chat_manager.get_message_body_preview(channel.last_message.body);
+ channel.last_message_preview = chat_manager.get_message_body_preview(channel.last_message.body);
if (channel.last_message.date.isSame(new Date(), 'd')) { // today
channel.last_message_date = channel.last_message.date.format('LT');
} else {
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml
index 4a987fdf992..2ce26f4d485 100644
--- a/addons/mail/static/src/xml/systray.xml
+++ b/addons/mail/static/src/xml/systray.xml
@@ -45,6 +45,7 @@
<span class="o_last_message_date"> <t t-esc="channel.last_message_date"/> </span>
</div>
<div class="o_last_message_preview">
+ <t t-esc="channel.last_message.displayed_author"/>:
<t t-raw="channel.last_message_preview"/>
</div>
</div>
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index b94428f91fe..871fe2a6a10 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -802,13 +802,7 @@ class mrp_production(osv.osv):
return True
def _compute_costs_from_production(self, cr, uid, ids, context=None):
- """ Generate workcenter costs and rectify the value of the quant
-
- Must be called at the end of the production.
- The value of the quant was not possible to compute before the end of
- the manufacturing order due to the cost of raw manterial and production
- costs. The price of the quant was not set in get_price_unit.
- """
+ """ Generate workcenter costs in analytic accounts"""
for production in self.browse(cr, uid, ids):
total_cost = self._costs_generate(cr, uid, production)
@@ -956,6 +950,16 @@ class mrp_production(osv.osv):
total_cost += sum([x.inventory_value for x in consumed_move.quant_ids if x.qty > 0])
return total_cost
+ def _calculate_workcenter_cost(self, cr, uid, production_id, context=None):
+ """ Compute the planned production cost from the workcenters """
+ production = self.browse(cr, uid, production_id, context=context)
+ total_cost = 0.0
+ for wc_line in production.workcenter_lines:
+ wc = wc_line.workcenter_id
+ total_cost += wc_line.hour*wc.costs_hour + wc_line.cycle*wc.costs_cycle
+
+ return total_cost
+
def action_produce(self, cr, uid, production_id, production_qty, production_mode, wiz=False, context=None):
""" To produce final product based on production mode (consume/consume&produce).
If Production mode is consume, all stock move lines of raw materials will be done/consumed.
@@ -1011,18 +1015,25 @@ class mrp_production(osv.osv):
total_consume_moves.append(extra_move_id)
if production_mode == 'consume_produce':
+ # add production lines that have already been consumed since the last 'consume & produce'
+ last_production_date = production.move_created_ids2 and max(production.move_created_ids2.mapped('date')) or False
+ already_consumed_lines = production.move_lines2.filtered(lambda l: l.date > last_production_date)
+ total_consume_moves += already_consumed_lines.ids
+
price_unit = 0
for produce_product in production.move_created_ids:
is_main_product = (produce_product.product_id.id == production.product_id.id) and production.product_id.cost_method=='real'
if is_main_product:
total_cost = self._calculate_total_cost(cr, uid, total_consume_moves, context=context)
- price_unit = total_cost / production_qty_uom
+ production_cost = self._calculate_workcenter_cost(cr, uid, production_id, context=context)
+ price_unit = (total_cost + production_cost) / production_qty_uom
+
subproduct_factor = self._get_subproduct_factor(cr, uid, production.id, produce_product.id, context=context)
lot_id = False
if wiz:
lot_id = wiz.lot_id.id
qty = min(subproduct_factor * production_qty_uom, produce_product.product_qty) #Needed when producing more than maximum quantity
- if is_main_product:
+ if is_main_product and price_unit:
stock_mov_obj.write(cr, uid, [produce_product.id], {'price_unit': price_unit}, context=context)
new_moves = stock_mov_obj.action_consume(cr, uid, [produce_product.id], qty,
location_id=produce_product.location_id.id, restrict_lot_id=lot_id, context=context)
diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml
index 7db53e35f8e..35a0a02e1e8 100644
--- a/addons/point_of_sale/point_of_sale_view.xml
+++ b/addons/point_of_sale/point_of_sale_view.xml
@@ -39,6 +39,7 @@
<field name="price_unit" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
<field name="discount" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
<field name="tax_ids_after_fiscal_position" widget="many2many_tags"/>
+ <field name="tax_ids" invisible="1"/>
<field name="price_subtotal" widget="monetary"/>
<field name="price_subtotal_incl" widget="monetary"/>
</tree>
diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js
index 507db3cfbd8..10885c1d9cf 100644
--- a/addons/point_of_sale/static/src/js/screens.js
+++ b/addons/point_of_sale/static/src/js/screens.js
@@ -1023,7 +1023,9 @@ var ClientListScreenWidget = ScreenWidget.extend({
if (this.editing_client) {
this.$('.detail.barcode').val(code.code);
} else if (this.pos.db.get_partner_by_barcode(code.code)) {
- this.display_client_details('show',this.pos.db.get_partner_by_barcode(code.code));
+ var partner = this.pos.db.get_partner_by_barcode(code.code);
+ this.new_client = partner;
+ this.display_client_details('show', partner);
}
},
perform_search: function(query, associate_result){
diff --git a/addons/product_expiry/product_expiry.py b/addons/product_expiry/product_expiry.py
index 25390891aa5..9e46ad72aaf 100644
--- a/addons/product_expiry/product_expiry.py
+++ b/addons/product_expiry/product_expiry.py
@@ -40,7 +40,7 @@ class stock_production_lot(osv.osv):
# Assign dates according to products data
def create(self, cr, uid, vals, context=None):
context = dict(context or {})
- context['product_id'] = vals.get('product_id', context.get('default_product_id'))
+ context['product_id'] = vals.get('product_id', context.get('default_product_id') or context.get('product_id'))
return super(stock_production_lot, self).create(cr, uid, vals, context=context)
_defaults = {
diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py
index 8dc89814a3c..c168e0e1770 100644
--- a/addons/sale_mrp/sale_mrp.py
+++ b/addons/sale_mrp/sale_mrp.py
@@ -144,6 +144,4 @@ class AccountInvoiceLine(models.Model):
average_price_unit += factor * self._compute_average_price(prod_qty_done, prod_quantity, prod_moves)
price_unit = average_price_unit or price_unit
price_unit = uom_obj._compute_qty_obj(self.uom_id, price_unit, self.product_id.uom_id, round=False)
- return price_unit
- else:
- return price_unit
+ return price_unit
diff --git a/addons/website_project_issue/controllers/main.py b/addons/website_project_issue/controllers/main.py
index 942fec9da53..98f06c0c281 100644
--- a/addons/website_project_issue/controllers/main.py
+++ b/addons/website_project_issue/controllers/main.py
@@ -10,15 +10,7 @@ class WebsiteAccount(website_account):
def account(self):
response = super(WebsiteAccount, self).account()
user = request.env.user
- # TDE FIXME: shouldn't that be mnaged by the access rule itself ?
- # portal projects where you or someone from your company are a follower
- project_issues = request.env['project.issue'].search([
- '&',
- ('project_id.privacy_visibility', '=', 'portal'),
- '|',
- ('message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
- ('message_partner_ids', 'child_of', [user.partner_id.id])
- ])
+ project_issues = request.env['project.issue'].search([])
response.qcontext.update({'issues': project_issues})
return response