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 efd5135c09b..9772984bc3b 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -824,8 +824,9 @@ class account_invoice(osv.osv): 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 @@ -1267,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..e198e9e3069 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -152,7 +152,7 @@ +
    -
    - - -
    @@ -188,7 +188,7 @@
    - + 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..846aa5881f2 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': [ + 'product_pricelist_demo.yml', + 'test/product_uom.yml', + 'test/product_pricelist.yml', + ], 'installable': True, 'active': False, 'certificate': '0068861431437', diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index db953c8a319..ea29292f445 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -271,7 +271,7 @@ class product_pricelist(osv.osv): if price is not False: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) - price = rounding(price, res['price_round']) + price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) diff --git a/addons/product/product.py b/addons/product/product.py index 874680cb17d..a443ebe6033 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -218,6 +218,8 @@ class product_category(osv.osv): 'child_id': fields.one2many('product.category', 'parent_id', string='Child Categories'), 'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of product categories."), 'type': fields.selection([('view','View'), ('normal','Normal')], 'Category Type'), + 'parent_left': fields.integer('Left Parent', select=1), + 'parent_right': fields.integer('Right Parent', select=1), } @@ -225,7 +227,11 @@ class product_category(osv.osv): 'type' : lambda *a : 'normal', } - _order = "sequence, name" + _parent_name = "parent_id" + _parent_store = True + _parent_order = 'sequence, name' + _order = 'parent_left' + def _check_recursion(self, cr, uid, ids, context=None): level = 100 while len(ids): @@ -406,10 +412,11 @@ class product_product(osv.osv): context = {} quantity = context.get('quantity') or 1.0 pricelist = context.get('pricelist', False) + partner = context.get('partner', False) if pricelist: for id in ids: try: - price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, context=context)[pricelist] + price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, partner=partner, context=context)[pricelist] except: price = 0.0 res[id] = price 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/product_pricelist_demo.yml b/addons/product/product_pricelist_demo.yml new file mode 100644 index 00000000000..d5228422a83 --- /dev/null +++ b/addons/product/product_pricelist_demo.yml @@ -0,0 +1,62 @@ +- + !record {model: product.product, id: product_product_pc2}: + uom_id: product_uom_unit + categ_id: product_category_pc +- + !record {model: product.pricelist, id: customer_pricelist}: + name: Customer Pricelist + type: sale + version_id: + - name: v1.0 + date_start: 2012-01-01 + items_id: + - name: Default pricelist + base: -1 + base_pricelist_id: list0 + - name: 10% Discount on PC2 + sequence: 1 + product_id: product_product_pc2 + base: !eval (ref('product.list_price')) + price_discount: -0.10 + - name: 1 surchange on PC3 + sequence: 1 + product_id: product_product_pc3 + base: !eval (ref('product.list_price')) + price_surcharge: 1 + - name: 5% Discount on all IT components + sequence: 1 + min_quantity: 2 + base: !eval (ref('product.list_price')) + categ_id: product_category_10 + price_discount: -0.05 + - name: v2.0 (Special Discount on all products during last 5 days in current year) + date_start: 2011-12-27 + date_end: 2011-12-31 + items_id: + - name: 30% Discount on all products + price_discount: -0.30 + sequence: 1 + base: !eval (ref('product.list_price')) +- + !record {model: product.pricelist, id: supplier_pricelist}: + name: Supplier Pricelist + type: sale + version_id: + - name: v1.0 + items_id: + - name: 20% Discount given by my supplier + sequence: 1 + price_min_margin: 2 + price_max_margin: -5 + product_id: product_product_pc2 + base: -2 +- + !record {model: pricelist.partnerinfo, id: supplier_pricelist0_product_pc2}: + suppinfo_id: supplierinfo6 + min_quantity: 3 + price: 405 +- + !record {model: pricelist.partnerinfo, id: supplier_pricelist1_product_pc2}: + suppinfo_id: supplierinfo6 + min_quantity: 1 + price: 455 diff --git a/addons/product/test/product_pricelist.yml b/addons/product/test/product_pricelist.yml new file mode 100644 index 00000000000..2dbc4be1120 --- /dev/null +++ b/addons/product/test/product_pricelist.yml @@ -0,0 +1,75 @@ +- + In order to check the calculation of price of the products according to pricelist, +- + I check sale price of PC2. +- + !python {model: product.product}: | + context.update({'pricelist': ref("customer_pricelist"), 'quantity':1}) + product = self.browse(cr, uid, ref("product_product_pc2"), context=context) + assert product.price == product.lst_price-product.lst_price*(0.10), "Sell price is not correspond." +- + I check sale price of PC3. +- + !python {model: product.product}: | + product = self.browse(cr, uid, ref("product_product_pc3"), context=context) + assert product.price == product.lst_price + 1, "Sell price is not correspond." +- + I check sale price of IT componet. +- + !python {model: product.product}: | + product = self.browse(cr, uid, ref("product_product_mb1"), context=context) + assert product.price == product.lst_price, "Sell price is not correspond." + +- + I check sale price of IT componet if more than 3 PCE. +- + !python {model: product.product}: | + context.update({'quantity':5}) + product = self.browse(cr, uid, ref("product_product_mb1"), context=context) + assert product.price == product.lst_price-product.lst_price*(0.05), "Sell price is not correspond." +- + I check sale price of PC4. +- + !python {model: product.product}: | + context.update({'quantity':1}) + product = self.browse(cr, uid, ref("product_product_pc4"), context=context) + assert product.price == product.lst_price, "Sell price is not correspond." + +- + I check sale price of PC4 on end of year. +- + !python {model: product.product}: | + context.update({'quantity':1, 'date': '2011-12-31'}) + product = self.browse(cr, uid, ref("product_product_pc4"), context=context) + assert product.price == product.lst_price-product.lst_price*(0.30), "Sell price is not correspond." + +- + I check cost price of PC2. +- + !python {model: product.product}: | + context.update({'quantity':1, 'date': False, 'partner': ref('base.res_partner_4'), 'pricelist': ref("supplier_pricelist")}) + product = self.browse(cr, uid, ref("product_product_pc2"), context=context) + assert product.price == 450, "cost price is not correspond." +- + I check cost price of PC2 if more than 3 PCE. +- + !python {model: product.product}: | + context.update({'quantity':3}) + product = self.browse(cr, uid, ref("product_product_pc2"), context=context) + assert product.price == 400, "cost price is not correspond." + +- + I print the sale prices report. +- + !python {model: product.product}: | + ctx = {'model': 'product.product', 'date': '2011-12-30', 'active_ids': [ref('product.product_product_pc1'), ref('product.product_product_pc2'), ref('product.product_product_pc3'), ref('product.product_product_pc4')]} + data_dict = { + 'qty1': 1, + 'qty2': 5, + 'qty3': 10, + 'qty4': 15, + 'qty5': 30, + 'price_list':ref('customer_pricelist'), + } + from tools import test_reports + test_reports.try_report_action(cr, uid, 'action_product_price_list',wiz_data=data_dict, context=ctx, our_module='product') diff --git a/addons/product/test/product_report.yml b/addons/product/test/product_report.yml deleted file mode 100644 index 397c2c9d0b6..00000000000 --- a/addons/product/test/product_report.yml +++ /dev/null @@ -1,16 +0,0 @@ -- - Print the Products Pricelists Report through the wizard -- - !python {model: product.product}: | - ctx={} - ctx.update({'model': 'product.product','active_ids': [ref('product.product_product_pc1'), ref('product.product_product_pc3')]}) - data_dict = {'qty1': 1, - 'qty2': 5, - 'qty3': 10, - 'qty4': 0, - 'qty5': 0, - 'price_list':ref('product.list0')} - from tools import test_reports - test_reports.try_report_action(cr, uid, 'action_product_price_list',wiz_data=data_dict, context=ctx, our_module='product') - - diff --git a/addons/product/test/product_test.yml b/addons/product/test/product_test.yml deleted file mode 100644 index ae75a552c79..00000000000 --- a/addons/product/test/product_test.yml +++ /dev/null @@ -1,33 +0,0 @@ -- - In order to test product,I start by creating a 20KG UOM for 'Sugar' -- - !record {model: product.uom, id: product_20k_uom_sugar}: - name: 20KG - uom_type: bigger - category_id: product.product_uom_categ_kgm - factor_inv: 20 -- - I create a 10KG UOM for 'Sugar' -- - !record {model: product.uom, id: product_10k_uom_sugar}: - name: 10KG - uom_type: bigger - category_id: product.product_uom_categ_kgm - factor_inv: 10 -- - I create a new product 'Sugar' in 20KG UOM. -- - !record {model: product.product, id: product_sugar_id1}: - categ_id: 'product.product_category_rawmaterial0' - name: Sugar 20KG - procure_method: make_to_order - standard_price: 400.0 - uom_id: product.product_20k_uom_sugar - uom_po_id: product.product_20k_uom_sugar -- - I test onchanged on UOM, Create Duplicate Product and Delete original Product. -- - !python {model: product.product}: | - self.onchange_uom(cr ,uid, [ref("product_sugar_id1")], ref("product.product_20k_uom_sugar"), ref("product.product_10k_uom_sugar")) - self.copy(cr, uid, ref("product_sugar_id1")) - self.unlink(cr, uid, [ref("product_sugar_id1")]) diff --git a/addons/product/test/product_uom.yml b/addons/product/test/product_uom.yml new file mode 100644 index 00000000000..04928d43d87 --- /dev/null +++ b/addons/product/test/product_uom.yml @@ -0,0 +1,15 @@ +- + In order to test conversation of UOM, +- + I convert Grams into TON with price. +- + !python {model: product.uom}: | + from_uom_id = ref("product_uom_gram") + to_uom_id = ref("product_uom_ton") + price = 2 + qty = 1020000 + price = self._compute_price(cr, uid, from_uom_id, price, to_uom_id) + qty = self._compute_qty(cr, uid, from_uom_id, qty, to_uom_id) + assert qty == 1.02, "Qty is not correspond." + assert price == 2000000.0, "Price is not correspond." + diff --git a/addons/project/security/ir.model.access.csv b/addons/project/security/ir.model.access.csv index e919f09cee1..3dc9cdbab46 100644 --- a/addons/project/security/ir.model.access.csv +++ b/addons/project/security/ir.model.access.csv @@ -17,3 +17,4 @@ access_account_analytic_line_project,account.analytic.line project,analytic.mode access_project_task_history,project.task.history project,project.model_project_task_history,project.group_project_user,1,1,1,0 access_project_task_history_cumulative,project.task.history project,project.model_project_task_history_cumulative,project.group_project_manager,1,0,0,0 access_resource_calendar,project.resource_calendar manager,resource.model_resource_calendar,project.group_project_manager,1,0,0,0 +access_mail_message_project_user,project.mail.message.user,mail.model_mail_message,project.group_project_user,1,1,1,0 diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 948352940a0..318e305b8ea 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -76,10 +76,10 @@ Dashboard for Sales Manager that includes: 'company_view.xml', 'sale_workflow.xml', 'sale_sequence.xml', + 'sale_report.xml', 'sale_data.xml', 'sale_view.xml', 'report/sale_report_view.xml', - 'sale_report.xml', 'stock_view.xml', 'process/sale_process.xml', 'board_sale_view.xml', diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 478c8276a90..f5b797c9f66 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -102,12 +102,16 @@ - - - - - - + + + + + + + + + + @@ -118,7 +122,7 @@ - + @@ -195,18 +199,20 @@