From 3cf3519e82efe735f5228bc83bced6366ec895af Mon Sep 17 00:00:00 2001 From: Darshan Kalola Date: Wed, 24 Jul 2013 19:15:48 +0530 Subject: [PATCH 01/59] [IMP]improve help of setting/configuration menus bzr revid: darshankalola@gmail.com-20130724134548-jmgot5zt3xpcx1ct --- addons/account/res_config.py | 36 +++++++------- addons/base_setup/res_config.py | 21 ++++---- addons/crm/res_config.py | 4 +- addons/hr_recruitment/res_config.py | 8 ++-- addons/hr_timesheet_sheet/res_config.py | 4 +- addons/knowledge/res_config.py | 14 +++--- addons/marketing/res_config.py | 14 +++--- addons/mrp/res_config.py | 64 ++++++++++++------------- addons/project/res_config.py | 34 ++++++------- addons/purchase/res_config.py | 28 +++++------ addons/sale/res_config.py | 42 ++++++++-------- addons/sale_stock/res_config.py | 8 ++-- addons/stock/res_config.py | 26 +++++----- 13 files changed, 151 insertions(+), 152 deletions(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index 89d238b16e9..edb34f54be2 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -81,31 +81,31 @@ class account_config_settings(osv.osv_memory): 'purchase_refund_sequence_next': fields.related('purchase_refund_journal_id', 'sequence_id', 'number_next', type='integer', string='Next supplier credit note number'), 'module_account_check_writing': fields.boolean('Pay your suppliers by check', - help="""This allows you to check writing and printing. - This installs the module account_check_writing."""), + help='This allows you to check writing and printing.\n' + 'This installs the module account_check_writing.'), 'module_account_accountant': fields.boolean('Full accounting features: journals, legal statements, chart of accounts, etc.', help="""If you do not check this box, you will be able to do invoicing & payments, but not accounting (Journal Items, Chart of Accounts, ...)"""), 'module_account_asset': fields.boolean('Assets management', - help="""This allows you to manage the assets owned by a company or a person. - It keeps track of the depreciation occurred on those assets, and creates account move for those depreciation lines. - This installs the module account_asset. If you do not check this box, you will be able to do invoicing & payments, - but not accounting (Journal Items, Chart of Accounts, ...)"""), + help='This allows you to manage the assets owned by a company or a person.\n' + 'It keeps track of the depreciation occurred on those assets, and creates account move for those depreciation lines.\n' + 'This installs the module account_asset. If you do not check this box, you will be able to do invoicing & payments, ' + 'but not accounting (Journal Items, Chart of Accounts, ...)'), 'module_account_budget': fields.boolean('Budget management', - help="""This allows accountants to manage analytic and crossovered budgets. - Once the master budgets and the budgets are defined, - the project managers can set the planned amount on each analytic account. - This installs the module account_budget."""), + help='This allows accountants to manage analytic and crossovered budgets. ' + 'Once the master budgets and the budgets are defined, ' + 'the project managers can set the planned amount on each analytic account.\n' + 'This installs the module account_budget.'), 'module_account_payment': fields.boolean('Manage payment orders', - help="""This allows you to create and manage your payment orders, with purposes to - * serve as base for an easy plug-in of various automated payment mechanisms, and - * provide a more efficient way to manage invoice payments. - This installs the module account_payment."""), + help='This allows you to create and manage your payment orders, with purposes to \n' + '* serve as base for an easy plug-in of various automated payment mechanisms, and \n' + '* provide a more efficient way to manage invoice payments.\n' + 'This installs the module account_payment.' ), 'module_account_voucher': fields.boolean('Manage customer payments', - help="""This includes all the basic requirements of voucher entries for bank, cash, sales, purchase, expense, contra, etc. - This installs the module account_voucher."""), + help='This includes all the basic requirements of voucher entries for bank, cash, sales, purchase, expense, contra, etc.\n' + 'This installs the module account_voucher.'), 'module_account_followup': fields.boolean('Manage customer payment follow-ups', - help="""This allows to automate letters for unpaid invoices, with multi-level recalls. - This installs the module account_followup."""), + help='This allows to automate letters for unpaid invoices, with multi-level recalls.\n' + 'This installs the module account_followup.'), 'group_proforma_invoices': fields.boolean('Allow pro-forma invoices', implied_group='account.group_proforma_invoices', help="Allows you to put invoices in pro-forma state."), diff --git a/addons/base_setup/res_config.py b/addons/base_setup/res_config.py index 6b8578bbf47..82828e5f30d 100644 --- a/addons/base_setup/res_config.py +++ b/addons/base_setup/res_config.py @@ -64,18 +64,17 @@ class sale_config_settings(osv.osv_memory): 'module_crm': fields.boolean('CRM'), 'module_sale' : fields.boolean('SALE'), 'module_plugin_thunderbird': fields.boolean('Enable Thunderbird plug-in', - help="""The plugin allows you archive email and its attachments to the selected - OpenERP objects. You can select a partner, or a lead and - attach the selected mail as a .eml file in - the attachment of a selected record. You can create documents for CRM Lead, - Partner from the selected emails. - This installs the module plugin_thunderbird."""), + help='The plugin allows you archive email and its attachments to the selected ' + 'OpenERP objects. You can select a partner, or a lead and ' + 'attach the selected mail as a .eml file in ' + 'the attachment of a selected record. You can create documents for CRM Lead, ' + 'Partner from the selected emails.\n' + 'This installs the module plugin_thunderbird.'), 'module_plugin_outlook': fields.boolean('Enable Outlook plug-in', - help="""The Outlook plugin allows you to select an object that you would like to add - to your email and its attachments from MS Outlook. You can select a partner, - or a lead object and archive a selected - email into an OpenERP mail message with attachments. - This installs the module plugin_outlook."""), + help='The Outlook plugin allows you to select an object that you would like to add ' + 'to your email and its attachments from MS Outlook. You can select a partner, ' + 'or a lead object and archive a selected email into an OpenERP mail message with attachments.\n' + 'This installs the module plugin_outlook.'), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py index ea37c24fe06..622af04ef75 100644 --- a/addons/crm/res_config.py +++ b/addons/crm/res_config.py @@ -58,8 +58,8 @@ class crm_configuration(osv.TransientModel): implied_group='crm.group_fund_raising', help="""Allows you to trace and manage your activities for fund raising."""), 'module_crm_claim': fields.boolean("Manage Customer Claims", - help="""Allows you to track your customers/suppliers claims and grievances. - This installs the module crm_claim."""), + help='Allows you to track your customers/suppliers claims and grievances.\n' + 'This installs the module crm_claim.'), 'module_crm_helpdesk': fields.boolean("Manage Helpdesk and Support", help="""Allows you to communicate with Customer, process Customer query, and provide better help and support. This installs the module crm_helpdesk."""), 'group_multi_salesteams': fields.boolean("Organize Sales activities into multiple Sales Teams", diff --git a/addons/hr_recruitment/res_config.py b/addons/hr_recruitment/res_config.py index ac53bf74ff3..a15ae541e7f 100644 --- a/addons/hr_recruitment/res_config.py +++ b/addons/hr_recruitment/res_config.py @@ -27,11 +27,11 @@ class hr_applicant_settings(osv.osv_memory): _columns = { 'module_document_ftp': fields.boolean('Allow the automatic indexation of resumes', - help="""Manage your CV's and motivation letter related to all applicants. - This installs the module document_ftp. This will install the knowledge management module in order to allow you to search using specific keywords through the content of all documents (PDF, .DOCx...)"""), + help='Manage your CV\'s and motivation letter related to all applicants.\n' + 'This installs the module document_ftp. This will install the knowledge management module in order to allow you to search using specific keywords through the content of all documents (PDF, .DOCx...)'), 'fetchmail_applicants': fields.boolean('Create applicants from an incoming email account', fetchmail_model='hr.applicant', fetchmail_name='Incoming HR Applications', - help ="""Allow applicants to send their job application to an email address (jobs@mycompany.com), - and create automatically application documents in the system."""), + help ='Allow applicants to send their job application to an email address (jobs@mycompany.com), ' + 'and create automatically application documents in the system.'), } diff --git a/addons/hr_timesheet_sheet/res_config.py b/addons/hr_timesheet_sheet/res_config.py index e767b4da8fa..f3ef5b8496a 100644 --- a/addons/hr_timesheet_sheet/res_config.py +++ b/addons/hr_timesheet_sheet/res_config.py @@ -28,8 +28,8 @@ class hr_timesheet_settings(osv.osv_memory): 'timesheet_range': fields.selection([('day','Day'),('week','Week'),('month','Month')], 'Validate timesheets every', help="Periodicity on which you validate your timesheets."), 'timesheet_max_difference': fields.float('Allow a difference of time between timesheets and attendances of (in hours)', - help="""Allowed difference in hours between the sign in/out and the timesheet - computation for one sheet. Set this to 0 if you do not want any control."""), + help='Allowed difference in hours between the sign in/out and the timesheet ' + 'computation for one sheet. Set this to 0 if you do not want any control.'), } def get_default_timesheet(self, cr, uid, fields, context=None): diff --git a/addons/knowledge/res_config.py b/addons/knowledge/res_config.py index fddbb5ebdc3..fd033772133 100644 --- a/addons/knowledge/res_config.py +++ b/addons/knowledge/res_config.py @@ -28,15 +28,15 @@ class knowledge_config_settings(osv.osv_memory): 'module_document_page': fields.boolean('Create static web pages', help="""This installs the module document_page."""), 'module_document': fields.boolean('Manage documents', - help="""This is a complete document management system, with: user authentication, - full document search (but pptx and docx are not supported), and a document dashboard. - This installs the module document."""), + help='This is a complete document management system, with: user authentication, ' + 'full document search (but pptx and docx are not supported), and a document dashboard.\n' + 'This installs the module document.'), 'module_document_ftp': fields.boolean('Share repositories (FTP)', - help="""Access your documents in OpenERP through an FTP interface. - This installs the module document_ftp."""), + help='Access your documents in OpenERP through an FTP interface.\n' + 'This installs the module document_ftp.'), 'module_document_webdav': fields.boolean('Share repositories (WebDAV)', - help="""Access your documents in OpenERP through WebDAV. - This installs the module document_webdav."""), + help='Access your documents in OpenERP through WebDAV.\n' + 'This installs the module document_webdav.'), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/marketing/res_config.py b/addons/marketing/res_config.py index 3c161c4d0d6..3d8eaf71fe6 100644 --- a/addons/marketing/res_config.py +++ b/addons/marketing/res_config.py @@ -26,15 +26,15 @@ class marketing_config_settings(osv.osv_memory): _inherit = 'res.config.settings' _columns = { 'module_marketing_campaign': fields.boolean('Marketing campaigns', - help="""Provides leads automation through marketing campaigns. - Campaigns can in fact be defined on any resource, not just CRM leads. - This installs the module marketing_campaign."""), + help='Provides leads automation through marketing campaigns. ' + 'Campaigns can in fact be defined on any resource, not just CRM leads.\n' + 'This installs the module marketing_campaign.'), 'module_marketing_campaign_crm_demo': fields.boolean('Demo data for marketing campaigns', - help="""Installs demo data like leads, campaigns and segments for Marketing Campaigns. - This installs the module marketing_campaign_crm_demo."""), + help='Installs demo data like leads, campaigns and segments for Marketing Campaigns.\n' + 'This installs the module marketing_campaign_crm_demo.'), 'module_crm_profiling': fields.boolean('Track customer profile to focus your campaigns', - help="""Allows users to perform segmentation within partners. - This installs the module crm_profiling."""), + help='Allows users to perform segmentation within partners.\n' + 'This installs the module crm_profiling.'), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/res_config.py b/addons/mrp/res_config.py index 22a14addcd1..7f54999e15b 100644 --- a/addons/mrp/res_config.py +++ b/addons/mrp/res_config.py @@ -28,48 +28,48 @@ class mrp_config_settings(osv.osv_memory): _columns = { 'module_mrp_repair': fields.boolean("Manage repairs of products ", - help="""Allows to manage all product repairs. - * Add/remove products in the reparation - * Impact for stocks - * Invoicing (products and/or services) - * Warranty concept - * Repair quotation report - * Notes for the technician and for the final customer. - This installs the module mrp_repair."""), + help='Allows to manage all product repairs.\n' + '* Add/remove products in the reparation\n' + '* Impact for stocks\n' + '* Invoicing (products and/or services)\n' + '* Warranty concept\n' + '* Repair quotation report\n' + '* Notes for the technician and for the final customer.\n' + 'This installs the module mrp_repair.'), 'module_mrp_operations': fields.boolean("Allow detailed planning of work order", - help="""This allows to add state, date_start,date_stop in production order operation lines (in the "Work Centers" tab). - This installs the module mrp_operations."""), + help='This allows to add state, date_start,date_stop in production order operation lines (in the "Work Centers" tab).\n' + 'This installs the module mrp_operations.'), 'module_mrp_byproduct': fields.boolean("Produce several products from one manufacturing order", - help="""You can configure by-products in the bill of material. - Without this module: A + B + C -> D. - With this module: A + B + C -> D + E. - This installs the module mrp_byproduct."""), + help='You can configure by-products in the bill of material.\n' + 'Without this module: A + B + C -> D.\n' + 'With this module: A + B + C -> D + E.\n' + 'This installs the module mrp_byproduct.'), 'module_mrp_jit': fields.boolean("Generate procurement in real time", - help="""This allows Just In Time computation of procurement orders. - All procurement orders will be processed immediately, which could in some - cases entail a small performance impact. - This installs the module mrp_jit."""), + help='This allows Just In Time computation of procurement orders.\n' + 'All procurement orders will be processed immediately, which could in some ' + 'cases entail a small performance impact.\n' + 'This installs the module mrp_jit.'), 'module_stock_no_autopicking': fields.boolean("Manage manual picking to fulfill manufacturing orders ", - help="""This module allows an intermediate picking process to provide raw materials to production orders. - For example to manage production made by your suppliers (sub-contracting). - To achieve this, set the assembled product which is sub-contracted to "No Auto-Picking" - and put the location of the supplier in the routing of the assembly operation. - This installs the module stock_no_autopicking."""), + help='This module allows an intermediate picking process to provide raw materials to production orders.\n' + 'For example to manage production made by your suppliers (sub-contracting).\n' + 'To achieve this, set the assembled product which is sub-contracted to "No Auto-Picking" ' + 'and put the location of the supplier in the routing of the assembly operation.\n' + 'This installs the module stock_no_autopicking.'), 'group_mrp_routings': fields.boolean("Manage routings and work orders ", implied_group='mrp.group_mrp_routings', - help="""Routings allow you to create and manage the manufacturing operations that should be followed - within your work centers in order to produce a product. They are attached to bills of materials - that will define the required raw materials."""), + help='Routings allow you to create and manage the manufacturing operations that should be followed ' + 'within your work centers in order to produce a product. They are attached to bills of materials ' + 'that will define the required raw materials.'), 'group_mrp_properties': fields.boolean("Allow several bill of materials per products using properties", implied_group='product.group_mrp_properties', help="""The selection of the right Bill of Material to use will depend on the properties specified on the sales order and the Bill of Material."""), 'module_product_manufacturer': fields.boolean("Define manufacturers on products ", - help="""This allows you to define the following for a product: - * Manufacturer - * Manufacturer Product Name - * Manufacturer Product Code - * Product Attributes. - This installs the module product_manufacturer."""), + help='This allows you to define the following for a product:\n' + '* Manufacturer\n' + '* Manufacturer Product Name\n' + '* Manufacturer Product Code\n' + '* Product Attributes.\n' + 'This installs the module product_manufacturer.'), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/res_config.py b/addons/project/res_config.py index ddf98582ef3..a8b8af3b90b 100644 --- a/addons/project/res_config.py +++ b/addons/project/res_config.py @@ -28,30 +28,30 @@ class project_configuration(osv.osv_memory): _columns = { 'module_project_mrp': fields.boolean('Generate tasks from sale orders', - help ="""This feature automatically creates project tasks from service products in sale orders. - More precisely, tasks are created for procurement lines with product of type 'Service', - procurement method 'Make to Order', and supply method 'Manufacture'. - This installs the module project_mrp."""), + help ='This feature automatically creates project tasks from service products in sale orders. ' + 'More precisely, tasks are created for procurement lines with product of type \'Service\', ' + 'procurement method \'Make to Order\', and supply method \'Manufacture\'.\n' + 'This installs the module project_mrp.'), 'module_pad': fields.boolean("Use integrated collaborative note pads on task", - help="""Lets the company customize which Pad installation should be used to link to new pads - (for example: http://ietherpad.com/). - This installs the module pad."""), + help='Lets the company customize which Pad installation should be used to link to new pads ' + '(for example: http://ietherpad.com/).\n' + 'This installs the module pad.'), 'module_project_timesheet': fields.boolean("Record timesheet lines per tasks", - help="""This allows you to transfer the entries under tasks defined for Project Management to - the timesheet line entries for particular date and user, with the effect of creating, - editing and deleting either ways. - This installs the module project_timesheet."""), + help='This allows you to transfer the entries under tasks defined for Project Management to ' + 'the timesheet line entries for particular date and user, with the effect of creating, ' + 'editing and deleting either ways.\n' + 'This installs the module project_timesheet.'), 'module_project_long_term': fields.boolean("Manage resources planning on gantt view", - help="""A long term project management module that tracks planning, scheduling, and resource allocation. - This installs the module project_long_term."""), + help='A long term project management module that tracks planning, scheduling, and resource allocation.\n' + 'This installs the module project_long_term.'), 'module_project_issue': fields.boolean("Track issues and bugs", - help="""Provides management of issues/bugs in projects. - This installs the module project_issue."""), + help='Provides management of issues/bugs in projects.\n' + 'This installs the module project_issue.'), 'time_unit': fields.many2one('product.uom', 'Working time unit', required=True, help="""This will set the unit of measure used in projects and tasks."""), 'module_project_issue_sheet': fields.boolean("Invoice working time on issues", - help="""Provides timesheet support for the issues/bugs management in project. - This installs the module project_issue_sheet."""), + help='Provides timesheet support for the issues/bugs management in project.\n' + 'This installs the module project_issue_sheet.'), 'group_tasks_work_on_tasks': fields.boolean("Log work activities on tasks", implied_group='project.group_tasks_work_on_tasks', help="Allows you to compute work on tasks."), diff --git a/addons/purchase/res_config.py b/addons/purchase/res_config.py index f5f2dfcdda5..930ee5f9f29 100644 --- a/addons/purchase/res_config.py +++ b/addons/purchase/res_config.py @@ -34,8 +34,8 @@ class purchase_config_settings(osv.osv_memory): ], 'Default invoicing control method', required=True, default_model='purchase.order'), 'group_purchase_pricelist':fields.boolean("Manage pricelist per supplier", implied_group='product.group_purchase_pricelist', - help="""Allows to manage different prices based on rules per category of Supplier. - Example: 10% for retailers, promotion of 5 EUR on this product, etc."""), + help='Allows to manage different prices based on rules per category of Supplier.\n' + 'Example: 10% for retailers, promotion of 5 EUR on this product, etc.'), 'group_uom':fields.boolean("Manage different units of measure for products", implied_group='product.group_uom', help="""Allows you to select and maintain different units of measure for products."""), @@ -43,19 +43,19 @@ class purchase_config_settings(osv.osv_memory): implied_group='product.group_costing_method', help="""Allows you to compute product cost price based on average cost."""), 'module_warning': fields.boolean("Alerts by products or supplier", - help="""Allow to configure notification on products and trigger them when a user wants to purchase a given product or a given supplier. -Example: Product: this product is deprecated, do not purchase more than 5. - Supplier: don't forget to ask for an express delivery."""), + help='Allow to configure notification on products and trigger them when a user wants to purchase a given product or a given supplier.\n' + 'Example: Product: this product is deprecated, do not purchase more than 5.\n' + 'Supplier: don\'t forget to ask for an express delivery.'), 'module_purchase_double_validation': fields.boolean("Force two levels of approvals", - help="""Provide a double validation mechanism for purchases exceeding minimum amount. - This installs the module purchase_double_validation."""), + help='Provide a double validation mechanism for purchases exceeding minimum amount.\n' + 'This installs the module purchase_double_validation.'), 'module_purchase_requisition': fields.boolean("Manage purchase requisitions", - help="""Purchase Requisitions are used when you want to request quotations from several suppliers for a given set of products. - You can configure per product if you directly do a Request for Quotation - to one supplier or if you want a purchase requisition to negotiate with several suppliers."""), + help='Purchase Requisitions are used when you want to request quotations from several suppliers for a given set of products.\n' + 'You can configure per product if you directly do a Request for Quotation ' + 'to one supplier or if you want a purchase requisition to negotiate with several suppliers.'), 'module_purchase_analytic_plans': fields.boolean('Use multiple analytic accounts on purchase orders', - help ="""Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans. - This installs the module purchase_analytic_plans."""), + help ='Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans.\n' + 'This installs the module purchase_analytic_plans.'), 'group_analytic_account_for_purchases': fields.boolean('Analytic accounting for purchases', implied_group='purchase.group_analytic_accounting', help="Allows you to specify an analytic account on purchase orders."), @@ -77,8 +77,8 @@ class account_config_settings(osv.osv_memory): _inherit = 'account.config.settings' _columns = { 'module_purchase_analytic_plans': fields.boolean('Use multiple analytic accounts on orders', - help ="""Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans. - This installs the module purchase_analytic_plans."""), + help ='Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans.\n' + 'This installs the module purchase_analytic_plans.'), 'group_analytic_account_for_purchases': fields.boolean('Analytic accounting for purchases', implied_group='purchase.group_analytic_accounting', help="Allows you to specify an analytic account on purchase orders."), diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index bfbaa5f0a6f..d570dfc8183 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -34,15 +34,15 @@ class sale_configuration(osv.osv_memory): implied_group='sale.group_invoice_so_lines', help="To allow your salesman to make invoices for sales order lines using the menu 'Lines to Invoice'."), 'timesheet': fields.boolean('Prepare invoices based on timesheets', - help = """For modifying account analytic view to show important data to project manager of services companies. - You can also view the report of account analytic summary user-wise as well as month wise. - This installs the module account_analytic_analysis."""), + help = 'For modifying account analytic view to show important data to project manager of services companies.' + 'You can also view the report of account analytic summary user-wise as well as month wise.\n' + 'This installs the module account_analytic_analysis.'), 'module_account_analytic_analysis': fields.boolean('Use contracts management', - help = """Allows to define your customer contracts conditions: invoicing - method (fixed price, on timesheet, advance invoice), the exact pricing - (650€/day for a developer), the duration (one year support contract). - You will be able to follow the progress of the contract and invoice automatically. - It installs the account_analytic_analysis module."""), + help = 'Allows to define your customer contracts conditions: invoicing ' + 'method (fixed price, on timesheet, advance invoice), the exact pricing ' + '(650€/day for a developer), the duration (one year support contract).\n' + 'You will be able to follow the progress of the contract and invoice automatically.\n' + 'It installs the account_analytic_analysis module.'), 'time_unit': fields.many2one('product.uom', 'The default working time unit for services is'), 'group_sale_pricelist':fields.boolean("Use pricelists to adapt your price per customers", implied_group='product.group_sale_pricelist', @@ -58,22 +58,22 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""), implied_group='product.group_product_variant', help="""Allow to manage several variants per product. As an example, if you sell T-Shirts, for the same "Linux T-Shirt", you may have variants on sizes or colors; S, M, L, XL, XXL."""), 'module_warning': fields.boolean("Allow configuring alerts by customer or products", - help="""Allow to configure notification on products and trigger them when a user wants to sell a given product or a given customer. -Example: Product: this product is deprecated, do not purchase more than 5. - Supplier: don't forget to ask for an express delivery."""), + help='Allow to configure notification on products and trigger them when a user wants to sell a given product or a given customer.\n' + 'Example: Product: this product is deprecated, do not purchase more than 5.\n' + 'Supplier: don\'t forget to ask for an express delivery.'), 'module_sale_margin': fields.boolean("Display margins on sales orders", - help="""This adds the 'Margin' on sales order. - This gives the profitability by calculating the difference between the Unit Price and Cost Price. - This installs the module sale_margin."""), + help='This adds the \'Margin\' on sales order.\n' + 'This gives the profitability by calculating the difference between the Unit Price and Cost Price.\n' + 'This installs the module sale_margin.'), 'module_sale_journal': fields.boolean("Allow batch invoicing of delivery orders through journals", - help="""Allows you to categorize your sales and deliveries (picking lists) between different journals, - and perform batch operations on journals. - This installs the module sale_journal."""), + help='Allows you to categorize your sales and deliveries (picking lists) between different journals, ' + 'and perform batch operations on journals.\n' + 'This installs the module sale_journal.'), 'module_analytic_user_function': fields.boolean("One employee can have different roles per contract", - help="""Allows you to define what is the default function of a specific user on a given account. - This is mostly used when a user encodes his timesheet. The values are retrieved and the fields are auto-filled. - But the possibility to change these values is still available. - This installs the module analytic_user_function."""), + help='Allows you to define what is the default function of a specific user on a given account.\n' + 'This is mostly used when a user encodes his timesheet. The values are retrieved and the fields are auto-filled. ' + 'But the possibility to change these values is still available.\n' + 'This installs the module analytic_user_function.'), 'module_project': fields.boolean("Project"), 'module_sale_stock': fields.boolean("Trigger delivery orders automatically from sales orders", help="""Allows you to Make Quotation, Sale Order using different Order policy and Manage Related Stock. diff --git a/addons/sale_stock/res_config.py b/addons/sale_stock/res_config.py index 4c3b92f1d33..ae81989aa52 100644 --- a/addons/sale_stock/res_config.py +++ b/addons/sale_stock/res_config.py @@ -33,10 +33,10 @@ class sale_configuration(osv.osv_memory): implied_group='sale_stock.group_invoice_deli_orders', help="To allow your salesman to make invoices for Delivery Orders using the menu 'Deliveries to Invoice'."), 'task_work': fields.boolean("Prepare invoices based on task's activities", - help="""Lets you transfer the entries under tasks defined for Project Management to - the Timesheet line entries for particular date and particular user with the effect of creating, editing and deleting either ways - and to automatically creates project tasks from procurement lines. - This installs the modules project_timesheet and project_mrp."""), + help='Lets you transfer the entries under tasks defined for Project Management to ' + 'the Timesheet line entries for particular date and particular user with the effect of creating, editing and deleting either ways ' + 'and to automatically creates project tasks from procurement lines.\n' + 'This installs the modules project_timesheet and project_mrp.'), 'default_order_policy': fields.selection( [('manual', 'Invoice based on sales orders'), ('picking', 'Invoice based on deliveries')], 'The default invoicing method is', default_model='sale.order', diff --git a/addons/stock/res_config.py b/addons/stock/res_config.py index d0b0563875c..4da23389214 100644 --- a/addons/stock/res_config.py +++ b/addons/stock/res_config.py @@ -27,12 +27,12 @@ class stock_config_settings(osv.osv_memory): _columns = { 'module_claim_from_delivery': fields.boolean("Allow claim on deliveries", - help="""Adds a Claim link to the delivery order. - This installs the module claim_from_delivery."""), + help='Adds a Claim link to the delivery order.\n' + 'This installs the module claim_from_delivery.'), 'module_stock_invoice_directly': fields.boolean("Create and open the invoice when the user finish a delivery order", - help="""This allows to automatically launch the invoicing wizard if the delivery is - to be invoiced when you send or deliver goods. - This installs the module stock_invoice_directly."""), + help='This allows to automatically launch the invoicing wizard if the delivery is ' + 'to be invoiced when you send or deliver goods.\n' + 'This installs the module stock_invoice_directly.'), 'module_product_expiry': fields.boolean("Expiry date on serial numbers", help="""Track different dates on products and serial numbers. The following dates can be tracked: @@ -42,17 +42,17 @@ The following dates can be tracked: - alert date. This installs the module product_expiry."""), 'module_stock_location': fields.boolean("Create push/pull logistic rules", - help="""Provide push and pull inventory flows. Typical uses of this feature are: - manage product manufacturing chains, manage default locations per product, - define routes within your warehouse according to business needs, etc. - This installs the module stock_location."""), + help='Provide push and pull inventory flows. Typical uses of this feature are: ' + 'manage product manufacturing chains, manage default locations per product, ' + 'define routes within your warehouse according to business needs, etc.\n' + 'This installs the module stock_location.'), 'group_uom': fields.boolean("Manage different units of measure for products", implied_group='product.group_uom', help="""Allows you to select and maintain different units of measure for products."""), 'group_uos': fields.boolean("Invoice products in a different unit of measure than the sales order", implied_group='product.group_uos', - help="""Allows you to sell units of a product, but invoice based on a different unit of measure. - For instance, you can sell pieces of meat that you invoice based on their weight."""), + help='Allows you to sell units of a product, but invoice based on a different unit of measure.\n' + 'For instance, you can sell pieces of meat that you invoice based on their weight.'), 'group_stock_packaging': fields.boolean("Allow to define several packaging methods on products", implied_group='product.group_stock_packaging', help="""Allows you to create and manage your packaging dimensions and types you want to be maintained in your system."""), @@ -67,8 +67,8 @@ This installs the module product_expiry."""), help="""Allows to configure inventory valuations on products and product categories."""), 'group_stock_multiple_locations': fields.boolean("Manage multiple locations and warehouses", implied_group='stock.group_locations', - help="""This allows to configure and use multiple stock locations and warehouses, - instead of having a single default one."""), + help='This allows to configure and use multiple stock locations and warehouses, ' + 'instead of having a single default one.'), 'decimal_precision': fields.integer('Decimal precision on weight', help="As an example, a decimal precision of 2 will allow weights like: 9.99 kg, whereas a decimal precision of 4 will allow weights like: 0.0231 kg."), } From c0a72b34914436bcee627d829ac7e89f3cac87f9 Mon Sep 17 00:00:00 2001 From: Darshan Kalola Date: Thu, 25 Jul 2013 11:44:42 +0530 Subject: [PATCH 02/59] [IMP]improve help of sales and General-setting menus in setting/configuration bzr revid: darshankalola@gmail.com-20130725061442-kchwc3eattox148j --- addons/base_setup/res_config.py | 4 ++-- addons/sale/res_config.py | 4 ++-- addons/sale_stock/res_config.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/base_setup/res_config.py b/addons/base_setup/res_config.py index 82828e5f30d..c7f6d4245ec 100644 --- a/addons/base_setup/res_config.py +++ b/addons/base_setup/res_config.py @@ -26,8 +26,8 @@ class base_config_settings(osv.osv_memory): _inherit = 'res.config.settings' _columns = { 'module_multi_company': fields.boolean('Manage multiple companies', - help="""Work in multi-company environments, with appropriate security access between companies. - This installs the module multi_company."""), + help='Work in multi-company environments, with appropriate security access between companies.\n' + 'This installs the module multi_company.'), 'module_share': fields.boolean('Allow documents sharing', help="""Share or embbed any screen of openerp."""), 'module_portal': fields.boolean('Activate the customer portal', diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index d570dfc8183..fe81a7cc6d8 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -76,8 +76,8 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""), 'This installs the module analytic_user_function.'), 'module_project': fields.boolean("Project"), 'module_sale_stock': fields.boolean("Trigger delivery orders automatically from sales orders", - help="""Allows you to Make Quotation, Sale Order using different Order policy and Manage Related Stock. - This installs the module sale_stock."""), + help='Allows you to Make Quotation, Sale Order using different Order policy and Manage Related Stock.\n' + 'This installs the module sale_stock.'), } def default_get(self, cr, uid, fields, context=None): diff --git a/addons/sale_stock/res_config.py b/addons/sale_stock/res_config.py index ae81989aa52..76cfbcb6fd3 100644 --- a/addons/sale_stock/res_config.py +++ b/addons/sale_stock/res_config.py @@ -42,9 +42,9 @@ class sale_configuration(osv.osv_memory): 'The default invoicing method is', default_model='sale.order', help="You can generate invoices based on sales orders or based on shippings."), 'module_delivery': fields.boolean('Allow adding shipping costs', - help ="""Allows you to add delivery methods in sales orders and delivery orders. - You can define your own carrier and delivery grids for prices. - This installs the module delivery."""), + help ='Allows you to add delivery methods in sales orders and delivery orders.\n' + 'You can define your own carrier and delivery grids for prices.\n' + 'This installs the module delivery.'), 'default_picking_policy' : fields.boolean("Deliver all at once when all products are available.", help = "Sales order by default will be configured to deliver all products at once instead of delivering each product when it is available. This may have an impact on the shipping price."), 'group_mrp_properties': fields.boolean('Product properties on order lines', From 497ba7dab96a15c965e1e2824d9111772a98210b Mon Sep 17 00:00:00 2001 From: "Mansi Kariya (OpenERP Trainee)" Date: Tue, 30 Jul 2013 17:17:45 +0530 Subject: [PATCH 03/59] [IMP] purchases Configuration menus location and name changed bzr revid: mansi.mk.179@gmail.com-20130730114745-o2xzb0h63ze29stq --- addons/purchase/purchase_view.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index dffe1ed54ff..0463527461e 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -14,9 +14,6 @@ - Pricelist Versions @@ -36,14 +33,18 @@

+ + + - From d1e7ad9be6f01644567df0fb8d0e68e6c40aff5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 6 Aug 2013 17:10:18 +0200 Subject: [PATCH 04/59] [IMP] tools: added a regex for bounce email addresses bzr revid: tde@openerp.com-20130806151018-0uom07dbr8b7ycb3 --- openerp/tools/mail.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py index 5970ce47040..36a4c1610c4 100644 --- a/openerp/tools/mail.py +++ b/openerp/tools/mail.py @@ -297,6 +297,11 @@ command_re = re.compile("^Set-([a-z]+) *: *(.+)$", re.I + re.UNICODE) # group(1) = the record ID ; group(2) = the model (if any) ; group(3) = the domain reference_re = re.compile("<.*-open(?:object|erp)-(\\d+)(?:-([\w.]+))?.*@(.*)>", re.UNICODE) +# Bounce regex +# Typical form of bounce is bounce-128-crm.lead-34@domain +# group(1) = the mail ID; group(2) = the model (if any); group(3) = the record ID +bounce_re = re.compile("[\w]+-(\d+)-?([\w.]+)?-?(\d+)?", re.UNICODE) + def generate_tracking_message_id(res_id): """Returns a string that can be used in the Message-ID RFC822 header field From 38a534dee0bf15a56a97874a01172cb67cd6b94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 6 Aug 2013 17:11:43 +0200 Subject: [PATCH 05/59] [IMP] mail: first implementation of tracking and bounce management. Added 2 fields on mail_mail to count read/bounce. Added bounce alias bounce-mail_id-model-res_id. Added message_receive_bounce method that try to incremetn message_bounce field. bzr revid: tde@openerp.com-20130806151143-7dw6xlj8n7mh0nqe --- addons/crm/crm_lead.py | 2 + addons/crm/crm_lead_view.xml | 1 + addons/mail/controllers/main.py | 21 ++++++--- addons/mail/data/mail_data.xml | 6 +++ addons/mail/mail_mail.py | 83 ++++++++++++++++++++++++--------- addons/mail/mail_mail_view.xml | 40 ++++++++++------ addons/mail/mail_thread.py | 28 +++++++++++ 7 files changed, 136 insertions(+), 45 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index c0f003f9792..52987de00e1 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -273,6 +273,8 @@ class crm_lead(format_address, osv.osv): selection=crm.AVAILABLE_STATES, string="Status", readonly=True, help='The Status is set to \'Draft\', when a case is created. If the case is in progress the Status is set to \'Open\'. When the case is over, the Status is set to \'Done\'. If the case needs to be reviewed then the Status is set to \'Pending\'.'), + # Messaging and marketing + 'message_bounce': fields.integer('Bounce'), # Only used for type opportunity 'probability': fields.float('Success Rate (%)',group_operator="avg"), 'planned_revenue': fields.float('Expected Revenue', track_visibility='always'), diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index aa5aac76b9d..113355eea83 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -182,6 +182,7 @@ + diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index ef3a60987d6..27373c34add 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -1,17 +1,17 @@ import base64 +import psycopg2 import openerp from openerp import SUPERUSER_ID -import openerp.addons.web.http as oeweb +import openerp.addons.web.http as http from openerp.addons.web.controllers.main import content_disposition +from openerp.addons.web.http import request -#---------------------------------------------------------- -# Controller -#---------------------------------------------------------- -class MailController(oeweb.Controller): + +class MailController(http.Controller): _cp_path = '/mail' - @oeweb.httprequest + @http.httprequest def download_attachment(self, req, model, id, method, attachment_id, **kw): Model = req.session.model(model) res = getattr(Model, method)(int(id), int(attachment_id)) @@ -24,7 +24,7 @@ class MailController(oeweb.Controller): ('Content-Disposition', content_disposition(filename, req))]) return req.not_found() - @oeweb.jsonrequest + @http.jsonrequest def receive(self, req): """ End-point to receive mail from an external SMTP server. """ dbs = req.jsonrequest.get('databases') @@ -38,3 +38,10 @@ class MailController(oeweb.Controller): except psycopg2.Error: pass return True + + @http.route('/mail/track//blank.gif', type='http', auth='admin') + def track_read_email(self, mail_id): + """ Email tracking. """ + mail_mail = request.registry.get('mail.mail') + mail_mail.set_opened(request.cr, request.uid, [mail_id]) + return False diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index 4e935e4aa88..8ba92a8205c 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -46,6 +46,12 @@ catchall + + + mail.bounce.alias + bounce + + Discussions diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index bf76216e7e4..5548608aeeb 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -61,15 +61,16 @@ class mail_mail(osv.Model): # Auto-detected based on create() - if 'mail_message_id' was passed then this mail is a notification # and during unlink() we will not cascade delete the parent and its attachments 'notification': fields.boolean('Is Notification', - help='Mail has been created to notify people of an existing mail.message') + help='Mail has been created to notify people of an existing mail.message'), + # Bounce and tracking + 'opened': fields.integer( + 'Opened', + help='Number of times this email has been seen, using the OpenERP tracking.'), + 'replied': fields.integer( + 'Reply Received', + help='If checked, a reply to this email has been received.'), } - def _get_default_from(self, cr, uid, context=None): - """ Kept for compatibility - TDE TODO: remove me in 8.0 - """ - return self.pool['mail.message']._get_default_from(cr, uid, context=context) - _defaults = { 'state': 'outgoing', } @@ -158,6 +159,18 @@ class mail_mail(osv.Model): def cancel(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'cancel'}, context=context) + def set_opened(self, cr, uid, ids, context=None): + """ Increment opened counter """ + for mail in self.browse(cr, uid, ids, context=context): + self.write(cr, uid, [mail.id], {'opened': (mail.opened + 1)}, context=context) + return True + + def set_replied(self, cr, uid, ids, context=None): + """ Increment replied counter """ + for mail in self.browse(cr, uid, ids, context=context): + self.write(cr, uid, [mail.id], {'replied': (mail.replied + 1)}, context=context) + return True + def process_email_queue(self, cr, uid, ids=None, context=None): """Send immediately queued messages, committing after each message is sent - this is not transactional and should @@ -226,13 +239,22 @@ class mail_mail(osv.Model): } if mail.notification: fragment.update({ - 'message_id': mail.mail_message_id.id, - }) + 'message_id': mail.mail_message_id.id, + }) url = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment))) return _("""Access your messages and documents in OpenERP""") % url else: return None + def _get_tracking_url(self, cr, uid, mail, partner=None, context=None): + if not mail.auto_delete: + base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + track_url = urljoin(base_url, 'mail/track/%d/blank.gif' % mail.id) + print base_url, track_url + return '' % track_url + else: + return '' + def send_get_mail_subject(self, cr, uid, mail, force=False, partner=None, context=None): """ If subject is void and record_name defined: ' posted on ' @@ -257,8 +279,11 @@ class mail_mail(osv.Model): # generate footer link = self._get_partner_access_link(cr, uid, mail, partner, context=context) + tracking_url = self._get_tracking_url(cr, uid, mail, partner, context=context) if link: body = tools.append_content_to_html(body, link, plaintext=False, container_tag='div') + if tracking_url: + body = tools.append_content_to_html(body, tracking_url, plaintext=False, container_tag='div') return body def send_get_email_dict(self, cr, uid, mail, partner=None, context=None): @@ -319,25 +344,37 @@ class mail_mail(osv.Model): email_list.append(self.send_get_email_dict(cr, uid, mail, context=context)) for partner in mail.recipient_ids: email_list.append(self.send_get_email_dict(cr, uid, mail, partner=partner, context=context)) + # headers + headers = {} + bounce_alias = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.bounce.alias", context=context) + catchall_domain = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.catchall.domain", context=context) + if bounce_alias and catchall_domain: + if mail.model and mail.res_id: + headers['Return-Path'] = '%s-%d-%s-%d@%s' % (bounce_alias, mail.id, mail.model, mail.res_id, catchall_domain) + else: + headers['Return-Path'] = '%s-%d@%s' % (bounce_alias, mail.id, catchall_domain) # build an RFC2822 email.message.Message object and send it without queuing + res = None for email in email_list: msg = ir_mail_server.build_email( - email_from = mail.email_from, - email_to = email.get('email_to'), - subject = email.get('subject'), - body = email.get('body'), - body_alternative = email.get('body_alternative'), - email_cc = tools.email_split(mail.email_cc), - reply_to = mail.reply_to, - attachments = attachments, - message_id = mail.message_id, - references = mail.references, - object_id = mail.res_id and ('%s-%s' % (mail.res_id, mail.model)), - subtype = 'html', - subtype_alternative = 'plain') + email_from=mail.email_from, + email_to=email.get('email_to'), + subject=email.get('subject'), + body=email.get('body'), + body_alternative=email.get('body_alternative'), + email_cc=tools.email_split(mail.email_cc), + reply_to=mail.reply_to, + attachments=attachments, + message_id=mail.message_id, + references=mail.references, + object_id=mail.res_id and ('%s-%s' % (mail.res_id, mail.model)), + subtype='html', + subtype_alternative='plain', + headers=headers) res = ir_mail_server.send_email(cr, uid, msg, - mail_server_id=mail.mail_server_id.id, context=context) + mail_server_id=mail.mail_server_id.id, + context=context) if res: mail.write({'state': 'sent', 'message_id': res}) mail_sent = True diff --git a/addons/mail/mail_mail_view.xml b/addons/mail/mail_mail_view.xml index f3728d4653a..3901a192225 100644 --- a/addons/mail/mail_mail_view.xml +++ b/addons/mail/mail_mail_view.xml @@ -14,7 +14,7 @@ - - - mail.mass_mailing.segment.tree - mail.mass_mailing.segment + + + mail.mass_mailing.tree + mail.mass_mailing 10 - + @@ -128,11 +128,11 @@ - - mail.mass_mailing.segment.form - mail.mass_mailing.segment + + mail.mass_mailing.form + mail.mass_mailing -
+ @@ -150,12 +150,12 @@ - - mail.mass_mailing.segment.form - mail.mass_mailing.segment + + mail.mass_mailing.form + mail.mass_mailing 18 - + @@ -173,9 +173,9 @@ - - mail.mass_mailing.segment.kanban - mail.mass_mailing.segment + + mail.mass_mailing.kanban + mail.mass_mailing @@ -229,9 +229,9 @@ - - Mass Mailing Segments - mail.mass_mailing.segment + + Mass Mailings + mail.mass_mailing form kanban,tree,form @@ -245,9 +245,9 @@ - + action="action_view_mass_mailings"/> diff --git a/addons/mass_mailing/security/ir.model.access.csv b/addons/mass_mailing/security/ir.model.access.csv index 54f3413e9f1..6931ab0265b 100644 --- a/addons/mass_mailing/security/ir.model.access.csv +++ b/addons/mass_mailing/security/ir.model.access.csv @@ -1,5 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_mass_mailing_campaign,mail.mass_mailing.campaign,model_mail_mass_mailing_campaign,,1,1,1,0 access_mass_mailing_campaign_system,mail.mass_mailing.campaign.system,model_mail_mass_mailing_campaign,base.group_system,1,1,1,1 -access_mass_mailing_segment,mail.mass_mailing.segment,model_mail_mass_mailing_segment,,1,1,1,0 -access_mass_mailing_segment_system,mail.mass_mailing.segment.system,model_mail_mass_mailing_segment,base.group_system,1,1,1,1 \ No newline at end of file +access_mass_mailing,mail.mass_mailing,model_mail_mass_mailing,,1,1,1,0 +access_mass_mailing_system,mail.mass_mailing.system,model_mail_mass_mailing,base.group_system,1,1,1,1 +access_mail_mail_statistics,mail.mail.statistics,model_mail_mail_statistics,,1,1,1,1 \ No newline at end of file diff --git a/addons/mass_mailing/wizard/mail_compose_message.py b/addons/mass_mailing/wizard/mail_compose_message.py index 4fe858734fe..7b22bc8f4aa 100644 --- a/addons/mass_mailing/wizard/mail_compose_message.py +++ b/addons/mass_mailing/wizard/mail_compose_message.py @@ -34,8 +34,8 @@ class MailComposeMessage(osv.TransientModel): 'mass_mailing_campaign_id': fields.many2one( 'mail.mass_mailing.campaign', 'Mass mailing campaign', ), - 'mass_mailing_segment_id': fields.many2one( - 'mail.mass_mailing.segment', 'Mass mailing segment', + 'mass_mailing_id': fields.many2one( + 'mail.mass_mailing', 'Mass mailing', domain="[('mass_mailing_campaign_id', '=', mass_mailing_campaign_id)]", ), } @@ -44,18 +44,18 @@ class MailComposeMessage(osv.TransientModel): 'use_mass_mailing_campaign': False, } - def onchange_mass_mail_campaign_id(self, cr, uid, ids, mass_mailing_campaign_id, mass_mail_segment_id, context=None): - if mass_mail_segment_id: - segment = self.pool['mail.mass_mailing.segment'].browse(cr, uid, mass_mail_segment_id, context=context) - if segment.mass_mailing_campaign_id.id == mass_mailing_campaign_id: + def onchange_mass_mail_campaign_id(self, cr, uid, ids, mass_mailing_campaign_id, mass_mailing_id, context=None): + if mass_mailing_id: + mass_mailing = self.pool['mail.mass_mailing'].browse(cr, uid, mass_mailing_id, context=context) + if mass_mailing.mass_mailing_campaign_id.id == mass_mailing_campaign_id: return {} - return {'value': {'mass_mailing_segment_id': False}} + return {'value': {'mass_mailing_id': False}} def render_message_batch(self, cr, uid, wizard, res_ids, context=None): """ Override method that generated the mail content by adding the mass mailing campaign, when doing pure email mass mailing. """ res = super(MailComposeMessage, self).render_message_batch(cr, uid, wizard, res_ids, context=context) - if wizard.composition_mode == 'mass_mail' and wizard.use_mass_mailing_campaign and wizard.mass_mailing_segment_id: # TODO: which kind of mass mailing ? + if wizard.composition_mode == 'mass_mail' and wizard.use_mass_mailing_campaign and wizard.mass_mailing_id: # TODO: which kind of mass mailing ? for res_id in res_ids: - res[res_id]['mass_mailing_segment_id'] = wizard.mass_mailing_segment_id.id + res[res_id]['mass_mailing_id'] = wizard.mass_mailing_id.id return res diff --git a/addons/mass_mailing/wizard/mail_compose_message_view.xml b/addons/mass_mailing/wizard/mail_compose_message_view.xml index 9dcf57682f6..bdd4431a71d 100644 --- a/addons/mass_mailing/wizard/mail_compose_message_view.xml +++ b/addons/mass_mailing/wizard/mail_compose_message_view.xml @@ -15,16 +15,16 @@
- + 'form_view_ref': 'mass_mailing.view_mail_mass_mailing_form_readonly'}"/>
diff --git a/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.py b/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.py index ffb7c004415..927c34ab5fd 100644 --- a/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.py +++ b/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.py @@ -24,11 +24,11 @@ from openerp.osv import osv, fields from openerp.tools.translate import _ -class MailMassMailingSegmentCreate(osv.TransientModel): - """Wizard to help creating mass mailing segments for a campaign. """ +class MailMassMailingCreate(osv.TransientModel): + """Wizard to help creating mass mailing waves for a campaign. """ - _name = 'mail.mass_mailing.segment.create' - _description = 'Mass mailing segment creation' + _name = 'mail.mass_mailing.create' + _description = 'Mass mailing creation' _columns = { 'mass_mailing_campaign_id': fields.many2one( @@ -55,11 +55,11 @@ class MailMassMailingSegmentCreate(osv.TransientModel): 'email.template', 'Template', required=True, domain="[('model_id', '=', model_id)]", ), - 'segment_name': fields.char( - 'Segment name', required=True, + 'name': fields.char( + 'Name', required=True, ), - 'mass_mailing_segment_id': fields.many2one( - 'mail.mass_mailing.segment', 'Mass Mailing Segment', + 'mass_mailing_id': fields.many2one( + 'mail.mass_mailing', 'Mass Mailing', ), } @@ -80,23 +80,23 @@ class MailMassMailingSegmentCreate(osv.TransientModel): domain = False return {'value': {'domain': domain}} - def create_segment(self, cr, uid, ids, context=None): - """ Create a segment based on wizard data, and update the wizard """ + def create_mass_mailing(self, cr, uid, ids, context=None): + """ Create a mass mailing based on wizard data, and update the wizard """ for wizard in self.browse(cr, uid, ids, context=context): - segment_values = { - 'name': wizard.segment_name, + mass_mailing_values = { + 'name': wizard.name, 'mass_mailing_campaign_id': wizard.mass_mailing_campaign_id.id, 'domain': wizard.domain, 'template_id': wizard.template_id.id, } - segment_id = self.pool['mail.mass_mailing.segment'].create(cr, uid, segment_values, context=context) - self.write(cr, uid, [wizard.id], {'mass_mailing_segment_id': segment_id}, context=context) + mass_mailing_id = self.pool['mail.mass_mailing'].create(cr, uid, mass_mailing_values, context=context) + self.write(cr, uid, [wizard.id], {'mass_mailing_id': mass_mailing_id}, context=context) return True def launch_composer(self, cr, uid, ids, context=None): - """ Main wizard action: create a new segment and launch the mail.compose.message + """ Main wizard action: create a new mailing and launch the mail.compose.message email composer with wizard data. """ - self.create_segment(cr, uid, ids, context=context) + self.create_mass_mailing(cr, uid, ids, context=context) wizard = self.browse(cr, uid, ids[0], context=context) ctx = dict(context) @@ -107,7 +107,7 @@ class MailMassMailingSegmentCreate(osv.TransientModel): 'default_use_active_domain': True, 'default_active_domain': wizard.domain, 'default_mass_mailing_campaign_id': wizard.mass_mailing_campaign_id.id, - 'default_mass_mailing_segment_id': wizard.mass_mailing_segment_id.id, + 'default_mass_mailing_id': wizard.mass_mailing_id.id, }) return { 'name': _('Compose Email for Mass Mailing'), diff --git a/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.xml b/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.xml index 5d211bb9eb4..a10101e9446 100644 --- a/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.xml +++ b/addons/mass_mailing/wizard/mail_mass_mailing_create_segment.xml @@ -3,17 +3,17 @@ - - mail.mass_mailing.segment.create.form - mail.mass_mailing.segment.create + + mail.mass_mailing.create.form + mail.mass_mailing.create - +

- Please choose a mass mailing campaign that will hold the new segment. + Please choose a mass mailing campaign that will hold the new mailing.

@@ -43,23 +43,23 @@ attrs="{'invisible': [('filter_id', '=', False)]}"/>

- Please choose the name of the campaign segment. + attrs="{'invisible': ['|', ('name', '!=', False), ('template_id', '=', False)]}"> + Please choose the name of the mailing.

-