From 14b82482893aae6b7c37298c962ecdab13a84487 Mon Sep 17 00:00:00 2001 From: "uco (Open ERP)" Date: Tue, 28 Sep 2010 17:27:44 +0530 Subject: [PATCH 01/18] [IMP] point_of_sale: Improved according to changes in account. bzr revid: uco@tinyerp.com-20100928115744-j0ljddt1lt480x7z --- addons/point_of_sale/account_bank_statement.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/point_of_sale/account_bank_statement.py b/addons/point_of_sale/account_bank_statement.py index 395319eeb64..c2d7577491c 100644 --- a/addons/point_of_sale/account_bank_statement.py +++ b/addons/point_of_sale/account_bank_statement.py @@ -46,8 +46,8 @@ class account_cash_statement(osv.osv): _inherit = 'account.bank.statement' - def _equal_balance(self, cr, uid, ids, statement, context={}): - + def _equal_balance(self, cr, uid, cash_id, context={}): + statement = self.browse(cr, uid, cash_id, context=context) if not statement.journal_id.check_dtls: return True From f548ef17747eb0d2221afc5f086402923f00718a Mon Sep 17 00:00:00 2001 From: "uco (Open ERP)" Date: Tue, 28 Sep 2010 17:53:28 +0530 Subject: [PATCH 02/18] [REM] point_of_sale: Removed unused import statements suggested by buildbot. bzr revid: uco@tinyerp.com-20100928122328-dxatkro1ygk85a6x --- addons/point_of_sale/account_bank_statement.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/point_of_sale/account_bank_statement.py b/addons/point_of_sale/account_bank_statement.py index c2d7577491c..c24dc221596 100644 --- a/addons/point_of_sale/account_bank_statement.py +++ b/addons/point_of_sale/account_bank_statement.py @@ -20,12 +20,8 @@ # ############################################################################## -import time from osv import osv from osv import fields -from mx import DateTime -from decimal import Decimal -from tools.translate import _ class account_journal(osv.osv): From 18412c566a8172ec3b8ebe3236a61743114840e6 Mon Sep 17 00:00:00 2001 From: "uco (Open ERP)" Date: Wed, 29 Sep 2010 11:21:28 +0530 Subject: [PATCH 03/18] [FIX] point_of_sale: Removed demo data resulting into error and kept it in yaml instead. bzr revid: uco@tinyerp.com-20100929055128-8ft419k4sos1w766 --- addons/point_of_sale/pos_demo.xml | 9 --------- addons/point_of_sale/test/pos_report.yml | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/point_of_sale/pos_demo.xml b/addons/point_of_sale/pos_demo.xml index 18029826008..80ba3d24397 100644 --- a/addons/point_of_sale/pos_demo.xml +++ b/addons/point_of_sale/pos_demo.xml @@ -61,14 +61,5 @@ Discount Applied - - St. 05/19 - 0.0 - 2010-05-19 - - - draft - - diff --git a/addons/point_of_sale/test/pos_report.yml b/addons/point_of_sale/test/pos_report.yml index 1747fb60305..c524ab13087 100644 --- a/addons/point_of_sale/test/pos_report.yml +++ b/addons/point_of_sale/test/pos_report.yml @@ -67,6 +67,16 @@ (data, format) = netsvc.LocalService('report.pos.details').create(cr, uid, [], {'model':'ir.ui.menu', 'form':{'date_start': time.strftime('%Y-%m-%d'), 'date_end': time.strftime('%Y-%m-%d') }}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale- pos details report'+format), 'wb+').write(data) +- + I create a record for Bank Statement. +- + !record {model: account.bank.statement, id: account_bank_statement_st0}: + name: St.05/19 + balance_end_real: 0.0 + date: '2010-05-19' + journal_id: account.bank_journal + period_id: account.period_5 + state: 'draft' - In order to test the PDF reports defined on a Point Of Sale, we will print a Account Statement Report - From 28f3bba64d6d2c9a9392ea8c1eabb34eee9ff969 Mon Sep 17 00:00:00 2001 From: "DHS(OpenERP)" <> Date: Wed, 29 Sep 2010 13:23:45 +0530 Subject: [PATCH 04/18] [FIX] project : When duplicating a task the stage should not be duplicated bzr revid: ach@tinyerp.com-20100929075345-jdyoich0f5wdd2bn --- addons/project/project.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/project/project.py b/addons/project/project.py index da3fef05f66..a1f02124c9d 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -389,6 +389,7 @@ class task(osv.osv): if not default.get('remaining_hours', False): default['remaining_hours'] = float(self.read(cr, uid, id, ['planned_hours'])['planned_hours']) default['active'] = True + default['type_id'] = False if not default.get('name', False): default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)') return super(task, self).copy_data(cr, uid, id, default, context) From 2db8aa4f9eb5fa1db4bbde6c20f0e97f06c94a46 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 29 Sep 2010 14:21:08 +0530 Subject: [PATCH 05/18] [FIX] project: change place of manager filter button on search view of project bzr revid: hmo@tinyerp.com-20100929085108-7x3oh14swkfi583v --- addons/project/project_view.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index e1b64ccbf1b..501c4787dee 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -107,11 +107,12 @@ - - + + + From 7f5e2da3d42fcb90bd765ad2042cb6c21b992772 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 29 Sep 2010 14:29:23 +0530 Subject: [PATCH 06/18] [FIX]l10n_lu: use get_module_resource to avoid fix path bzr revid: hmo@tinyerp.com-20100929085923-xy5iyns88n7bzdn0 --- addons/l10n_lu/wizard/print_vat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/l10n_lu/wizard/print_vat.py b/addons/l10n_lu/wizard/print_vat.py index 0e16c5ccf4c..3f356d31cf6 100644 --- a/addons/l10n_lu/wizard/print_vat.py +++ b/addons/l10n_lu/wizard/print_vat.py @@ -10,7 +10,7 @@ import tools from tools.translate import _ from report.render import render from report.interface import report_int - +import addons class external_pdf(render): def __init__(self, pdf): @@ -46,7 +46,7 @@ class report_custom(report_int): result['info_address'] = partner.address[0].street result['info_address2'] = (partner.address[0].zip or '') + ' ' + (partner.address[0].city or '') try: - tools.pdf_utils.fill_pdf(tools.config['addons_path']+'/l10n_lu/wizard/2008_DECL_F_M10.pdf', '/tmp/output.pdf', result) + tools.pdf_utils.fill_pdf(addons.get_module_resource('l10n_lu','wizard', '2008_DECL_F_M10.pdf'), '/tmp/output.pdf', result) self.obj = external_pdf(file('/tmp/output.pdf').read()) self.obj.render() return (self.obj.pdf, 'pdf') @@ -75,4 +75,4 @@ class vat_declaration_report(osv.osv_memory): vat_declaration_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 2bdd3062d6eaaf9adfc2ba666f7f495e3e065dc6 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Mon, 27 Sep 2010 16:21:50 +0200 Subject: [PATCH 07/18] [IMP] pricelist: performance improvement: created a 'price_get_multi' method to retrieve prices for several products at once bzr revid: olt@tinyerp.com-20100927142150-4yf58feypg0sxn3r --- addons/point_of_sale/pos.py | 67 +++++++++++++-- addons/product/pricelist.py | 163 +++++++++++++++++++++++++++++++++++- 2 files changed, 222 insertions(+), 8 deletions(-) diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py index 769d3a0460e..2e3e9c1445f 100644 --- a/addons/point_of_sale/pos.py +++ b/addons/point_of_sale/pos.py @@ -1022,15 +1022,16 @@ class pos_order_line(osv.osv): def _amount_line_ttc(self, cr, uid, ids, field_name, arg, context): res = dict.fromkeys(ids, 0.0) account_tax_obj = self.pool.get('account.tax') + prices = self.price_by_product_multi(cr, uid, ids) for line in self.browse(cr, uid, ids): tax_amount = 0.0 taxes = [t for t in line.product_id.taxes_id] - if line.qty == 0.0: - continue + if line.qty == 0.0: + continue computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit, line.qty)['taxes'] for tax in computed_taxes: tax_amount += tax['amount'] - price = self.price_by_product(cr, uid, ids, line.order_id.pricelist_id.id, line.product_id.id, line.qty, line.order_id.partner_id.id) + price = prices[line.id] if line.discount!=0.0: res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) else: @@ -1041,14 +1042,70 @@ class pos_order_line(osv.osv): def _amount_line(self, cr, uid, ids, field_name, arg, context): res = {} + prices = self.price_by_product_multi(cr, uid, ids) for line in self.browse(cr, uid, ids): - price = self.price_by_product(cr, uid, ids, line.order_id.pricelist_id.id, line.product_id.id, line.qty, line.order_id.partner_id.id) + price = prices[line.id] if line.discount!=0.0: res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) else: res[line.id]=line.price_unit*line.qty return res + def price_by_product_multi(self, cr, uid, ids, context=None): + if context is None: + context = {} + + res = {}.fromkeys(ids, 0.0) + + lines = self.browse(cr, uid, ids, context=context) + # product_map: + # {10, 1): {'qty': 5, 'uom_id': 1, 'partner_id': 512}, + # (22, 3): {'qty': 10, 'uom_id': 2, 'partner_id', 35}, + # } + # key = (product_id, pricelist_id) + product_map = dict([((line.product_id.id, line.order_id.pricelist_id.id), { + 'qty': line.qty, + 'uom_id': line.product_id.uom_po_id.id, + 'partner_id': line.order_id.partner_id.id, + }) + for line + in lines]) + + price_get_multi_res = self.pool.get('product.pricelist').price_get_multi(cr, uid, product_map) + + for line in lines: + pricelist = line.order_id.pricelist_id.id + product_id = line.product_id + qty = line.qty or 0 + partner_id = line.order_id.partner_id.id or False + + if not product_id: + res[line.id] = 0.0 + continue + if not pricelist: + raise osv.except_osv(_('No Pricelist !'), + _('You have to select a pricelist in the sale form !\n' \ + 'Please set one before choosing a product.')) + + uom_id = product_id.uom_po_id.id + + #old_price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist], product_id.id, qty or 1.0, partner_id, {'uom': uom_id})[pricelist] + #print "prod_id: %s, pricelist: %s, price: %s" % (product_id.id, pricelist, price) + price = price_get_multi_res[line.product_id.id][pricelist] + #print "prod_id: %s, pricelist: %s, price2: %s" % (product_id.id, pricelist, price2) + + #if old_price != price: + # raise Exception('old_price != price') + + unit_price = price or product_id.list_price + res[line.id] = unit_price + if unit_price is False: + raise osv.except_osv(_('No valid pricelist line found !'), + _("Couldn't find a pricelist line matching this product" \ + " and quantity.\nYou have to change either the product," \ + " the quantity or the pricelist.")) + return res + def price_by_product(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False): if not product_id: return 0.0 @@ -1057,7 +1114,7 @@ class pos_order_line(osv.osv): _('You have to select a pricelist in the sale form !\n' \ 'Please set one before choosing a product.')) p_obj = self.pool.get('product.product').browse(cr,uid,[product_id])[0] - uom_id=p_obj.uom_po_id.id + uom_id = p_obj.uom_po_id.id price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist], product_id, qty or 1.0, partner_id,{'uom': uom_id})[pricelist] unit_price=price or p_obj.list_price diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index aae62228748..0dbc9cadcef 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -126,6 +126,162 @@ class product_pricelist(osv.osv): "currency_id": _get_currency } + def price_get_multi(self, cr, uid, product_map, context=None): + """multi products 'price_get' + @param context: { + 'date': Date of the pricelist (%Y-%m-%d), + @return: a dict with product_id as key and the product price as value + } + """ + + def _create_parent_category_list(id, lst): + if not id: + return [] + parent = product_category_tree.get(id) + if parent: + lst.append(parent) + return _create_parent_category_list(parent, lst) + else: + return lst + # _create_parent_category_list + + context = context or {} + + # XXX + date = time.strftime('%Y-%m-%d') + if 'date' in context: + date = context['date'] + + currency_obj = self.pool.get('res.currency') + product_obj = self.pool.get('product.product') + product_category_obj = self.pool.get('product.category') + supplierinfo_obj = self.pool.get('product.supplierinfo') + price_type_obj = self.pool.get('product.price.type') + product_pricelist_version_obj = self.pool.get('product.pricelist.version') + + # product.pricelist.version: + pricelist_version_ids = list(set([k[1] for k in product_map.keys()])) + plversions_search_args = [ + ('pricelist_id', 'in', pricelist_version_ids), + '|', + ('date_start', '=', False), + ('date_start', '<=', date), + '|', + ('date_end', '=', False), + ('date_end', '>=', date), + ] + + plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args) + if len(pricelist_version_ids) != len(plversion_ids): + msg = "At least one pricelist has no active version !\nPlease create or activate one." + raise osv.except_osv(_('Warning !'), _(msg)) + + # product.product: + product_ids = list(set([k[0] for k in product_map.keys()])) + products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id'])]) + + # product.category: + product_category_ids = product_category_obj.search(cr, uid, []) + product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) + product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) + + results = {} + for (product_id, pricelist_id), line in product_map.items(): + price = False + + partner = line['partner_id'] + qty = line['qty'] + uom_id = line['uom_id'] + tmpl_id = products[product_id]['product_tmpl_id'] and products[product_id]['product_tmpl_id'][0] or False + + categ_id = products[product_id]['categ_id'] and products[product_id]['categ_id'][0] or False + categ_ids = _create_parent_category_list(categ_id, [categ_id]) + if categ_ids: + categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' + else: + categ_where = '(categ_id IS NULL)' + + cr.execute( + 'SELECT i.*, pl.currency_id ' + 'FROM product_pricelist_item AS i, ' + 'product_pricelist_version AS v, product_pricelist AS pl ' + 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' + 'AND (product_id IS NULL OR product_id = %s) ' + 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' + 'AND price_version_id = %s ' + 'AND (min_quantity IS NULL OR min_quantity <= %s) ' + 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' + 'ORDER BY sequence', + (tmpl_id, product_id, pricelist_id, qty)) + res1 = cr.dictfetchall() + + for res in res1: + if res: + if res['base'] == -1: + if not res['base_pricelist_id']: + price = 0.0 + else: + price_tmp = self.price_get(cr, uid, + [res['base_pricelist_id']], prod_id, + qty)[res['base_pricelist_id']] + ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id + price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) + break + elif res['base'] == -2: + # this section could be improved by moving the queries outside the loop: + where = [] + if partner: + where = [('name', '=', partner) ] + sinfo = supplierinfo_obj.search(cr, uid, + [('product_id', '=', tmpl_id)] + where) + price = 0.0 + if sinfo: + cr.execute('SELECT * ' \ + 'FROM pricelist_partnerinfo ' \ + 'WHERE suppinfo_id IN %s' \ + 'AND min_quantity <= %s ' \ + 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,)) + res2 = cr.dictfetchone() + if res2: + price = res2['price'] + break + else: + price_type = price_type_obj.browse(cr, uid, int(res['base'])) + price = currency_obj.compute(cr, uid, + price_type.currency_id.id, res['currency_id'], + product_obj.price_get(cr, uid, [product_id], + price_type.field)[product_id], round=False, context=context) + + if price: + price_limit = price + + price = price * (1.0+(res['price_discount'] or 0.0)) + price = rounding(price, res['price_round']) + price += (res['price_surcharge'] or 0.0) + if res['price_min_margin']: + price = max(price, price_limit+res['price_min_margin']) + if res['price_max_margin']: + price = min(price, price_limit+res['price_max_margin']) + break + + else: + # False means no valid line found ! But we may not raise an + # exception here because it breaks the search + price = False + + if results.get(product_id): + results[product_id][pricelist_id] = price + else: + results[product_id] = {pricelist_id: price} + + # XXX + #if 'uom' in context: + # product = product_obj.browse(cr, uid, product_id) + # uom = product.uos_id or product.uom_id + # results[product_id] = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, result[id], context['uom']) + + return results + def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None): ''' context = { @@ -134,8 +290,8 @@ class product_pricelist(osv.osv): 'date': Date of the pricelist (%Y-%m-%d), } ''' - price=False - item_id=0 + price = False + item_id = 0 context = context or {} currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') @@ -219,7 +375,7 @@ class product_pricelist(osv.osv): elif res['base'] == -2: where = [] if partner: - where = [('name', '=', partner) ] + where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 @@ -264,6 +420,7 @@ class product_pricelist(osv.osv): uom = product.uos_id or product.uom_id result[id] = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, result[id], context['uom']) + return result product_pricelist() From ccb069187bbe913b35d485dd25293f1de6386090 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Mon, 27 Sep 2010 16:40:24 +0200 Subject: [PATCH 08/18] [IMP] pos: pos.order.line: performance improvement: configured 2 function fields with multi ('price_subtotal', 'price_subtotal_incl') bzr revid: olt@tinyerp.com-20100927144024-87kb4xzuzmdvie2g --- addons/point_of_sale/pos.py | 40 +++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py index 2e3e9c1445f..b5b17d54d34 100644 --- a/addons/point_of_sale/pos.py +++ b/addons/point_of_sale/pos.py @@ -1051,6 +1051,38 @@ class pos_order_line(osv.osv): res[line.id]=line.price_unit*line.qty return res + def _amount_line_all(self, cr, uid, ids, field_names, arg, context): + res = dict([(i, {}) for i in ids]) + + account_tax_obj = self.pool.get('account.tax') + + prices = self.price_by_product_multi(cr, uid, ids) + for line in self.browse(cr, uid, ids): + for f in field_names: + if f == 'price_subtotal': + price = prices[line.id] + if line.discount != 0.0: + res[line.id][f] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) + else: + res[line.id][f] = line.price_unit * line.qty + elif f == 'price_subtotal_incl': + tax_amount = 0.0 + taxes = [t for t in line.product_id.taxes_id] + if line.qty == 0.0: + continue + computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit, line.qty)['taxes'] + for tax in computed_taxes: + tax_amount += tax['amount'] + price = prices[line.id] + if line.discount!=0.0: + res[line.id][f] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) + else: + res[line.id][f] = line.price_unit * line.qty + res[line.id][f] += tax_amount + print ids + print res + return res + def price_by_product_multi(self, cr, uid, ids, context=None): if context is None: context = {} @@ -1177,13 +1209,13 @@ class pos_order_line(osv.osv): return {'value': {'notice':'Minimum Discount','price_ded':price*discount*0.01 or 0.0 }} else : return {'value': {'notice':'No Discount', 'price_ded':price*discount*0.01 or 0.0}} - + def onchange_qty(self, cr, uid, ids, discount, qty, price, context=None): subtotal = qty * price if discount: subtotal = subtotal - (subtotal * discount / 100) return {'value': {'price_subtotal_incl': subtotal}} - + _columns = { 'name': fields.char('Line Description', size=512), 'company_id':fields.many2one('res.company', 'Company', required=True), @@ -1194,8 +1226,8 @@ class pos_order_line(osv.osv): 'price_ded': fields.float('Discount(Amount)',digits_compute=dp.get_precision('Point Of Sale')), 'qty': fields.float('Quantity'), 'qty_rfd': fields.float('Refunded Quantity'), - 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o Tax'), - 'price_subtotal_incl': fields.function(_amount_line_ttc, method=True, string='Subtotal'), + 'price_subtotal': fields.function(_amount_line_all, method=True, multi='pos_order_line_amount', string='Subtotal w/o Tax'), + 'price_subtotal_incl': fields.function(_amount_line_all, method=True, multi='pos_order_line_amount', string='Subtotal'), 'discount': fields.float('Discount (%)', digits=(16, 2)), 'order_id': fields.many2one('pos.order', 'Order Ref', ondelete='cascade'), 'create_date': fields.datetime('Creation Date', readonly=True), From e49a06c5188a3c632c958dc0cae10016d533187e Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Tue, 28 Sep 2010 11:24:45 +0200 Subject: [PATCH 09/18] [IMP] stock: performance improvement: * rewriten '_product_value' method ('multi' function field) * removed '_product_qty_available' method (not used anymore): fields are now computed in '_product_value' bzr revid: olt@tinyerp.com-20100928092445-4apj6d8ai4n2ze3z --- addons/stock/stock.py | 94 +++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index d14f891e016..d73a842bedd 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -21,6 +21,8 @@ from datetime import datetime from dateutil.relativedelta import relativedelta import time +from operator import itemgetter +from itertools import groupby from osv import fields, osv from tools.translate import _ @@ -103,66 +105,42 @@ class stock_location(osv.osv): res[m.id] = _get_one_full_name(m) return res - def _product_qty_available(self, cr, uid, ids, field_names, arg, context=None): - """ Finds real and virtual quantity for product available at particular location. - @return: Dictionary of values - """ - res = {} - for id in ids: - res[id] = {}.fromkeys(field_names, 0.0) - if ('product_id' not in context) or not ids: - return res - for loc in ids: - context['location'] = [loc] - prod = self.pool.get('product.product').browse(cr, uid, context['product_id'], context) - if 'stock_real' in field_names: - res[loc]['stock_real'] = prod.qty_available - if 'stock_virtual' in field_names: - res[loc]['stock_virtual'] = prod.virtual_available - return res - - def product_detail(self, cr, uid, id, field, context=None): - """ Finds detail of product like price type, currency and then calculates its price. - @param field: Field name - @return: Calculated price - """ - res = {} - res[id] = {} - final_value = 0.0 - field_to_read = 'virtual_available' - if context is None: - context = {} - if field == 'stock_real_value': - field_to_read = 'qty_available' - cr.execute('select distinct product_id from stock_move where (location_id=%s) or (location_dest_id=%s)', (id, id)) - result = cr.dictfetchall() - if result: - # Choose the right filed standard_price to read - # Take the user company - price_type_id = self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id - pricetype = self.pool.get('product.price.type').browse(cr, uid, price_type_id, context=context) - for r in result: - c = (context or {}).copy() - c['location'] = id - product = self.pool.get('product.product').read(cr, uid, r['product_id'], [field_to_read], context=c) - # Compute the amount_unit in right currency - context['currency_id'] = self.pool.get('res.users').browse(cr,uid,uid).company_id.currency_id.id - amount_unit = self.pool.get('product.product').browse(cr,uid,r['product_id']).price_get(pricetype.field, context)[r['product_id']] - final_value += (product[field_to_read] * amount_unit) - return final_value - def _product_value(self, cr, uid, ids, field_names, arg, context=None): - """ Calculates real and virtual stock value of a product. + """Computes stock value (real and virtual) for a product, as well as stock qty (real and virtual). @param field_names: Name of field @return: Dictionary of values """ - result = {} - for id in ids: - result[id] = {}.fromkeys(field_names, 0.0) - for field_name in field_names: - for loc in ids: - ret_dict = self.product_detail(cr, uid, loc, field=field_name) - result[loc][field_name] = ret_dict + result = dict([(i, {}.fromkeys(field_names, 0.0)) for i in ids]) + + product_product_obj = self.pool.get('product.product') + + cr.execute('select distinct product_id, location_id from stock_move where location_id in %s or location_dest_id in %s', (tuple(ids), tuple(ids))) + res_products_by_location = sorted(cr.dictfetchall(), key=itemgetter('location_id')) + products_by_location = dict((k, [v['product_id'] for v in itr]) for k, itr in groupby(res_products_by_location, itemgetter('location_id'))) + + currency_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id + currency_obj = self.pool.get('res.currency') + currency = self.pool.get('res.currency').browse(cr, uid, currency_id) + currency_obj.round(cr, uid, currency, 300) + + for loc_id, product_ids in products_by_location.items(): + c = (context or {}).copy() + c['location'] = loc_id + for prod in product_product_obj.browse(cr, uid, product_ids, context=c): + for f in field_names: + if f == 'stock_real': + result[loc_id][f] += prod.qty_available + elif f == 'stock_virtual': + result[loc_id][f] += prod.virtual_available + elif f == 'stock_real_value': + amount = prod.qty_available * prod.standard_price + amount = currency_obj.round(cr, uid, currency, amount) + result[loc_id][f] += amount + elif f == 'stock_virtual_value': + amount = prod.virtual_available * prod.standard_price + amount = currency_obj.round(cr, uid, currency, amount) + result[loc_id][f] += amount + return result _columns = { @@ -180,8 +158,8 @@ class stock_location(osv.osv): # temporarily removed, as it's unused: 'allocation_method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO'), ('nearest', 'Nearest')], 'Allocation Method', required=True), 'complete_name': fields.function(_complete_name, method=True, type='char', size=100, string="Location Name"), - 'stock_real': fields.function(_product_qty_available, method=True, type='float', string='Real Stock', multi="stock"), - 'stock_virtual': fields.function(_product_qty_available, method=True, type='float', string='Virtual Stock', multi="stock"), + 'stock_real': fields.function(_product_value, method=True, type='float', string='Real Stock', multi="stock"), + 'stock_virtual': fields.function(_product_value, method=True, type='float', string='Virtual Stock', multi="stock"), 'location_id': fields.many2one('stock.location', 'Parent Location', select=True, ondelete='cascade'), 'child_ids': fields.one2many('stock.location', 'location_id', 'Contains'), From 02ab26f946972de08fb4e70d89c4a64d6249b3f0 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Tue, 28 Sep 2010 14:28:07 +0200 Subject: [PATCH 10/18] [IMP] sale_mrp: performance improvement: '_get_sale_ref' now uses browse instead of read bzr revid: olt@tinyerp.com-20100928122807-5sy8lypoo31up2e0 --- addons/sale_mrp/sale_mrp.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py index e8cb0c61f91..c278ef98db1 100644 --- a/addons/sale_mrp/sale_mrp.py +++ b/addons/sale_mrp/sale_mrp.py @@ -58,17 +58,17 @@ class mrp_production(osv.osv): return move_id res = {} - productions = self.read(cr, uid, ids, ['id','move_prod_id']) + productions = self.browse(cr, uid, ids) for production in productions: - res[production['id']] = False - if production.get('move_prod_id',False): - parent_move_line = get_parent_move(production['move_prod_id'][0]) + res[production.id] = False + if production.move_prod_id: + parent_move_line = get_parent_move(production.move_prod_id) if parent_move_line: move = move_obj.browse(cr,uid,parent_move_line) if field_name == 'name': - res[production['id']] = move.sale_line_id and move.sale_line_id.order_id.name or False + res[production.id] = move.sale_line_id and move.sale_line_id.order_id.name or False if field_name == 'client_order_ref': - res[production['id']] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False + res[production.id] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False return res _columns = { @@ -78,4 +78,4 @@ class mrp_production(osv.osv): mrp_production() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From c5de222c6616c268ab9364a76ab481c145c8110b Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Tue, 28 Sep 2010 14:28:45 +0200 Subject: [PATCH 11/18] [FIX] product_margin: same multi value for the same function field method bzr revid: olt@tinyerp.com-20100928122845-rvjqg7bo6d6a009p --- addons/product_margin/product_margin.py | 108 ++++++++++++++---------- 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py index d8d6d7a1702..132f6e27d55 100644 --- a/addons/product_margin/product_margin.py +++ b/addons/product_margin/product_margin.py @@ -23,6 +23,7 @@ import time from osv import fields, osv + class product_product(osv.osv): _inherit = "product.product" @@ -30,30 +31,31 @@ class product_product(osv.osv): res = {} if context is None: context = {} - for val in self.browse(cr, uid, ids,context=context): + + for val in self.browse(cr, uid, ids, context=context): res[val.id] = {} date_from = context.get('date_from', time.strftime('%Y-01-01')) date_to = context.get('date_to', time.strftime('%Y-12-31')) invoice_state = context.get('invoice_state', 'open_paid') if 'date_from' in field_names: - res[val.id]['date_from']=date_from + res[val.id]['date_from'] = date_from if 'date_to' in field_names: - res[val.id]['date_to']=date_to + res[val.id]['date_to'] = date_to if 'invoice_state' in field_names: - res[val.id]['invoice_state']=invoice_state + res[val.id]['invoice_state'] = invoice_state invoice_types = () states = () - if invoice_state=='paid': - states=('paid',) - elif invoice_state=='open_paid': - states=('open','paid') - elif invoice_state=='draft_open_paid': - states=('draft','open','paid') + if invoice_state == 'paid': + states = ('paid',) + elif invoice_state == 'open_paid': + states = ('open', 'paid') + elif invoice_state == 'draft_open_paid': + states = ('draft', 'open', 'paid') if 'sale_avg_price' in field_names or 'sale_num_invoiced' in field_names or 'turnover' in field_names or 'sale_expected' in field_names: - invoice_types=('out_invoice','in_refund') + invoice_types = ('out_invoice', 'in_refund') if 'purchase_avg_price' in field_names or 'purchase_num_invoiced' in field_names or 'total_cost' in field_names or 'normal_cost' in field_names: - invoice_types=('in_invoice','out_refund') + invoice_types = ('in_invoice', 'out_refund') if len(invoice_types): cr.execute("""select avg(l.price_unit) as avg_unit_price, @@ -65,51 +67,65 @@ class product_product(osv.osv): left join account_invoice i on (l.invoice_id = i.id) left join product_template product on (product.id=l.product_id) where l.product_id = %s and i.state in %s and i.type IN %s and i.date_invoice>=%s and i.date_invoice<=%s - """,(val.id,states,invoice_types,date_from,date_to)) - result=cr.fetchall()[0] + """, (val.id, states, invoice_types, date_from, date_to)) + result = cr.fetchall()[0] if 'sale_avg_price' in field_names or 'sale_num_invoiced' in field_names or 'turnover' in field_names or 'sale_expected' in field_names: - res[val.id]['sale_avg_price']=result[0] and result[0] or 0.0 - res[val.id]['sale_num_invoiced']=result[1] and result[1] or 0.0 - res[val.id]['turnover']=result[2] and result[2] or 0.0 - res[val.id]['sale_expected']=result[3] and result[3] or 0.0 - res[val.id]['sales_gap']=res[val.id]['sale_expected']-res[val.id]['turnover'] + res[val.id]['sale_avg_price'] = result[0] and result[0] or 0.0 + res[val.id]['sale_num_invoiced'] = result[1] and result[1] or 0.0 + res[val.id]['turnover'] = result[2] and result[2] or 0.0 + res[val.id]['sale_expected'] = result[3] and result[3] or 0.0 + res[val.id]['sales_gap'] = res[val.id]['sale_expected']-res[val.id]['turnover'] if 'purchase_avg_price' in field_names or 'purchase_num_invoiced' in field_names or 'total_cost' in field_names or 'normal_cost' in field_names: - res[val.id]['purchase_avg_price']=result[0] and result[0] or 0.0 - res[val.id]['purchase_num_invoiced']=result[1] and result[1] or 0.0 - res[val.id]['total_cost']=result[2] and result[2] or 0.0 - res[val.id]['normal_cost']=result[4] and result[4] or 0.0 - res[val.id]['purchase_gap']=res[val.id]['normal_cost']-res[val.id]['total_cost'] + res[val.id]['purchase_avg_price'] = result[0] and result[0] or 0.0 + res[val.id]['purchase_num_invoiced'] = result[1] and result[1] or 0.0 + res[val.id]['total_cost'] = result[2] and result[2] or 0.0 + res[val.id]['normal_cost'] = result[4] and result[4] or 0.0 + res[val.id]['purchase_gap'] = res[val.id]['normal_cost']-res[val.id]['total_cost'] if 'total_margin' in field_names: - res[val.id]['total_margin']=val.turnover-val.standard_price + res[val.id]['total_margin'] = val.turnover - val.standard_price if 'expected_margin' in field_names: - res[val.id]['expected_margin']=val.sale_expected-val.normal_cost + res[val.id]['expected_margin'] = val.sale_expected - val.normal_cost if 'total_margin_rate' in field_names: - res[val.id]['total_margin_rate']=val.turnover and val.total_margin * 100 / val.turnover or 0.0 + res[val.id]['total_margin_rate'] = val.turnover and val.total_margin * 100 / val.turnover or 0.0 if 'expected_margin_rate' in field_names: - res[val.id]['expected_margin_rate']=val.sale_expected and val.expected_margin * 100 / val.sale_expected or 0.0 + res[val.id]['expected_margin_rate'] = val.sale_expected and val.expected_margin * 100 / val.sale_expected or 0.0 return res _columns = { - 'date_from': fields.function(_product_margin, method=True, type='date', string='From Date', multi=True), - 'date_to': fields.function(_product_margin, method=True, type='date', string='To Date', multi=True), + 'date_from': fields.function(_product_margin, method=True, type='date', string='From Date', multi='product_margin'), + 'date_to': fields.function(_product_margin, method=True, type='date', string='To Date', multi='product_margin'), 'invoice_state': fields.function(_product_margin, method=True, type='selection', selection=[ - ('paid','Paid'),('open_paid','Open and Paid'),('draft_open_paid','Draft, Open and Paid') - ], string='Invoice State',multi=True, readonly=True), - 'sale_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='sale',help="Avg. Price in Customer Invoices)"), - 'purchase_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='purchase',help="Avg. Price in Supplier Invoices "), - 'sale_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='sale',help="Sum of Quantity in Customer Invoices"), - 'purchase_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='purchase',help="Sum of Quantity in Supplier Invoices"), - 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='sale',help="Expected Sale - Turn Over"), - 'purchase_gap' : fields.function(_product_margin, method=True, type='float', string='Purchase Gap', multi='purchase',help="Normal Cost - Total Cost"), - 'turnover' : fields.function(_product_margin, method=True, type='float', string='Turnover' ,multi='sale',help="Sum of Multification of Invoice price and quantity of Customer Invoices"), - 'total_cost' : fields.function(_product_margin, method=True, type='float', string='Total Cost', multi='purchase',help="Sum of Multification of Invoice price and quantity of Supplier Invoices "), - 'sale_expected' : fields.function(_product_margin, method=True, type='float', string='Expected Sale', multi='sale',help="Sum of Multification of Sale Catalog price and quantity of Customer Invoices"), - 'normal_cost' : fields.function(_product_margin, method=True, type='float', string='Normal Cost', multi='purchase',help="Sum of Multification of Cost price and quantity of Supplier Invoices"), - 'total_margin' : fields.function(_product_margin, method=True, type='float', string='Total Margin', multi='total',help="Turnorder - Standard price"), - 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='total',help="Expected Sale - Normal Cost"), - 'total_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Total Margin (%)', multi='margin',help="Total margin * 100 / Turnover"), - 'expected_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Expected Margin (%)', multi='margin',help="Expected margin * 100 / Expected Sale"), + ('paid','Paid'),('open_paid','Open and Paid'),('draft_open_paid','Draft, Open and Paid') + ], string='Invoice State',multi='product_margin', readonly=True), + 'sale_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='product_margin', + help="Avg. Price in Customer Invoices)"), + 'purchase_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='product_margin', + help="Avg. Price in Supplier Invoices "), + 'sale_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='product_margin', + help="Sum of Quantity in Customer Invoices"), + 'purchase_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='product_margin', + help="Sum of Quantity in Supplier Invoices"), + 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='product_margin', + help="Expected Sale - Turn Over"), + 'purchase_gap' : fields.function(_product_margin, method=True, type='float', string='Purchase Gap', multi='product_margin', + help="Normal Cost - Total Cost"), + 'turnover' : fields.function(_product_margin, method=True, type='float', string='Turnover' ,multi='product_margin', + help="Sum of Multification of Invoice price and quantity of Customer Invoices"), + 'total_cost' : fields.function(_product_margin, method=True, type='float', string='Total Cost', multi='product_margin', + help="Sum of Multification of Invoice price and quantity of Supplier Invoices "), + 'sale_expected' : fields.function(_product_margin, method=True, type='float', string='Expected Sale', multi='product_margin', + help="Sum of Multification of Sale Catalog price and quantity of Customer Invoices"), + 'normal_cost' : fields.function(_product_margin, method=True, type='float', string='Normal Cost', multi='product_margin', + help="Sum of Multification of Cost price and quantity of Supplier Invoices"), + 'total_margin' : fields.function(_product_margin, method=True, type='float', string='Total Margin', multi='product_margin', + help="Turnorder - Standard price"), + 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='product_margin', + help="Expected Sale - Normal Cost"), + 'total_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Total Margin (%)', multi='product_margin', + help="Total margin * 100 / Turnover"), + 'expected_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Expected Margin (%)', multi='product_margin', + help="Expected margin * 100 / Expected Sale"), } product_product() From 3833852f93b51d841560f2832390c43f7e8dbe2d Mon Sep 17 00:00:00 2001 From: "aag (OpenERP)" Date: Tue, 28 Sep 2010 18:47:10 +0530 Subject: [PATCH 12/18] diff --git a/addons/account_analytic_default/account_analytic_default_view.xml b/addons/account_analytic_default/account_analytic_default_view.xml index 2513d1229b6..95a39eb11e6 100644 --- a/addons/account_analytic_default/account_analytic_default_view.xml +++ b/addons/account_analytic_default/account_analytic_default_view.xml @@ -66,14 +66,16 @@ id="act_account_acount_move_line_open" res_model="account.move.line" src_model="account.account" - domain="[('account_id', '=', active_id)]"/> + context="{'search_default_account_id': [active_id]}" + /> + diff --git a/addons/account_budget/crossovered_budget_view.xml b/addons/account_budget/crossovered_budget_view.xml index 263dee3f686..448fc12fef6 100644 --- a/addons/account_budget/crossovered_budget_view.xml +++ b/addons/account_budget/crossovered_budget_view.xml @@ -260,7 +260,7 @@ diff --git a/addons/account_voucher/voucher_view.xml b/addons/account_voucher/voucher_view.xml index d007d20acab..972850e0114 100644 --- a/addons/account_voucher/voucher_view.xml +++ b/addons/account_voucher/voucher_view.xml @@ -161,10 +161,10 @@ diff --git a/addons/auction/auction_view.xml b/addons/auction/auction_view.xml index d149fc89f1c..c3068753a6e 100644 --- a/addons/auction/auction_view.xml +++ b/addons/auction/auction_view.xml @@ -765,7 +765,7 @@ diff --git a/addons/base_contact/base_contact_view.xml b/addons/base_contact/base_contact_view.xml index 1f22b550bdc..59894ab55d0 100644 --- a/addons/base_contact/base_contact_view.xml +++ b/addons/base_contact/base_contact_view.xml @@ -408,8 +408,9 @@ diff --git a/addons/crm/crm_meeting_menu.xml b/addons/crm/crm_meeting_menu.xml index 53eabcf0136..7601fcdab43 100644 --- a/addons/crm/crm_meeting_menu.xml +++ b/addons/crm/crm_meeting_menu.xml @@ -8,8 +8,7 @@ res_model="crm.meeting" src_model="res.partner" view_mode="calendar,tree,form,gantt" - context="{'default_partner_id': active_id, 'default_duration': 4.0}" - domain="[('partner_id', '=', active_id)]" + context="{'search_default_partner_id': active_id, 'default_duration': 4.0}" /> diff --git a/addons/crm/crm_phonecall_menu.xml b/addons/crm/crm_phonecall_menu.xml index 8585ddc7fe4..cd1f75b01f5 100644 --- a/addons/crm/crm_phonecall_menu.xml +++ b/addons/crm/crm_phonecall_menu.xml @@ -8,8 +8,7 @@ res_model="crm.phonecall" src_model="res.partner" view_mode="calendar,tree,form" - context="{'default_partner_id': active_id, 'default_duration': 1.0}" - domain="[('partner_id', '=', active_id)]" + context="{'search_default_partner_id': [active_id], 'default_duration': 1.0}" groups="base.group_extended" /> diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml index a341915bc39..3062c15364c 100644 --- a/addons/crm_claim/crm_claim_view.xml +++ b/addons/crm_claim/crm_claim_view.xml @@ -311,8 +311,7 @@ - diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index c791b0baefd..f58a948fad2 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -264,7 +264,7 @@ res_model="event.registration" src_model="event.event" view_mode="tree,form,calendar,graph" - domain="[('event_id', '=', active_id)]" + context="{'search_default_event_id': [active_id]}" view_type="form"/> diff --git a/addons/event_project/event_view.xml b/addons/event_project/event_view.xml index 5060ed2cb3f..7793d4fbcf7 100644 --- a/addons/event_project/event_view.xml +++ b/addons/event_project/event_view.xml @@ -36,7 +36,7 @@ res_model="project.task" src_model="event.event" view_mode="tree,form,calendar,graph" - domain="[('project_id', '=', project_id)]" + context="{'search_default_project_id': project_id}" view_type="form"/> diff --git a/addons/hr_contract/hr_contract_view.xml b/addons/hr_contract/hr_contract_view.xml index cb486df91b1..c8f84ce55cc 100644 --- a/addons/hr_contract/hr_contract_view.xml +++ b/addons/hr_contract/hr_contract_view.xml @@ -279,7 +279,12 @@ - + diff --git a/addons/hr_evaluation/hr_evaluation_view.xml b/addons/hr_evaluation/hr_evaluation_view.xml index 9ec02b4ad0b..5dcc7b6f346 100644 --- a/addons/hr_evaluation/hr_evaluation_view.xml +++ b/addons/hr_evaluation/hr_evaluation_view.xml @@ -385,7 +385,12 @@ action="action_hr_evaluation_send_mail" sequence="45"/> - + diff --git a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml index ba155d3590a..c0f82b0475b 100644 --- a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml +++ b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml @@ -395,13 +395,34 @@ - + + - + - + - + diff --git a/addons/hr_timesheet_invoice/report/report_analytic_view.xml b/addons/hr_timesheet_invoice/report/report_analytic_view.xml index 32129287470..f5573a394ef 100644 --- a/addons/hr_timesheet_invoice/report/report_analytic_view.xml +++ b/addons/hr_timesheet_invoice/report/report_analytic_view.xml @@ -134,7 +134,13 @@ - + diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml index 19a9af3c33d..f078be2dbe1 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml @@ -290,11 +290,27 @@ - + - + + - + hr.timesheet.sheet.tree.simplified diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml index 7d1c8d3d2bf..614055dddcd 100644 --- a/addons/marketing_campaign/marketing_campaign_view.xml +++ b/addons/marketing_campaign/marketing_campaign_view.xml @@ -446,18 +446,20 @@ view_type="form" view_mode="tree,form" id="act_marketing_campaing_segment_opened" - domain="[('campaign_id','=',active_id)]" + context="{'search_default_campaign_id': [active_id]}" /> - - - + - + diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 81834ebbdbf..4ae9f9e1ac8 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -360,15 +360,14 @@ - + - + diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml index fd09f362000..f4305329d0d 100644 --- a/addons/sale_journal/sale_journal_view.xml +++ b/addons/sale_journal/sale_journal_view.xml @@ -303,7 +303,7 @@ @@ -311,7 +311,8 @@ @@ -319,7 +320,8 @@ @@ -327,7 +329,8 @@ @@ -335,7 +338,8 @@ diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index e80e9856023..0a741d4a3ff 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1851,8 +1851,7 @@ src_model="stock.location"/> - - - tree,form - - Date: Wed, 29 Sep 2010 13:35:01 +0530 Subject: [PATCH 13/18] [REMOVE]: mx.Date from trunk bzr revid: aag@tinyerp.co.in-20100929080501-j7hqsb3qfftp6qbo --- addons/account/report/account_report.py | 11 ++++----- .../account_report_aged_partner_balance.py | 16 ++++++------- addons/account_report/account.py | 3 --- ...ccount_report_print_indicators_with_pdf.py | 1 - addons/account_reporting/account.py | 3 --- .../wizard/base_calendar_set_exrule.py | 1 - addons/crm/crm_lead.py | 5 ++-- addons/crm/crm_opportunity.py | 1 - .../document_ics_config_wizard.py | 1 - .../report/attendance_by_month.py | 10 ++++---- addons/hr_attendance/report/timesheet.py | 20 +++++++++------- .../report/report_emp_salary_structure.py | 1 - .../report/report_employees_detail.py | 2 -- .../report/report_payroll_advice.py | 4 ++-- .../report/report_payroll_register.py | 4 ++-- addons/hr_payroll/report/report_payslip.py | 4 ++-- .../hr_payroll/report/report_year_salary.py | 2 -- addons/l10n_ch/report/bvr_report.py | 2 +- addons/l10n_ch/wizard/create_dta.py | 8 +++---- addons/mrp/report/workcenter_load.py | 12 ++++++---- addons/mrp_repair/mrp_repair.py | 9 ++++--- addons/project_planning/project_planning.py | 5 ++-- .../project_timesheet/report/task_report.py | 7 +++--- addons/stock_planning/stock_planning.py | 19 ++++++++------- .../wizard/stock_planning_create_periods.py | 24 +++++++++---------- addons/survey/survey.py | 6 ++--- 26 files changed, 86 insertions(+), 95 deletions(-) diff --git a/addons/account/report/account_report.py b/addons/account/report/account_report.py index 362d0adb414..b7d3441913f 100644 --- a/addons/account/report/account_report.py +++ b/addons/account/report/account_report.py @@ -20,9 +20,8 @@ ############################################################################## import time -import datetime -import mx.DateTime - +from datetime import datetime +from dateutil.relativedelta import relativedelta import pooler import tools from osv import fields,osv @@ -128,13 +127,13 @@ class report_aged_receivable(osv.osv): LIST_RANGES = [] if fy_id: fy_start_date = pool_obj_fy.read(cr, uid, fy_id, ['date_start'])['date_start'] - fy_start_date = mx.DateTime.strptime(fy_start_date, '%Y-%m-%d') - last_month_date = mx.DateTime.strptime(today, '%Y-%m-%d') - mx.DateTime.RelativeDateTime(months=1) + fy_start_date = datetime.strptime(fy_start_date, '%Y-%m-%d') + last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1) while (last_month_date > fy_start_date): LIST_RANGES.append(today + " to " + last_month_date.strftime('%Y-%m-%d')) today = (last_month_date- 1).strftime('%Y-%m-%d') - last_month_date = mx.DateTime.strptime(today, '%Y-%m-%d') - mx.DateTime.RelativeDateTime(months=1) + last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1) LIST_RANGES.append(today +" to " + fy_start_date.strftime('%Y-%m-%d')) cr.execute('delete from temp_range') diff --git a/addons/account/wizard/account_report_aged_partner_balance.py b/addons/account/wizard/account_report_aged_partner_balance.py index 99983654c82..10548095131 100644 --- a/addons/account/wizard/account_report_aged_partner_balance.py +++ b/addons/account/wizard/account_report_aged_partner_balance.py @@ -20,8 +20,8 @@ ############################################################################## import time -import datetime -from mx.DateTime import * +from datetime import datetime +from dateutil.relativedelta import relativedelta from lxml import etree from osv import osv, fields @@ -69,26 +69,26 @@ class account_aged_trial_balance(osv.osv_memory): if not data['form']['date_from']: raise osv.except_osv(_('UserError'), _('Enter a Start date !')) - start = datetime.date.fromtimestamp(time.mktime(time.strptime(data['form']['date_from'], "%Y-%m-%d"))) - start = DateTime(int(start.year), int(start.month), int(start.day)) + start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d") + if data['form']['direction_selection'] == 'past': for i in range(5)[::-1]: - stop = start - RelativeDateTime(days=period_length) + stop = start - relativedelta(days=period_length) res[str(i)] = { 'name': (i!=0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))), 'stop': start.strftime('%Y-%m-%d'), 'start': (i!=0 and stop.strftime('%Y-%m-%d') or False), } - start = stop - RelativeDateTime(days=1) + start = stop - relativedelta(days=1) else: for i in range(5): - stop = start + RelativeDateTime(days=period_length) + stop = start + relativedelta(days=period_length) res[str(5-(i+1))] = { 'name' : (i!=4 and str((i) * period_length)+'-' + str((i+1) * period_length) or ('+'+str(4 * period_length))), 'start': start.strftime('%Y-%m-%d'), 'stop': (i!=4 and stop.strftime('%Y-%m-%d') or False), } - start = stop + RelativeDateTime(days=1) + start = stop + relativedelta(days=1) data['form'].update(res) return { diff --git a/addons/account_report/account.py b/addons/account_report/account.py index 5dffc0c6a78..6e5fbc94026 100644 --- a/addons/account_report/account.py +++ b/addons/account_report/account.py @@ -26,9 +26,6 @@ import pooler from tools.misc import currency from tools.translate import _ -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime - class account_report(osv.osv): _name = "account.report.report" diff --git a/addons/account_report/wizard/account_report_print_indicators_with_pdf.py b/addons/account_report/wizard/account_report_print_indicators_with_pdf.py index 9e71d3e88c9..2ae373e58f0 100644 --- a/addons/account_report/wizard/account_report_print_indicators_with_pdf.py +++ b/addons/account_report/wizard/account_report_print_indicators_with_pdf.py @@ -19,7 +19,6 @@ # ############################################################################## import time -from mx.DateTime import * import os import base64 import StringIO diff --git a/addons/account_reporting/account.py b/addons/account_reporting/account.py index c1c68f04d9b..7fc08401496 100644 --- a/addons/account_reporting/account.py +++ b/addons/account_reporting/account.py @@ -24,9 +24,6 @@ from osv import fields, osv from tools.misc import currency -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime - class color_rml(osv.osv): _name = "color.rml" diff --git a/addons/base_calendar/wizard/base_calendar_set_exrule.py b/addons/base_calendar/wizard/base_calendar_set_exrule.py index ab458c8f7f5..995d2a98dcc 100644 --- a/addons/base_calendar/wizard/base_calendar_set_exrule.py +++ b/addons/base_calendar/wizard/base_calendar_set_exrule.py @@ -23,7 +23,6 @@ from base_calendar import base_calendar from osv import fields, osv from tools.translate import _ import tools -import mx.DateTime import re diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 0a552a4165a..c15307530f1 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -23,7 +23,6 @@ from osv import fields, osv from datetime import datetime import crm import time -import mx.DateTime from tools.translate import _ from crm import crm_case import binascii @@ -84,12 +83,12 @@ class crm_lead(crm_case, osv.osv): new_dates = cal_obj.interval_get(cr, uid, lead.section_id.resource_calendar_id and lead.section_id.resource_calendar_id.id or False, - mx.DateTime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'), + datetime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'), duration, resource=resource_id ) no_days = [] - date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S') + date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S') for in_time, out_time in new_dates: if in_time.date not in no_days: no_days.append(in_time.date) diff --git a/addons/crm/crm_opportunity.py b/addons/crm/crm_opportunity.py index 84e1392168f..771212a171d 100644 --- a/addons/crm/crm_opportunity.py +++ b/addons/crm/crm_opportunity.py @@ -24,7 +24,6 @@ from osv import fields,osv,orm from tools.translate import _ import crm import time -import mx.DateTime AVAILABLE_STATES = [ ('draft','Draft'), diff --git a/addons/document_ics/document_ics_config_wizard.py b/addons/document_ics/document_ics_config_wizard.py index 611c804a62c..51ccab59204 100644 --- a/addons/document_ics/document_ics_config_wizard.py +++ b/addons/document_ics/document_ics_config_wizard.py @@ -23,7 +23,6 @@ import time import tools from osv import fields, osv, orm import os -import mx.DateTime import base64 import pooler diff --git a/addons/hr_attendance/report/attendance_by_month.py b/addons/hr_attendance/report/attendance_by_month.py index 650df0048bf..a4a50f61320 100644 --- a/addons/hr_attendance/report/attendance_by_month.py +++ b/addons/hr_attendance/report/attendance_by_month.py @@ -19,9 +19,9 @@ # ############################################################################## -from mx import DateTime -from mx.DateTime import now import time +from datetime import datetime +from dateutil.relativedelta import relativedelta import datetime import netsvc import pooler @@ -31,7 +31,7 @@ from report.interface import toxml from report import report_sxw -one_day = DateTime.RelativeDateTime(days=1) +one_day = relativedelta(days=1) month2name = [0, 'January', 'February', 'March', 'April', 'May', 'Jun', 'July', 'August', 'September', 'October', 'November', 'December'] #def hour2str(h): @@ -57,7 +57,7 @@ class report_custom(report_rml): obj_emp = pooler.get_pool(cr.dbname).get('hr.employee') if context is None: context = {} - month = DateTime.DateTime(datas['form']['year'], datas['form']['month'], 1) + month = datetime(datas['form']['year'], datas['form']['month'], 1) emp_ids = context.get('active_ids', []) user_xml = ['%s' % month2name[month.month], '%s' % month.year] if emp_ids: @@ -89,7 +89,7 @@ class report_custom(report_rml): attendences.append({'name': tomor.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_out'}) # sum up the attendances' durations for att in attendences: - dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') + dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') if att['action'] == 'sign_out': wh += (dt - ldt).hours ldt = dt diff --git a/addons/hr_attendance/report/timesheet.py b/addons/hr_attendance/report/timesheet.py index 94dc1edcbbd..1465be81bc8 100644 --- a/addons/hr_attendance/report/timesheet.py +++ b/addons/hr_attendance/report/timesheet.py @@ -19,16 +19,16 @@ # ############################################################################## -from mx import DateTime -from mx.DateTime import now +from datetime import datetime +from dateutil.relativedelta import relativedelta import pooler from report.interface import report_rml from report.interface import toxml -one_week = DateTime.RelativeDateTime(days=7) +one_week = relativedelta(days=7) num2day = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] def to_hour(h): @@ -38,10 +38,12 @@ class report_custom(report_rml): def create_xml(self, cr, uid, ids, datas, context=None): obj_emp = pooler.get_pool(cr.dbname).get('hr.employee') - start_date = DateTime.strptime(datas['form']['init_date'], '%Y-%m-%d') - end_date = DateTime.strptime(datas['form']['end_date'], '%Y-%m-%d') - first_monday = start_date - DateTime.RelativeDateTime(days=start_date.day_of_week) - last_monday = end_date + DateTime.RelativeDateTime(days=7 - end_date.day_of_week) + + start_date = datetime.strptime(datas['form']['init_date'], '%Y-%m-%d') + end_date = datetime.strptime(datas['form']['end_date'], '%Y-%m-%d') + first_monday = start_date - relativedelta(days=start_date.day_of_week) + last_monday = end_date + relativedelta(days=7 - end_date.day_of_week) + if last_monday < first_monday: first_monday, last_monday = last_monday, first_monday @@ -67,7 +69,7 @@ class report_custom(report_rml): order by att.name ''' for idx in range(7): - cr.execute(sql, (monday.strftime('%Y-%m-%d %H:%M:%S'), (monday + DateTime.RelativeDateTime(days=idx+1)).strftime('%Y-%m-%d %H:%M:%S'), employee_id)) + cr.execute(sql, (monday.strftime('%Y-%m-%d %H:%M:%S'), (monday + relativedelta(days=idx+1)).strftime('%Y-%m-%d %H:%M:%S'), employee_id)) attendances = cr.dictfetchall() week_wh = {} # Fake sign ins/outs at week ends, to take attendances across week ends into account @@ -78,7 +80,7 @@ class report_custom(report_rml): attendances.append({'name': n_monday.strftime('%Y-%m-%d %H:%M:%S'), 'action': 'sign_out'}) # sum up the attendances' durations for att in attendances: - dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') + dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') if att['action'] == 'sign_out': week_wh[ldt.day_of_week] = week_wh.get(ldt.day_of_week, 0) + (dt - ldt).hours ldt = dt diff --git a/addons/hr_payroll/report/report_emp_salary_structure.py b/addons/hr_payroll/report/report_emp_salary_structure.py index d4365a8423b..7deafcf63e4 100644 --- a/addons/hr_payroll/report/report_emp_salary_structure.py +++ b/addons/hr_payroll/report/report_emp_salary_structure.py @@ -23,7 +23,6 @@ ############################################################################## import time -import mx.DateTime from report import report_sxw from tools import amount_to_text_en diff --git a/addons/hr_payroll/report/report_employees_detail.py b/addons/hr_payroll/report/report_employees_detail.py index ca06af969e7..5a9f25afa9f 100644 --- a/addons/hr_payroll/report/report_employees_detail.py +++ b/addons/hr_payroll/report/report_employees_detail.py @@ -5,8 +5,6 @@ from report import report_sxw import time import pooler import rml_parse -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime class employees_salary_report(rml_parse.rml_parse): diff --git a/addons/hr_payroll/report/report_payroll_advice.py b/addons/hr_payroll/report/report_payroll_advice.py index 2f4d82c263b..1c7fbd91357 100644 --- a/addons/hr_payroll/report/report_payroll_advice.py +++ b/addons/hr_payroll/report/report_payroll_advice.py @@ -1,5 +1,5 @@ import time -import mx.DateTime +from datetime import datetime from report import report_sxw from tools import amount_to_text_en @@ -22,7 +22,7 @@ class payroll_advice_report(report_sxw.rml_parse): res = { 'mname':'' } - date = mx.DateTime.strptime(input_date, '%Y-%m-%d') + date = datetime.strptime(input_date, '%Y-%m-%d') res['mname']= date.strftime('%B')+'-'+date.strftime('%Y') return res diff --git a/addons/hr_payroll/report/report_payroll_register.py b/addons/hr_payroll/report/report_payroll_register.py index 6ab5b0c35c9..b146e2900af 100644 --- a/addons/hr_payroll/report/report_payroll_register.py +++ b/addons/hr_payroll/report/report_payroll_register.py @@ -1,5 +1,5 @@ import time -import mx.DateTime +from datetime import datetime from report import report_sxw from tools import amount_to_text_en @@ -56,7 +56,7 @@ class report_payroll_register(report_sxw.rml_parse): return self.net def get_month(self, indate): - new_date = mx.DateTime.strptime(indate, '%Y-%m-%d') + new_date = datetime.strptime(indate, '%Y-%m-%d') out_date = new_date.strftime('%B')+'-'+new_date.strftime('%Y') return out_date diff --git a/addons/hr_payroll/report/report_payslip.py b/addons/hr_payroll/report/report_payslip.py index 4fc9410861d..e818e0f3727 100755 --- a/addons/hr_payroll/report/report_payslip.py +++ b/addons/hr_payroll/report/report_payslip.py @@ -23,7 +23,7 @@ ############################################################################## import time -import mx.DateTime +from datetime import datetime from report import report_sxw from tools import amount_to_text_en @@ -93,7 +93,7 @@ class payslip_report(report_sxw.rml_parse): res = { 'mname':'' } - date = mx.DateTime.strptime(obj.date, '%Y-%m-%d') + date = datetime.strptime(obj.date, '%Y-%m-%d') res['mname']= date.strftime('%B')+"-"+date.strftime('%Y') return res['mname'] diff --git a/addons/hr_payroll/report/report_year_salary.py b/addons/hr_payroll/report/report_year_salary.py index 66cf05db601..31dae5abffe 100755 --- a/addons/hr_payroll/report/report_year_salary.py +++ b/addons/hr_payroll/report/report_year_salary.py @@ -5,8 +5,6 @@ from report import report_sxw import time import pooler import rml_parse -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime class year_salary_report(rml_parse.rml_parse): diff --git a/addons/l10n_ch/report/bvr_report.py b/addons/l10n_ch/report/bvr_report.py index 646806b202f..e0c7ca624a5 100644 --- a/addons/l10n_ch/report/bvr_report.py +++ b/addons/l10n_ch/report/bvr_report.py @@ -35,7 +35,7 @@ import os import sys import shutil import time -from mx.DateTime import * +from datetime import datetime from report import report_sxw from tools import mod10r diff --git a/addons/l10n_ch/wizard/create_dta.py b/addons/l10n_ch/wizard/create_dta.py index 8bde159013a..d3e2856387d 100644 --- a/addons/l10n_ch/wizard/create_dta.py +++ b/addons/l10n_ch/wizard/create_dta.py @@ -31,7 +31,7 @@ ############################################################################## import time -import mx.DateTime +from datetime import datetime import base64 from osv import osv, fields @@ -469,11 +469,11 @@ def _create_dta(obj, cr, uid, data, context=None): 'on line: ' + pline.name) if pline.order_id.date_scheduled: - date_value = mx.DateTime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d') + date_value = datetime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d') elif pline.date: - date_value = mx.DateTime.strptime(pline.date, '%Y-%m-%d') + date_value = datetime.strptime(pline.date, '%Y-%m-%d') else: - date_value = mx.DateTime.now() + date_value = datetime.now() v['date_value'] = date_value.strftime("%y%m%d") # si compte iban -> iban (836) diff --git a/addons/mrp/report/workcenter_load.py b/addons/mrp/report/workcenter_load.py index 473dedd9d1a..15e94bd6f4c 100644 --- a/addons/mrp/report/workcenter_load.py +++ b/addons/mrp/report/workcenter_load.py @@ -23,8 +23,12 @@ from report.render import render from report.interface import report_int from pychart import * from mx.DateTime import * +import time +from datetime import datetime +from dateutil.relativedelta import relativedelta + from report.misc import choice_colors -import time, mx + import random import StringIO @@ -62,8 +66,8 @@ class report_custom(report_int): months = {1:"January",2:"February",3:"March",4:"April",5:"May",6:"June",7:"July",8:"August",9:"September",10:"October",11:"November",12:"December"} dates[i] = { 'name' :months[month], - 'start':(Date(year, month, 2) + RelativeDateTime(day=1)).strftime('%Y-%m-%d'), - 'stop' :(Date(year, month, 2) + RelativeDateTime(day=-1)).strftime('%Y-%m-%d'), + 'start':(datetime.date(year, month, 2) + relativedelta(day=1)).strftime('%Y-%m-%d'), + 'stop' :(datetime.date(year, month, 2) + relativedelta(day=-1)).strftime('%Y-%m-%d'), } return dates elif time_unit == 'week': @@ -90,7 +94,7 @@ class report_custom(report_int): 'start':i.strftime('%Y-%m-%d'), 'stop' :i.strftime('%Y-%m-%d'), } - i = i + RelativeDateTime(days=+1) + i = i + relativedelta(days=+1) return dates return {} diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 7aafee1a447..af88c32f42a 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -21,8 +21,8 @@ from osv import fields,osv import netsvc -import mx.DateTime -from mx.DateTime import RelativeDateTime, today +from datetime import datetime, date +from dateutil.relativedelta import relativedelta from tools.translate import _ import decimal_precision as dp @@ -222,8 +222,7 @@ class mrp_repair(osv.osv): if move_id: move = self.pool.get('stock.move').browse(cr, uid, move_id) product = self.pool.get('product.product').browse(cr, uid, prod_id) - date = move.date_planned - limit = mx.DateTime.strptime(date, '%Y-%m-%d %H:%M:%S') + RelativeDateTime(months=product.warranty) + limit = datetime.strptime(move.date_planned, '%Y-%m-%d %H:%M:%S') + relativedelta(months=product.warranty) data['value']['guarantee_limit'] = limit.strftime('%Y-%m-%d') data['value']['location_id'] = move.location_dest_id.id data['value']['location_dest_id'] = move.location_dest_id.id @@ -688,7 +687,7 @@ class mrp_repair_line(osv.osv, ProductChangeMixin): if type == 'add': stock_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0] to_invoice = False - if guarantee_limit and today() > mx.DateTime.strptime(guarantee_limit, '%Y-%m-%d'): + if guarantee_limit and date.today() > datetime.strptime(guarantee_limit, '%Y-%m-%d'): to_invoice=True return {'value': { 'to_invoice': to_invoice, diff --git a/addons/project_planning/project_planning.py b/addons/project_planning/project_planning.py index 2044772e6cc..729a8ee6bbb 100644 --- a/addons/project_planning/project_planning.py +++ b/addons/project_planning/project_planning.py @@ -21,7 +21,8 @@ ############################################################################## import time -import mx.DateTime +from datetime import datetime +from dateutil.relativedelta import relativedelta from osv import fields, osv from tools.translate import _ @@ -139,7 +140,7 @@ class report_account_analytic_planning(osv.osv): } _defaults = { 'date_from': time.strftime('%Y-%m-01'), - 'date_to': (mx.DateTime.now()+mx.DateTime.RelativeDateTime(months=1, day=1, days=-1)).strftime('%Y-%m-%d'), + 'date_to': (datetime.now()+relativedelta(months=1, day=1, days=-1)).strftime('%Y-%m-%d'), 'user_id': lambda self, cr, uid, c: uid, 'state': 'draft', 'business_days': 20, diff --git a/addons/project_timesheet/report/task_report.py b/addons/project_timesheet/report/task_report.py index ea454519394..261f4e17c64 100644 --- a/addons/project_timesheet/report/task_report.py +++ b/addons/project_timesheet/report/task_report.py @@ -18,7 +18,8 @@ # along with this program. If not, see . # ############################################################################## -import mx.DateTime +from datetime import datetime +from dateutil.relativedelta import relativedelta from osv import fields,osv import tools @@ -31,7 +32,7 @@ class report_timesheet_task_user(osv.osv): def _get_task_hours(self, cr, uid, ids, name,args,context): result = {} for record in self.browse(cr, uid, ids,context): - last_date = mx.DateTime.strptime(record.name, '%Y-%m-%d') + mx.DateTime.RelativeDateTime(months=1) - 1 + last_date = datetime(record.name, '%Y-%m-%d') + relativedelta(months=1) - 1 task_obj=self.pool.get('project.task.work') task_ids = task_obj.search(cr, uid, [('user_id','=',record.user_id.id),('date','>=',record.name),('date','<=',last_date.strftime('%Y-%m-%d'))]) tsk_hrs = task_obj.read(cr, uid, task_ids, ['hours','date','user_id']) @@ -45,7 +46,7 @@ class report_timesheet_task_user(osv.osv): result = {} sum = 0.0 for record in self.browse(cr, uid, ids, context): - last_date = mx.DateTime.strptime(record.name, '%Y-%m-%d') + mx.DateTime.RelativeDateTime(months=1) - 1 + last_date = datetime.strptime(record.name, '%Y-%m-%d') + relativedelta(months=1) - 1 obj=self.pool.get('hr_timesheet_sheet.sheet.day') sheet_ids = obj.search(cr, uid, [('sheet_id.user_id','=',record.user_id.id),('name','>=',record.name),('name','<=',last_date.strftime('%Y-%m-%d'))]) data_days = obj.read(cr, uid, sheet_ids, ['name','sheet_id.user_id','total_attendance']) diff --git a/addons/stock_planning/stock_planning.py b/addons/stock_planning/stock_planning.py index f6668130415..9d08fe3077e 100644 --- a/addons/stock_planning/stock_planning.py +++ b/addons/stock_planning/stock_planning.py @@ -20,8 +20,8 @@ ############################################################################## import time -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime +from datetime import datetime +from dateutil.relativedelta import relativedelta from osv import osv, fields import netsvc @@ -538,14 +538,14 @@ class stock_planning(osv.osv): return res / product.uom_id.factor, uom.rounding def calculate_planning(self, cr, uid, ids, context, *args): - one_minute = RelativeDateTime(minutes=1) - current_date_beginning_c = mx.DateTime.today() - current_date_end_c = current_date_beginning_c + RelativeDateTime(days=1, minutes=-1) # to get hour 23:59:00 + one_minute = relativedelta(minutes=1) + current_date_beginning_c = datetime.today() + current_date_end_c = current_date_beginning_c + relativedelta(days=1, minutes=-1) # to get hour 23:59:00 current_date_beginning = current_date_beginning_c.strftime('%Y-%m-%d %H:%M:%S') current_date_end = current_date_end_c.strftime('%Y-%m-%d %H:%M:%S') for val in self.browse(cr, uid, ids, context=context): - day = mx.DateTime.strptime(val.period_id.date_start, '%Y-%m-%d %H:%M:%S') - dbefore = mx.DateTime.DateTime(day.year, day.month, day.day) - one_minute + day = datetime.strptime(val.period_id.date_start, '%Y-%m-%d %H:%M:%S') + dbefore = datetime(day.year, day.month, day.day) - one_minute day_before_calculated_period = dbefore.strftime('%Y-%m-%d %H:%M:%S') # one day before start of calculated period cr.execute("SELECT date_start \ FROM stock_period AS period \ @@ -556,8 +556,9 @@ class stock_planning(osv.osv): date = cr.fetchone() start_date_current_period = date and date[0] or False start_date_current_period = start_date_current_period or current_date_beginning - day = mx.DateTime.strptime(start_date_current_period, '%Y-%m-%d %H:%M:%S') - dbefore = mx.DateTime.DateTime(day.year, day.month, day.day) - one_minute + + day = datetime.strptime(start_date_current_period, '%Y-%m-%d %H:%M:%S') + dbefore = datetime.datetime(day.year, day.month, day.day) - one_minute date_for_start = dbefore.strftime('%Y-%m-%d %H:%M:%S') # one day before current period already_out = self._get_in_out(cr, uid, val, start_date_current_period, current_date_end, direction='out', done=True, context=context), already_in = self._get_in_out(cr, uid, val, start_date_current_period, current_date_end, direction='in', done=True, context=context), diff --git a/addons/stock_planning/wizard/stock_planning_create_periods.py b/addons/stock_planning/wizard/stock_planning_create_periods.py index 61e699c84f7..12e0d56e755 100644 --- a/addons/stock_planning/wizard/stock_planning_create_periods.py +++ b/addons/stock_planning/wizard/stock_planning_create_periods.py @@ -20,8 +20,8 @@ ############################################################################## import time -import mx.DateTime -from mx.DateTime import RelativeDateTime, now, DateTime, localtime +from datetime import datetime +from dateutil.relativedelta import relativedelta from osv import osv, fields @@ -35,10 +35,10 @@ class stock_period_createlines(osv.osv_memory): result = cr.fetchone() last_date = result and result[0] or False if last_date: - period_start = mx.DateTime.strptime(last_date,"%Y-%m-%d %H:%M:%S")+ RelativeDateTime(days=1) - period_start = period_start - RelativeDateTime(hours=period_start.hour, minutes=period_start.minute, seconds=period_start.second) + period_start = datetime(last_date,"%Y-%m-%d %H:%M:%S")+ relativedelta(days=1) + period_start = period_start - relativedelta(hours=period_start.hour, minutes=period_start.minute, seconds=period_start.second) else: - period_start = mx.DateTime.today() + period_start = datetime.today() return period_start.strftime('%Y-%m-%d') @@ -59,35 +59,35 @@ class stock_period_createlines(osv.osv_memory): lines = [] for p in self.browse(cr, uid, ids, context=context): dt = p.date_start - ds = mx.DateTime.strptime(p.date_start, '%Y-%m-%d') + ds = datetime.strptime(p.date_start, '%Y-%m-%d') while ds.strftime('%Y-%m-%d') < p.date_stop: if name =='Daily': - de = ds + RelativeDateTime(days=interval, minutes =-1) + de = ds + relativedelta(days=interval, minutes =-1) new_name = de.strftime('%Y-%m-%d') new_id = period_obj.create(cr, uid, { 'name': new_name, 'date_start': ds.strftime('%Y-%m-%d'), 'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'), }) - ds = ds + RelativeDateTime(days=interval) + 1 + ds = ds + relativedelta(days=interval) + 1 if name =="Weekly": - de = ds + RelativeDateTime(days=interval, minutes =-1) + de = ds + relativedelta(days=interval, minutes =-1) new_name = de.strftime('%Y, week %W') new_id = period_obj.create(cr, uid, { 'name': new_name, 'date_start': ds.strftime('%Y-%m-%d'), 'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'), }) - ds = ds + RelativeDateTime(days=interval) + 1 + ds = ds + relativedelta(days=interval) + 1 if name == "Monthly": - de = ds + RelativeDateTime(months=interval, minutes=-1) + de = ds + relativedelta(months=interval, minutes=-1) new_name = ds.strftime('%Y/%m') new_id =period_obj.create(cr, uid, { 'name': new_name, 'date_start': ds.strftime('%Y-%m-%d'), 'date_stop': de.strftime('%Y-%m-%d %H:%M:%S'), }) - ds = ds + RelativeDateTime(months=interval) + ds = ds + relativedelta(months=interval) lines.append(new_id) return { 'domain': "[('id','in', ["+','.join(map(str, lines))+"])]", diff --git a/addons/survey/survey.py b/addons/survey/survey.py index 61d96f792f8..57a78e9ac5d 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -27,9 +27,9 @@ import netsvc from tools.translate import _ from time import strftime -import datetime +from datetime import datetime +from dateutil.relativedelta import relativedelta import copy -from mx.DateTime import * import os class survey_type(osv.osv): @@ -694,7 +694,7 @@ class survey_request(osv.osv): } _defaults = { 'state': lambda * a: 'draft', -# 'date_deadline': lambda * a : (now() + RelativeDateTime(months=+1)).strftime("%Y-%m-%d %H:%M:%S") +# 'date_deadline': lambda * a : (datetime.now() + relativedelta(months=+1)).strftime("%Y-%m-%d %H:%M:%S") } def survey_req_waiting_answer(self, cr, uid, ids, arg): self.write(cr, uid, ids, { 'state' : 'waiting_answer'}) From 960fc8e27c6f5010cf9c218447f35b228a7ba831 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Wed, 29 Sep 2010 11:52:55 +0200 Subject: [PATCH 14/18] [IMP] base_contact: performance imporovement: 'job_id' field (res.partner.contact object) was generating a lot of queries bzr revid: olt@tinyerp.com-20100929095255-wxn4u9dfn8j0dd8z --- addons/base_contact/base_contact.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py index 8e3a4ded7eb..13ee62bf768 100644 --- a/addons/base_contact/base_contact.py +++ b/addons/base_contact/base_contact.py @@ -26,7 +26,7 @@ class res_partner_contact(osv.osv): _name = "res.partner.contact" _description = "Contact" - + def _main_job(self, cr, uid, ids, fields, arg, context=None): """ @param self: The object pointer @@ -36,12 +36,16 @@ class res_partner_contact(osv.osv): @fields: Get Fields @param context: A standard dictionary for contextual values @param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """ - - res = dict.fromkeys(ids, False) + + res_partner_job_obj = self.pool.get('res.partner.job') + all_job_ids = res_partner_job_obj.search(cr, uid, []) + all_job_names = dict(zip(all_job_ids, res_partner_job_obj.name_get(cr, uid, all_job_ids, context=context))) + for contact in self.browse(cr, uid, ids, context): if contact.job_ids: - res[contact.id] = contact.job_ids[0].name_get()[0] + res[contact.id] = all_job_names.get(contact.job_ids[0].id, False) + return res _columns = { @@ -61,7 +65,7 @@ class res_partner_contact(osv.osv): 'function': fields.related('job_ids', 'function', type='char', \ string='Main Function'), 'job_id': fields.function(_main_job, method=True, type='many2one',\ - relation='res.partner.job', string='Main Job', store=True), + relation='res.partner.job', string='Main Job'), 'email': fields.char('E-Mail', size=240), 'comment': fields.text('Notes', translate=True), 'photo': fields.binary('Image'), @@ -138,8 +142,7 @@ class res_partner_address(osv.osv): res_partner_address() class res_partner_job(osv.osv): - - def name_get(self, cr, uid, ids, context={}): + def name_get(self, cr, uid, ids, context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, @@ -147,12 +150,15 @@ class res_partner_job(osv.osv): @param ids: List of partner address’s IDs @param context: A standard dictionary for contextual values """ + if context is None: + context = {} - if not len(ids): + if not ids: return [] res = [] jobs = self.browse(cr, uid, ids) + contact_ids = [rec.contact_id.id for rec in jobs] contact_names = dict(self.pool.get('res.partner.contact').name_get(cr, uid, contact_ids, context=context)) @@ -160,6 +166,7 @@ class res_partner_job(osv.osv): function_name = r.function funct = function_name and (", " + function_name) or "" res.append((r.id, contact_names.get(r.contact_id.id, '') + funct)) + return res def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): From 47867b8d71cefca520be4b245076d77d74e370d9 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Wed, 29 Sep 2010 11:57:42 +0200 Subject: [PATCH 15/18] [IMP] point_of_sale: performance improvement in pricelist (price_get) bzr revid: olt@tinyerp.com-20100929095742-yi2ldls09prywt48 --- addons/point_of_sale/pos.py | 19 +--- addons/product/pricelist.py | 188 ++++++++++++++++++++++++++++++++++-- addons/product/product.py | 13 ++- 3 files changed, 193 insertions(+), 27 deletions(-) diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py index b5b17d54d34..0d6ab5f2b33 100644 --- a/addons/point_of_sale/pos.py +++ b/addons/point_of_sale/pos.py @@ -1079,8 +1079,6 @@ class pos_order_line(osv.osv): else: res[line.id][f] = line.price_unit * line.qty res[line.id][f] += tax_amount - print ids - print res return res def price_by_product_multi(self, cr, uid, ids, context=None): @@ -1090,20 +1088,11 @@ class pos_order_line(osv.osv): res = {}.fromkeys(ids, 0.0) lines = self.browse(cr, uid, ids, context=context) - # product_map: - # {10, 1): {'qty': 5, 'uom_id': 1, 'partner_id': 512}, - # (22, 3): {'qty': 10, 'uom_id': 2, 'partner_id', 35}, - # } - # key = (product_id, pricelist_id) - product_map = dict([((line.product_id.id, line.order_id.pricelist_id.id), { - 'qty': line.qty, - 'uom_id': line.product_id.uom_po_id.id, - 'partner_id': line.order_id.partner_id.id, - }) - for line - in lines]) - price_get_multi_res = self.pool.get('product.pricelist').price_get_multi(cr, uid, product_map) + pricelist_ids = [line.order_id.pricelist_id.id for line in lines] + products_by_qty_by_partner = [(line.product_id.id, line.qty, line.order_id.partner_id.id) for line in lines] + + price_get_multi_res = self.pool.get('product.pricelist').price_get_multi(cr, uid, pricelist_ids, products_by_qty_by_partner, context=context) for line in lines: pricelist = line.order_id.pricelist_id.id diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 0dbc9cadcef..a4b93827660 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -126,7 +126,7 @@ class product_pricelist(osv.osv): "currency_id": _get_currency } - def price_get_multi(self, cr, uid, product_map, context=None): + def price_get_multi_old(self, cr, uid, product_map, context=None): """multi products 'price_get' @param context: { 'date': Date of the pricelist (%Y-%m-%d), @@ -155,6 +155,7 @@ class product_pricelist(osv.osv): currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_category_obj = self.pool.get('product.category') + product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') product_pricelist_version_obj = self.pool.get('product.pricelist.version') @@ -178,7 +179,7 @@ class product_pricelist(osv.osv): # product.product: product_ids = list(set([k[0] for k in product_map.keys()])) - products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id'])]) + products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) @@ -191,7 +192,6 @@ class product_pricelist(osv.osv): partner = line['partner_id'] qty = line['qty'] - uom_id = line['uom_id'] tmpl_id = products[product_id]['product_tmpl_id'] and products[product_id]['product_tmpl_id'][0] or False categ_id = products[product_id]['categ_id'] and products[product_id]['categ_id'][0] or False @@ -269,20 +269,192 @@ class product_pricelist(osv.osv): # exception here because it breaks the search price = False + if price: + p_uom_id = products[product_id]['uos_id'] and products[product_id]['uos_id'][0] or products[product_id]['uom_id'] and products[product_id]['uom_id'][0] or False + if p_uom_id: + price = product_uom_obj._compute_price(cr, uid, p_uom_id, price, context.get('uom', False)) + if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} - # XXX - #if 'uom' in context: - # product = product_obj.browse(cr, uid, product_id) - # uom = product.uos_id or product.uom_id - # results[product_id] = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, result[id], context['uom']) + return results + + #def price_get_multi(self, cr, uid, product_ids, context=None): + def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None): + """multi products 'price_get'. + @param pricelist_ids: + @param products_by_qty: + @param partner: + @param context: { + 'date': Date of the pricelist (%Y-%m-%d),} + @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value + """ + + def _create_parent_category_list(id, lst): + if not id: + return [] + parent = product_category_tree.get(id) + if parent: + lst.append(parent) + return _create_parent_category_list(parent, lst) + else: + return lst + # _create_parent_category_list + + if context is None: + context = {} + + date = time.strftime('%Y-%m-%d') + if 'date' in context: + date = context['date'] + + currency_obj = self.pool.get('res.currency') + product_obj = self.pool.get('product.product') + product_category_obj = self.pool.get('product.category') + product_uom_obj = self.pool.get('product.uom') + supplierinfo_obj = self.pool.get('product.supplierinfo') + price_type_obj = self.pool.get('product.price.type') + product_pricelist_version_obj = self.pool.get('product.pricelist.version') + + # product.pricelist.version: + if pricelist_ids: + pricelist_version_ids = pricelist_ids + else: + # all pricelists: + pricelist_version_ids = product_pricelist_version_obj.search(cr, uid, []) + + pricelist_version_ids = list(set(pricelist_version_ids)) + + plversions_search_args = [ + ('pricelist_id', 'in', pricelist_version_ids), + '|', + ('date_start', '=', False), + ('date_start', '<=', date), + '|', + ('date_end', '=', False), + ('date_end', '>=', date), + ] + + plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args) + if len(pricelist_version_ids) != len(plversion_ids): + msg = "At least one pricelist has no active version !\nPlease create or activate one." + raise osv.except_osv(_('Warning !'), _(msg)) + + # product.product: + product_ids = [i[0] for i in products_by_qty_by_partner] + #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) + products = product_obj.browse(cr, uid, product_ids, context=context) + products_dict = dict([(item.id, item) for item in products]) + + # product.category: + product_category_ids = product_category_obj.search(cr, uid, []) + product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) + product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) + + results = {} + for product_id, qty, partner in products_by_qty_by_partner: + for pricelist_id in pricelist_version_ids: + price = False + + tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False + + categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False + categ_ids = _create_parent_category_list(categ_id, [categ_id]) + if categ_ids: + categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' + else: + categ_where = '(categ_id IS NULL)' + + cr.execute( + 'SELECT i.*, pl.currency_id ' + 'FROM product_pricelist_item AS i, ' + 'product_pricelist_version AS v, product_pricelist AS pl ' + 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' + 'AND (product_id IS NULL OR product_id = %s) ' + 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' + 'AND price_version_id = %s ' + 'AND (min_quantity IS NULL OR min_quantity <= %s) ' + 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' + 'ORDER BY sequence', + (tmpl_id, product_id, pricelist_id, qty)) + res1 = cr.dictfetchall() + + for res in res1: + if res: + if res['base'] == -1: + if not res['base_pricelist_id']: + price = 0.0 + else: + price_tmp = self.price_get(cr, uid, + [res['base_pricelist_id']], prod_id, + qty)[res['base_pricelist_id']] + ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id + price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) + break + elif res['base'] == -2: + # this section could be improved by moving the queries outside the loop: + where = [] + if partner: + where = [('name', '=', partner) ] + sinfo = supplierinfo_obj.search(cr, uid, + [('product_id', '=', tmpl_id)] + where) + price = 0.0 + if sinfo: + cr.execute('SELECT * ' \ + 'FROM pricelist_partnerinfo ' \ + 'WHERE suppinfo_id IN %s' \ + 'AND min_quantity <= %s ' \ + 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,)) + res2 = cr.dictfetchone() + if res2: + price = res2['price'] + break + else: + price_type = price_type_obj.browse(cr, uid, int(res['base'])) + price = currency_obj.compute(cr, uid, + price_type.currency_id.id, res['currency_id'], + product_obj.price_get(cr, uid, [product_id], + price_type.field)[product_id], round=False, context=context) + + if price: + price_limit = price + + price = price * (1.0+(res['price_discount'] or 0.0)) + price = rounding(price, res['price_round']) + price += (res['price_surcharge'] or 0.0) + if res['price_min_margin']: + price = max(price, price_limit+res['price_min_margin']) + if res['price_max_margin']: + price = min(price, price_limit+res['price_max_margin']) + break + + else: + # False means no valid line found ! But we may not raise an + # exception here because it breaks the search + price = False + + if price: + if 'uom' in context: + product = products_dict[product_id] + uom = product.uos_id or product.uom_id + price = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, price, context['uom']) + + if results.get(product_id): + results[product_id][pricelist_id] = price + else: + results[product_id] = {pricelist_id: price} return results def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None): + res_multi = self.price_get_multi(cr, uid, pricelist_ids=ids, products_by_qty_by_partner=[(prod_id, qty, partner)], context=context) + res = res_multi[prod_id] + res.update({'item_id': {ids[-1]: ids[-1]}}) + return res + + def price_get_old(self, cr, uid, ids, prod_id, qty, partner=None, context=None): ''' context = { 'uom': Unit of Measure (int), diff --git a/addons/product/product.py b/addons/product/product.py index 1b74bef87f9..6c1125268a9 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -503,7 +503,15 @@ class product_product(osv.osv): # # Could be overrided for variants matrices prices # - def price_get(self, cr, uid, ids, ptype='list_price', context={}): + def price_get(self, cr, uid, ids, ptype='list_price', context=None): + if context is None: + context = {} + + if 'currency_id' in context: + pricetype_obj = self.pool.get('product.price.type') + price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0] + price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id + res = {} product_uom_obj = self.pool.get('product.uom') for product in self.browse(cr, uid, ids, context=context): @@ -517,11 +525,8 @@ class product_product(osv.osv): uom.id, res[product.id], context['uom']) # Convert from price_type currency to asked one if 'currency_id' in context: - pricetype_obj = self.pool.get('product.price.type') # Take the price_type currency from the product field # This is right cause a field cannot be in more than one currency - price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0] - price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id, context['currency_id'], res[product.id],context=context) From 6913627b66e90df99ea738bf6ae8533742f8fd78 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 29 Sep 2010 15:42:08 +0530 Subject: [PATCH 16/18] [MERGE] Fix yml issue on mrp_subproduct bzr revid: hmo@tinyerp.com-20100929101208-q9dx3byqko2hbpuw --- addons/mrp_subproduct/test/mrp_subproduct.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mrp_subproduct/test/mrp_subproduct.yml b/addons/mrp_subproduct/test/mrp_subproduct.yml index 520a4e98163..56c62b94d09 100644 --- a/addons/mrp_subproduct/test/mrp_subproduct.yml +++ b/addons/mrp_subproduct/test/mrp_subproduct.yml @@ -164,6 +164,6 @@ I see that stock moves of Wood and Nails including Wooden Table are done now. - !python {model: stock.move}: | - move_ids = self.search(cr, uid, [('product_id','in',[ref("product_product_woodenchair0"),ref("product_product_woodentable0"),ref("product_product_wood0"),ref("product_product_nails0")])]) + move_ids = self.search(cr, uid, [('product_id','in',[ref("product_product_woodentable0"),ref("product_product_wood0"),ref("product_product_nails0")])]) moves = self.browse(cr, uid, move_ids) assert all(move.state == 'done' for move in moves), 'Moves are not done!' From f78b03a134690db4f722bd3e490f83964a17ff7f Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Wed, 29 Sep 2010 14:13:40 +0200 Subject: [PATCH 17/18] [IMP] resource: performance improvement: created a 'resource.calendar' interval_get_multi which takes a list of tuples instead of single arguments 'interval_get' is not removed and now uses the multi method to avoid duplicated code bzr revid: olt@tinyerp.com-20100929121340-g9hpmkavpguizajg --- addons/mrp_operations/mrp_operations.py | 14 ++-- addons/resource/resource.py | 99 ++++++++++++++++--------- 2 files changed, 72 insertions(+), 41 deletions(-) diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index 919f65903ae..52a8a81cb49 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -62,26 +62,30 @@ class mrp_production_workcenter_line(osv.osv): else: res[op.id]=False return res - + def _get_date_end(self, cr, uid, ids, field_name, arg, context): """ Finds ending date. @return: Dictionary of values. """ + ops = self.browse(cr, uid, ids, context=context) + date_and_hours_by_cal = [(op.date_planned, op.hour, op.workcenter_id.calendar_id.id) for op in ops] + intervals = self.pool.get('resource.calendar').interval_get_multi(cr, uid, date_and_hours_by_cal) + res = {} - for op in self.browse(cr, uid, ids, context=context): + for op in ops: res[op.id] = False if op.date_planned: d = DateTime.strptime(op.date_planned,'%Y-%m-%d %H:%M:%S') - i = self.pool.get('resource.calendar').interval_get(cr, uid, op.workcenter_id.calendar_id.id or False, d, op.hour or 0.0) + i = intervals[(op.date_planned, op.hour, op.workcenter_id.calendar_id.id)] if i: res[op.id] = i[-1][1].strftime('%Y-%m-%d %H:%M:%S') else: res[op.id] = op.date_planned return res - + _inherit = 'mrp.production.workcenter.line' _order = "sequence, date_planned" - + _columns = { 'state': fields.selection([('draft','Draft'),('startworking', 'In Progress'),('pause','Pause'),('cancel','Cancelled'),('done','Finished')],'State', readonly=True, help="* When a work order is created it is set in 'Draft' state.\n" \ diff --git a/addons/resource/resource.py b/addons/resource/resource.py index 4a2ff3e34dd..24efc179c03 100644 --- a/addons/resource/resource.py +++ b/addons/resource/resource.py @@ -20,12 +20,17 @@ ############################################################################## from datetime import datetime, timedelta +from mx import DateTime import math from faces import * from new import classobj from osv import fields, osv from tools.translate import _ +from itertools import groupby +from operator import itemgetter + + class resource_calendar(osv.osv): _name = "resource.calendar" _description = "Resource Calendar" @@ -44,11 +49,12 @@ class resource_calendar(osv.osv): dt_leave = [] resource_leave_ids = resource_cal_leaves.search(cr, uid, [('calendar_id','=',id), '|', ('resource_id','=',False), ('resource_id','=',resource)]) - res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to']) + #res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to']) + res_leaves = resource_cal_leaves.browse(cr, uid, resource_leave_ids) for leave in res_leaves: - dtf = datetime.strptime(leave['date_from'], '%Y-%m-%d %H:%M:%S') - dtt = datetime.strptime(leave['date_to'], '%Y-%m-%d %H:%M:%S') + dtf = datetime.strptime(leave.date_from, '%Y-%m-%d %H:%M:%S') + dtt = datetime.strptime(leave.date_to, '%Y-%m-%d %H:%M:%S') no = dtt - dtf [dt_leave.append((dtf + timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))] dt_leave.sort() @@ -92,40 +98,61 @@ class resource_calendar(osv.osv): result.reverse() return result + # def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True): + def interval_get_multi(self, cr, uid, date_and_hours_by_cal, resource=False, byday=True): + def group(lst, key): + lst.sort(key=itemgetter(key)) + grouped = groupby(lst, itemgetter(key)) + return dict([(k, [v for v in itr]) for k, itr in grouped]) + # END group + + cr.execute("select calendar_id, dayofweek, hour_from, hour_to from resource_calendar_attendance order by hour_from") + hour_res = cr.dictfetchall() + hours_by_cal = group(hour_res, 'calendar_id') + + results = {} + + for d, hours, id in date_and_hours_by_cal: + dt_from = DateTime.strptime(d, '%Y-%m-%d %H:%M:%S') + if not id: + td = int(hours)*3 + results[(d, hours, id)] = [(dt_from, dt_from + timedelta(hours=td))] + continue + + dt_leave = self._get_leaves(cr, uid, id, resource) + todo = hours + result = [] + maxrecur = 100 + current_hour = dt_from.hour + while (todo>0) and maxrecur: + for (hour_from,hour_to) in [(item['hour_from'], item['hour_to']) for item in hours_by_cal[id] if item['dayofweek'] == str(dt_from.weekday())]: + leave_flag = False + if (hour_to>current_hour) and (todo>0): + m = max(hour_from, current_hour) + if (hour_to-m)>todo: + hour_to = m+todo + dt_check = dt_from.strftime('%Y-%m-%d') + for leave in dt_leave: + if dt_check == leave: + dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1) + leave_flag = True + if leave_flag: + break + else: + d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60)) + d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60)) + result.append((d1, d2)) + current_hour = hour_to + todo -= (hour_to - m) + dt_from += timedelta(days=1) + current_hour = 0 + maxrecur -= 1 + results[(d, hours, id)] = result + return results + def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True): - if not id: - td = int(hours)*3 - return [(dt_from, dt_from + timedelta(hours=td))] - dt_leave = self._get_leaves(cr, uid, id, resource) - todo = hours - result = [] - maxrecur = 100 - current_hour = dt_from.hour - while (todo>0) and maxrecur: - cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id)) - for (hour_from,hour_to) in cr.fetchall(): - leave_flag = False - if (hour_to>current_hour) and (todo>0): - m = max(hour_from, current_hour) - if (hour_to-m)>todo: - hour_to = m+todo - dt_check = dt_from.strftime('%Y-%m-%d') - for leave in dt_leave: - if dt_check == leave: - dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1) - leave_flag = True - if leave_flag: - break - else: - d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60)) - d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60)) - result.append((d1, d2)) - current_hour = hour_to - todo -= (hour_to - m) - dt_from += timedelta(days=1) - current_hour = 0 - maxrecur -= 1 - return result + res = self.interval_get_multi(cr, uid, [(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)], resource, byday)[(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)] + return res def interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource=False): if not id: From c97280933d63cd91fc6e739f6f00eeca3cb44440 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Wed, 29 Sep 2010 19:16:11 +0530 Subject: [PATCH 18/18] [FIX]l10n_ch: remove font's hack, register the font into the main engine. For some reason, reportlab still fails to embed the font into the PDF. Please fix that. bzr revid: hmo@tinyerp.com-20100929134611-rx5b9wwp5w3aq7eh --- addons/l10n_ch/__openerp__.py | 2 +- addons/l10n_ch/report/bvr_invoice_report.rml | 2 -- addons/l10n_ch/report/bvr_report.py | 37 +++++++++----------- addons/l10n_ch/report/bvr_report.rml | 1 - 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/addons/l10n_ch/__openerp__.py b/addons/l10n_ch/__openerp__.py index a9315abdf55..bca3c7ebcd6 100644 --- a/addons/l10n_ch/__openerp__.py +++ b/addons/l10n_ch/__openerp__.py @@ -66,7 +66,7 @@ TODO : """, - "version" : "5.0", + "version" : "5.1", "author" : "Camptocamp SA", "category" : "Localisation/Europe", "website": "http://www.camptocamp.com", diff --git a/addons/l10n_ch/report/bvr_invoice_report.rml b/addons/l10n_ch/report/bvr_invoice_report.rml index e00c061522a..46798ae7da4 100755 --- a/addons/l10n_ch/report/bvr_invoice_report.rml +++ b/addons/l10n_ch/report/bvr_invoice_report.rml @@ -1,8 +1,6 @@ - -