diff --git a/addons/account/account.py b/addons/account/account.py
index 8ef4da0d66b..a5b170a9e46 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -1681,7 +1681,8 @@ class account_move_reconcile(osv.osv):
if not total:
self.pool.get('account.move.line').write(cr, uid,
map(lambda x: x.id, rec.line_partial_ids),
- {'reconcile_id': rec.id }
+ {'reconcile_id': rec.id },
+ context=context
)
return True
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index b7d4e6b7fb9..bbe70b3881e 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -802,11 +802,14 @@ class account_move_line(osv.osv):
if self.pool.get('res.currency').is_zero(cr, uid, currency_id, total):
res = self.reconcile(cr, uid, merges+unmerge, context=context, writeoff_acc_id=writeoff_acc_id, writeoff_period_id=writeoff_period_id, writeoff_journal_id=writeoff_journal_id)
return res
+ # marking the lines as reconciled does not change their validity, so there is no need
+ # to revalidate their moves completely.
+ reconcile_context = dict(context, novalidate=True)
r_id = move_rec_obj.create(cr, uid, {
'type': type,
'line_partial_ids': map(lambda x: (4,x,False), merges+unmerge)
- }, context=context)
- move_rec_obj.reconcile_partial_check(cr, uid, [r_id] + merges_rec, context=context)
+ }, context=reconcile_context)
+ move_rec_obj.reconcile_partial_check(cr, uid, [r_id] + merges_rec, context=reconcile_context)
return True
def reconcile(self, cr, uid, ids, type='auto', writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False, context=None):
@@ -931,11 +934,14 @@ class account_move_line(osv.osv):
writeoff_line_ids = [writeoff_line_ids[1]]
ids += writeoff_line_ids
+ # marking the lines as reconciled does not change their validity, so there is no need
+ # to revalidate their moves completely.
+ reconcile_context = dict(context, novalidate=True)
r_id = move_rec_obj.create(cr, uid, {
'type': type,
'line_id': map(lambda x: (4, x, False), ids),
'line_partial_ids': map(lambda x: (3, x, False), ids)
- })
+ }, context=reconcile_context)
# the id of the move.reconcile is written in the move.line (self) by the create method above
# because of the way the line_id are defined: (4, x, False)
for id in ids:
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index ae2d0dcdcfb..3ac0efb3263 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -358,7 +358,7 @@ class account_voucher(osv.osv):
\n* The \'Posted\' status is used when user create voucher,a voucher number is generated and voucher entries are created in account \
\n* The \'Cancelled\' status is used when user cancel voucher.'),
'amount': fields.float('Total', digits_compute=dp.get_precision('Account'), required=True, readonly=True, states={'draft':[('readonly',False)]}),
- 'tax_amount':fields.float('Tax Amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
+ 'tax_amount':fields.float('Tax Amount', digits_compute=dp.get_precision('Account'), readonly=True),
'reference': fields.char('Ref #', size=64, readonly=True, states={'draft':[('readonly',False)]}, help="Transaction reference number."),
'number': fields.char('Number', size=32, readonly=True,),
'move_id':fields.many2one('account.move', 'Account Entry'),
@@ -1323,10 +1323,14 @@ class account_voucher(osv.osv):
if voucher.payment_option == 'with_writeoff':
account_id = voucher.writeoff_acc_id.id
write_off_name = voucher.comment
- elif voucher.type in ('sale', 'receipt'):
- account_id = voucher.partner_id.property_account_receivable.id
+ elif voucher.partner_id:
+ if voucher.type in ('sale', 'receipt'):
+ account_id = voucher.partner_id.property_account_receivable.id
+ else:
+ account_id = voucher.partner_id.property_account_payable.id
else:
- account_id = voucher.partner_id.property_account_payable.id
+ # fallback on account of voucher
+ account_id = voucher.account_id.id
sign = voucher.type == 'payment' and -1 or 1
move_line = {
'name': write_off_name or name,
diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml
index b7ea4b8fc71..c3a1c5c60a8 100644
--- a/addons/account_voucher/account_voucher_view.xml
+++ b/addons/account_voucher/account_voucher_view.xml
@@ -159,7 +159,7 @@
account.voucher
form
tree,form,graph
- {'type':'general'}
+ {}
diff --git a/addons/auth_oauth/auth_oauth.py b/addons/auth_oauth/auth_oauth.py
index 34b6aa44936..f9fb206f51e 100644
--- a/addons/auth_oauth/auth_oauth.py
+++ b/addons/auth_oauth/auth_oauth.py
@@ -21,4 +21,5 @@ class auth_oauth_provider(osv.osv):
}
_defaults = {
'enabled' : False,
+ 'css_class' : "zocial",
}
diff --git a/addons/point_of_sale/report/pos_order_report.py b/addons/point_of_sale/report/pos_order_report.py
index 5489ccf7099..501a829a46e 100644
--- a/addons/point_of_sale/report/pos_order_report.py
+++ b/addons/point_of_sale/report/pos_order_report.py
@@ -27,7 +27,7 @@ class pos_order_report(osv.osv):
_description = "Point of Sale Orders Statistics"
_auto = False
_columns = {
- 'date': fields.date('Date Order', readonly=True),
+ 'date': fields.datetime('Date Order', readonly=True),
'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'state': fields.selection([('draft', 'New'), ('paid', 'Closed'), ('done', 'Synchronized'), ('invoiced', 'Invoiced'), ('cancel', 'Cancelled')],
diff --git a/addons/product/product.py b/addons/product/product.py
index 8496245ea91..76270b6e796 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -684,6 +684,9 @@ class product_product(osv.osv):
unlink_ids = []
unlink_product_tmpl_ids = []
for product in self.browse(cr, uid, ids, context=context):
+ # Check if product still exists, in case it has been unlinked by unlinking its template
+ if not product.exists():
+ continue
tmpl_id = product.product_tmpl_id.id
# Check if the product is last product of this template
other_product_ids = self.search(cr, uid, [('product_tmpl_id', '=', tmpl_id), ('id', '!=', product.id)], context=context)
diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py
index 2d5dea89d35..7cec0137155 100644
--- a/addons/purchase/stock.py
+++ b/addons/purchase/stock.py
@@ -126,7 +126,7 @@ class stock_partial_picking(osv.osv_memory):
# Overridden to inject the purchase price as true 'cost price' when processing
# incoming pickings.
def _product_cost_for_average_update(self, cr, uid, move):
- if move.picking_id.purchase_id:
+ if move.picking_id.purchase_id and move.purchase_line_id:
return {'cost': move.purchase_line_id.price_unit,
'currency': move.picking_id.purchase_id.currency_id.id}
return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
diff --git a/addons/stock/product.py b/addons/stock/product.py
index 1cd93225d45..724a2097ba0 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -277,6 +277,8 @@ class product_product(osv.osv):
if prodlot_id:
prodlot_clause = ' and prodlot_id = %s '
where += [prodlot_id]
+ elif 'prodlot_id' in context and not prodlot_id:
+ prodlot_clause = ' and prodlot_id is null '
# TODO: perhaps merge in one query.
if 'in' in what:
diff --git a/addons/stock/test/opening_stock.yml b/addons/stock/test/opening_stock.yml
index 9efcfd3af99..5dfb5c4b9fa 100644
--- a/addons/stock/test/opening_stock.yml
+++ b/addons/stock/test/opening_stock.yml
@@ -37,6 +37,36 @@
!python {model: product.product}: |
product = self.browse(cr, uid, ref('product_product_6'), context=context)
assert product.qty_available == 10, "Stock is not updated."
+-
+ I update the current stock of the Ice-cream with 10 kgm without Production Lot.
+-
+ !record {model: stock.change.product.qty, id: change_qty_nolot}:
+ location_id: location_monitor_small
+ new_quantity: 10
+ product_id: product_product_6
+-
+ !python {model: stock.change.product.qty}: |
+ self.change_product_qty(cr, uid, [ref('change_qty_nolot')], context=dict(context, active_id=ref('product_product_6')))
+-
+ I check available stock of Ice-cream after update stock.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_product_6'), context=context)
+ assert product.qty_available == 20, "Real stock is not updated."
+-
+ I revert 10kgm updated stock again with no production lot in order to level the stock
+-
+ !record {model: stock.change.product.qty, id: change_qty_nolot_1}:
+ location_id: location_monitor_small
+ new_quantity: 0
+ product_id: product_product_6
+-
+ !python {model: stock.change.product.qty}: |
+ self.change_product_qty(cr, uid, [ref('change_qty_nolot_1')], context=dict(context, active_id=ref('product_product_6')))
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_product_6'), context=context)
+ assert product.qty_available == 10, "Real stock is not updated."
-
Stock user can merge inventory, so let's check data with giving the access rights of user.
-
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 144de8eb21c..4bff19baf30 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -258,7 +258,7 @@
if (!focus_field){
focus_field = _.find(self.editor.form.fields_order, function(field){ return fields[field] && fields[field].$el.is(':visible:has(input)'); });
}
- if (focus_field) fields[focus_field].$el.find('input').select();
+ if (focus_field && fields[focus_field]) fields[focus_field].$el.find('input').select();
return record.attributes;
});
}).fail(function () {
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 1fa1c544845..3fcc4786419 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1214,16 +1214,18 @@
-