diff --git a/addons/account/account.py b/addons/account/account.py index a9b03208d0b..6589ec724a2 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -2651,7 +2651,7 @@ class account_tax_code_template(osv.osv): company = self.pool.get('res.company').browse(cr, uid, company_id, context=context) #find all the children of the tax_code_root_id - children_tax_code_template = obj_tax_code_template.search(cr, uid, [('parent_id','child_of',[tax_code_root_id])], order='id') + children_tax_code_template = tax_code_root_id and obj_tax_code_template.search(cr, uid, [('parent_id','child_of',[tax_code_root_id])], order='id') or [] for tax_code_template in obj_tax_code_template.browse(cr, uid, children_tax_code_template, context=context): vals = { 'name': (tax_code_root_id == tax_code_template.id) and company.name or tax_code_template.name, diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 62a90dfdaf9..9772984bc3b 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -794,34 +794,39 @@ class account_invoice(osv.osv): line.append((0,0,val)) return line - def action_move_create(self, cr, uid, ids, *args): + def action_move_create(self, cr, uid, ids, context=None): """Creates invoice related analytics and financial move lines""" ait_obj = self.pool.get('account.invoice.tax') cur_obj = self.pool.get('res.currency') period_obj = self.pool.get('account.period') - context = {} - for inv in self.browse(cr, uid, ids): + payment_term_obj = self.pool.get('account.payment.term') + journal_obj = self.pool.get('account.journal') + move_obj = self.pool.get('account.move') + if context is None: + context = {} + for inv in self.browse(cr, uid, ids, context=context): if not inv.journal_id.sequence_id: raise osv.except_osv(_('Error !'), _('Please define sequence on the journal related to this invoice.')) if not inv.invoice_line: raise osv.except_osv(_('No Invoice Lines !'), _('Please create some invoice lines.')) if inv.move_id: continue - + + ctx = context.copy() + ctx.update({'lang': inv.partner_id.lang}) if not inv.date_invoice: - self.write(cr, uid, [inv.id], {'date_invoice':time.strftime('%Y-%m-%d')}) + self.write(cr, uid, [inv.id], {'date_invoice':time.strftime('%Y-%m-%d')}, context=ctx) company_currency = inv.company_id.currency_id.id # create the analytical lines # one move line per invoice line - iml = self._get_analytic_lines(cr, uid, inv.id) + iml = self._get_analytic_lines(cr, uid, inv.id, context=ctx) # check if taxes are all computed - ctx = context.copy() - ctx.update({'lang': inv.partner_id.lang}) compute_taxes = ait_obj.compute(cr, uid, inv.id, context=ctx) self.check_tax_lines(cr, uid, inv, compute_taxes, ait_obj) - if inv.type in ('in_invoice', 'in_refund') and abs(inv.check_total - inv.amount_total) >= (inv.currency_id.rounding/2.0): - raise osv.except_osv(_('Bad total !'), _('Please verify the price of the invoice !\nThe real total does not match the computed total.')) + # I disabled the check_total feature + #if inv.type in ('in_invoice', 'in_refund') and abs(inv.check_total - inv.amount_total) >= (inv.currency_id.rounding/2.0): + # raise osv.except_osv(_('Bad total !'), _('Please verify the price of the invoice !\nThe real total does not match the computed total.')) if inv.payment_term: total_fixed = total_percent = 0 @@ -859,8 +864,8 @@ class account_invoice(osv.osv): name = inv['name'] or '/' totlines = False if inv.payment_term: - totlines = self.pool.get('account.payment.term').compute(cr, - uid, inv.payment_term.id, total, inv.date_invoice or False) + totlines = payment_term_obj.compute(cr, + uid, inv.payment_term.id, total, inv.date_invoice or False, context=ctx) if totlines: res_amount_currency = total_currency i = 0 @@ -906,12 +911,12 @@ class account_invoice(osv.osv): date = inv.date_invoice or time.strftime('%Y-%m-%d') part = inv.partner_id.id - line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, part, date, context={})),iml) + line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, part, date, context=ctx)),iml) line = self.group_lines(cr, uid, iml, line, inv) journal_id = inv.journal_id.id - journal = self.pool.get('account.journal').browse(cr, uid, journal_id) + journal = journal_obj.browse(cr, uid, journal_id, context=ctx) if journal.centralisation: raise osv.except_osv(_('UserError'), _('You cannot create an invoice on a centralised journal. Uncheck the centralised counterpart box in the related journal from the configuration menu.')) @@ -935,13 +940,14 @@ class account_invoice(osv.osv): for i in line: i[2]['period_id'] = period_id - move_id = self.pool.get('account.move').create(cr, uid, move, context=context) - new_move_name = self.pool.get('account.move').browse(cr, uid, move_id).name + move_id = move_obj.create(cr, uid, move, context=ctx) + new_move_name = move_obj.browse(cr, uid, move_id, context=ctx).name # make the invoice point to that move - self.write(cr, uid, [inv.id], {'move_id': move_id,'period_id':period_id, 'move_name':new_move_name}) + self.write(cr, uid, [inv.id], {'move_id': move_id,'period_id':period_id, 'move_name':new_move_name}, context=ctx) # Pass invoice in context in method post: used if you want to get the same # account move reference when creating the same invoice after a cancelled one: - self.pool.get('account.move').post(cr, uid, [move_id], context={'invoice':inv}) + ctx.update({'invoice':inv}) + move_obj.post(cr, uid, [move_id], context=ctx) self._log_event(cr, uid, ids) return True @@ -1262,7 +1268,7 @@ class account_invoice_line(osv.osv): def _price_unit_default(self, cr, uid, context=None): if context is None: context = {} - if 'check_total' in context: + if context.get('check_total', False): t = context['check_total'] for l in context.get('invoice_line', {}): if isinstance(l, (list, tuple)) and len(l) >= 3 and l[2]: diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index 2928d5421a2..41e5aff24c8 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -168,7 +168,7 @@ - + @@ -179,7 +179,7 @@ - + @@ -303,7 +303,6 @@ +
    -
    - - -
    @@ -188,7 +188,7 @@
    - + diff --git a/addons/point_of_sale/wizard/pos_box_entries.py b/addons/point_of_sale/wizard/pos_box_entries.py index eff86611278..3a4675a8296 100644 --- a/addons/point_of_sale/wizard/pos_box_entries.py +++ b/addons/point_of_sale/wizard/pos_box_entries.py @@ -44,7 +44,6 @@ def get_journal(self, cr, uid, context=None): res = [(r['journal_id']) for r in res] if not len(res): raise osv.except_osv(_('Error !'), _('You do not have any open cash register. You must create a payment method or open a cash register.')) - res.insert(0, ('', '')) return res class pos_box_entries(osv.osv_memory): @@ -70,8 +69,8 @@ class pos_box_entries(osv.osv_memory): _columns = { 'name': fields.char('Reason', size=32, required=True), - 'journal_id': fields.selection(get_journal, "Cash Register", required=True), - 'product_id': fields.selection(_get_income_product, "Operation", required=True), + 'journal_id': fields.selection(get_journal, "Cash Register", required=True, size=-1), + 'product_id': fields.selection(_get_income_product, "Operation", required=True, size=-1), 'amount': fields.float('Amount', digits=(16, 2), required=True), 'ref': fields.char('Ref', size=32), } diff --git a/addons/point_of_sale/wizard/pos_box_out.py b/addons/point_of_sale/wizard/pos_box_out.py index 4fdc79738ae..f07c05cb2e6 100644 --- a/addons/point_of_sale/wizard/pos_box_out.py +++ b/addons/point_of_sale/wizard/pos_box_out.py @@ -45,13 +45,12 @@ class pos_box_out(osv.osv_memory): ids = product_obj.search(cr, uid, ['&', ('expense_pdt', '=', True), '|', ('company_id', '=', company_id), ('company_id', '=', None)], context=context) res = product_obj.read(cr, uid, ids, ['id', 'name'], context=context) res = [(r['id'], r['name']) for r in res] - res.insert(0, ('', '')) return res _columns = { 'name': fields.char('Description / Reason', size=32, required=True), - 'journal_id': fields.selection(pos_box_entries.get_journal, "Cash Register", required=True), - 'product_id': fields.selection(_get_expense_product, "Operation", required=True), + 'journal_id': fields.selection(pos_box_entries.get_journal, "Cash Register", required=True, size=-1), + 'product_id': fields.selection(_get_expense_product, "Operation", required=True, size=-1), 'amount': fields.float('Amount', digits=(16, 2), required=True), } _defaults = { diff --git a/addons/portal/portal.py b/addons/portal/portal.py index de39944e69f..4a96df1a65f 100644 --- a/addons/portal/portal.py +++ b/addons/portal/portal.py @@ -98,6 +98,7 @@ class portal(osv.osv): def do_create_menu(self, cr, uid, ids, context=None): """ create a parent menu for the given portals """ menu_obj = self.pool.get('ir.ui.menu') + ir_data = self.pool.get('ir.model.data') menu_root = self._res_xml_id(cr, uid, 'portal', 'portal_menu') for p in self.browse(cr, uid, ids, context): @@ -110,7 +111,13 @@ class portal(osv.osv): menu_id = menu_obj.create(cr, uid, menu_values, context) # set the parent_menu_id to item_id self.write(cr, uid, [p.id], {'parent_menu_id': menu_id}, context) - + menu_values.pop('parent_id') + menu_values.pop('groups_id') + menu_values.update({'model': 'ir.ui.menu', + 'module': 'portal', + 'res_id': menu_id, + 'noupdate': 'True'}) + data_id = ir_data.create(cr, uid, menu_values, context) return True def _assign_menu(self, cr, uid, ids, context=None): diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 55b843ec68b..164314c4573 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -567,4 +567,12 @@ class stock_warehouse_orderpoint(osv.osv): return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context=context) stock_warehouse_orderpoint() + +class product_product(osv.osv): + _inherit="product.product" + _columns = { + 'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rule') + } +product_product() + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index 400412298cc..518a8900072 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -275,5 +275,30 @@ + + + product.normal.form.orderpoint.inherit + product.product + form + + + + + + + + + + + + + + + + + + + + diff --git a/addons/product/__openerp__.py b/addons/product/__openerp__.py index 81ec3a0ae64..d63e4cc130b 100644 --- a/addons/product/__openerp__.py +++ b/addons/product/__openerp__.py @@ -61,7 +61,11 @@ Print product labels with barcode. 'partner_view.xml', 'process/product_process.xml' ], - 'test':['test/product_report.yml','test/product_test.yml'], + 'test':[ + 'test/product_test.yml', + 'test/product_price_list.yml', + 'test/product_report.yml', + ], 'installable': True, 'active': False, 'certificate': '0068861431437', diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index 2ed53ce0acf..a331d5c8b6b 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -321,6 +321,7 @@ product + TOW1 37.5 diff --git a/addons/product/test/product_price_list.yml b/addons/product/test/product_price_list.yml new file mode 100644 index 00000000000..1ebb75d78dd --- /dev/null +++ b/addons/product/test/product_price_list.yml @@ -0,0 +1,124 @@ +- + In order to check the calculation of price of the products according to selected pricelist, + I create a pricelist rule for giving discount on some quantities of product. +- + !record {model: product.pricelist.item, id: item0}: + name: Default Public Pricelist for More Qty + min_quantity: 15 + price_discount: -0.10 +- + I check whether the product consumes the price, based on the given quantities, correctly or not. +- + !python {model: product.pricelist}: | + product_obj = self.pool.get("product.product") + result = self.price_get_multi(cr, uid, [ref("product.list0")], [(ref("product_product_pc1"),15,False)]) + new_price = result[ref("product_product_pc1")].values() + context.update({'pricelist': ref("product.list0"), 'quantity': 15}) + product_price = product_obj.browse(cr, uid, ref("product_product_pc1"), context=context).price + assert new_price[0] == product_price,"Discount is not given on price of the product." +- + I create a pricelist rule to give discount for a specific product. +- + !record {model: product.pricelist.item, id: pricelist_rules_for_pc2}: + name: Default Public Pricelist for PC2 + min_quantity: 1 + product_id: product.product_product_pc2 + sequence: 4 + base: !eval (ref('product.list_price')) + price_version_id: product.ver0 + price_discount: -0.20 +- + I check whether the selected product is having the price correctly or not. +- + !python {model: product.pricelist}: | + result = self.price_get_multi(cr, uid, [ref("product.list0")], [(ref("product_product_pc2"),1,False)]) + product_obj = self.pool.get("product.product") + new_price = result[ref("product_product_pc2")].values() + context.update({'pricelist': ref("product.list0"), 'quantity': 1}) + product_price = product_obj.browse(cr, uid, ref("product_product_pc2"), context=context).price + assert new_price[0] == product_price,"Discount is not given on price of the special product." +- + I create a pricelist rule to give discount for a specific category of products. +- + !record {model: product.pricelist.item, id: pricelist_rules_category_1}: + name: Default Public Pricelist for Category + min_quantity: 1 + categ_id: product.cat1 + sequence: 3 + base: !eval (ref('product.list_price')) + price_version_id: product.ver0 + price_discount: -0.25 +- + I check whether the price of products of selected product category is correctly set or not. +- + !python {model: product.pricelist}: | + result = self.price_get_multi(cr, uid, [ref("product.list0")], [(ref("product_product_fan2"),1,False)]) + product_obj = self.pool.get("product.product") + new_price = result[ref("product_product_fan2")].values() + context.update({'pricelist': ref("product.list0"), 'quantity': 1}) + product_price = product_obj.browse(cr, uid, ref("product_product_fan2"), context=context).price + assert new_price[0] == product_price,"Discount is not given on price of the special category of products." +- + I create a pricelist to give the discount at the end of year. +- + !record {model: product.pricelist, id: product_price_list_end_year}: + name: End of Year Price List + type: sale + version_id: + - name: End of Year Price List Version + items_id: + - name: End of Year Price List Version Rule + min_quantity: 1 + base: !eval (ref('product.list_price')) + price_discount: -0.30 +- + !record {model: product.pricelist.item, id: pricelist_rules_for_end_year1}: + name: End of Year Price List Version Rule - Public Pricelist + min_quantity: 1 + sequence: 2 + base: -1 + price_version_id: product.ver0 + base_pricelist_id: product_price_list_end_year +- + Now, I check that the end of the year pricelist rule is applied on products. +- + !python {model: product.pricelist}: | + result = self.price_get_multi(cr, uid, [ref("product.list0")], [(ref("product_product_pc1"),1,False)]) + new_price = result[ref("product_product_pc1")].values() + product_obj = self.pool.get("product.product") + context.update({'pricelist': ref("product.list0"), 'quantity': 1}) + product_price = product_obj.browse(cr, uid, ref("product_product_pc1"), context=context).price + assert new_price[0] == product_price,"Discount is not given on price of product at the end of the year." +- + I create a pricelist for special customers by which they can get discount on products. +- + !record {model: product.pricelist, id: special_customer_price_list1}: + name: Price List For Special Customer + type: sale + version_id: + - name: Special Customer Price List Version + items_id: + - name: Special Customer Price List Version Rule + min_quantity: 1 + base: !eval (ref('product.list_price')) + price_discount: -0.40 +- + !record {model: res.partner, id: base.res_partner_agrolait}: + property_product_pricelist: special_customer_price_list1 +- + I check that the customer is getting the discount according to the pricelist. +- + !python {model: product.pricelist}: | + result = self.price_get_multi(cr, uid, [ref("product.special_customer_price_list1")], [(ref("product_product_pc4"),1,ref("base.res_partner_agrolait"))]) + product_obj = self.pool.get("product.product") + new_price = result[ref("product_product_pc4")].values() + context.update({'pricelist': ref("product.special_customer_price_list1"), 'quantity': 1}) + product_price = product_obj.browse(cr, uid, ref("product_product_pc4"), context=context).price + assert new_price[0] == product_price,"Discount is not given to special customer." +- + I set the supplier pricelist for a product to get the discount at the time of purchase. +- + !record {model: product.supplierinfo, id: supplierinfo5}: + pricelist_ids: + - min_quantity: 10 + price: 200 diff --git a/addons/project/project.py b/addons/project/project.py index c0fb9d61438..5dcfef1a47e 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -517,7 +517,7 @@ class task(osv.osv): if not project_id: return {} data = self.pool.get('project.project').browse(cr, uid, [project_id]) - partner_id=data and data[0].parent_id.partner_id + partner_id=data and data[0].partner_id if partner_id: return {'value':{'partner_id':partner_id.id}} return {} diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index 1ed2bc034e6..8f666067d50 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -41,7 +41,7 @@ - + @@ -49,7 +49,7 @@