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 @@ -
- - - Edit - - + diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index d6eba17d0f4..0b7f540f4ac 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -183,7 +183,7 @@ - + diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 5f6ab74f517..c44415fabab 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1222,9 +1222,9 @@ class function(_column): # if we already have a value, don't recompute it. # This happen if case of stored many2one fields if values and not multi and name in values[0]: - result = {v['id']: v[name] for v in values} + result = dict((v['id'], v[name]) for v in values) elif values and multi and all(n in values[0] for n in name): - result = {v['id']: dict((n, v[n]) for n in name) for v in values} + result = dict((v['id'], dict((n, v[n]) for n in name)) for v in values) else: result = self._fnct(obj, cr, uid, ids, name, self._arg, context) for id in ids: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index e7a7c6282b4..b99dff9aa2b 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -788,7 +788,7 @@ def trans_generate(lang, modules, cr): def get_module_paths(): # default addons path (base) def_path = os.path.abspath(os.path.join(config.config['root_path'], 'addons')) - mod_paths = { def_path } + mod_paths = set([ def_path ]) ad_paths = map(lambda m: os.path.abspath(m.strip()),config.config['addons_path'].split(',')) for adp in ad_paths: mod_paths.add(adp) @@ -796,7 +796,7 @@ def trans_generate(lang, modules, cr): mod_paths.add(adp) elif adp != def_path and adp.startswith(def_path): mod_paths.add(adp[len(def_path)+1:]) - return mod_paths + return list(mod_paths) def get_module_from_path(path, mod_paths): for mp in mod_paths: