From 3b6ba554a34ea59f7b7401a2375385dad8db1cf1 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 23 Jul 2010 18:47:30 +0530 Subject: [PATCH 01/10] [IMP] product, mrp: added new function field 'seller_id' to get main supplier who has highet priority in Supplier Information also 'seller_qty'. added new function 'price_get' in 'product.supplierinfo' model to get price from supplier pricelist. improved and clean product cost structure report in product form. bzr revid: hmo@tinyerp.com-20100723131730-hx8nw4tkotmfj4ov --- addons/mrp/mrp.py | 4 +- addons/mrp/report/price.py | 88 ++++++++++++++----------------- addons/mrp/wizard/mrp_price.py | 3 ++ addons/procurement/procurement.py | 3 +- addons/product/product.py | 60 ++++++++++++++++++--- addons/product/product_view.xml | 2 + addons/purchase/purchase.py | 11 ++-- 7 files changed, 108 insertions(+), 63 deletions(-) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index acfab2d6f09..2d31adabb5f 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -48,10 +48,10 @@ class mrp_workcenter(osv.osv): 'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."), 'time_start': fields.float('Time before prod.', help="Time in hours for the setup."), 'time_stop': fields.float('Time after prod.', help="Time in hours for the cleaning."), - 'costs_hour': fields.float('Cost per hour'), + 'costs_hour': fields.float('Cost per hour', help="Specify Cost of Workcenter per hour."), 'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','<>','view')], help="Complete this only if you want automatic analytic accounting entries on production orders."), - 'costs_cycle': fields.float('Cost per cycle'), + 'costs_cycle': fields.float('Cost per cycle', help="Specify Cost of Workcenter per cycle."), 'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','<>','view')], help="Complete this only if you want automatic analytic accounting entries on production orders."), 'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'), diff --git a/addons/mrp/report/price.py b/addons/mrp/report/price.py index 0a6a21de971..e261c3941fb 100644 --- a/addons/mrp/report/price.py +++ b/addons/mrp/report/price.py @@ -31,53 +31,46 @@ from tools.translate import _ class report_custom(report_rml): def create_xml(self, cr, uid, ids, datas, context={}): number = (datas.get('form', False) and datas['form']['number']) or 1 - - def process_bom(bom, currency_id): + pool = pooler.get_pool(cr.dbname) + product_pool = pool.get('product.product') + product_uom_pool = pool.get('product.uom') + supplier_info_pool = pool.get('product.supplierinfo') + workcenter_pool = pool.get('mrp.workcenter') + user_pool = pool.get('res.users') + bom_pool = pool.get('mrp.bom') + def process_bom(bom, currency_id, factor=1): xml = '' sum = 0 sum_strd = 0 - prod = pooler.get_pool(cr.dbname).get('product.product').browse(cr, uid, bom['product_id']) + prod = product_pool.browse(cr, uid, bom['product_id']) prod_name = bom['name'] - prod_qtty = bom['product_qty'] - prod_uom = prod.uom_id.name + prod_qtty = factor * bom['product_qty'] + product_uom = product_uom_pool.browse(cr, uid, bom['product_uom'], context=context) level = 1 - main_sp_price = '' - main_sp_name = '' - main_strd_price = '' - main_strd_price = '' - if prod.seller_ids and prod.seller_ids[0] : - main_sp_name = '' + prod.seller_ids[0].name.name + '\r\n' - pricelist_id = prod.seller_ids[0].name.property_product_pricelist_purchase.id - if pricelist_id: - pricelist_obj = pooler.get_pool(cr.dbname).get('product.pricelist') - price = pricelist_obj.price_get(cr,uid,[pricelist_id], prod.id, number*prod_qtty or 1.0).setdefault(pricelist_id, 0) - price = pooler.get_pool(cr.dbname).get('res.currency').compute(cr, uid, pricelist_obj.browse(cr, uid, pricelist_id).currency_id.id, currency_id, price) - else: - price = 0 - main_sp_price = '%.2f' % price + '\r\n' + main_sp_price, main_sp_name , main_strd_price = '','','' + sellers, sellers_price = '','' + + if prod.seller_id: + main_sp_name = "%s\r\n" %(prod.seller_id.name) + price = supplier_info_pool.price_get(cr, uid, prod.seller_id.id, prod.id, number*prod_qtty)[prod.seller_id.id] + price = product_uom_pool._compute_price(cr, uid, prod.uom_id.id, price, to_uom_id=product_uom.id) + main_sp_price = '%s\r\n' %(str(price)) sum += prod_qtty*price + std_price = product_uom_pool._compute_price(cr, uid, prod.uom_id.id, prod.standard_price, to_uom_id=product_uom.id) + main_strd_price = str(std_price) + '\r\n' + sum_strd = prod_qtty*std_price - main_strd_price = '%.2f' % prod.standard_price + '\r\n' - sum_strd = prod_qtty*prod.standard_price - - sellers = '' - sellers_price = '' for seller_id in prod.seller_ids: sellers += '- '+ seller_id.name.name +'\r\n' - pricelist_id = seller_id.name.property_product_pricelist_purchase.id - if pricelist_id: - pricelist_obj = pooler.get_pool(cr.dbname).get('product.pricelist') - price = pricelist_obj.price_get(cr,uid,[pricelist_id], prod.id, number*prod_qtty or 1.0).setdefault(pricelist_id, 0) - price = pooler.get_pool(cr.dbname).get('res.currency').compute(cr, uid, pricelist_obj.browse(cr, uid, pricelist_id).currency_id.id, currency_id, price) - else: - price = 0 - sellers_price += '%.2f' % price + '\r\n' + price = supplier_info_pool.price_get(cr, uid, seller_id.name.id, prod.id, number*prod_qtty)[seller_id.name.id] + price = product_uom_pool._compute_price(cr, uid, prod.uom_id.id, price, to_uom_id=product_uom.id) + sellers_price += str(price) + '\r\n' xml += "" + prod_name + '' xml += "" + main_sp_name + sellers + '' xml += "" + str(prod_qtty) + '' - xml += "" + prod_uom + '' + xml += "" + product_uom.name + '' xml += "" + main_strd_price + '' xml += "" + main_sp_price + sellers_price + '' @@ -88,9 +81,9 @@ class report_custom(report_rml): def process_workcenter(wrk): xml = '' - workcenter = pooler.get_pool(cr.dbname).get('mrp.workcenter').browse(cr, uid, wrk['workcenter_id']) + workcenter = workcenter_pool.browse(cr, uid, wrk['workcenter_id']) - xml += "" + wrk['name'] + '' + xml += "" + workcenter.name + '' xml += "" + '' xml += "" + '' xml += "" @@ -150,22 +143,23 @@ class report_custom(report_rml): """ % (_('Product name'), _('Product supplier'), _('Product Quantity'), _('Product uom'), _('Product Standard Price'), _('Unit Product Price')) - company_currency = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid).company_id.currency_id.id + company_currency = user_pool.browse(cr, uid, uid).company_id.currency_id.id first = True - for prod_id in ids: - bom_ids = pooler.get_pool(cr.dbname).get('mrp.bom').search(cr, uid, [('product_id','=',prod_id)]) - prod = pooler.get_pool(cr.dbname).get('product.product').browse(cr, uid, prod_id) - - for bom_id in bom_ids: - bom = pooler.get_pool(cr.dbname).get('mrp.bom').browse(cr, uid, bom_id) - - sub_boms = pooler.get_pool(cr.dbname).get('mrp.bom')._bom_explode(cr, uid, bom, number, []) + for product in product_pool.browse(cr, uid, ids, context=context): + bom_ids = bom_pool.search(cr, uid, [('product_id','=',product.id)]) + for bom in bom_pool.browse(cr, uid, bom_ids, context=context): + sub_boms = bom_pool._bom_explode(cr, uid, bom, number, []) total = 0 total_strd = 0 - parent_bom = {'product_qty': bom.product_qty, 'name': bom.product_id.name, 'product_uom': bom.product_id.uom_id.factor, 'product_id': bom.product_id.id} + parent_bom = { + 'product_qty': bom.product_qty, + 'name': bom.product_id.name, + 'product_uom': bom.product_uom.id, + 'product_id': bom.product_id.id + } xml_tmp = '' for sub_bom in (sub_boms and sub_boms[0]) or [parent_bom]: - txt, sum, sum_strd = process_bom(sub_bom, company_currency) + txt, sum, sum_strd = process_bom(sub_bom, company_currency, factor=1/bom.product_qty) xml_tmp += txt total += sum total_strd += sum_strd @@ -187,7 +181,7 @@ class report_custom(report_rml): first = False - xml = '' + config_start + '%s\n\r' % (_('Product Cost Structure')) + prod.name + ''+ config_stop + header + xml + '' + xml = '' + config_start + '%s\n\r' % (_('Product Cost Structure')) + product.name + ''+ config_stop + header + xml + '' return xml diff --git a/addons/mrp/wizard/mrp_price.py b/addons/mrp/wizard/mrp_price.py index 53d1d031ad9..9c216f7cff1 100644 --- a/addons/mrp/wizard/mrp_price.py +++ b/addons/mrp/wizard/mrp_price.py @@ -27,6 +27,9 @@ class mrp_price(osv.osv_memory): _columns = { 'number': fields.integer('Quantity', required=True, help="Specify quantity of products to produce. Report of Cost structure will be displayed base on this qunatity."), } + _defaults = { + 'number': 1, + } def print_report(self, cr, uid, ids, context=None): """ To print the report of Product cost structure diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 840c5f74d67..4aad723b2f9 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -291,8 +291,7 @@ class procurement_order(osv.osv): if not procurement.product_id.seller_ids: cr.execute('update procurement_order set message=%s where id=%s', (_('No supplier defined for this product !'), procurement.id)) return False - partner_list = sorted([(partner_id.sequence, partner_id) for partner_id in procurement.product_id.seller_ids if partner_id and partner_id.sequence]) - partner = partner_list and partner_list[0] and partner_list[0][1] and partner_list[0][1].name or False + partner = procurement.product_id.seller_id #Taken Main Supplier of Product of Procurement. if user.company_id and user.company_id.partner_id: if partner.id == user.company_id.partner_id.id: diff --git a/addons/product/product.py b/addons/product/product.py index 304c95d7d2e..516787fa3ce 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -59,7 +59,7 @@ class product_uom(osv.osv): def _factor_inv_write(self, cursor, user, id, name, value, arg, context): return self.write(cursor, user, id, {'factor': self._compute_factor_inv(value)}, context=context) - + def create(self, cr, uid, data, context={}): if 'factor_inv' in data: if data['factor_inv'] <> 1: @@ -180,7 +180,7 @@ class product_category(osv.osv): 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."), 'type': fields.selection([('view','View'), ('normal','Normal')], 'Category Type'), } - + _defaults = { 'type' : lambda *a : 'normal', @@ -212,14 +212,18 @@ product_category() class product_template(osv.osv): _name = "product.template" _description = "Product Template" - def _calc_seller_delay(self, cr, uid, ids, name, arg, context={}): + def _calc_seller(self, cr, uid, ids, fields, arg, context={}): result = {} for product in self.browse(cr, uid, ids, context): + for field in fields: + result[product.id] = {field:False} + result[product.id]['seller_delay'] = 1 if product.seller_ids: partner_list = sorted([(partner_id.sequence, partner_id) for partner_id in product.seller_ids if partner_id and partner_id.sequence]) - result[product.id] = partner_list and partner_list[0] and partner_list[0][1] and partner_list[0][1].delay or False - else: - result[product.id] = 1 + main_supplier = partner_list and partner_list[0] and partner_list[0][1] or False + result[product.id]['seller_delay'] = main_supplier and main_supplier.delay or 1 + result[product.id]['seller_qty'] = main_supplier and main_supplier.qty or 0.0 + result[product.id]['seller_id'] = main_supplier and main_supplier.name.id or False return result _columns = { @@ -254,7 +258,9 @@ class product_template(osv.osv): help='Coefficient to convert UOM to UOS\n' ' uos = uom * coeff'), 'mes_type': fields.selection((('fixed', 'Fixed'), ('variable', 'Variable')), 'Measure Type', required=True), - 'seller_delay': fields.function(_calc_seller_delay, method=True, type='integer', string='Supplier Lead Time', help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."), + 'seller_delay': fields.function(_calc_seller, method=True, type='integer', string='Supplier Lead Time', multi="seller_delay", help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."), + 'seller_qty': fields.function(_calc_seller, method=True, type='float', string='Supplier Quantity', multi="seller_qty", help="This is minimum quantity to purchase from Main Supplier."), + 'seller_id': fields.function(_calc_seller, method=True, type='many2one', relation="res.partner", string='Main Supplier', help="Main Supplier who has highest priority in Supplier List.", multi="seller_id"), 'seller_ids': fields.one2many('product.supplierinfo', 'product_id', 'Partners'), 'loc_rack': fields.char('Rack', size=16), 'loc_row': fields.char('Row', size=16), @@ -633,6 +639,46 @@ class product_supplierinfo(osv.osv): 'delay': lambda *a: 1, 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'product.supplierinfo', context=c) } + def price_get(self, cr, uid, supplier_ids, product_id, product_qty=1, context=None): + """ + Calculate price from supplier pricelist. + @param supplier_ids: Ids of res.partner object. + @param product_id: Id of product. + @param product_qty: specify quantity to purchase. + """ + if not context: + context = {} + if type(supplier_ids) in (int,long,): + supplier_ids = [supplier_ids] + res = {} + product_pool = self.pool.get('product.product') + partner_pool = self.pool.get('res.partner') + pricelist_pool = self.pool.get('product.pricelist') + currency_pool = self.pool.get('res.currency') + currency_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id + for supplier in partner_pool.browse(cr, uid, supplier_ids, context=context): + # Compute price from standard price of product + price = product_pool.price_get(cr, uid, [product_id], 'standard_price')[product_id] + + # Compute price from Purchase pricelist of supplier + pricelist_id = supplier.property_product_pricelist_purchase.id + if pricelist_id: + price = pricelist_pool.price_get(cr, uid, [pricelist_id], product_id, product_qty).setdefault(pricelist_id, 0) + price = currency_pool.compute(cr, uid, pricelist_pool.browse(cr, uid, pricelist_id).currency_id.id, currency_id, price) + + # Compute price from supplier pricelist which are in Supplier Information + supplier_info_ids = self.search(cr, uid, [('name','=',supplier.id),('product_id','=',product_id)]) + if supplier_info_ids: + cr.execute('SELECT * ' \ + 'FROM pricelist_partnerinfo ' \ + 'WHERE suppinfo_id IN %s' \ + 'AND min_quantity <= %s ' \ + 'ORDER BY min_quantity DESC LIMIT 1', (tuple(supplier_info_ids),product_qty,)) + res2 = cr.dictfetchone() + if res2: + price = res2['price'] + res[supplier.id] = price + return res _order = 'sequence' product_supplierinfo() diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index f8620931b5e..5ad599d5b94 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -149,6 +149,8 @@ + + diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index acb8280757f..9fdb4f1b213 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -746,23 +746,24 @@ class procurement_order(osv.osv): po_obj = self.pool.get('purchase.order') for procurement in self.browse(cr, uid, ids): res_id = procurement.move_id.id - partner = procurement.product_id.seller_ids[0].name + partner = procurement.product_id.seller_id # Taken Main Supplier of Product of Procurement. + seller_qty = procurement.product_id.seller_qty + seller_delay = int(procurement.product_id.seller_delay) partner_id = partner.id - partner_rec = procurement.product_id.seller_ids[0] address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery'] pricelist_id = partner.property_product_pricelist_purchase.id uom_id = procurement.product_id.uom_po_id.id qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id) - if procurement.product_id.seller_ids[0].qty: - qty = max(qty,partner_rec.qty) + if seller_qty: + qty = max(qty,seller_qty) price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, False, {'uom': uom_id})[pricelist_id] newdate = DateTime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') newdate = newdate - DateTime.RelativeDateTime(days=company.po_lead) - newdate = newdate - partner_rec.delay + newdate = newdate - seller_delay #Passing partner_id to context for purchase order line integrity of Line name context.update({'lang': partner.lang, 'partner_id': partner_id}) From 6d83dde301b0a157e0322826fba7f485e3d2e316 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Fri, 23 Jul 2010 15:30:57 +0200 Subject: [PATCH 02/10] [IMP] crm: 'forward to partner' wizard: added 'lead category' and 'lead description' to email sent bzr revid: olt@tinyerp.com-20100723133057-39ifk5bvhzhg60m1 --- addons/crm/wizard/crm_forward_to_partner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/crm/wizard/crm_forward_to_partner.py b/addons/crm/wizard/crm_forward_to_partner.py index 2bd8aebe9c3..e25a397d09f 100644 --- a/addons/crm/wizard/crm_forward_to_partner.py +++ b/addons/crm/wizard/crm_forward_to_partner.py @@ -244,6 +244,8 @@ class crm_lead_forward_to_partner(osv.osv_memory): "Phone: %s" % (pa.phone or ''), "Fax: %s" % (pa.fax or ''), "Mobile: %s" % (pa.mobile or ''), + "Lead Category: %s" % (lead.categ_id and lead.categ_id.name or ''), + "Details: %s" % (lead.description or ''), ] return "\n".join(body + ['---']) From 9110935b2e2d3b32ce4317fd95ec94afca14b51a Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Fri, 23 Jul 2010 19:11:26 +0530 Subject: [PATCH 03/10] [FIX]: stock: Fixed problem of wrong log message for consumed products bzr revid: rpa@tinyerp.com-20100723134126-44lkag0fxm4euo3q --- addons/stock/stock.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index bb5af627ebb..83f828203f6 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2079,9 +2079,10 @@ class stock_move(osv.osv): self.write(cr, uid, [move.id], update_val) product_obj = self.pool.get('product.product') - for (id, name) in product_obj.name_get(cr, uid, [move.product_id.id]): - message = _('Product ') + " '" + name + "' "+ _("is consumed with") + " '" + str(move.product_qty) + "' "+ _("quantity.") - self.log(cr, uid, move.id, message) + for new_move in self.browse(cr, uid, res, context=context): + for (id, name) in product_obj.name_get(cr, uid, [new_move.product_id.id]): + message = _('Product ') + " '" + name + "' "+ _("is consumed with") + " '" + str(new_move.product_qty) + "' "+ _("quantity.") + self.log(cr, uid, new_move.id, message) self.action_done(cr, uid, res) return res From 6c896b9767aa2bf102ba43050cbee96d23564386 Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Fri, 23 Jul 2010 19:12:17 +0530 Subject: [PATCH 04/10] [IMP]: mrp: Improved log messages bzr revid: rpa@tinyerp.com-20100723134217-q9hnz0bxg191kjca --- addons/mrp/mrp.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 2d31adabb5f..4b673880ab6 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -635,13 +635,11 @@ class mrp_production(osv.osv): move_obj.write(cr, uid, [production.move_prod_id.id], {'location_id': production.location_dest_id.id}) - message = ("%s %s %s %s %s %s") % ( - _('Manufacturing Order '), - name, - _("scheduled the"), - datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d'), - _("for"), - production.product_id.name) + message = ("Manufacturing Order '%s' for %s %s is Ready to produce.") % ( + name, + production.product_qty, + production.product_id.name, + ) self.log(cr, uid, production_id, message) return True @@ -740,7 +738,7 @@ class mrp_production(osv.osv): wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'mrp.production', production_id, 'button_produce_done', cr) - message = _('Manufacturing order ') + " '" + production.name + "' "+ _("is finished.") + message = str(production_qty) + " '[" + production.product_id.code + '] ' + production.product_id.name + _("' have been manufactured for ") + production.name self.log(cr, uid, production_id, message) return True @@ -910,7 +908,16 @@ class mrp_production(osv.osv): proc_ids.append(proc_id) wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr) self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'}) - message = _('Manufacturing order ') + " '" + production.name + "' "+ _("is confirmed.") + message = ("%s '%s' %s %s %s %s %s %s.") % ( + _('Manufacturing Order'), + name, + _('for'), + production.product_qty, + production.product_id.name, + _('scheduled for date '), + datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d'), + _('is waiting') + ) self.log(cr, uid, production.id, message) return picking_id From 5b6f1af9e716aa5ab8619c915c60cdacd6110fb1 Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Fri, 23 Jul 2010 19:25:34 +0530 Subject: [PATCH 05/10] [Fix] purchase : set the right id bzr revid: sbh@tinyerp.com-20100723135534-2vl5pwtgyab0gkrd --- addons/purchase/purchase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 9fdb4f1b213..2ffdd78e284 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -305,7 +305,7 @@ class purchase_order(osv.osv): def inv_line_create(self, cr, uid, a, ol): return (0, False, { 'name': ol.name, - 'account_id': a.id, + 'account_id': a, 'price_unit': ol.price_unit or 0.0, 'quantity': ol.product_qty, 'product_id': ol.product_id.id or False, @@ -344,7 +344,7 @@ class purchase_order(osv.osv): if not a: raise osv.except_osv(_('Error !'), _('There is no expense account defined for this product: "%s" (id:%d)') % (ol.product_id.name, ol.product_id.id,)) else: - a = self.pool.get('ir.property').get(cr, uid, 'property_account_expense_categ', 'product.category') + a = self.pool.get('ir.property').get(cr, uid, 'property_account_expense_categ', 'product.category').id fpos = o.fiscal_position or False a = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, a) il.append(self.inv_line_create(cr, uid, a, ol)) From bb78b5c34a4ae53751abf96ff04f8601afabfd1d Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Fri, 23 Jul 2010 19:35:55 +0530 Subject: [PATCH 06/10] [Fix] resource: Remove the week_id from view bzr revid: sbh@tinyerp.com-20100723140555-nalwmktyim6pcn6n --- addons/resource/resource_view.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/resource/resource_view.xml b/addons/resource/resource_view.xml index e84fa6fc34d..98afe8f5a03 100644 --- a/addons/resource/resource_view.xml +++ b/addons/resource/resource_view.xml @@ -78,8 +78,7 @@ - - + From c5c499418d2aca8eff8bc5e77091f3cc5f69b5ae Mon Sep 17 00:00:00 2001 From: Mantavya Gajjar Date: Fri, 23 Jul 2010 19:37:26 +0530 Subject: [PATCH 07/10] [IMP]: improvement in accounting bzr revid: mga@tinyerp.com-20100723140726-9dcas1qebivvy4vo --- addons/account/account.py | 107 ++++++++++++++-------------- addons/account/account_move_line.py | 34 ++++++++- addons/account/account_view.xml | 31 +++++--- addons/account/installer.py | 7 +- 4 files changed, 110 insertions(+), 69 deletions(-) diff --git a/addons/account/account.py b/addons/account/account.py index 1178712362e..61851b30f1f 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -248,59 +248,59 @@ class account_account(osv.osv): def __compute(self, cr, uid, ids, field_names, arg=None, context=None, query='', query_params=()): - """ compute the balance, debit and/or credit for the provided - account ids - Arguments: - `ids`: account ids - `field_names`: the fields to compute (a list of any of - 'balance', 'debit' and 'credit') - `arg`: unused fields.function stuff - `query`: additional query filter (as a string) - `query_params`: parameters for the provided query string - (__compute will handle their escaping) as a - tuple - """ - mapping = { - 'balance': "COALESCE(SUM(l.debit),0) " \ - "- COALESCE(SUM(l.credit), 0) as balance", - 'debit': "COALESCE(SUM(l.debit), 0) as debit", - 'credit': "COALESCE(SUM(l.credit), 0) as credit" - } - #get all the necessary accounts - children_and_consolidated = self._get_children_and_consol(cr, uid, ids, context=context) - #compute for each account the balance/debit/credit from the move lines - accounts = {} - if children_and_consolidated: - aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context) + """ compute the balance, debit and/or credit for the provided + account ids + Arguments: + `ids`: account ids + `field_names`: the fields to compute (a list of any of + 'balance', 'debit' and 'credit') + `arg`: unused fields.function stuff + `query`: additional query filter (as a string) + `query_params`: parameters for the provided query string + (__compute will handle their escaping) as a + tuple + """ + mapping = { + 'balance': "COALESCE(SUM(l.debit),0) " \ + "- COALESCE(SUM(l.credit), 0) as balance", + 'debit': "COALESCE(SUM(l.debit), 0) as debit", + 'credit': "COALESCE(SUM(l.credit), 0) as credit" + } + #get all the necessary accounts + children_and_consolidated = self._get_children_and_consol(cr, uid, ids, context=context) + #compute for each account the balance/debit/credit from the move lines + accounts = {} + if children_and_consolidated: + aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context) - wheres = [""] - if query.strip(): - wheres.append(query.strip()) - if aml_query.strip(): - wheres.append(aml_query.strip()) - filters = " AND ".join(wheres) - self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG, - 'Filters: %s'%filters) - # IN might not work ideally in case there are too many - # children_and_consolidated, in that case join on a - # values() e.g.: - # SELECT l.account_id as id FROM account_move_line l - # INNER JOIN (VALUES (id1), (id2), (id3), ...) AS tmp (id) - # ON l.account_id = tmp.id - # or make _get_children_and_consol return a query and join on that - request = ("SELECT l.account_id as id, " +\ - ' , '.join(map(mapping.__getitem__, field_names)) + - " FROM account_move_line l" \ - " WHERE l.account_id IN %s " \ - + filters + - " GROUP BY l.account_id") - params = (tuple(children_and_consolidated),) + query_params - cr.execute(request, params) - self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG, - 'Status: %s'%cr.statusmessage) + wheres = [""] + if query.strip(): + wheres.append(query.strip()) + if aml_query.strip(): + wheres.append(aml_query.strip()) + filters = " AND ".join(wheres) + self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG, + 'Filters: %s'%filters) + # IN might not work ideally in case there are too many + # children_and_consolidated, in that case join on a + # values() e.g.: + # SELECT l.account_id as id FROM account_move_line l + # INNER JOIN (VALUES (id1), (id2), (id3), ...) AS tmp (id) + # ON l.account_id = tmp.id + # or make _get_children_and_consol return a query and join on that + request = ("SELECT l.account_id as id, " +\ + ' , '.join(map(mapping.__getitem__, field_names)) + + " FROM account_move_line l" \ + " WHERE l.account_id IN %s " \ + + filters + + " GROUP BY l.account_id") + params = (tuple(children_and_consolidated),) + query_params + cr.execute(request, params) + self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG, + 'Status: %s'%cr.statusmessage) - for res in cr.dictfetchall(): - accounts[res['id']] = res + for res in cr.dictfetchall(): + accounts[res['id']] = res # consolidate accounts with direct children children_and_consolidated.reverse() @@ -2539,9 +2539,9 @@ class wizard_multi_charts_accounts(osv.osv_memory): 'account_paid_id': acc_template_ref[value['account_paid_id']], }) - # Creating Journals + # Creating Journals Sales and Purchase vals_journal={} - data_id = data_pool.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_view')]) + data_id = data_pool.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_sp_journal_view')]) data = data_pool.browse(cr, uid, data_id[0]) view_id = data.res_id @@ -2573,6 +2573,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): vals_journal['type'] = 'purchase' vals_journal['code'] = _('EXJ') vals_journal['sequence_id'] = seq_id_purchase + vals_journal['view_id'] = view_id if obj_multi.chart_template_id.property_account_payable: vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id] diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index bf12bdc2087..76989d2f02c 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -183,7 +183,7 @@ class account_move_line(osv.osv): # Compute the current move move_id = False partner_id = False - if context.get('journal_id',False) and context.get('period_id',False): + if context.get('journal_id', False) and context.get('period_id', False): if 'move_id' in fields: cr.execute('select move_id \ from \ @@ -199,6 +199,7 @@ class account_move_line(osv.osv): return data else: data['move_id'] = move_id + if 'date' in fields: cr.execute('select date \ from \ @@ -214,7 +215,6 @@ class account_move_line(osv.osv): period = period_obj.browse(cr, uid, context['period_id'], context=context) data['date'] = period.date_start - if not move_id: return data @@ -786,6 +786,31 @@ class account_move_line(osv.osv): return j+(p and (':'+p) or '') return False +# def onchange_date(self, cr, user, ids, date, context={}): +# """ +# Returns a dict that contains new values and context +# @param cr: A database cursor +# @param user: ID of the user currently logged in +# @param date: latest value from user input for field date +# @param args: other arguments +# @param context: context arguments, like lang, time zone +# @return: Returns a dict which contains new values, and context +# """ +# res = {} +# period_pool = self.pool.get('account.period') +# pids = period_pool.search(cr, user, [('date_start','<=',date), ('date_stop','>=',date)]) +# if pids: +# res.update({ +# 'period_id':pids[0] +# }) +# context.update({ +# 'period_id':pids[0] +# }) +# return { +# 'value':res, +# 'context':context, +# } + def fields_view_get(self, cr, uid, view_id=None, view_type='form', context={}, toolbar=False, submenu=False): result = super(osv.osv, self).fields_view_get(cr, uid, view_id,view_type,context,toolbar=toolbar, submenu=submenu) if view_type != 'tree': @@ -848,11 +873,14 @@ class account_move_line(osv.osv): elif field == 'credit': attrs.append('sum="Total credit"') elif field == 'account_tax_id': - attrs.append('domain="[(\'parent_id\',\'=\',False)]"') + attrs.append('domain="[(\'parent_id\',\'=\',False), (\'type_tax_use\',\'=\',context.get(journal_id.type, \'sale\'))]"') elif field == 'account_id' and journal.id: attrs.append('domain="[(\'journal_id\', \'=\', '+str(journal.id)+'),(\'type\',\'<>\',\'view\'), (\'type\',\'<>\',\'closed\')]" on_change="onchange_account_id(account_id, partner_id)"') elif field == 'partner_id': attrs.append('on_change="onchange_partner_id(move_id, partner_id, account_id, debit, credit, date, journal_id)"') +# elif field == 'date': +# attrs.append('on_change="onchange_date(date)"') + # if field.readonly: # attrs.append('readonly="1"') # if field.required: diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 93567fb2b5a..be650a4613f 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -269,9 +269,9 @@ - - - + + + @@ -283,8 +283,8 @@ - - + + @@ -295,11 +295,18 @@ form
- + + + Journal Views + account.journal.view + form + tree,form + + - Price List + Price per unit product.price_list form -
+ + @@ -19,15 +20,17 @@