diff --git a/MANIFEST.in b/MANIFEST.in
index f5170b3b2fa..464c8141863 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,6 +4,7 @@ include README.md
recursive-include openerp *.css
recursive-include openerp *.csv
recursive-include openerp *.doc
+recursive-include openerp *.eml
recursive-include openerp *.gif
recursive-include openerp *.html
recursive-include openerp *.ico
diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py
index 6da8085e961..d9202d319fe 100644
--- a/addons/account/models/account_payment.py
+++ b/addons/account/models/account_payment.py
@@ -33,7 +33,7 @@ class account_abstract_payment(models.AbstractModel):
payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money')], string='Payment Type', required=True)
payment_method_id = fields.Many2one('account.payment.method', string='Payment Type', required=True, oldname="payment_method")
payment_method_code = fields.Char(related='payment_method_id.code',
- help="Technical field used to adapt the interface to the payment type selected.")
+ help="Technical field used to adapt the interface to the payment type selected.", readonly=True)
partner_type = fields.Selection([('customer', 'Customer'), ('supplier', 'Vendor')])
partner_id = fields.Many2one('res.partner', string='Partner')
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index 6a04dadda15..14be0557085 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -34,13 +34,15 @@
-
+
+
+
diff --git a/addons/hr_holidays/report/available_holidays_view.xml b/addons/hr_holidays/report/available_holidays_view.xml
index f6537aff812..b134384eae8 100644
--- a/addons/hr_holidays/report/available_holidays_view.xml
+++ b/addons/hr_holidays/report/available_holidays_view.xml
@@ -35,7 +35,7 @@
form
graph,pivot,calendar,form
- [('type','=','remove')]
+ {'search_default_leaves':1}
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 33910244d5c..22c3b662867 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1526,7 +1526,7 @@ exports.Order = Backbone.Model.extend({
return this;
},
save_to_db: function(){
- if (!this.init_locked) {
+ if (!this.temporary && !this.init_locked) {
this.pos.db.save_unpaid_order(this);
}
},
diff --git a/addons/pos_restaurant/static/src/js/splitbill.js b/addons/pos_restaurant/static/src/js/splitbill.js
index 745c8282c20..cce3dcbe490 100644
--- a/addons/pos_restaurant/static/src/js/splitbill.js
+++ b/addons/pos_restaurant/static/src/js/splitbill.js
@@ -107,6 +107,7 @@ var SplitbillScreenWidget = screens.ScreenWidget.extend({
return;
}
+ delete neworder.temporary;
if(full){
this.gui.show_screen('payment');
diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py
index 9cfa29bbf30..54a4a2a3b84 100644
--- a/addons/project_timesheet/project_timesheet.py
+++ b/addons/project_timesheet/project_timesheet.py
@@ -50,6 +50,8 @@ class task(osv.osv):
# Compute: effective_hours, total_hours, progress
def _hours_get(self, cr, uid, ids, field_names, args, context=None):
res = {}
+ for task in self.browse(cr, uid, ids, context=context):
+ res[task.id] = {'effective_hours': 0.0, 'remaining_hours': task.planned_hours, 'progress': 0.0, 'total_hours': task.planned_hours, 'delay_hours': 0.0}
tasks_data = self.pool['account.analytic.line'].read_group(cr, uid, [('task_id', 'in', ids)], ['task_id','unit_amount'], ['task_id'], context=context)
for data in tasks_data:
task = self.browse(cr, uid, data['task_id'][0], context=context)
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 1a82c08fe98..33c9d656952 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -447,7 +447,7 @@ class PurchaseOrderLine(models.Model):
@api.depends('order_id.state', 'move_ids.state')
def _compute_qty_received(self):
- ProductUom = self.env['product.uom']
+ productuom = self.env['product.uom']
for line in self:
if line.order_id.state not in ['purchase', 'done']:
line.qty_received = 0.0
@@ -455,15 +455,48 @@ class PurchaseOrderLine(models.Model):
if line.product_id.type not in ['consu', 'product']:
line.qty_received = line.product_qty
continue
- total = 0.0
- for move in line.move_ids:
- if move.state == 'done':
- if move.product_uom != line.product_uom:
- total += ProductUom._compute_qty_obj(move.product_uom, move.product_uom_qty, line.product_uom)
- else:
- total += move.product_uom_qty
+ bom_delivered = self.sudo()._get_bom_delivered(line.sudo())
+ if bom_delivered and any(bom_delivered.values()):
+ total = self.product_qty
+ elif bom_delivered:
+ total = 0.0
+ else:
+ total = 0.0
+ for move in line.move_ids:
+ if move.state == 'done':
+ if move.product_uom != line.product_uom:
+ total += productuom._compute_qty_obj(move.product_uom, move.product_uom_qty, line.product_uom)
+ else:
+ total += move.product_uom_qty
line.qty_received = total
+ def _get_bom_delivered(self, line):
+ precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+ bom_delivered = {}
+ # There is no dependencies between purchase and mrp
+ if 'mrp.bom' in self.env:
+ # In the case of a kit, we need to check if all components are shipped. We use a all or
+ # nothing policy. A product can have several BoMs, we don't know which one was used when the
+ # delivery was created.
+ for bom in line.product_id.product_tmpl_id.bom_ids:
+ if bom.type != 'phantom':
+ continue
+ bom_delivered[bom.id] = False
+ bom_exploded = self.env['mrp.bom']._bom_explode(bom, line.product_id, line.product_qty)[0]
+ for bom_line in bom_exploded:
+ qty = 0.0
+ for move in line.move_ids:
+ if move.state == 'done' and move.product_id.id == bom_line.get('product_id', False):
+ qty += self.env['product.uom']._compute_qty_obj(move.product_uom, move.product_uom_qty, self.product_uom)
+ if float_compare(qty, bom_line['product_qty'], precision_digits=precision) < 0:
+ bom_delivered[bom.id] = False
+ break
+ else:
+ bom_delivered[bom.id] = True
+ return bom_delivered
+
+
+
name = fields.Text(string='Description', required=True)
product_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True)
date_planned = fields.Datetime(string='Scheduled Date', required=True, select=True)
diff --git a/addons/website_theme_install/models/ir_module_module.py b/addons/website_theme_install/models/ir_module_module.py
index 09258d3385e..3a464bacd27 100644
--- a/addons/website_theme_install/models/ir_module_module.py
+++ b/addons/website_theme_install/models/ir_module_module.py
@@ -10,8 +10,8 @@ class IrModuleModule(models.Model):
string='Screenshots', readonly=True)
@api.model
- def update_list(self, context=None):
- res = super(IrModuleModule, self).update_list(context=context)
+ def update_list(self):
+ res = super(IrModuleModule, self).update_list()
IrAttachment = self.env['ir.attachment']
existing_urls = IrAttachment.search_read([['res_model', '=', self._name], ['type', '=', 'url']], ['url'])
@@ -36,15 +36,15 @@ class IrModuleModule(models.Model):
return res
@api.multi
- def button_choose_theme(self, context):
+ def button_choose_theme(self):
theme_category_id = self.env.ref('base.module_category_theme').id
self.search([ # Uninstall the theme(s) which is (are) installed
('state', '=', 'installed'),
'|', ('category_id', 'not in', [self.env.ref('base.module_category_hidden').id, self.env.ref('base.module_category_theme_hidden').id]), ('name', '=', 'theme_default'),
'|', ('category_id', '=', theme_category_id), ('category_id.parent_id', '=', theme_category_id)
- ]).button_immediate_uninstall(context=context)
+ ]).button_immediate_uninstall()
- next_action = self.button_immediate_install(context=context) # Then install the new chosen one
+ next_action = self.button_immediate_install() # Then install the new chosen one
if next_action.get('tag') == 'reload' and not next_action.get('params', {}).get('menu_id'):
next_action = self.env.ref('website.action_website_tutorial').read()[0]