From ba69c9f7d691ee25e6293db8362ec10beb553d5e Mon Sep 17 00:00:00 2001 From: "grzegorz.grzelak@cirrus.pl" <> Date: Fri, 21 Jan 2011 10:13:05 +0100 Subject: [PATCH 0001/1547] [REF] modification for new 6.0 lookout bzr revid: grzegorz.grzelak@cirrus.pl-20110121091305-a4cq8oahe3k8xks7 --- addons/stock_planning/__openerp__.py | 34 ++++----- addons/stock_planning/stock_planning.py | 73 +++++++++++++------ addons/stock_planning/stock_planning_view.xml | 20 +++-- .../stock_planning_create_periods_view.xml | 8 +- .../stock_planning_createlines_view.xml | 21 ++++-- .../wizard/stock_planning_forecast_view.xml | 1 + 6 files changed, 99 insertions(+), 58 deletions(-) diff --git a/addons/stock_planning/__openerp__.py b/addons/stock_planning/__openerp__.py index d0566424cca..cf36d5db0fd 100644 --- a/addons/stock_planning/__openerp__.py +++ b/addons/stock_planning/__openerp__.py @@ -22,17 +22,17 @@ { "name":"Master Procurement Schedule", "version":"1.1", - "author":"OpenERP SA and Grzegorz Grzelak (Cirrus)", - "category":"Custom", - "depends":["hr","stock","sale"], + "author":"OpenERP SA and Grzegorz Grzelak (OpenGLOBE)", + "category":"Stock", + "depends":["hr","stock","sale","procurement"], "description": """ This module is based on original OpenERP SA module stock_planning version 1.0 of the same name Master Procurement Schedule. Purpose of MPS is to allow create a manual procurement (requisition) apart of MRP scheduler (which works automatically on minimum stock rules). Terms used in the module: -- Stock and Sales Period - is the time (between Start Date and End Date) for which you plan Stock and Sales Forecast and make Procurement Planning. -- Stock and Sales Forecast - is the quantity of products you plan to sell in the Period. +- Stock Period - is the time (between Start Date and End Date) for which you plan Stock and Sales Forecast and make Procurement Planning. +- Sales Forecast - is the quantity of products you plan to sell in the Period. - Stock Planning - is the quantity of products you plan to purchase or produce for the Period. Because we have another module sale_forecast which uses terms "Sales Forecast" and "Planning" as amount values we will use terms "Stock and Sales Forecast" and "Stock Planning" to emphasize that we use quantity values. @@ -44,14 +44,14 @@ Activity with this module is divided to three steps: Periods ======= -You have two menu items for Periods in "Sales Management - Configuration". There are: -- "Create Sales Periods" - Which automates creating daily, weekly or monthly periods. -- "Stock and sales Periods" - Which allows to create any type of periods, change the dates and change the State of period. +You have two menu items for Periods in "Warehouse - Configuration - Stock Periods". There are: +- "Create Stock Periods" - Which automates creating daily, weekly or monthly periods. +- "Stock Periods" - Which allows to create any type of periods, change the dates and change the State of period. -Creating periods is the first step you have to do to use modules features. You can create custom periods using "New" button in "Stock and Sales Periods" form or view but it is recommended to use automating tool. +Creating periods is the first step you have to do to use modules features. You can create custom periods using "New" button in "Stock Periods" form or view but it is recommended to use automating tool "Create Stock Periods". Remarks: -- These periods (officially Stock and Sales Periods) are separated of Financial or other periods in the system. +- These periods (Stock Periods) are separated of Financial or other periods in the system. - Periods are not assigned to companies (when you use multicompany feature at all). Module suppose that you use the same periods across companies. If you wish to use different periods for different companies define them as you wish (they can overlap). Later on in this text will be indications how to use such periods. - When periods are created automatically their start and finish dates are with start hour 00:00:00 and end hour 23:59:00. Fe. when you create daily periods they will have start date 31.01.2010 00:00:00 and end date 31.01.2010 23:59:00. It works only in automatic creation of periods. When you create periods manually you have to take care about hours because you can have incorrect values form sales or stock. - If you use overlapping periods for the same product, warehouse and company results can be unpredictable. @@ -59,11 +59,11 @@ Remarks: Sales Forecasts =============== -You have few menus for Sales forecast in "Sales Management - Sales Forecasts". -- "Create Sales Forecasts for Sales Periods" - which automates creating forecasts lines according to some parameters. +You have few menus for Sales forecast in "Sales - Sales Forecasts". +- "Create Sales Forecasts" - which automates creating forecasts lines according to some parameters. - "Sales Forecasts" - few menus for working with forecasts lists and forms. -Menu "Create Sales Forecasts for Sales Periods" creates Forecasts for products from selected Category, for selected Period and for selected Warehouse. It is an option "Copy Last Forecast" to copy forecast and other settings of period before this one to created one. +Menu "Create Sales Forecasts" creates Forecasts for products from selected Category, for selected Period and for selected Warehouse. It is an option "Copy Last Forecast" to copy forecast and other settings of period before this one to created one. Remarks: - This tool doesn't create lines, if relevant lines (for the same Product, Period, Warehouse and validated or created by you) already exists. If you wish to create another forecast, if relevant lines exists you have to do it manually using menus described bellow. @@ -71,21 +71,21 @@ Remarks: - When you choose "Copy Last Forecast" created line takes quantity and some settings from your (validated by you or created by you if not validated yet) forecast which is for last period before period of created forecast. If there are few your forecasts for period before this one (it is possible) system takes one of them (no rule which of them). -Menus "Sales Forecasts" +Menu "Sales Forecasts" On "Sales Forecast" form mainly you have to enter a forecast quantity in "Product Quantity". Further calculation can work for draft forecasts. But validation can save your data against any accidental changes. You can click "Validate" button but it is not mandatory. Instead of forecast quantity you can enter amount of forecast sales in field "Product Amount". System will count quantity from amount according to Sale price of the Product. -All values on the form are expressed in unit of measure selected on form. You can select one of unit of measure from default category or from second category. When you change unit of measure the quanities will be recalculated according to new UoM: editable values (blue fields) immediately, non edited fields after clicking of "Calculate Planning" button. +All values on the form are expressed in unit of measure selected on form. You can select one of unit of measure from default category or from second category. When you change unit of measure the quanities will be recalculated according to new UoM: editable values (blue fields) immediately, non edited fields after clicking of "Calculate Sales History" button. To find proper value for Sale Forecast you can use "Sales History" table for this product. You have to enter parameters to the top and left of this table and system will count sale quantities according to these parameters. So you can select fe. your department (at the top) then (to the left): last period, period before last and period year ago. Remarks: - +- Developers can consider to replace sales history "per Department" with "per Sales Team" as Sales Team was introduced in 6.0. Procurement Planning ==================== -Menu for Planning you can find in "Warehouse - Stock Planning". +Menu for Planning you can find in "Warehouse - Manual Planning". - "Create Stock Planning Lines" - allows you to automate creating planning lines according to some parameters. - "Master Procurement Scheduler" - is the most important menu of the module which allows to create procurement. diff --git a/addons/stock_planning/stock_planning.py b/addons/stock_planning/stock_planning.py index 9fdd94c909d..94da7b027a1 100644 --- a/addons/stock_planning/stock_planning.py +++ b/addons/stock_planning/stock_planning.py @@ -26,6 +26,8 @@ from dateutil.relativedelta import relativedelta from osv import osv, fields import netsvc from tools.translate import _ +import logging + def rounding(fl, round_value): if not round_value: @@ -76,15 +78,15 @@ class stock_sale_forecast(osv.osv): 'product_id': fields.many2one('product.product', 'Product', readonly=True, required=True, states={'draft':[('readonly',False)]}, \ help = 'Shows which product this forecast concerns.'), 'product_qty': fields.float('Product Quantity', required=True, readonly=True, states={'draft':[('readonly',False)]}, \ - help= 'Forecasted quantity.'), + help= 'Forecast quantity.'), 'product_amt': fields.float('Product Amount', readonly=True, states={'draft':[('readonly',False)]}, \ help='Forecast value which will be converted to Product Quantity according to prices.'), 'product_uom_categ': fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uom domain 'product_uom': fields.many2one('product.uom', 'Product UoM', required=True, readonly=True, states={'draft':[('readonly',False)]}, \ - help = "Unit of Measure used to show the quanities of stock calculation." \ + help = "Unit of Measure used to show the quantities of stock calculation." \ "You can use units form default category or from second category (UoS category)."), 'product_uos_categ' : fields.many2one('product.uom.categ', 'Product UoS Category'), # Invisible field for product_uos domain -# Field used in onchange_uom to check what uom was before change and recalculate quantities acording to old uom (active_uom) and new uom. +# Field used in onchange_uom to check what uom was before change and recalculate quantities according to old uom (active_uom) and new uom. 'active_uom': fields.many2one('product.uom', string = "Active UoM"), 'state': fields.selection([('draft','Draft'),('validated','Validated')],'State',readonly=True), 'analyzed_period1_id': fields.many2one('stock.period', 'Period1', readonly=True, states={'draft':[('readonly',False)]},), @@ -114,7 +116,7 @@ class stock_sale_forecast(osv.osv): 'analyzed_period3_per_warehouse': fields.float('This Warehouse Period3', readonly=True), 'analyzed_period4_per_warehouse': fields.float('This Warehouse Period4', readonly=True), 'analyzed_period5_per_warehouse': fields.float('This Warehouse Period5', readonly=True), - 'analyzed_period1_per_company': fields.float('This Copmany Period1', readonly=True), + 'analyzed_period1_per_company': fields.float('This Company Period1', readonly=True), 'analyzed_period2_per_company': fields.float('This Company Period2', readonly=True), 'analyzed_period3_per_company': fields.float('This Company Period3', readonly=True), 'analyzed_period4_per_company': fields.float('This Company Period4', readonly=True), @@ -196,7 +198,7 @@ class stock_sale_forecast(osv.osv): uom = uom_obj.browse(cr, uid, uom_id, context=context) coef = uom.factor if uom.category_id.id <> product.uom_id.category_id.id: - coef = coef / product.uos_coeff + coef = coef * product.uos_coeff return product.uom_id.factor / coef def _from_default_uom_factor(self, cr, uid, product_id, uom_id, context=None): @@ -206,7 +208,7 @@ class stock_sale_forecast(osv.osv): uom = uom_obj.browse(cr, uid, uom_id, context=context) res = uom.factor if uom.category_id.id <> product.uom_id.category_id.id: - res = res / product.uos_coeff + res = res * product.uos_coeff return res / product.uom_id.factor, uom.rounding def _sales_per_users(self, cr, uid, so, so_line, company, users): @@ -343,18 +345,41 @@ class stock_planning(osv.osv): GROUP BY planning.product_uom", \ (date_start, date_stop, val.product_id.id, val.company_id.id,)) planning_qtys = cr.fetchall() - res = self._to_planning_uom(cr, uid, val, planning_qtys, context) + res = self._to_default_uom(cr, uid, val, planning_qtys, context) return res - def _to_planning_uom(self, cr, uid, val, qtys, context=None): + def _to_default_uom(self, cr, uid, val, qtys, context=None): + res_qty = 0 + if qtys: + uom_obj = self.pool.get('product.uom') + for qty, prod_uom in qtys: + coef = self._to_default_uom_factor(cr, uid, val.product_id.id, prod_uom, context=context) +# res_coef, round_value = self._from_default_uom_factor(cr, uid, val.product_id.id, val.product_uom.id, context=context) +# logging.getLogger().info(str(coef)+" "+str(qty)+" "+str(res_qty)) +# print coef +# print res_coef +# raise osv.except_osv(_('Error !'), _('coef and res_coef %s %s')%(coef,res_coef,)) +# coef = coef * res_coef +# res_qty += rounding(qty * coef, round_value) + res_qty += qty * coef +# logging.getLogger().info(str(coef)+" "+str(qty)+" "+str(res_qty)) + return res_qty + + def _to_form_uom(self, cr, uid, val, qtys, context=None): res_qty = 0 if qtys: uom_obj = self.pool.get('product.uom') for qty, prod_uom in qtys: coef = self._to_default_uom_factor(cr, uid, val.product_id.id, prod_uom, context=context) res_coef, round_value = self._from_default_uom_factor(cr, uid, val.product_id.id, val.product_uom.id, context=context) +# logging.getLogger().info(str(coef)+" "+str(qty)+" "+str(res_qty)) +# print coef +# print res_coef +# raise osv.except_osv(_('Error !'), _('coef and res_coef %s %s')%(coef,res_coef,)) coef = coef * res_coef res_qty += rounding(qty * coef, round_value) +# res_qty += qty * coef +# logging.getLogger().info(str(coef)+" "+str(qty)+" "+str(res_qty)) return res_qty @@ -369,7 +394,7 @@ class stock_planning(osv.osv): 'GROUP BY product_uom', \ (val.product_id.id,val.period_id.id, val.company_id.id)) company_qtys = cr.fetchall() - res[val.id]['company_forecast'] = self._to_planning_uom(cr, uid, val, company_qtys, context) + res[val.id]['company_forecast'] = self._to_form_uom(cr, uid, val, company_qtys, context) cr.execute('SELECT sum(product_qty), product_uom \ FROM stock_sale_forecast \ @@ -377,8 +402,8 @@ class stock_planning(osv.osv): 'GROUP BY product_uom', \ (val.product_id.id,val.period_id.id, val.warehouse_id.id)) warehouse_qtys = cr.fetchall() - res[val.id]['warehouse_forecast'] = self._to_planning_uom(cr, uid, val, warehouse_qtys, context) - res[val.id]['warehouse_forecast'] = rounding(res[val.id]['warehouse_forecast'], val.product_id.uom_id.rounding) + res[val.id]['warehouse_forecast'] = self._to_form_uom(cr, uid, val, warehouse_qtys, context) +# res[val.id]['warehouse_forecast'] = rounding(res[val.id]['warehouse_forecast'], val.product_id.uom_id.rounding) return res def _get_stock_start(self, cr, uid, val, date, context=None): @@ -419,7 +444,7 @@ class stock_planning(osv.osv): res_coef, round_value = self._from_default_uom_factor(cr, uid, val.product_id.id, val.product_uom.id, context=context) coef = coef * res_coef res[val.id]['minimum_op'] = rounding(ret[0]*coef, round_value) - res[val.id]['maximum_op'] = ret[1]*coef + res[val.id]['maximum_op'] = rounding(ret[1]*coef, round_value) return res def onchange_company(self, cr, uid, ids, company_id=False): @@ -451,11 +476,11 @@ class stock_planning(osv.osv): 'warehouse_id': fields.many2one('stock.warehouse','Warehouse', required=True), 'product_id': fields.many2one('product.product' , 'Product', required=True, help = 'Product which this planning is created for.'), 'product_uom_categ' : fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uom domain - 'product_uom': fields.many2one('product.uom', 'UoM', required=True, help = "Unit of Measure used to show the quanities of stock calculation." \ - "You can use units form default category or from second category (UoS category)."), + 'product_uom': fields.many2one('product.uom', 'UoM', required=True, help = "Unit of Measure used to show the quantities of stock calculation." \ + "You can use units from default category or from second category (UoS category)."), 'product_uos_categ': fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uos domain -# Field used in onchange_uom to check what uom was before change to recalculate quantities acording to old uom (active_uom) and new uom. - 'active_uom': fields.many2one('product.uom', string = "Active UoM"), +# Field used in onchange_uom to check what uom was before change to recalculate quantities according to old uom (active_uom) and new uom. + 'active_uom': fields.many2one('product.uom', string = "Active UoM"), # It works only in Forecast 'planned_outgoing': fields.float('Planned Out', required=True, \ help = 'Enter planned outgoing quantity from selected Warehouse during the selected Period of selected Product. '\ 'To plan this value look at Confirmed Out or Sales Forecasts. This value should be equal or greater than Confirmed Out.'), @@ -475,16 +500,16 @@ class stock_planning(osv.osv): help = 'Quantity left to Planned incoming quantity. This is calculated difference between Planned In and Confirmed In. ' \ 'For current period Already In is also calculated. This value is used to create procurement for lacking quantity.'), 'outgoing_left': fields.float('Expected Out', readonly=True, \ - help = 'Quantity expected to go out in selected period. As a difference between Planned Out and Confirmed Out. ' \ + help = 'Quantity expected to go out in selected period besides Confirmed Out. As a difference between Planned Out and Confirmed Out. ' \ 'For current period Already Out is also calculated'), 'to_procure': fields.float(string='Planned In', required=True, \ help = 'Enter quantity which (by your plan) should come in. Change this value and observe Stock simulation. ' \ 'This value should be equal or greater than Confirmed In.'), 'line_time': fields.function(_get_past_future, method=True,type='char', string='Past/Future'), 'minimum_op': fields.function(_get_op, method=True, type='float', string = 'Minimum Rule', multi= 'minimum', \ - help = 'Minimum quantity set in Minimum Stock Rules for this Warhouse'), + help = 'Minimum quantity set in Minimum Stock Rules for this Warehouse'), 'maximum_op': fields.function(_get_op, method=True, type='float', string = 'Maximum Rule', multi= 'maximum', \ - help = 'Maximum quantity set in Minimum Stock Rules for this Warhouse'), + help = 'Maximum quantity set in Minimum Stock Rules for this Warehouse'), 'outgoing_before': fields.float('Planned Out Before', readonly=True, \ help= 'Planned Out in periods before calculated. '\ 'Between start date of current period and one day before start of calculated period.'), @@ -499,13 +524,13 @@ class stock_planning(osv.osv): help= 'Quantity which is already picked up to this warehouse in current period.'), 'stock_only': fields.boolean("Stock Location Only", help = "Check to calculate stock location of selected warehouse only. " \ "If not selected calculation is made for input, stock and output location of warehouse."), - "procure_to_stock": fields.boolean("Procure To Stock Location", help = "Chect to make procurement to stock location of selected warehouse. " \ + "procure_to_stock": fields.boolean("Procure To Stock Location", help = "Check to make procurement to stock location of selected warehouse. " \ "If not selected procurement will be made into input location of warehouse."), "confirmed_forecasts_only": fields.boolean("Validated Forecasts", help = "Check to take validated forecasts only. " \ "If not checked system takes validated and draft forecasts."), - 'supply_warehouse_id': fields.many2one('stock.warehouse','Source Warehouse', help = "Warehouse used as source in supply pick move created by 'Supply from Another Warhouse'."), + 'supply_warehouse_id': fields.many2one('stock.warehouse','Source Warehouse', help = "Warehouse used as source in supply pick move created by 'Supply from Another Warehouse'."), "stock_supply_location": fields.boolean("Stock Supply Location", help = "Check to supply from Stock location of Supply Warehouse. " \ - "If not checked supply will be made from Output location of Supply Warehouse. Used in 'Supply from Another Warhouse' with Supply Warehouse."), + "If not checked supply will be made from Output location of Supply Warehouse. Used in 'Supply from Another Warehouse' with Supply Warehouse."), } @@ -525,7 +550,7 @@ class stock_planning(osv.osv): uom = uom_obj.browse(cr, uid, uom_id, context=context) coef = uom.factor if uom.category_id.id != product.uom_id.category_id.id: - coef = coef / product.uos_coeff + coef = coef * product.uos_coeff return product.uom_id.factor / coef @@ -536,7 +561,7 @@ class stock_planning(osv.osv): uom = uom_obj.browse(cr, uid, uom_id, context=context) res = uom.factor if uom.category_id.id != product.uom_id.category_id.id: - res = res / product.uos_coeff + res = res * product.uos_coeff return res / product.uom_id.factor, uom.rounding def calculate_planning(self, cr, uid, ids, context, *args): diff --git a/addons/stock_planning/stock_planning_view.xml b/addons/stock_planning/stock_planning_view.xml index 9995752cb03..d7b6d312500 100644 --- a/addons/stock_planning/stock_planning_view.xml +++ b/addons/stock_planning/stock_planning_view.xml @@ -2,8 +2,8 @@ + name="Stock Periods" + parent="stock.menu_stock_configuration" sequence="20"/> @@ -12,7 +12,7 @@ stock.period form -
+ @@ -46,7 +46,7 @@ stock.period search - + @@ -58,11 +58,13 @@ - Stock and Sales Periods + Stock Periods stock.period form tree,form + Stock periods are used for stock planning. Stock periods are independent of account periods. You can use wizard for creating periods and review them here. + tree,form,graph {"search_default_create_uid":uid} + This quantity sales forecast is an indication for Stock Planner to make procurement manually or to complement automatic procurement. You can use manual procurement with this forecast when some periods are exceptional for usual minimum stock rules. - + stock.planning.form @@ -247,6 +250,7 @@ + @@ -339,11 +343,13 @@ form tree,form + Manual planning can be used as basic planning in the company or can complement automatic planning (schedulers). On planning form you can see quantities of stock at the beginning of current period, sum of outgoing moves, sum of incoming moves and simulation of stock at the end of period. Changing values of Planned In and Planned Out you can simulate other situation. When you are satisfied with value of Stock Simulation you can manually procure additional quantity of Incoming Left. + diff --git a/addons/stock_planning/wizard/stock_planning_create_periods_view.xml b/addons/stock_planning/wizard/stock_planning_create_periods_view.xml index 35b55b8f4e7..bb18769fdfd 100644 --- a/addons/stock_planning/wizard/stock_planning_create_periods_view.xml +++ b/addons/stock_planning/wizard/stock_planning_create_periods_view.xml @@ -8,8 +8,7 @@ stock.period.createlines form - - + @@ -24,16 +23,17 @@ - Stock and Sales Planning Periods + Stock Periods stock.period.createlines form form + This wizard simplify creating periods used for stock planning. These periods are independent of account periods. If you wish to create periods other than day, week or month you have to create them manually in Stock Periods. new diff --git a/addons/stock_planning/wizard/stock_planning_createlines_view.xml b/addons/stock_planning/wizard/stock_planning_createlines_view.xml index 7dc4504daef..3b26e6446f8 100644 --- a/addons/stock_planning/wizard/stock_planning_createlines_view.xml +++ b/addons/stock_planning/wizard/stock_planning_createlines_view.xml @@ -10,15 +10,11 @@ form - + - - - - Forward to Partner crm.lead.forward.to.partner form form - + new From 204ecec4f28ca095de960de798ada77c16272e8d Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Fri, 25 Feb 2011 12:24:03 +0530 Subject: [PATCH 0144/1547] [IMP] crm, emails,crm_partner_assign:- change model name crm_send_new_email_attachment with crm_add_note_email_attachment in crm module, and bug fix of web-client wizard not close must return thy type:ir.action.act_window.close' in button click bzr revid: ysa@tinyerp.com-20110225065403-expnty80rkb9m2jr --- addons/crm/wizard/crm_add_note.py | 8 ++++---- .../crm_partner_assign/wizard/crm_forward_to_partner.py | 4 ++-- .../email_template/wizard/email_template_send_wizard.py | 4 ++-- addons/emails/wizard/email_compose_message.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/addons/crm/wizard/crm_add_note.py b/addons/crm/wizard/crm_add_note.py index e9919c059db..ff89f56cd9d 100644 --- a/addons/crm/wizard/crm_add_note.py +++ b/addons/crm/wizard/crm_add_note.py @@ -5,8 +5,8 @@ import base64 AVAILABLE_STATES = crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')] -class crm_send_new_email_attachment(osv.osv_memory): - _name = 'crm.send.mail.attachment' +class crm_add_note_email_attachment(osv.osv_memory): + _name = 'crm.add.note.email.attachment' _columns = { 'binary' : fields.binary('Attachment', required=True), @@ -14,7 +14,7 @@ class crm_send_new_email_attachment(osv.osv_memory): 'wizard_id' : fields.many2one('crm.add.note', 'Wizard', required=True), } -crm_send_new_email_attachment() +crm_add_note_email_attachment() class crm_add_note(osv.osv_memory): """Adds a new note to the case.""" @@ -25,7 +25,7 @@ class crm_add_note(osv.osv_memory): 'body': fields.text('Note Body', required=True), 'state': fields.selection(AVAILABLE_STATES, string='Set New State To', required=True), - 'attachment_ids' : fields.one2many('crm.send.mail.attachment', 'wizard_id'), + 'attachment_ids' : fields.one2many('crm.add.note.email.attachment', 'wizard_id'), } def action_add(self, cr, uid, ids, context=None): diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py index ae653ec9c92..9086750aeec 100644 --- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py +++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py @@ -170,14 +170,14 @@ class crm_lead_forward_to_partner(osv.osv_memory): context = {} super(crm_lead_forward_to_partner, self).save_to_drafts(cr, uid, ids, context=context) self.action_forward(cr, uid, ids, context) - return {} + return {'type': 'ir.actions.act_window_close'} def send_mail(self, cr, uid, ids, context=None): if context is None: context = {} super(crm_lead_forward_to_partner, self).send_mail(cr, uid, ids, context=context) self.action_forward(cr, uid, ids, context) - return {} + return {'type': 'ir.actions.act_window_close'} def action_forward(self, cr, uid, ids, context=None): """ diff --git a/addons/email_template/wizard/email_template_send_wizard.py b/addons/email_template/wizard/email_template_send_wizard.py index 8911e406a85..4cd2e5294c2 100644 --- a/addons/email_template/wizard/email_template_send_wizard.py +++ b/addons/email_template/wizard/email_template_send_wizard.py @@ -133,13 +133,13 @@ class email_template_send_wizard(osv.osv_memory): context = {} mailid = self.save_to_mailbox(cr, uid, ids, context=context) self.pool.get('email.message').write(cr, uid, mailid, {'folder':'drafts', 'state': 'draft'}, context) - return {} + return {'type': 'ir.actions.act_window_close'} def send_mail(self, cr, uid, ids, context=None): if context is None: context = {} mailid = self.save_to_mailbox(cr, uid, ids, context) - return {} + return {'type': 'ir.actions.act_window_close'} def get_generated(self, cr, uid, ids=None, context=None): if ids is None: diff --git a/addons/emails/wizard/email_compose_message.py b/addons/emails/wizard/email_compose_message.py index 1f4dfb464be..96fe112c533 100644 --- a/addons/emails/wizard/email_compose_message.py +++ b/addons/emails/wizard/email_compose_message.py @@ -141,13 +141,13 @@ class email_compose_message(osv.osv_memory): context = {} email_id = self.save_to_mailbox(cr, uid, ids, context=context) self.pool.get('email.message').write(cr, uid, email_id, {'folder':'drafts', 'state': 'draft'}, context) - return {} + return {'type': 'ir.actions.act_window_close'} def send_mail(self, cr, uid, ids, context=None): if context is None: context = {} email_id = self.save_to_mailbox(cr, uid, ids, context) - return {} + return {'type': 'ir.actions.act_window_close'} def save_to_mailbox(self, cr, uid, ids, context=None): email_ids = [] From 900676436835ca3c8478e8252efd09ed5e85ad24 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 25 Feb 2011 13:44:18 +0530 Subject: [PATCH 0145/1547] [REM] email_template: remove email_template_security.xml bzr revid: hmo@tinyerp.com-20110225081418-91ynfdq1klcbv7zi --- addons/email_template/__openerp__.py | 1 - .../email_template/security/email_template_security.xml | 9 --------- 2 files changed, 10 deletions(-) delete mode 100644 addons/email_template/security/email_template_security.xml diff --git a/addons/email_template/__openerp__.py b/addons/email_template/__openerp__.py index fb89261f516..15ccec71ab7 100644 --- a/addons/email_template/__openerp__.py +++ b/addons/email_template/__openerp__.py @@ -32,7 +32,6 @@ """, "init_xml": [], "update_xml": [ - 'security/email_template_security.xml', 'wizard/email_template_preview_view.xml', 'email_template_view.xml', 'wizard/email_template_send_wizard_view.xml', diff --git a/addons/email_template/security/email_template_security.xml b/addons/email_template/security/email_template_security.xml deleted file mode 100644 index e16293f435d..00000000000 --- a/addons/email_template/security/email_template_security.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - Marketing / User - - - - From 5b28eaa8689e8c02dff790afc2d84f644f3ec059 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Fri, 25 Feb 2011 14:41:12 +0530 Subject: [PATCH 0146/1547] [FIX] fix problem in emails.compose.message wizard. bzr revid: ysa@tinyerp.com-20110225091112-t5pcq27rxk6ln0h3 --- addons/emails/wizard/email_compose_message.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/emails/wizard/email_compose_message.py b/addons/emails/wizard/email_compose_message.py index 96fe112c533..059e5f5e9b0 100644 --- a/addons/emails/wizard/email_compose_message.py +++ b/addons/emails/wizard/email_compose_message.py @@ -31,7 +31,6 @@ class email_compose_message(osv.osv_memory): def default_get(self, cr, uid, fields, context=None): if context is None: context = {} - result = super(email_compose_message, self).default_get(cr, uid, fields, context=context) message_pool = self.pool.get('email.message') message_id = context.get('message_id', False) @@ -120,7 +119,7 @@ class email_compose_message(osv.osv_memory): elif context.get('email_model',False): model = context.get('email_model') model_pool = self.pool.get(model) - record_ids = context.get('record_ids',[]) + record_ids = context.get('active_ids',[]) if not record_ids: record_ids = model_pool.search(cr, uid, []) if model_pool: From 35df09c02820dc3486009b8cf5a88e9c9285ae89 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 25 Feb 2011 17:27:15 +0530 Subject: [PATCH 0147/1547] [FIX] crm: set False value in email_from instead of None Value bzr revid: hmo@tinyerp.com-20110225115715-di6jxycn7wvvs5d1 --- addons/crm/wizard/email_compose_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm/wizard/email_compose_message.py b/addons/crm/wizard/email_compose_message.py index 595394478ba..f2241abfdcc 100644 --- a/addons/crm/wizard/email_compose_message.py +++ b/addons/crm/wizard/email_compose_message.py @@ -44,7 +44,7 @@ class email_compose_message(osv.osv_memory): result['email_to'] = data.email_from if 'email_from' in fields: - result['email_from'] = data.user_id and data.user_id.address_id and data.user_id.address_id.email + result['email_from'] = data.user_id and data.user_id.address_id and data.user_id.address_id.email or False if 'description' in fields: result['description'] = '\n' + (tools.ustr(data.user_id.signature or '')) From 8c4be231cc4f62b2e677bf237cfc9c9ada95e159 Mon Sep 17 00:00:00 2001 From: "ARA (OpenERP)" Date: Fri, 25 Feb 2011 18:09:01 +0530 Subject: [PATCH 0148/1547] [FIX] sale_margin: sale margin module : wrong computation lp bug: https://launchpad.net/bugs/715470 fixed bzr revid: ara@tinyerp.com-20110225123901-d5jn5p87blk73ksj --- addons/sale_margin/sale_margin.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/addons/sale_margin/sale_margin.py b/addons/sale_margin/sale_margin.py index f7bbf41e5d3..51fd4987825 100644 --- a/addons/sale_margin/sale_margin.py +++ b/addons/sale_margin/sale_margin.py @@ -48,8 +48,18 @@ class sale_order_line(osv.osv): res[line.id] = round((line.price_unit*line.product_uos_qty*(100.0-line.discount)/100.0) -(line.product_id.standard_price*line.product_uos_qty), 2) return res + def _get_sale_order(self, cr, uid, ids, context=None): + list_order_line = [] + for line in self.pool.get('sale.order').browse(cr, uid, ids, context=context): + for i in line.order_line: + list_order_line.append(i.id) + return list_order_line + _columns = { - 'margin': fields.function(_product_margin, method=True, string='Margin', store=True), + 'margin': fields.function(_product_margin, method=True, string='Margin', + store = { + 'sale.order': (_get_sale_order, None, 6), + }), 'purchase_price': fields.float('Cost Price', digits=(16,2)) } From fc5860236967d4d3c5f27f56fc7ef852df147184 Mon Sep 17 00:00:00 2001 From: "ARA (OpenERP)" Date: Fri, 25 Feb 2011 18:50:10 +0530 Subject: [PATCH 0149/1547] [FIX] sale_margin: sale margin module : wrong computation bzr revid: ara@tinyerp.com-20110225132010-iox9poe0eptdbynr --- addons/sale_margin/sale_margin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/sale_margin/sale_margin.py b/addons/sale_margin/sale_margin.py index 51fd4987825..8c7fc7bf4f1 100644 --- a/addons/sale_margin/sale_margin.py +++ b/addons/sale_margin/sale_margin.py @@ -48,9 +48,10 @@ class sale_order_line(osv.osv): res[line.id] = round((line.price_unit*line.product_uos_qty*(100.0-line.discount)/100.0) -(line.product_id.standard_price*line.product_uos_qty), 2) return res - def _get_sale_order(self, cr, uid, ids, context=None): + def _get_order_line(self, cr, uid, ids, context=None): + obj_sale_order = self.pool.get('sale.order') list_order_line = [] - for line in self.pool.get('sale.order').browse(cr, uid, ids, context=context): + for line in obj_sale_order.browse(cr, uid, ids, context=context): for i in line.order_line: list_order_line.append(i.id) return list_order_line @@ -58,7 +59,7 @@ class sale_order_line(osv.osv): _columns = { 'margin': fields.function(_product_margin, method=True, string='Margin', store = { - 'sale.order': (_get_sale_order, None, 6), + 'sale.order': (_get_order_line, None, 5), }), 'purchase_price': fields.float('Cost Price', digits=(16,2)) } From 7675254982427108fd3e70bd2306b36c58660f11 Mon Sep 17 00:00:00 2001 From: Quentin THEURET Date: Fri, 25 Feb 2011 16:04:03 +0100 Subject: [PATCH 0150/1547] [FIX] Duplicated menus entries -- Call the good view on 'Synchronized object' wizard lp bug: https://launchpad.net/bugs/725033 fixed bzr revid: quentin@tempo-quentin-20110225150403-tsxsukf1wvmhkoam --- addons/base_synchro/wizard/base_synchro_view.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/base_synchro/wizard/base_synchro_view.xml b/addons/base_synchro/wizard/base_synchro_view.xml index c0c140f3791..e4ffc8e323c 100644 --- a/addons/base_synchro/wizard/base_synchro_view.xml +++ b/addons/base_synchro/wizard/base_synchro_view.xml @@ -25,22 +25,22 @@ base.synchro form form + new - Base Synchronization base.synchro form -
+
-
- Forward to Partner crm.lead.forward.to.partner From 6b38a3a097023fce6ef017001296acb568040cbb Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Thu, 28 Apr 2011 15:45:28 +0530 Subject: [PATCH 0420/1547] [FIX] outlook: removed encodeing for the attachment content bzr revid: rha@tinyerp.com-20110428101528-pljylyati4kq3xls --- addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py b/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py index 90aa90fd09e..4bafe893704 100644 --- a/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py +++ b/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py @@ -336,9 +336,8 @@ class XMLRpcConn(object): att_path = os.path.join(att_folder_path,fn) attachments[i].SaveAsFile(att_path) f=open(att_path,"rb") - content = "".join(f.readlines()).encode('base64') + content = "".join(f.readlines()) f.close() - content = content.decode('base64') attachment[fn] = content return attachment From a3ba8c8e204d3de5cbe90abb79cc2a495413b70d Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Thu, 28 Apr 2011 18:12:57 +0530 Subject: [PATCH 0421/1547] [IMP]: Add document attachment and link meeting with project partner. bzr revid: atp@tinyerp.com-20110428124257-ucyut8csllb1oy1d --- addons/import_sugarcrm/import_sugarcrm.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index 472734cce62..849a6a77982 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -24,6 +24,7 @@ import sugar import sugarcrm_fields_mapping from tools.translate import _ import pprint +import base64 pp = pprint.PrettyPrinter(indent=4) OPENERP_FIEDS_MAPS = {'Leads': 'crm.lead', @@ -504,24 +505,28 @@ def get_account(sugar_obj, cr, uid, val, context=None): partner_phone = issue_id.partner_address_id.phone partner_mobile = issue_id.partner_address_id.mobile - return partner_id, partner_address_id, partner_phone,partner_mobile + return partner_id, partner_address_id, partner_phone,partner_mobile + def import_documents(sugar_obj, cr, uid, context=None): if not context: context = {} map_document = {'id' : 'id', - 'name': 'document_name', + 'name': 'filename', 'description': 'description', 'datas': 'datas', 'datas_fname': 'datas_fname', } attach_obj = sugar_obj.pool.get('ir.attachment') PortType,sessionid = sugar.login(context.get('username',''), context.get('password',''), context.get('url','')) - sugar_data = sugar.search(PortType,sessionid, 'Documents') + sugar_data = sugar.search(PortType,sessionid, 'DocumentRevisions') for val in sugar_data: - file, filename = sugar.attachment_search(PortType, sessionid, 'DocumentRevisions', val.get('document_revision_id')) - val['datas'] = file - val['datas_fname'] = filename + filepath = '/var/www/sugarcrm/cache/upload/'+ val.get('id') + f = open(filepath, "r") + datas = f.read() + f.close() + val['datas'] = base64.encodestring(datas) + val['datas_fname'] = val.get('filename') fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_document, context) attach_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) return True @@ -648,7 +653,6 @@ def import_calls(sugar_obj, cr, uid, context=None): categ_id = get_category(sugar_obj, cr, uid, 'crm.phonecall', val.get('direction')) val['categ_id/id'] = categ_id partner_id, partner_address_id, partner_phone, partner_mobile = get_account(sugar_obj, cr, uid, val, context) - val['partner_id/.id'] = partner_id val['partner_address_id/.id'] = partner_address_id val['partner_phone'] = partner_phone @@ -1163,7 +1167,7 @@ MAP_FIELDS = {'Opportunities': #Object Mapping name 'process' : import_documents, }, 'Meetings': - {'dependencies' : ['Accounts', 'Contacts', 'Users'], + {'dependencies' : ['Accounts', 'Contacts', 'Users', 'Projects', 'Opportunities'], 'process' : import_meetings, }, 'Tasks': From 436919a952256df673c5788fb24becb9f2063233 Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Thu, 28 Apr 2011 18:38:59 +0530 Subject: [PATCH 0422/1547] [IMP] bzr revid: atp@tinyerp.com-20110428130859-cc8bffq5eu8c7u9p --- addons/import_sugarcrm/import_sugarcrm.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index 849a6a77982..bc74ddf0f1f 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -468,16 +468,18 @@ def get_account(sugar_obj, cr, uid, val, context=None): if val.get('parent_type') == 'Contacts': model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'res.partner.address')]) - for model in model_obj.browse(cr, uid, model_ids): + if model_ids: + model = model_obj.browse(cr, uid, model_ids)[0] partner_address_id = model.res_id address_id = address_obj.browse(cr, uid, partner_address_id) partner_phone = address_id.phone partner_mobile = address_id.mobile - partner_id = address_id and address_id.partner_id or False + partner_id = address_id and address_id.partner_id.id or False if val.get('parent_type') == 'Opportunities': model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'crm.lead')]) - for model in model_obj.browse(cr, uid, model_ids): + if model_ids: + model = model_obj.browse(cr, uid, model_ids)[0] opportunity_id = model.res_id opportunity_id = crm_obj.browse(cr, uid, opportunity_id) partner_id = opportunity_id.partner_id.id @@ -487,7 +489,8 @@ def get_account(sugar_obj, cr, uid, val, context=None): if val.get('parent_type') == 'Project': model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'project.project')]) - for model in model_obj.browse(cr, uid, model_ids): + if model_ids: + model = model_obj.browse(cr, uid, model_ids)[0] proj_ids = model.res_id proj_id = project_obj.browse(cr, uid, proj_ids) partner_id = proj_id.partner_id.id @@ -497,14 +500,14 @@ def get_account(sugar_obj, cr, uid, val, context=None): if val.get('parent_type') == 'Bugs': model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'project.issue')]) - for model in model_obj.browse(cr, uid, model_ids): + if model_ids: + model = model_obj.browse(cr, uid, model_ids)[0] issue_ids = model.res_id issue_id = issue_obj.browse(cr, uid, issue_ids) partner_id = issue_id.partner_id.id partner_address_id = issue_id.partner_address_id.id partner_phone = issue_id.partner_address_id.phone partner_mobile = issue_id.partner_address_id.mobile - return partner_id, partner_address_id, partner_phone,partner_mobile From f3f9bb58bb19e8627cc0ff15cdd3b70bee2d6ed7 Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Thu, 28 Apr 2011 18:54:42 +0530 Subject: [PATCH 0423/1547] [ADD]: Add tasks in meeting dependency bzr revid: atp@tinyerp.com-20110428132442-jgvncbj0zg1dmvye --- addons/import_sugarcrm/import_sugarcrm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index bc74ddf0f1f..2792e9f4b7d 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -1170,7 +1170,7 @@ MAP_FIELDS = {'Opportunities': #Object Mapping name 'process' : import_documents, }, 'Meetings': - {'dependencies' : ['Accounts', 'Contacts', 'Users', 'Projects', 'Opportunities'], + {'dependencies' : ['Accounts', 'Contacts', 'Users', 'Projects', 'Opportunities', 'Tasks'], 'process' : import_meetings, }, 'Tasks': From 1803ba3dab7ea24148fb93f9b3f2b851d2043d9d Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Fri, 29 Apr 2011 10:30:46 +0530 Subject: [PATCH 0424/1547] [Fix]: Add context inplace of None context bzr revid: atp@tinyerp.com-20110429050046-5kd4ag72ifebikby --- addons/import_sugarcrm/import_sugarcrm.py | 42 ++++++++++++++++------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index 2792e9f4b7d..585869fad33 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -44,11 +44,13 @@ OPENERP_FIEDS_MAPS = {'Leads': 'crm.lead', } -def find_mapped_id(obj, cr, uid, res_model, sugar_id, context): +def find_mapped_id(obj, cr, uid, res_model, sugar_id, context=None): + if not context: + context = {} model_obj = obj.pool.get('ir.model.data') return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', 'sugarcrm_import'), ('name', '=', sugar_id)], context=context) -def mapped_id(obj, cr, uid, res_model, sugar_id, id, context): +def mapped_id(obj, cr, uid, res_model, sugar_id, id, context=None): """ This function create the mapping between an already existing data and the similar data of sugarcrm @param res_model: model of the mapped object @@ -57,6 +59,8 @@ def mapped_id(obj, cr, uid, res_model, sugar_id, id, context): @return : the xml_id or sugar_id """ + if not context: + context = {} ir_model_data_obj = obj.pool.get('ir.model.data') id = ir_model_data_obj._update(cr, uid, res_model, 'sugarcrm_import', {}, mode='update', xml_id=sugar_id, @@ -78,6 +82,8 @@ def import_object(sugar_obj, cr, uid, fields, data, model, table, name, domain_s @return: the xml_id of the ressources """ + if not context: + context = {} domain_search = not domain_search and [('name', 'ilike', name)] or domain_search obj = sugar_obj.pool.get(model) xml_id = generate_xml_id(name, table) @@ -107,6 +113,8 @@ def generate_xml_id(name, table): return sugar_instance + "_" + table + "_" + name def get_all(sugar_obj, cr, uid, model, sugar_val, context=None): + if not context: + context = {} models = sugar_obj.pool.get(model) model_code = sugar_val[0:2] all_model_ids = models.search(cr, uid, [('name', '=', sugar_val)]) or models.search(cr, uid, [('code', '=', model_code.upper())]) @@ -117,6 +125,8 @@ def get_all(sugar_obj, cr, uid, model, sugar_val, context=None): def get_all_states(sugar_obj, cr, uid, sugar_val, country_id, context=None): """Get states or create new state""" + if not context: + context = {} state_id = False res_country_state_obj = sugar_obj.pool.get('res.country.state') @@ -130,6 +140,8 @@ def get_all_states(sugar_obj, cr, uid, sugar_val, country_id, context=None): def get_all_countries(sugar_obj, cr, uid, sugar_country_val, context=None): """Get Country or Create new country""" + if not context: + context = {} res_country_obj = sugar_obj.pool.get('res.country') country_id = False country_code = sugar_country_val[0:2] @@ -189,14 +201,11 @@ def import_users(sugar_obj, cr, uid, context=None): } def get_users_department(sugar_obj, cr, uid, val, context=None): - department_id = False - department_obj = sugar_obj.pool.get('hr.department') - department_ids = department_obj.search(cr, uid, [('name', '=', val)]) - if department_ids: - department_id = department_ids[0] - elif val: - department_id = department_obj.create(cr, uid, {'name': val}) - return department_id + if not context: + context = {} + fields = ['name'] + data = [val] + return import_object(sugar_obj, cr, uid, fields, data, 'hr.department', 'hr_department_user', val, context=context) if not context: context = {} @@ -243,6 +252,8 @@ def get_lead_state(surgar_obj, cr, uid, sugar_val,context=None): return state def get_user_address(sugar_obj, cr, uid, val, context=None): + if not context: + context = {} address_obj = sugar_obj.pool.get('res.partner.address') map_user_address = { 'name': ['first_name', 'last_name'], @@ -268,6 +279,8 @@ def get_user_address(sugar_obj, cr, uid, val, context=None): return True def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context=None): + if not context: + context = {} address_obj = sugar_obj.pool.get('res.partner.address') new_address_id = False if type == 'invoice': @@ -295,6 +308,8 @@ def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context return new_address_id def get_address(sugar_obj, cr, uid, val, context=None): + if not context: + context = {} map_partner_address={} address_id=[] address_obj = sugar_obj.pool.get('res.partner.address') @@ -356,7 +371,8 @@ def get_category(sugar_obj, cr, uid, model, name, context=None): return import_object(sugar_obj, cr, uid, fields, data, 'crm.case.categ', 'crm_categ', name, [('object_id.model','=',model), ('name', 'ilike', name)], context) def get_alarm_id(sugar_obj, cr, uid, val, context=None): - + if not context: + context = {} alarm_dict = {'60': '1 minute before', '300': '5 minutes before', '600': '10 minutes before', @@ -823,14 +839,14 @@ def get_job_id(sugar_obj, cr, uid, val, context=None): context={} fields = ['name'] data = [val] - return import_object(sugar_obj, cr, uid, fields, data, 'hr.job', 'hr_job', val, [('name', 'ilike', val)], context) + return import_object(sugar_obj, cr, uid, fields, data, 'hr.job', 'hr_job', val, context=context) def get_campaign_id(sugar_obj, cr, uid, val, context=None): if not context: context={} fields = ['name'] data = [val] - return import_object(sugar_obj, cr, uid, fields, data, 'crm.case.resource.type', 'crm_campaign', val, [('name', 'ilike', val)], context) + return import_object(sugar_obj, cr, uid, fields, data, 'crm.case.resource.type', 'crm_campaign', val, context=context) def get_attachment(sugar_obj, cr, uid, val, model, File, Filename, parent_type, context=None): if not context: From 7e33edf5ad5df85159f00eb27a441234125bd3dd Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Fri, 29 Apr 2011 10:57:56 +0530 Subject: [PATCH 0425/1547] [FIX]: small Fix bzr revid: atp@tinyerp.com-20110429052756-ms0phghh9d4dkifz --- addons/import_sugarcrm/import_sugarcrm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index 585869fad33..bedfeaae8fd 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -197,7 +197,7 @@ def import_users(sugar_obj, cr, uid, context=None): 'context_lang' : 'context_lang', 'password' : 'password', '.id' : '.id', - 'context_department_id.id': 'context_department_id.id', + 'context_department_id/id': 'context_department_id/id', } def get_users_department(sugar_obj, cr, uid, val, context=None): @@ -221,7 +221,7 @@ def import_users(sugar_obj, cr, uid, context=None): else: val['password'] = 'sugarcrm' #default password for all user department_id = get_users_department(sugar_obj, cr, uid, val.get('department'), context=context) - val['context_department_id.id'] = department_id + val['context_department_id/id'] = department_id val['context_lang'] = context.get('lang','en_US') fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user, context) #All data has to be imported separatly because they don't have the same field From a94a27fbb3b848d876626f5ed6cfad5177addc52 Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Fri, 29 Apr 2011 17:38:28 +0530 Subject: [PATCH 0426/1547] [FIX]stock:locations cannot be sorted and put parent location field in search view lp bug: https://launchpad.net/bugs/765559 fixed bzr revid: ron@tinyerp.com-20110429120828-j33844o6a9qd7ien --- addons/stock/stock.py | 2 +- addons/stock/stock_view.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index d6cef8bc458..633a74923ec 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -164,7 +164,7 @@ class stock_location(osv.osv): \n* Production: Virtual counterpart location for production operations: this location consumes the raw material and produces finished products """, select = True), # 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"), + 'complete_name': fields.function(_complete_name, method=True, type='char', size=100, string="Location Name", store=True), '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"), diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index a22ece14fc5..3eb93cd6618 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -559,6 +559,7 @@ string="Supplier" domain="[('usage', '=', 'supplier')]" help="Supplier Locations" /> + From c839aed3de93203235153443357eb4369203844a Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Mon, 2 May 2011 12:25:22 +0530 Subject: [PATCH 0427/1547] [IMP]: Timezone fix bzr revid: atp@tinyerp.com-20110502065522-d1wld5qzaiw1v4d9 --- addons/import_sugarcrm/import_sugarcrm_view.xml | 2 +- addons/import_sugarcrm/sugarcrm_fields_mapping.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm_view.xml b/addons/import_sugarcrm/import_sugarcrm_view.xml index f956d0d1984..715c02e0a4b 100644 --- a/addons/import_sugarcrm/import_sugarcrm_view.xml +++ b/addons/import_sugarcrm/import_sugarcrm_view.xml @@ -14,7 +14,7 @@ - + diff --git a/addons/import_sugarcrm/sugarcrm_fields_mapping.py b/addons/import_sugarcrm/sugarcrm_fields_mapping.py index 3dd46b78fe6..46f7a038670 100644 --- a/addons/import_sugarcrm/sugarcrm_fields_mapping.py +++ b/addons/import_sugarcrm/sugarcrm_fields_mapping.py @@ -49,7 +49,7 @@ def sugarcrm_fields_mapp(dict_sugar, openerp_dict, context=None): updated_dt = date.fromtimestamp(time.mktime(time.strptime(dict_sugar.get(val), '%Y-%m-%d'))) else: convert_date = datetime.strptime(dict_sugar.get(val), '%Y-%m-%d %H:%M:%S') - edate = convert_date.replace(tzinfo=dateutil.tz.gettz('UTC')) + edate = convert_date.replace(tzinfo=au_tz) au_dt = au_tz.normalize(edate.astimezone(au_tz)) updated_dt = datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') data_lst.append(updated_dt) From 96a33521da4a5a01440a31b95ec34aba3394999b Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Mon, 2 May 2011 12:28:49 +0530 Subject: [PATCH 0428/1547] [IMP] crm,crm_claim,crm_helpdesk,hr_recruitment,project_issue,project_mailgate: improvement in message_new() bzr revid: rha@tinyerp.com-20110502065849-19nilmvniw28n8ts --- addons/crm/crm_lead.py | 4 ++++ addons/crm_claim/crm_claim.py | 4 ++++ addons/crm_helpdesk/crm_helpdesk.py | 4 ++++ addons/hr_recruitment/hr_recruitment.py | 4 ++++ addons/project_issue/project_issue.py | 4 ++++ addons/project_mailgate/project_mailgate.py | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 132f95e3438..3f900c39045 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -378,6 +378,10 @@ class crm_lead(crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) return res_id diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index 04836a2ed79..26a7ac009b4 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -215,6 +215,10 @@ class crm_claim(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) return res_id diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py index 8c52618719d..59f19659d2c 100644 --- a/addons/crm_helpdesk/crm_helpdesk.py +++ b/addons/crm_helpdesk/crm_helpdesk.py @@ -138,6 +138,10 @@ class crm_helpdesk(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) return res_id diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 3c2c5b9af0b..f7414f5229d 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -338,6 +338,10 @@ class hr_applicant(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) return res_id diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 5bbd94c5a34..39c15bf85ca 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -420,6 +420,10 @@ class project_issue(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) self.convert_to_bug(cr, uid, [res_id], context=context) return res_id diff --git a/addons/project_mailgate/project_mailgate.py b/addons/project_mailgate/project_mailgate.py index cea05b3fa44..c4698540053 100644 --- a/addons/project_mailgate/project_mailgate.py +++ b/addons/project_mailgate/project_mailgate.py @@ -65,6 +65,10 @@ class project_tasks(osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority', False), context = context) return res_id From be4d3edd78cc3f98596591de63e4832a1316f309 Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Mon, 2 May 2011 14:14:29 +0530 Subject: [PATCH 0429/1547] [FIX] mail: put attrs on page instead of field for the field body and body_html bzr revid: rha@tinyerp.com-20110502084429-075rjxhkvcvnl21g --- addons/mail/email_view.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/mail/email_view.xml b/addons/mail/email_view.xml index 7e52ec5a0af..3681202da07 100644 --- a/addons/mail/email_view.xml +++ b/addons/mail/email_view.xml @@ -40,11 +40,11 @@ - - + + - - + + From 48e0f09e685234fa48359e234a215ed32856fb6f Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Mon, 2 May 2011 15:00:40 +0530 Subject: [PATCH 0430/1547] [FIX] mail: removed variable has_plain_text variable from parse_message() so now be able to add html part in the email message bzr revid: rha@tinyerp.com-20110502093040-o3pamdy99a7porb8 --- addons/mail/email_message.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/addons/mail/email_message.py b/addons/mail/email_message.py index e68597eb851..d1d8ea37d75 100644 --- a/addons/mail/email_message.py +++ b/addons/mail/email_message.py @@ -399,18 +399,12 @@ class email_message(osv.osv): content = part.get_payload(decode=True) if filename: attachments[filename] = content - elif not has_plain_text: - # main content parts should have 'text' maintype - # and no filename. we ignore the html part if - # there is already a plaintext part without filename, - # because presumably these are alternatives. - content = tools.ustr(content, encoding) - if part.get_content_subtype() == 'html': - msg['body_html'] = content - body = tools.ustr(tools.html2plaintext(content)) - elif part.get_content_subtype() == 'plain': - body = content - #has_plain_text = True + content = tools.ustr(content, encoding) + if part.get_content_subtype() == 'html': + msg['body_html'] = content + body = tools.ustr(tools.html2plaintext(content)) + elif part.get_content_subtype() == 'plain': + body = content elif part.get_content_maintype() in ('application', 'image'): if filename : attachments[filename] = part.get_payload(decode=True) From a42fa42d5a22088695c4206f67ce919093098f5b Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Mon, 2 May 2011 15:07:05 +0530 Subject: [PATCH 0431/1547] [IMP]product:Improve supplier dealy time value bzr revid: ron@tinyerp.com-20110502093705-rk3ayy0x8ejonzzy --- addons/product/product_demo.xml | 16 ++++++++-------- addons/sale/company.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index 55feb1dd9d8..e7fc3760d49 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -449,7 +449,7 @@ Wood 2mm - + product @@ -515,7 +515,7 @@ Rear Panel SHE100 - + product @@ -528,7 +528,7 @@ Rear Panel SHE200 - + product @@ -541,7 +541,7 @@ Side Panel - + product @@ -554,7 +554,7 @@ Rack 100cm - + product @@ -567,7 +567,7 @@ Rack 200cm - + product @@ -593,7 +593,7 @@ Wood Lintel 4m - + product @@ -605,7 +605,7 @@ Metal Cleats - + product diff --git a/addons/sale/company.py b/addons/sale/company.py index 2b310925107..3bf32c17d70 100644 --- a/addons/sale/company.py +++ b/addons/sale/company.py @@ -29,7 +29,7 @@ class company(osv.osv): "for security purpose"), } _defaults = { - 'security_lead': 5.0, + 'security_lead': 1.0, } company() From 364b09896623cf5cc061b96915ead68f0880dcca Mon Sep 17 00:00:00 2001 From: Osenda <> Date: Mon, 2 May 2011 11:55:04 +0200 Subject: [PATCH 0432/1547] [IMP] bareme rule, employee view bzr revid: osenda-20110502095504-oii83zji4mst0tjg --- .../data/hr.salary.rule.csv | 20 +++++++++---------- .../hr_payroll_l10n_be/hr_payroll_l10n_be.py | 4 ++-- .../hr_payroll_l10n_be_data.xml | 4 ++-- .../hr_payroll_l10n_be_view.xml | 5 +++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/addons/hr_payroll_l10n_be/data/hr.salary.rule.csv b/addons/hr_payroll_l10n_be/data/hr.salary.rule.csv index 1ce84969cb5..8788e7e060e 100644 --- a/addons/hr_payroll_l10n_be/data/hr.salary.rule.csv +++ b/addons/hr_payroll_l10n_be/data/hr.salary.rule.csv @@ -1422,13 +1422,13 @@ 1418,"fix",9,9,,1452,"Child Allowance Belgium","Child Allowance Belgium",140,"Ch.A","hr_payroll_rules_child","range","employee.children", 1419,"fix",10,10,,1673,"Child Allowance Belgium","Child Allowance Belgium",140,"Ch.A","hr_payroll_rules_child","range","employee.children", ,,,,,,,,,,,,, -1420,"fix",1,1,,62,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1421,"fix",2,2,,170,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1422,"fix",3,3,,458,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1423,"fix",4,4,,836,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1424,"fix",5,5,,1236,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1425,"fix",6,6,,1634,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1426,"fix",7,7,,2032,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1427,"fix",8,8,,2462,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1428,"fix",9,9,,2904,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", -1429,"fix",10,10,,3346,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1420,"fix",1,1,,85,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1421,"fix",2,2,,418,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1422,"fix",3,3,,817,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1423,"fix",4,4,,1231,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1424,"fix",5,5,,1673,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1425,"fix",6,6,,2115,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1426,"fix",7,7,,2557,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1427,"fix",8,8,,2999,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1428,"fix",9,9,,3441,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", +1429,"fix",10,10,,3883,"Child Allowance for the Disabled Belgium","Child Allowance Belgium",141,"Ch.Handicap","hr_payroll_rules_child_handicap","range","employee.number_handicap", diff --git a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be.py b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be.py index 2f667da1666..0dd0fcf5ac3 100644 --- a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be.py +++ b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be.py @@ -49,8 +49,8 @@ class hr_contract_be(osv.osv): 'advantage':fields.float('Benefits of various nature ', digits=(16,2)), 'suppl_net':fields.float('Net supplements', digits=(16,2)), 'retained_net':fields.float('Net retained ', digits=(16,2)), - 'vol_tax':fields.float('Voluntary tax ', digits=(16,2)), - 'horaire_effectif': fields.many2one('resource.calendar','Actual Work', help="Hours of work means the actual working time elapsing between the beginning and end of the workday, regardless of where it runs, excluding the stop work devoted to meals, breaks and, more generally, any interruptions between 2 sequences of work that are not actually worked since the employee can go freely about his personal affairs"), +# 'vol_tax':fields.float('Voluntary tax ', digits=(16,2)), +# 'horaire_effectif': fields.many2one('resource.calendar','Actual Work', help="Hours of work means the actual working time elapsing between the beginning and end of the workday, regardless of where it runs, excluding the stop work devoted to meals, breaks and, more generally, any interruptions between 2 sequences of work that are not actually worked since the employee can go freely about his personal affairs"), } hr_contract_be() diff --git a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml index c0dd0417688..4c570704c75 100644 --- a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml +++ b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml @@ -76,7 +76,7 @@ python - result = (((employee.marital=='single') or (employee.marital=='married' and statut_fiscal=='with income')) and (employee.resident!=True)) + result = (((employee.marital=='single') or (employee.marital=='married' and employee.statut_fiscal=='with income')) and (employee.resident!=True)) @@ -88,7 +88,7 @@ 120 python - result = (employee.marital=='married' and statut_fiscal=='without income') + result = ((employee.marital=='married' and employee.statut_fiscal=='without income') and (employee.resident!=True)) diff --git a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_view.xml b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_view.xml index 769b6e8ea4a..fa14cb45b04 100644 --- a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_view.xml +++ b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_view.xml @@ -9,9 +9,10 @@ - + @@ -22,7 +23,7 @@ - + From d337219345fe7dd261d666095d6169ff1368ed04 Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Mon, 2 May 2011 15:44:38 +0530 Subject: [PATCH 0433/1547] [IMP]stock:order by location complete name bzr revid: ron@tinyerp.com-20110502101438-g7kw8njfe1yaje4a --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 633a74923ec..d8042a3d5b1 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -71,7 +71,7 @@ class stock_location(osv.osv): _parent_name = "location_id" _parent_store = True _parent_order = 'posz,name' - _order = 'parent_left' + _order = 'complete_name' def name_get(self, cr, uid, ids, context=None): res = [] From 6923e2e880ea3d9d389dcf741a0ee6025d03b4c2 Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Mon, 2 May 2011 17:43:59 +0530 Subject: [PATCH 0434/1547] [FIX]: Fix datetime issue, contacts by emails issue. bzr revid: atp@tinyerp.com-20110502121359-i107e95eqxf4ojvs --- addons/import_sugarcrm/import_sugarcrm.py | 11 ++++++++--- addons/import_sugarcrm/sugar.py | 12 ------------ addons/import_sugarcrm/sugarcrm_fields_mapping.py | 8 +++++--- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index bedfeaae8fd..5b1adfc8e29 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -159,7 +159,7 @@ def import_partner_address(sugar_obj, cr, uid, context=None): map_partner_address = { 'id': 'id', 'name': ['first_name', 'last_name'], - 'partner_id/id': 'account_id', + 'partner_id/id': 'partner_id/id', 'phone': 'phone_work', 'mobile': 'phone_mobile', 'fax': 'phone_fax', @@ -172,13 +172,18 @@ def import_partner_address(sugar_obj, cr, uid, context=None): 'email': 'email', 'type': 'type' } + model_obj = sugar_obj.pool.get('ir.model.data') address_obj = sugar_obj.pool.get('res.partner.address') PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url','')) sugar_data = sugar.search(PortType, sessionid, 'Contacts') for val in sugar_data: + account_xml_id = model_obj.search(cr, uid, [('model', '=', 'res.partner'), ('name', 'like', val.get('account_id'))]) + if not account_xml_id: + raise osv.except_osv(_('Warning !'), _('Reference Partner %s cannot be created, due to Lower Record Limit in SugarCRM Configuration.') % val.get('account_name')) + else: + val['partner_id/id'] = val.get('account_id') val['type'] = 'contact' - contact_emails = sugar.contact_emails_search(PortType, context.get('username', ''), context.get('password', ''), email_address=val.get('email1')) - val['email'] = (','.join(map(lambda x : x, contact_emails))) + val['email'] = val.get('email1') + ','+ val.get('email2') if val.get('primary_address_country'): country_id = get_all_countries(sugar_obj, cr, uid, val.get('primary_address_country'), context) state = get_all_states(sugar_obj,cr, uid, val.get('primary_address_state'), country_id, context) diff --git a/addons/import_sugarcrm/sugar.py b/addons/import_sugarcrm/sugar.py index 6987071f443..ada2253e548 100644 --- a/addons/import_sugarcrm/sugar.py +++ b/addons/import_sugarcrm/sugar.py @@ -93,18 +93,6 @@ def user_get_attendee_list(portType, sessionid, module_name=None, module_id=None attendee_list.append(attendee_dict) return attendee_list -def contact_emails_search(portType, username, password, email_address=None): - se_req = contact_by_emailRequest() - se_req._user_name = username - se_req._password = password - se_req._email_address = email_address - se_resp = portType.contact_by_email(se_req) - ans_list = [] - for list in se_resp._return: - if list.Email_address and list.Email_address not in ans_list: - ans_list.append(list.Email_address) - return ans_list - def search(portType, sessionid, module_name=None): se_req = get_entry_listRequest() se_req._session = sessionid diff --git a/addons/import_sugarcrm/sugarcrm_fields_mapping.py b/addons/import_sugarcrm/sugarcrm_fields_mapping.py index 46f7a038670..0a94740ccad 100644 --- a/addons/import_sugarcrm/sugarcrm_fields_mapping.py +++ b/addons/import_sugarcrm/sugarcrm_fields_mapping.py @@ -43,15 +43,17 @@ def sugarcrm_fields_mapp(dict_sugar, openerp_dict, context=None): if len(val) >= 1 and val[0] == "__prettyprint__": val = val[1:] data_lst.append('\n\n'.join(map(lambda x : x + ": " + dict_sugar.get(x,''), val))) - elif val[0] == '__datetime__' and dict_sugar.get(val[1]): + elif val[0] == '__datetime__': val = val[1] if dict_sugar.get(val) and len(dict_sugar.get(val))<=10: - updated_dt = date.fromtimestamp(time.mktime(time.strptime(dict_sugar.get(val), '%Y-%m-%d'))) - else: + updated_dt = date.fromtimestamp(time.mktime(time.strptime(dict_sugar.get(val), '%Y-%m-%d'))) or False + elif dict_sugar.get(val): convert_date = datetime.strptime(dict_sugar.get(val), '%Y-%m-%d %H:%M:%S') edate = convert_date.replace(tzinfo=au_tz) au_dt = au_tz.normalize(edate.astimezone(au_tz)) updated_dt = datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') + else: + updated_dt = False data_lst.append(updated_dt) else: if key == 'duration': From a64854f513fd54ab8cc84dcb1156e1c83039f356 Mon Sep 17 00:00:00 2001 From: "tfr@openerp.com" <> Date: Mon, 2 May 2011 16:51:13 +0200 Subject: [PATCH 0435/1547] [IMP] framework to import link between objects bzr revid: tfr@openerp.com-20110502145113-un90wjz1svfwqlyp --- addons/import_sugarcrm/import_sugarcrm.py | 193 ++++++++++++---------- 1 file changed, 109 insertions(+), 84 deletions(-) diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index cf9cca7363b..a8e51d20502 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -26,10 +26,13 @@ from tools.translate import _ import pprint pp = pprint.PrettyPrinter(indent=4) +MODULE_NAME = 'sugarcrm_import' +DO_NOT_FIND_DOMAIN = [('id', '=', 0)] + def find_mapped_id(obj, cr, uid, res_model, sugar_id, context): model_obj = obj.pool.get('ir.model.data') - return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', 'sugarcrm_import'), ('name', '=', sugar_id)], context=context) + return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', MODULE_NAME), ('name', '=', sugar_id)], context=context) def mapped_id(obj, cr, uid, res_model, sugar_id, id, context): """ @@ -42,10 +45,27 @@ def mapped_id(obj, cr, uid, res_model, sugar_id, id, context): """ ir_model_data_obj = obj.pool.get('ir.model.data') id = ir_model_data_obj._update(cr, uid, res_model, - 'sugarcrm_import', {}, mode='update', xml_id=sugar_id, + MODULE_NAME, {}, mode='update', xml_id=sugar_id, noupdate=True, res_id=id, context=context) return sugar_id + + + +def mapped_id_if_exist(sugar_obj, cr, uid, model, domain, xml_id, context=None): + """ + @param domain : search domain to find existing record, should return a unique record + @param xml_id: xml_id give to the mapping + + @return : the xml_id if the record exist in the db, False otherwise + """ + obj = sugar_obj.pool.get(model) + ids = obj.search(cr, uid, domain, context=context) + print "ids", ids, "domain", domain + if ids: + return MODULE_NAME + "." + mapped_id(obj, cr, uid, model, xml_id, ids[0], context=context) + return False + def import_object(sugar_obj, cr, uid, fields, data, model, table, name, domain_search=False, context=None): """ This method will import an object in the openerp, usefull for field that is only a char in sugar and is an object in openerp @@ -64,19 +84,30 @@ def import_object(sugar_obj, cr, uid, fields, data, model, table, name, domain_s domain_search = not domain_search and [('name', 'ilike', name)] or domain_search obj = sugar_obj.pool.get(model) xml_id = generate_xml_id(name, table) - - def mapped_id_if_exist(obj, domain, xml_id): - ids = obj.search(cr, uid, domain, context=context) - if ids: - return mapped_id(obj, cr, uid, model, xml_id, ids[0], context=context) - return False + xml_ref = mapped_id_if_exist(obj, cr, uid, model, domain_search, xml_id, context=context) - mapped_id_if_exist(obj, domain_search, xml_id) fields.append('id') data.append(xml_id) - obj.import_data(cr, uid, fields, [data], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) - return xml_id + + obj.import_data(cr, uid, fields, [data], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) + return xml_ref or MODULE_NAME + "." + xml_id + +def add_m2o_data(data, fields, column, xml_ids): + """ + @param fields: list of fields + @param data: the list of the data, in the same order as the field + ex : fields = ['firstname', 'lastname'] ; data = ['John', 'Mc donalds'] + @param column : name of the column that will contains the xml_id of o2m data + ex : contact_id/id + @param xml_ids : the list of xml id of the data + + @return fields and data with the last column "column", "xml_id1,xml_id2,xml_id3,.." + """ + fields.append(column) + data.append(','.join(xml_ids)) + return fields, data + def generate_xml_id(name, table): """ @@ -99,30 +130,21 @@ def get_all(sugar_obj, cr, uid, model, sugar_val, context=None): return output def get_all_states(sugar_obj, cr, uid, sugar_val, country_id, context=None): - """Get states or create new state""" - state_id = False - res_country_state_obj = sugar_obj.pool.get('res.country.state') + """Get states or create new state unless country_id is False""" - state = get_all(sugar_obj, - cr, uid, 'res.country.state', sugar_val, context=context) - if state: - state_id = state and state[0][0] - else: - state_id = res_country_state_obj.create(cr, uid, {'name': sugar_val, 'code': sugar_val, 'country_id': country_id}) - return state_id + state_code = sugar_val[0:3] #take the tree first char + fields = ['country_id/id', 'name', 'code'] + data = [country_id, sugar_val, state_code] + if country_id: + return import_object(sugar_obj, cr, uid, fields, data, 'res.country.state', 'country_state', sugar_val, context=context) + + return False + def get_all_countries(sugar_obj, cr, uid, sugar_country_val, context=None): - """Get Country or Create new country""" - res_country_obj = sugar_obj.pool.get('res.country') - country_id = False - country_code = sugar_country_val[0:2] - country = get_all(sugar_obj, - cr, uid, 'res.country', sugar_country_val, context=context) - if country: - country_id = country and country[0][0] - else: - country_id = res_country_obj.create(cr, uid, {'name': sugar_country_val, 'code': country_code}) - return country_id + """Get Country, if no country match do not create anything, to avoid duplicate country code""" + xml_id = generate_xml_id(sugar_country_val, 'country') + return mapped_id_if_exist(sugar_obj, cr, uid, 'res.country', [('name', 'ilike', sugar_country_val)], xml_id, context=context) def import_partner_address(sugar_obj, cr, uid, context=None): if not context: @@ -137,8 +159,8 @@ def import_partner_address(sugar_obj, cr, uid, context=None): 'street': 'primary_address_street', 'zip': 'primary_address_postalcode', 'city': 'primary_address_city', - 'country_id.id': 'country_id.id', - 'state_id.id': 'state_id.id' + 'country_id/id': 'country_id/id', + 'state_id/id': 'state_id/id' } address_obj = sugar_obj.pool.get('res.partner.address') PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url','')) @@ -147,10 +169,10 @@ def import_partner_address(sugar_obj, cr, uid, context=None): if val.get('primary_address_country'): country_id = get_all_countries(sugar_obj, cr, uid, val.get('primary_address_country'), context) state = get_all_states(sugar_obj,cr, uid, val.get('primary_address_state'), country_id, context) - val['country_id.id'] = country_id - val['state_id.id'] = state + val['country_id/id'] = country_id + val['state_id/id'] = state fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address) - address_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + address_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True @@ -194,7 +216,7 @@ def import_users(sugar_obj, cr, uid, context=None): val['context_lang'] = context.get('lang','en_US') fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user) #All data has to be imported separatly because they don't have the same field - user_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + user_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_lead_status(surgar_obj, cr, uid, sugar_val,context=None): @@ -238,8 +260,8 @@ def get_user_address(sugar_obj, cr, uid, val, context=None): map_user_address = { 'name': ['first_name', 'last_name'], 'city': 'address_city', - 'country_id': 'country_id', - 'state_id': 'state_id', + 'country_id/id': 'country_id/id', + 'state_id/id': 'state_id/id', 'street': 'address_street', 'zip': 'address_postalcode', } @@ -247,8 +269,8 @@ def get_user_address(sugar_obj, cr, uid, val, context=None): if val.get('address_country'): country_id = get_all_countries(sugar_obj, cr, uid, val.get('address_country'), context) state_id = get_all_states(sugar_obj, cr, uid, val.get('address_state'), country_id, context) - val['country_id'] = country_id - val['state_id'] = state_id + val['country_id/id'] = country_id + val['state_id/id'] = state_id fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user_address) dict_val = dict(zip(fields,datas)) if address_ids: @@ -260,7 +282,6 @@ def get_user_address(sugar_obj, cr, uid, val, context=None): def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context=None): address_obj = sugar_obj.pool.get('res.partner.address') - new_address_id = False if type == 'invoice': type_address = 'billing' else: @@ -270,31 +291,31 @@ def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context 'street': type_address + '_address_street', 'zip': type_address +'_address_postalcode', 'city': type_address +'_address_city', - 'country_id': 'country_id', + 'country_id/id': 'country_id/id', 'type': 'type', }) val['type'] = type if val.get(type_address +'_address_country'): country_id = get_all_countries(sugar_obj, cr, uid, val.get(type_address +'_address_country'), context) state = get_all_states(sugar_obj, cr, uid, val.get(type_address +'_address_state'), country_id, context) - val['country_id'] = country_id - val['state_id'] = state + val['country_id/id'] = country_id + val['state_id/id'] = state + fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address) + print 'fields', fields + print 'data' + pp.pprint(datas) + unique_name = val['id'] + '_address_' + type #Convert To list into Dictionary(Key, val). value pair. - dict_val = dict(zip(fields,datas)) - new_address_id = address_obj.create(cr,uid, dict_val) - return new_address_id + #dict_val = dict(zip(fields,datas)) + #pp.pprint(dict_val) + return import_object(sugar_obj, cr, uid, fields, datas, 'res.partner.address', 'contact', unique_name, DO_NOT_FIND_DOMAIN, context=context) + #new_address_id = address_obj.create(cr,uid, dict_val) + #return new_address_id def get_address(sugar_obj, cr, uid, val, context=None): - map_partner_address={} address_id=[] - address_obj = sugar_obj.pool.get('res.partner.address') - address_ids = address_obj.search(cr, uid, [('name', '=',val.get('name')), ('type', 'in', ('invoice', 'delivery')), ('street', '=', val.get('billing_address_street'))]) - if address_ids: - return address_ids - else: - map_partner_address = { - 'id': 'id', + map_partner_address = { 'name': 'name', 'partner_id/id': 'account_id', 'phone': 'phone_office', @@ -302,13 +323,16 @@ def get_address(sugar_obj, cr, uid, val, context=None): 'fax': 'phone_fax', 'type': 'type', } - if val.get('billing_address_street'): - address_id.append(get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'invoice', context)) + if val.get('billing_address_street'): + id = get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'invoice', context) + print "xml id billing", id + address_id.append(id) - if val.get('shipping_address_street'): - address_id.append(get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'delivery', context)) - return address_id - return True + if val.get('shipping_address_street'): + id = get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'delivery', context) + print "xml id shipping", id + address_id.append(id) + return address_id def import_partners(sugar_obj, cr, uid, context=None): if not context: @@ -324,19 +348,18 @@ def import_partners(sugar_obj, cr, uid, context=None): 'supplier': 'supplier', } partner_obj = sugar_obj.pool.get('res.partner') - address_obj = sugar_obj.pool.get('res.partner.address') PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url','')) sugar_data = sugar.search(PortType, sessionid, 'Accounts') for val in sugar_data: add_id = get_address(sugar_obj, cr, uid, val, context) val['customer'] = '1' val['supplier'] = '0' - fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner) - partner_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) - for address in address_obj.browse(cr,uid,add_id): - data_id = partner_obj.search(cr,uid,[('name','like',address.name),('website','like',val.get('website'))]) - if data_id: - address_obj.write(cr,uid,address.id,{'partner_id':data_id[0]}) + fields, data = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner) + fields, data = add_m2o_data(data, fields, 'address/id', add_id) + print "fields, data" + print fields + print data + partner_obj.import_data(cr, uid, fields, [data], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_category(sugar_obj, cr, uid, model, name, context=None): @@ -488,7 +511,7 @@ def import_tasks(sugar_obj, cr, uid, context=None): val['categ_id/.id'] = categ_id val['state'] = get_task_state(sugar_obj, cr, uid, val.get('status'), context=None) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_task) - meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, module_name, module_id, context=None): @@ -538,7 +561,7 @@ def import_meetings(sugar_obj, cr, uid, context=None): val['state'] = get_meeting_state(sugar_obj, cr, uid, val.get('status'),context) val['alarm_id/.id'] = get_alarm_id(sugar_obj, cr, uid, val.get('reminder_time'), context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_meeting) - meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, 'Meetings', val.get('id'), context) return True @@ -579,7 +602,7 @@ def import_calls(sugar_obj, cr, uid, context=None): val['partner_address_id/.id'] = partner_address_id val['state'] = get_calls_state(sugar_obj, cr, uid, val.get('status'), context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_calls) - phonecall_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + phonecall_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def import_resources(sugar_obj, cr, uid, context=None): @@ -593,7 +616,7 @@ def import_resources(sugar_obj, cr, uid, context=None): sugar_data = sugar.search(PortType, sessionid, 'Employees') for val in sugar_data: fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_resource) - resource_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + resource_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_bug_priority(sugar_obj, cr, uid, val,context=None): @@ -659,7 +682,7 @@ def import_bug(sugar_obj, cr, uid, context=None): val['priority'] = get_bug_priority(sugar_obj, cr, uid, val.get('priority'),context) val['state'] = get_bug_state(sugar_obj, cr, uid, val.get('status'),context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_resource) - issue_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + issue_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_job_id(sugar_obj, cr, uid, val, context=None): @@ -710,7 +733,7 @@ def import_history(sugar_obj, cr, uid, context=None): val['res_id'] = model.res_id val['model'] = model.model fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_attachment) - mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) get_attachment(sugar_obj, cr, uid, val, 'mailgate.message', File, context) return True @@ -741,7 +764,7 @@ def import_employees(sugar_obj, cr, uid, context=None): val['resource_id/.id'] = resource_id[0].res_id val['job_id/.id'] = get_job_id(sugar_obj, cr, uid, val.get('title'), context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_employee) - employee_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + employee_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_contact_title(sugar_obj, cr, uid, salutation, domain, context=None): @@ -780,9 +803,11 @@ def import_emails(sugar_obj, cr, uid, context=None): val['res_id'] = model.res_id val['model'] = model.model fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_emails) - mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True - + + +#TODO more simplier use xml id please !!!! def get_project_account(sugar_obj,cr,uid, PortType, sessionid, val, context=None): if not context: context={} @@ -822,7 +847,7 @@ def import_projects(sugar_obj, cr, uid, context=None): val['contact_id/.id'] = partner_invoice_id val['state'] = get_project_state(sugar_obj, cr, uid, val.get('status'),context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project) - project_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + project_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True @@ -849,7 +874,7 @@ def import_project_tasks(sugar_obj, cr, uid, context=None): val['state'] = get_project_task_state(sugar_obj, cr, uid, val.get('status'),context) val['priority'] = get_project_task_priority(sugar_obj, cr, uid, val.get('priority'),context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project_task) - task_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + task_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def import_leads(sugar_obj, cr, uid, context=None): @@ -889,7 +914,7 @@ def import_leads(sugar_obj, cr, uid, context=None): val['stage_id.id'] = stage_id val['state'] = get_lead_state(sugar_obj, cr, uid, val,context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_lead) - lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_xml_id, context=None): @@ -898,7 +923,7 @@ def get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_ partner_contact_name = False model_obj = sugar_obj.pool.get('ir.model.data') partner_address_obj = sugar_obj.pool.get('res.partner.address') - model_account_ids = model_obj.search(cr, uid, [('res_id', '=', partner_xml_id[0]), ('model', '=', 'res.partner'), ('module', '=', 'sugarcrm_import')]) + model_account_ids = model_obj.search(cr, uid, [('res_id', '=', partner_xml_id[0]), ('model', '=', 'res.partner'), ('module', '=', MODULE_NAME)]) model_xml_id = model_obj.browse(cr, uid, model_account_ids)[0].name sugar_account_contact = set(sugar.relation_search(PortType, sessionid, 'Accounts', module_id=model_xml_id, related_module='Contacts', query=None, deleted=None)) sugar_opportunities_contact = set(sugar.relation_search(PortType, sessionid, 'Opportunities', module_id=val.get('id'), related_module='Contacts', query=None, deleted=None)) @@ -945,7 +970,7 @@ def import_opportunities(sugar_obj, cr, uid, context=None): val['type'] = 'opportunity' val['stage_id/id'] = get_opportunity_status(sugar_obj, cr, uid, val, context) fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_opportunity) - lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context) + lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context) return True def get_opportunity_status(sugar_obj, cr, uid, sugar_val,context=None): From 3a904e407b6b1a7122bac98470e3b9330926ffab Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Tue, 3 May 2011 12:08:44 +0530 Subject: [PATCH 0436/1547] [IMP] mail: able to retrive priority of an email message and related changes in message_new() and message_update() bzr revid: rha@tinyerp.com-20110503063844-yhlhlnpvciveh219 --- addons/crm/crm_lead.py | 7 ++++++- addons/crm_claim/crm_claim.py | 6 +++++- addons/crm_helpdesk/crm_helpdesk.py | 6 +++++- addons/hr_recruitment/hr_recruitment.py | 6 +++++- addons/mail/email_message.py | 12 ++++++++++-- addons/mail/email_thread.py | 7 ++++--- addons/project_issue/project_issue.py | 6 +++++- addons/project_mailgate/project_mailgate.py | 6 +++++- 8 files changed, 45 insertions(+), 11 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 3f900c39045..b95d00a101c 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -170,6 +170,7 @@ class crm_lead(crm_case, osv.osv): \nWhen the case is over, the state is set to \'Done\'.\ \nIf the case needs to be reviewed then the state is set to \'Pending\'.'), 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]), + 'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', method=True, type='char', size=64), } @@ -381,7 +382,7 @@ class crm_lead(crm_case, osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) return res_id @@ -433,6 +434,10 @@ class crm_lead(crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return res diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index 26a7ac009b4..f6719edcb5b 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -218,7 +218,7 @@ class crm_claim(crm.crm_case, osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) return res_id @@ -270,6 +270,10 @@ class crm_claim(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return res diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py index 59f19659d2c..24ea1418bf8 100644 --- a/addons/crm_helpdesk/crm_helpdesk.py +++ b/addons/crm_helpdesk/crm_helpdesk.py @@ -141,7 +141,7 @@ class crm_helpdesk(crm.crm_case, osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) return res_id @@ -193,6 +193,10 @@ class crm_helpdesk(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return res diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index f7414f5229d..ef44b22eb55 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -341,7 +341,7 @@ class hr_applicant(crm.crm_case, osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) return res_id @@ -391,6 +391,10 @@ class hr_applicant(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return res diff --git a/addons/mail/email_message.py b/addons/mail/email_message.py index d1d8ea37d75..8ef0dde0228 100644 --- a/addons/mail/email_message.py +++ b/addons/mail/email_message.py @@ -60,6 +60,13 @@ email_content_types = [ ('html', 'text/html') ] +priorities = { + '1 (Highest)': '1', + '2 (High)': '2', + '3 (Normal)': '3', + '4 (Low)': '4', + '5 (Lowest)': '5', +} LOGGER = netsvc.Logger() _logger = logging.getLogger('mail') @@ -328,7 +335,6 @@ class email_message(osv.osv): msg_txt['message-id'] = message_id _logger.info('Parsing Message without message-id, generating a random one: %s', message_id) - fields = msg_txt.keys() msg['id'] = message_id msg['message-id'] = message_id @@ -364,7 +370,9 @@ class email_message(osv.osv): msg['in-reply-to'] = msg_txt.get('In-Reply-To') if 'X-Priority' in fields: - msg['priority'] = msg_txt.get('X-Priority', '3 (Normal)').split(' ')[0] #TOFIX: + msg['priority'] = priorities[msg_txt.get('X-Priority')] + else: + msg['priority'] = priorities['3 (Normal)'] msg['headers'] = {} for item in msg_txt.items(): diff --git a/addons/mail/email_thread.py b/addons/mail/email_thread.py index 0fb6f45819e..44d957c7ee1 100644 --- a/addons/mail/email_thread.py +++ b/addons/mail/email_thread.py @@ -96,6 +96,7 @@ class email_thread(osv.osv): sub_type = msg.get('sub_type', False), headers = msg.get('headers', False), reply = msg.get('reply', False), + priority = msg.get('priority'), context = context) return res_id @@ -125,6 +126,7 @@ class email_thread(osv.osv): sub_type = msg.get('sub_type', False), headers = msg.get('headers', False), reply = msg.get('reply', False), + priority = msg.get('priority'), context = context) return True @@ -168,8 +170,6 @@ class email_thread(osv.osv): if attach is None: attach = {} - - if email_date: edate = parsedate(email_date) if edate is not None: @@ -244,7 +244,8 @@ class email_thread(osv.osv): 'body_html': body_html, 'sub_type': sub_type, 'headers': headers, - 'reply_to': reply + 'reply_to': reply, + 'priority': priority } obj.create(cr, uid, data, context=context) return True diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 39c15bf85ca..def289ecc0f 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -423,7 +423,7 @@ class project_issue(crm.crm_case, osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) self.convert_to_bug(cr, uid, [res_id], context=context) return res_id @@ -481,6 +481,10 @@ class project_issue(crm.crm_case, osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return res diff --git a/addons/project_mailgate/project_mailgate.py b/addons/project_mailgate/project_mailgate.py index c4698540053..a7768fc862d 100644 --- a/addons/project_mailgate/project_mailgate.py +++ b/addons/project_mailgate/project_mailgate.py @@ -68,7 +68,7 @@ class project_tasks(osv.osv): body_html= msg.get('body_html'), sub_type = msg.get('sub_type'), headers = msg.get('headers'), - priority = msg.get('priority', False), + priority = msg.get('priority'), context = context) return res_id @@ -108,6 +108,10 @@ class project_tasks(osv.osv): references = msg.get('references', False) or msg.get('in-reply-to', False), attach = attachments, email_date = msg.get('date'), + body_html= msg.get('body_html'), + sub_type = msg.get('sub_type'), + headers = msg.get('headers'), + priority = msg.get('priority'), context = context) return True From 8890c2b820f04a25b76ad4df6a0e424e876a14cf Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Tue, 3 May 2011 12:55:13 +0530 Subject: [PATCH 0437/1547] [FIX]stock:Fixed:cannot change date in Incoming shipment order,delivery order and internal shipment lp bug: https://launchpad.net/bugs/770168 fixed bzr revid: ron@tinyerp.com-20110503072513-ms2lwczlsjdcj65r --- addons/stock/stock.py | 12 +++++++++++- addons/stock/stock_view.xml | 10 +++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 8e60ba9ab50..2c46e8dd63e 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1517,7 +1517,7 @@ class stock_move(osv.osv): 'name': fields.char('Name', size=64, required=True, select=True), 'priority': fields.selection([('0', 'Not urgent'), ('1', 'Urgent')], 'Priority'), 'create_date': fields.datetime('Creation Date', readonly=True, select=True), - 'date': fields.datetime('Date', required=True, select=True, help="Move date: scheduled date until move is done, then date of actual move processing", readonly=True), + 'date': fields.datetime('Date', required=True, select=True, help="Move date: scheduled date until move is done, then date of actual move processing", states={'done': [('readonly', True)]}), 'date_expected': fields.datetime('Scheduled Date', states={'done': [('readonly', True)]},required=True, select=True, help="Scheduled date for the processing of this move"), 'product_id': fields.many2one('product.product', 'Product', required=True, select=True, domain=[('type','<>','service')],states={'done': [('readonly', True)]}), @@ -1753,6 +1753,16 @@ class stock_move(osv.osv): result['location_dest_id'] = loc_dest_id return {'value': result} + def onchange_date(self, cr, uid, ids, date, date_expected, context=None): + """ On change of Scheduled Date gives a Move date. + @param date_expected: Scheduled Date + @param date: Move Date + @return: Move Date + """ + if not date_expected: + date_expected = time.strftime('%Y-%m-%d'), + return {'value':{'date': date_expected}} + def _chain_compute(self, cr, uid, moves, context=None): """ Finds whether the location has chained location type or not. @param moves: Stock moves diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 6dfd38c37b1..d1bc8cfd19a 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -769,7 +769,7 @@ - + @@ -961,7 +961,7 @@ - + @@ -1181,7 +1181,7 @@ - + @@ -1449,7 +1449,7 @@ - + @@ -1644,7 +1644,7 @@ - + From 30f6afd2aaf7ec0af7d46b3a0820494dff022958 Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Wed, 4 May 2011 10:41:34 +0530 Subject: [PATCH 0438/1547] [IMP]:stock:include time value in Move Date field bzr revid: ron@tinyerp.com-20110504051134-x1ok2q9hv30b5mvh --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 2c46e8dd63e..ccc9ac54949 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1760,7 +1760,7 @@ class stock_move(osv.osv): @return: Move Date """ if not date_expected: - date_expected = time.strftime('%Y-%m-%d'), + date_expected = time.strftime('%Y-%m-%d %H:%M:%S') return {'value':{'date': date_expected}} def _chain_compute(self, cr, uid, moves, context=None): From 5d8b8dd7fdefa8f729e0a1f690858a3f1f32e338 Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Wed, 4 May 2011 14:35:49 +0530 Subject: [PATCH 0439/1547] [IMP]product:improve product demo supplier dealy bzr revid: ron@tinyerp.com-20110504090549-se4ooa0zh3w54l4g --- addons/product/product_demo.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index e7fc3760d49..3aebec13715 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -736,21 +736,21 @@ 1 1 - 10 + 5 1 1 - 10 + 5 1 1 - 10 + 5 @@ -758,7 +758,7 @@ 1 5 - 10 + 5 @@ -766,7 +766,7 @@ 1 5 - 10 + 5 @@ -774,7 +774,7 @@ 1 5 - 10 + 5 @@ -39,7 +46,7 @@ MAJ none percentage - contract.wage + rules['MAJ'] 108.00 @@ -137,7 +144,7 @@ Child Allowance for the Disabled Belgium Ch.Handicap fix - 142 + 143 "Disabled child" means: the child reaches at least 66% of failure or reduced physical or mental capacity @@ -150,6 +157,17 @@ result = bool(employee.number_handicap) + + + Disabled Spouse Allowance + Sp.handicap + fix + 145 + 31 + python + result = employee.handicap==True + + From 9483dc163ea99ac054ab9ecb0bca740940145933 Mon Sep 17 00:00:00 2001 From: Osenda <> Date: Mon, 9 May 2011 15:03:04 +0200 Subject: [PATCH 0447/1547] [FIX] 4482 revision pour ONSS bzr revid: osenda-20110509130304-00a1n82d066oyo91 --- .../hr_payroll_l10n_be_data.xml | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml index fa7b85e9508..4f749e5d2d6 100644 --- a/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml +++ b/addons/hr_payroll_l10n_be/hr_payroll_l10n_be_data.xml @@ -2,10 +2,16 @@ - Salaire Majore + Premium pay 108% Worker MAJ + + + Employee Salary + NON-MAJ + + Office National Securite Sociale ONSS @@ -42,14 +48,21 @@ - Salaire Majore - MAJ + Premium pay 108% Worker + SALARY none - percentage - rules['MAJ'] - 108.00 + code + result = contract.wage * 1.08 + + + Salary Employee + SALARY + none + code + result = contract.wage * 1 + @@ -58,10 +71,12 @@ 41 none percentage - contract.wage + rules['SALARY'] -13.07 + + Precompte Professionnel Bareme 2011 @@ -319,7 +334,7 @@ C.P.218 Belgian Employee - + From 5c0308f078e30e5b6a2aa4d4bb5fba0682ecd760 Mon Sep 17 00:00:00 2001 From: "Rifakat Haradwala (Open ERP)" Date: Tue, 10 May 2011 19:20:48 +0530 Subject: [PATCH 0448/1547] [FIX] bzr revid: rha@tinyerp.com-20110510135048-f044stg7gaij0867 --- addons/email_template/email_template.py | 4 +-- .../wizard/email_compose_message.py | 34 ++++++++++--------- .../wizard/email_template_preview.py | 2 +- .../wizard/email_compose_message_view.xml | 2 +- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index 20a98c009ca..6169b7a2937 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -45,7 +45,7 @@ class email_template(osv.osv): "Return Template Object" if context is None: context = {} - + if not template_id: return False @@ -404,7 +404,7 @@ class email_template(osv.osv): # Add document attachments for attach in template.attachment_ids: #attach = attahcment_obj.browse(cr, uid, attachment_id, context) - attachment[attach.datas_fname] = attach.datas + attachment[attach.datas_fname] = base64.decodestring(attach.datas) values['attachment'] = attachment return values diff --git a/addons/email_template/wizard/email_compose_message.py b/addons/email_template/wizard/email_compose_message.py index 9dbb940d3da..ef6058ff892 100644 --- a/addons/email_template/wizard/email_compose_message.py +++ b/addons/email_template/wizard/email_compose_message.py @@ -61,22 +61,24 @@ class email_compose_message(osv.osv_memory): if context is None: context = {} att_ids = [] - res_id = context.get('active_id', False) - values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context) - if values['attachment']: - attachment = values['attachment'] - attachment_obj = self.pool.get('ir.attachment') - for fname, fcontent in attachment.items(): - data_attach = { - 'name': fname, - 'datas': binascii.b2a_base64(str(fcontent)), - 'datas_fname': fname, - 'description': _('Mail attachment'), - 'res_model' : self._name, - 'res_id' : ids and ids[0] or False - } - att_ids.append(attachment_obj.create(cr, uid, data_attach)) - values['attachment_ids'] = att_ids + values = {} + if template_id: + res_id = context.get('active_id', False) + values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context) + if values['attachment']: + attachment = values['attachment'] + attachment_obj = self.pool.get('ir.attachment') + for fname, fcontent in attachment.items(): + data_attach = { + 'name': fname, + 'datas': binascii.b2a_base64(str(fcontent)), + 'datas_fname': fname, + 'description': _('Mail attachment'), + 'res_model' : self._name, + 'res_id' : ids and ids[0] or False + } + att_ids.append(attachment_obj.create(cr, uid, data_attach)) + values['attachment_ids'] = att_ids return {'value': values} def save_as_template(self, cr, uid, ids, context=None): diff --git a/addons/email_template/wizard/email_template_preview.py b/addons/email_template/wizard/email_template_preview.py index 94b86deec8b..6b2b546c267 100644 --- a/addons/email_template/wizard/email_template_preview.py +++ b/addons/email_template/wizard/email_template_preview.py @@ -38,7 +38,7 @@ class email_template_preview(osv.osv_memory): if context is None: context = {} - template_id = context.get('active_id', False) + template_id = context.get('template_id', False) if not template_id: return [] template_pool = self.pool.get('email.template') diff --git a/addons/mail/wizard/email_compose_message_view.xml b/addons/mail/wizard/email_compose_message_view.xml index dd89d0267ff..0cc90f3e7c9 100644 --- a/addons/mail/wizard/email_compose_message_view.xml +++ b/addons/mail/wizard/email_compose_message_view.xml @@ -33,7 +33,7 @@