From 7699504d62f33dd0b124ff66850485add6641637 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Fri, 28 Mar 2014 15:28:35 +0530 Subject: [PATCH 01/46] [Add new sale_team module] --- addons/crm/__openerp__.py | 1 + addons/crm/crm.py | 100 +------ addons/crm/crm_case_section_view.xml | 244 +++------------ addons/crm/crm_lead.py | 13 +- addons/crm/res_config_view.xml | 11 - addons/crm/security/crm_security.xml | 14 +- addons/crm/security/ir.model.access.csv | 3 - addons/sale/__openerp__.py | 3 +- addons/sale/report/__init__.py | 3 +- .../report/sale_analysis_report.py} | 0 .../report/sale_analysis_report_view.xml} | 0 .../sales_crm_account_invoice_report.py | 0 addons/sale/sale.py | 81 ++++- addons/sale/sale_view.xml | 237 +++++++++++++++ addons/sale_crm/report/__init__.py | 4 +- addons/sale_crm/sale_crm.py | 108 +------ addons/sale_crm/sale_crm_view.xml | 278 +----------------- addons/sale_team/__init__.py | 25 ++ addons/sale_team/__openerp__.py | 36 +++ addons/sale_team/ir.model.access.csv | 5 + addons/sale_team/res_config_view.xml | 27 ++ addons/sale_team/sale_team.py | 153 ++++++++++ addons/sale_team/sale_team.xml | 232 +++++++++++++++ addons/sale_team/sale_team_config.py | 45 +++ addons/sale_team/sale_team_security.xml | 18 ++ 25 files changed, 917 insertions(+), 724 deletions(-) rename addons/{sale_crm/report/sale_report.py => sale/report/sale_analysis_report.py} (100%) rename addons/{sale_crm/report/sale_report_view.xml => sale/report/sale_analysis_report_view.xml} (100%) rename addons/{sale_crm => sale}/report/sales_crm_account_invoice_report.py (100%) create mode 100644 addons/sale_team/__init__.py create mode 100644 addons/sale_team/__openerp__.py create mode 100644 addons/sale_team/ir.model.access.csv create mode 100644 addons/sale_team/res_config_view.xml create mode 100644 addons/sale_team/sale_team.py create mode 100644 addons/sale_team/sale_team.xml create mode 100644 addons/sale_team/sale_team_config.py create mode 100644 addons/sale_team/sale_team_security.xml diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 1b0cbed7937..7d5052c1c4e 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -51,6 +51,7 @@ Dashboard for CRM will include: 'depends': [ 'base_action_rule', 'base_setup', + 'sale_team', 'process', 'mail', 'email_template', diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 20e2a6e8aff..eb10e468602 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -90,45 +90,8 @@ class crm_case_stage(osv.osv): class crm_case_section(osv.osv): """ Model for sales teams. """ - _name = "crm.case.section" - _inherits = {'mail.alias': 'alias_id'} - _inherit = "mail.thread" + _inherit = 'crm.case.section' _description = "Sales Teams" - _order = "complete_name" - # number of periods for lead/opportunities/... tracking in salesteam kanban dashboard/kanban view - _period_number = 5 - - def get_full_name(self, cr, uid, ids, field_name, arg, context=None): - return dict(self.name_get(cr, uid, ids, context=context)) - - def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None): - """ Generic method to generate data for bar chart values using SparklineBarWidget. - This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field). - - :param obj: the target model (i.e. crm_lead) - :param domain: the domain applied to the read_group - :param list read_fields: the list of fields to read in the read_group - :param str value_field: the field used to compute the value of the bar slice - :param str groupby_field: the fields used to group - - :return list section_result: a list of dicts: [ - { 'value': (int) bar_column_value, - 'tootip': (str) bar_column_tooltip, - } - ] - """ - month_begin = date.today().replace(day=1) - section_result = [{ - 'value': 0, - 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B %Y'), - } for i in range(self._period_number - 1, -1, -1)] - group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) - pattern = tools.DEFAULT_SERVER_DATE_FORMAT if obj.fields_get(cr, uid, groupby_field)[groupby_field]['type'] == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT - for group in group_obj: - group_begin_date = datetime.strptime(group['__domain'][0][2], pattern) - month_delta = relativedelta.relativedelta(month_begin, group_begin_date) - section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group.get(groupby_field, 0)} - return section_result def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None): """ Get opportunities-related data for salesteam kanban view @@ -155,25 +118,7 @@ class crm_case_section(osv.osv): return res _columns = { - 'name': fields.char('Sales Team', size=64, required=True, translate=True), - 'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True), - 'code': fields.char('Code', size=8), - 'active': fields.boolean('Active', help="If the active field is set to "\ - "true, it will allow you to hide the sales team without removing it."), - 'change_responsible': fields.boolean('Reassign Escalated', help="When escalating to this team override the salesman with the team leader."), - 'user_id': fields.many2one('res.users', 'Team Leader'), - 'member_ids': fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'), - 'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by OpenERP about cases in this sales team"), - 'parent_id': fields.many2one('crm.case.section', 'Parent Team'), - 'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'), - 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), - 'note': fields.text('Description'), - 'working_hours': fields.float('Working Hours', digits=(16, 2)), 'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'), - 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, - help="The email address associated with this team. New emails received will automatically " - "create new leads assigned to the team."), - 'color': fields.integer('Color Index'), 'use_leads': fields.boolean('Leads', help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."), @@ -190,52 +135,11 @@ class crm_case_section(osv.osv): return ids _defaults = { - 'active': 1, 'stage_ids': _get_stage_common, 'use_leads': True, } - _sql_constraints = [ - ('code_uniq', 'unique (code)', 'The code of the sales team must be unique !') - ] - - _constraints = [ - (osv.osv._check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id']) - ] - - def name_get(self, cr, uid, ids, context=None): - """Overrides orm name_get method""" - if not isinstance(ids, list): - ids = [ids] - res = [] - if not ids: - return res - reads = self.read(cr, uid, ids, ['name', 'parent_id'], context) - - for record in reads: - name = record['name'] - if record['parent_id']: - name = record['parent_id'][1] + ' / ' + name - res.append((record['id'], name)) - return res - - def create(self, cr, uid, vals, context=None): - if context is None: - context = {} - create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name) - section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) - section = self.browse(cr, uid, section_id, context=context) - self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) - return section_id - - def unlink(self, cr, uid, ids, context=None): - # Cascade-delete mail aliases as well, as they should not exist without the sales team. - mail_alias = self.pool.get('mail.alias') - alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] - res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) - mail_alias.unlink(cr, uid, alias_ids, context=context) - return res - + class crm_case_categ(osv.osv): """ Category of Case """ _name = "crm.case.categ" diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index d3ad226dbea..a56459a7065 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -84,195 +84,34 @@ crm.case.section.kanban crm.case.section + - + + - - - - - - - - - - - - - - - - - - - Case Sections - Search - crm.case.section - - - - - - - - - - - - - - - - - - - - Sales Teams - crm.case.section - form - kanban,tree,form - {'search_default_personal': True} - - -

- Click here to define a new sales team. -

- Use sales team to organize your different salespersons or - departments into separate teams. Each team will work in - its own list of opportunities. -

-
-
- - - - - crm.case.section.form - crm.case.section - -
- -
-
- - - - - - - - - - - - - - - - - - -
- X -
-
- -
-
-
-
-
-
-
-
- - - - - - - -
-
-
- - + + + + + + @@ -303,29 +142,26 @@ crm.case.section [('parent_id','=',False)] tree - + - - Sales Teams - crm.case.section - form - - -

- Click here to define a new sales team. -

- Use sales team to organize your different salespersons or - departments into separate teams. Each team will work in - its own list of opportunities. -

+ + crm.case.section.form + crm.case.section + + + +
+
+
+ + + + + +
- - \ No newline at end of file diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 4da0a509ed1..f97b7d0adf8 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -346,7 +346,18 @@ class crm_lead(format_address, osv.osv): if section_ids: section_id = section_ids[0] return {'value': {'section_id': section_id}} - + + def on_change_user(self, cr, uid, ids, user_id, context=None): + """ Override of on change user_id on lead/opportunity; when having sale + the new logic is : + - use user.default_section_id + - or fallback on previous behavior """ + if user_id: + user = self.pool.get('res.users').browse(cr, uid, user_id, context=context) + if user.default_section_id and user.default_section_id.id: + return {'value': {'section_id': user.default_section_id.id}} + return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context) + def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None): """ Override of the base.stage method Parameter of the stage search taken from the lead: diff --git a/addons/crm/res_config_view.xml b/addons/crm/res_config_view.xml index b964cca5c7f..0ef4cfa6f1e 100644 --- a/addons/crm/res_config_view.xml +++ b/addons/crm/res_config_view.xml @@ -23,17 +23,6 @@
- - - diff --git a/addons/crm/security/crm_security.xml b/addons/crm/security/crm_security.xml index dfc3a56858e..bd2c3cdb3a4 100644 --- a/addons/crm/security/crm_security.xml +++ b/addons/crm/security/crm_security.xml @@ -24,19 +24,7 @@
- - Do Not Use Sales Teams - - - - - - - - Manage Sales Teams - - - + Manage Fund Raising diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv index f3c6bdf5c1f..fde894e4c31 100644 --- a/addons/crm/security/ir.model.access.csv +++ b/addons/crm/security/ir.model.access.csv @@ -5,15 +5,12 @@ access_crm_segmentation,crm.segmentation,model_crm_segmentation,base.group_sale_ access_crm_segmentation_line,crm.segmentation.line,model_crm_segmentation_line,base.group_sale_manager,1,1,1,1 access_crm_case_channel_user,crm.case.channel user,model_crm_case_channel,base.group_sale_salesman,1,0,0,0 access_crm_case_channel_manager,crm.case.channel manager,model_crm_case_channel,base.group_sale_manager,1,1,1,1 -access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_sale_salesman,1,1,1,0 access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager,1,1,1,1 access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0 access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0 access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0 -access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,0,0,0 -access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0 access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1 access_crm_case_resource_type_user,crm_case_resource_type user,model_crm_case_resource_type,base.group_sale_salesman,1,1,1,0 diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index bb5bac89e46..44cbb3227ca 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -59,7 +59,7 @@ The Dashboard for the Sales Manager will include 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', 'images': ['images/sale_dashboard.jpeg','images/Sale_order_line_to_invoice.jpeg','images/sale_order.jpeg','images/sales_analysis.jpeg'], - 'depends': ['account_voucher'], + 'depends': ['sale_team','account_voucher'], 'data': [ 'wizard/sale_make_invoice_advance.xml', 'wizard/sale_line_invoice.xml', @@ -73,6 +73,7 @@ The Dashboard for the Sales Manager will include 'sale_view.xml', 'res_partner_view.xml', 'report/sale_report_view.xml', + 'report/sale_analysis_report_view.xml', 'process/sale_process.xml', 'board_sale_view.xml', 'edi/sale_order_action_data.xml', diff --git a/addons/sale/report/__init__.py b/addons/sale/report/__init__.py index 12d484c3e25..f1d48dd38e9 100644 --- a/addons/sale/report/__init__.py +++ b/addons/sale/report/__init__.py @@ -18,7 +18,8 @@ # along with this program. If not, see . # ############################################################################## - +import sales_crm_account_invoice_report import sale_report +import sale_analysis_report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/report/sale_report.py b/addons/sale/report/sale_analysis_report.py similarity index 100% rename from addons/sale_crm/report/sale_report.py rename to addons/sale/report/sale_analysis_report.py diff --git a/addons/sale_crm/report/sale_report_view.xml b/addons/sale/report/sale_analysis_report_view.xml similarity index 100% rename from addons/sale_crm/report/sale_report_view.xml rename to addons/sale/report/sale_analysis_report_view.xml diff --git a/addons/sale_crm/report/sales_crm_account_invoice_report.py b/addons/sale/report/sales_crm_account_invoice_report.py similarity index 100% rename from addons/sale_crm/report/sales_crm_account_invoice_report.py rename to addons/sale/report/sales_crm_account_invoice_report.py diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 667f15a375d..93e4d90f612 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -18,9 +18,11 @@ # along with this program. If not, see . # ############################################################################## - -from datetime import datetime, timedelta +import calendar +from openerp import tools +from datetime import date, datetime, timedelta from dateutil.relativedelta import relativedelta +from dateutil import relativedelta import time from openerp.osv import fields, osv from openerp.tools.translate import _ @@ -162,6 +164,11 @@ class sale_order(osv.osv): if not company_id: raise osv.except_osv(_('Error!'), _('There is no default company for the current user!')) return company_id + + def _get_default_section_id(self, cr, uid, context=None): + """ Gives default section by checking if present in the context """ + section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False + return section_id _columns = { 'name': fields.char('Order Reference', size=64, required=True, @@ -226,6 +233,7 @@ class sale_order(osv.osv): 'payment_term': fields.many2one('account.payment.term', 'Payment Term'), 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'), 'company_id': fields.many2one('res.company', 'Company'), + 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } _defaults = { 'date_order': fields.date.context_today, @@ -237,7 +245,9 @@ class sale_order(osv.osv): 'invoice_quantity': 'order', 'partner_invoice_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['invoice'])['invoice'], 'partner_shipping_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['delivery'])['delivery'], - 'note': lambda self, cr, uid, context: self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.sale_note + 'note': lambda self, cr, uid, context: self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.sale_note, + 'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c), + } _sql_constraints = [ ('name_uniq', 'unique(name, company_id)', 'Order Reference must be unique per Company!'), @@ -372,12 +382,14 @@ class sale_order(osv.osv): 'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id, 'date_invoice': context.get('date_invoice', False), 'company_id': order.company_id.id, - 'user_id': order.user_id and order.user_id.id or False + 'user_id': order.user_id and order.user_id.id or False, + 'section_id' : order.section_id.id } # Care for deprecated _inv_get() hook - FIXME: to be removed after 6.1 invoice_vals.update(self._inv_get(cr, uid, order, context=context)) return invoice_vals + def _make_invoice(self, cr, uid, order, lines, context=None): inv_obj = self.pool.get('account.invoice') @@ -1000,11 +1012,14 @@ class mail_compose_message(osv.Model): context = dict(context, mail_post_autofollow=True) self.pool.get('sale.order').signal_quotation_sent(cr, uid, [context['default_res_id']]) return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context) - + class account_invoice(osv.Model): _inherit = 'account.invoice' - + _columns = { + 'section_id': fields.many2one('crm.case.section', 'Sales Team'), + } + def confirm_paid(self, cr, uid, ids, context=None): sale_order_obj = self.pool.get('sale.order') res = super(account_invoice, self).confirm_paid(cr, uid, ids, context=context) @@ -1023,5 +1038,59 @@ class account_invoice(osv.Model): for id in ids: workflow.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr) return super(account_invoice, self).unlink(cr, uid, ids, context=context) + + _defaults = { + 'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, + } + +class crm_case_section(osv.osv): + _inherit = 'crm.case.section' + + def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None): + obj = self.pool.get('sale.order') + res = dict.fromkeys(ids, False) + month_begin = date.today().replace(day=1) + date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + for id in ids: + res[id] = dict() + created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] + res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) + validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] + res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) + return res + + def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None): + obj = self.pool.get('account.invoice.report') + res = dict.fromkeys(ids, False) + month_begin = date.today().replace(day=1) + date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + for id in ids: + created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)] + res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context) + return res + + _columns = { + 'invoiced_forecast': fields.integer(string='Invoice Forecast', + help="Forecast of the invoice revenue for the current month. This is the amount the sales \n" + "team should invoice this month. It is used to compute the progression ratio \n" + " of the current and forecast revenue on the kanban view."), + 'invoiced_target': fields.integer(string='Invoice Target', + help="Target of invoice revenue for the current month. This is the amount the sales \n" + "team estimates to be able to invoice this month."), + 'monthly_quoted': fields.function(_get_sale_orders_data, + type='string', readonly=True, multi='_get_sale_orders_data', + string='Rate of created quotation per duration'), + 'monthly_confirmed': fields.function(_get_sale_orders_data, + type='string', readonly=True, multi='_get_sale_orders_data', + string='Rate of validate sales orders per duration'), + 'monthly_invoiced': fields.function(_get_invoices_data, + type='string', readonly=True, + string='Rate of sent invoices per duration'), + } + + def action_forecast(self, cr, uid, id, value, context=None): + return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index c9ffb94b985..9a6ef2a2e32 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -202,6 +202,7 @@ + @@ -255,12 +256,14 @@ + + @@ -518,5 +521,239 @@ + + + + Account Invoice + account.invoice + + + + + + + + + + + + + account.invoice.groupby + account.invoice + + + + + + + + + + + + + + Account Invoice + account.invoice + + + + + + + + + + + + + + + Sales Orders + ir.actions.act_window + sale.order + form + tree,form,calendar,graph + + [('state','not in',('draft','sent','cancel'))] + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id, + } + + +

+ Click to create a quotation that can be converted into a sales + order. +

+ OpenERP will help you efficiently handle the complete sales flow: + quotation, sales order, delivery, invoicing and payment. +

+
+
+ + + Quotations + ir.actions.act_window + sale.order + form + + tree,form,calendar,graph + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id, + 'show_address': 1, + } + + [('state','in',('draft','sent','cancel'))] + + +

+ Click to create a quotation, the first step of a new sale. +

+ OpenERP will help you handle efficiently the complete sale flow: + from the quotation to the sales order, the + delivery, the invoicing and the payment collection. +

+ The social feature helps you organize discussions on each sales + order, and allow your customers to keep track of the evolution + of the sales order. +

+
+
+ + + Invoices + account.invoice + form + tree,form,calendar,graph + + [ + ('state', 'not in', ['draft', 'cancel']), + ('type', '=', 'out_invoice')] + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id, + 'default_type':'out_invoice', + 'type':'out_invoice', + 'journal_type': 'sale', + } + + + + + + 1 + tree + + + + + 2 + form + + + + + + Quotations Analysis + sale.report + graph + [('state','=','draft'),('section_id', '=', active_id)] + {'search_default_order_month':1} + This report performs analysis on your quotations. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. + + + + Sales Analysis + sale.report + graph + [('state','not in',('draft','sent','cancel')),('section_id', '=', active_id)] + {'search_default_order_month':1} + This report performs analysis on your sales orders. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. + + + + Invoices Analysis + account.invoice.report + graph + [('section_id', '=', active_id),('state', 'not in', ['draft', 'cancel'])] + {'search_default_month':1} + From this report, you can have an overview of the amount invoiced to your customer. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs. + + + + crm.case.section.form + crm.case.section + + + + + + + + + + + + + crm.case.section.kanban + crm.case.section + + + + + + + + + + + + + + + + +
+ Invoiced + Forecast +
+
+
Define an invoicing target in the sales team settings to see the period's achievement and forecast at a glance. +
+
+
+
+
diff --git a/addons/sale_crm/report/__init__.py b/addons/sale_crm/report/__init__.py index d86b3e66de9..3fd45ac3f8f 100644 --- a/addons/sale_crm/report/__init__.py +++ b/addons/sale_crm/report/__init__.py @@ -19,8 +19,8 @@ # ############################################################################## -import sales_crm_account_invoice_report -import sale_report + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/sale_crm.py b/addons/sale_crm/sale_crm.py index 9bcb5adf6ae..510daf30c3b 100644 --- a/addons/sale_crm/sale_crm.py +++ b/addons/sale_crm/sale_crm.py @@ -26,117 +26,11 @@ from dateutil import relativedelta from openerp import tools from openerp.osv import osv, fields -class res_users(osv.Model): - _inherit = 'res.users' - _columns = { - 'default_section_id': fields.many2one('crm.case.section', 'Default Sales Team'), - } - - def __init__(self, pool, cr): - init_res = super(res_users, self).__init__(pool, cr) - # duplicate list to avoid modifying the original reference - self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) - self.SELF_WRITEABLE_FIELDS.extend(['default_section_id']) - return init_res - class sale_order(osv.osv): _inherit = 'sale.order' _columns = { - 'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Categories', \ domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}") } - - def _get_default_section_id(self, cr, uid, context=None): - """ Gives default section by checking if present in the context """ - section_id = self.pool.get('crm.lead')._resolve_section_id_from_context(cr, uid, context=context) or False - if not section_id: - section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False - return section_id - - _defaults = { - 'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c), - } - - def _prepare_invoice(self, cr, uid, order, lines, context=None): - invoice_vals = super(sale_order, self)._prepare_invoice(cr, uid, order, lines, context=context) - if order.section_id and order.section_id.id: - invoice_vals['section_id'] = order.section_id.id - return invoice_vals - - -class crm_case_section(osv.osv): - _inherit = 'crm.case.section' - - def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None): - obj = self.pool.get('sale.order') - res = dict.fromkeys(ids, False) - month_begin = date.today().replace(day=1) - date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - for id in ids: - res[id] = dict() - created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] - res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) - validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] - res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) - return res - - def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None): - obj = self.pool.get('account.invoice.report') - res = dict.fromkeys(ids, False) - month_begin = date.today().replace(day=1) - date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - for id in ids: - created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)] - res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context) - return res - - _columns = { - 'invoiced_forecast': fields.integer(string='Invoice Forecast', - help="Forecast of the invoice revenue for the current month. This is the amount the sales \n" - "team should invoice this month. It is used to compute the progression ratio \n" - " of the current and forecast revenue on the kanban view."), - 'invoiced_target': fields.integer(string='Invoice Target', - help="Target of invoice revenue for the current month. This is the amount the sales \n" - "team estimates to be able to invoice this month."), - 'monthly_quoted': fields.function(_get_sale_orders_data, - type='string', readonly=True, multi='_get_sale_orders_data', - string='Rate of created quotation per duration'), - 'monthly_confirmed': fields.function(_get_sale_orders_data, - type='string', readonly=True, multi='_get_sale_orders_data', - string='Rate of validate sales orders per duration'), - 'monthly_invoiced': fields.function(_get_invoices_data, - type='string', readonly=True, - string='Rate of sent invoices per duration'), - } - - def action_forecast(self, cr, uid, id, value, context=None): - return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context) - -class sale_crm_lead(osv.Model): - _inherit = 'crm.lead' - - def on_change_user(self, cr, uid, ids, user_id, context=None): - """ Override of on change user_id on lead/opportunity; when having sale - the new logic is : - - use user.default_section_id - - or fallback on previous behavior """ - if user_id: - user = self.pool.get('res.users').browse(cr, uid, user_id, context=context) - if user.default_section_id and user.default_section_id.id: - return {'value': {'section_id': user.default_section_id.id}} - return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context) - - -class account_invoice(osv.osv): - _inherit = 'account.invoice' - _columns = { - 'section_id': fields.many2one('crm.case.section', 'Sales Team'), - } - _defaults = { - 'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, - } - + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index 88d7fe8be6c..102eb9462fa 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -27,285 +27,9 @@ - - - - sale.order.list.select - sale.order - - - - - - - - - - - - - - - Account Invoice - account.invoice - - - - - - - - - - - - - account.invoice.groupby - account.invoice - - - - - - - - - - - - - - Account Invoice - account.invoice - - - - - - - - - - - - - Users Preferences - res.users - - - - - - - - - - - - - res.users.preferences.form - res.users - - - - - - - - - - - - - - Sales Orders - ir.actions.act_window - sale.order - form - tree,form,calendar,graph - - [('state','not in',('draft','sent','cancel'))] - { - 'search_default_section_id': [active_id], - 'default_section_id': active_id, - } - - -

- Click to create a quotation that can be converted into a sales - order. -

- OpenERP will help you efficiently handle the complete sales flow: - quotation, sales order, delivery, invoicing and payment. -

-
-
- - - Quotations - ir.actions.act_window - sale.order - form - - tree,form,calendar,graph - { - 'search_default_section_id': [active_id], - 'default_section_id': active_id, - 'show_address': 1, - } - - [('state','in',('draft','sent','cancel'))] - - -

- Click to create a quotation, the first step of a new sale. -

- OpenERP will help you handle efficiently the complete sale flow: - from the quotation to the sales order, the - delivery, the invoicing and the payment collection. -

- The social feature helps you organize discussions on each sales - order, and allow your customers to keep track of the evolution - of the sales order. -

-
-
- - - Invoices - account.invoice - form - tree,form,calendar,graph - - [ - ('state', 'not in', ['draft', 'cancel']), - ('type', '=', 'out_invoice')] - { - 'search_default_section_id': [active_id], - 'default_section_id': active_id, - 'default_type':'out_invoice', - 'type':'out_invoice', - 'journal_type': 'sale', - } - - - - - - 1 - tree - - - - - 2 - form - - - - - - Quotations Analysis - sale.report - graph - [('state','=','draft'),('section_id', '=', active_id)] - {'search_default_order_month':1} - This report performs analysis on your quotations. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. - - - - Sales Analysis - sale.report - graph - [('state','not in',('draft','sent','cancel')),('section_id', '=', active_id)] - {'search_default_order_month':1} - This report performs analysis on your sales orders. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application. - - - - Invoices Analysis - account.invoice.report - graph - [('section_id', '=', active_id),('state', 'not in', ['draft', 'cancel'])] - {'search_default_month':1} - From this report, you can have an overview of the amount invoiced to your customer. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs. - - - - crm.case.section.form - crm.case.section - - - - - - - - - - - - - crm.case.section.kanban - crm.case.section - - - - - - - - - - - - - - - - - - -
- Invoiced - Forecast -
-
-
Define an invoicing target in the sales team settings to see the period's achievement and forecast at a glance. -
-
-
-
-
- + diff --git a/addons/sale_team/__init__.py b/addons/sale_team/__init__.py new file mode 100644 index 00000000000..6bac200f0db --- /dev/null +++ b/addons/sale_team/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import sale_team +import sale_team_config + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py new file mode 100644 index 00000000000..9c303ae3ae3 --- /dev/null +++ b/addons/sale_team/__openerp__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + 'name' : 'Sale Team', + 'version' : '1.0', + 'author' : 'OpenERP SA', + 'category': 'hidden', + 'sequence': 10, + 'summary': 'Sales Team', + 'description': """ """, + 'website': 'http://www.openerp.com', + 'depends' : ['base','web_kanban','calendar'], + 'data': ['sale_team.xml','sale_team_security.xml','res_config_view.xml','ir.model.access.csv'], + 'demo': [], + 'installable': True, + 'auto_install': True, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_team/ir.model.access.csv b/addons/sale_team/ir.model.access.csv new file mode 100644 index 00000000000..9817ad834f6 --- /dev/null +++ b/addons/sale_team/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 +access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,0,0,0 +access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 + diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml new file mode 100644 index 00000000000..7723fda48fc --- /dev/null +++ b/addons/sale_team/res_config_view.xml @@ -0,0 +1,27 @@ + + + + + + crm settings + sale.team.config.settings + + + +
+ + + +
+
+
+
+
diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py new file mode 100644 index 00000000000..3643a6dc26c --- /dev/null +++ b/addons/sale_team/sale_team.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +import calendar +from datetime import date, datetime +from dateutil import relativedelta + +from openerp import tools +from openerp.osv import fields +from openerp.osv import osv + + + +class crm_case_section(osv.osv): + _name = "crm.case.section" + _inherits = {'mail.alias': 'alias_id'} + _inherit = ['mail.thread', 'ir.needaction_mixin'] + _description = "Sales Teams" + _order = "complete_name" + # number of periods for lead/opportunities/... tracking in salesteam kanban dashboard/kanban view + _period_number = 5 + + def get_full_name(self, cr, uid, ids, field_name, arg, context=None): + return dict(self.name_get(cr, uid, ids, context=context)) + + def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None): + + """ Generic method to generate data for bar chart values using SparklineBarWidget. + This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field). + + :param obj: the target model (i.e. crm_lead) + :param domain: the domain applied to the read_group + :param list read_fields: the list of fields to read in the read_group + :param str value_field: the field used to compute the value of the bar slice + :param str groupby_field: the fields used to group + + :return list section_result: a list of dicts: [ + { 'value': (int) bar_column_value, + 'tootip': (str) bar_column_tooltip, + } + ] + """ + month_begin = date.today().replace(day=1) + section_result = [{ + 'value': 0, + 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B %Y'), + } for i in range(self._period_number - 1, -1, -1)] + group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) + pattern = tools.DEFAULT_SERVER_DATE_FORMAT if obj.fields_get(cr, uid, groupby_field)[groupby_field]['type'] == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT + for group in group_obj: + group_begin_date = datetime.strptime(group['__domain'][0][2], pattern) + month_delta = relativedelta.relativedelta(month_begin, group_begin_date) + section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group.get(groupby_field, 0)} + return section_result + + _columns = { + 'name': fields.char('Sales Team', size=64, required=True, translate=True), + 'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True), + 'code': fields.char('Code', size=8), + 'active': fields.boolean('Active', help="If the active field is set to "\ + "true, it will allow you to hide the sales team without removing it."), + 'change_responsible': fields.boolean('Reassign Escalated', help="When escalating to this team override the salesman with the team leader."), + 'user_id': fields.many2one('res.users', 'Team Leader'), + 'member_ids': fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'), + 'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by OpenERP about cases in this sales team"), + 'parent_id': fields.many2one('crm.case.section', 'Parent Team'), + 'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'), + 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), + 'note': fields.text('Description'), + 'working_hours': fields.float('Working Hours', digits=(16, 2)), + 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), + 'color': fields.integer('Color Index'), + } + + _defaults = { + 'active': 1, + } + + _sql_constraints = [ + ('code_uniq', 'unique (code)', 'The code of the sales team must be unique !') + ] + + _constraints = [ + (osv.osv._check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id']) + ] + + def name_get(self, cr, uid, ids, context=None): + """Overrides orm name_get method""" + if not isinstance(ids, list): + ids = [ids] + res = [] + if not ids: + return res + reads = self.read(cr, uid, ids, ['name', 'parent_id'], context) + + for record in reads: + name = record['name'] + if record['parent_id']: + name = record['parent_id'][1] + ' / ' + name + res.append((record['id'], name)) + return res + + def create(self, cr, uid, vals, context=None): + if context is None: + context = {} + create_context = dict(context, alias_model_name=self._name, alias_parent_model_name=self._name) + section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) + section = self.browse(cr, uid, section_id, context=context) + self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) + return section_id + + def unlink(self, cr, uid, ids, context=None): + # Cascade-delete mail aliases as well, as they should not exist without the sales team. + mail_alias = self.pool.get('mail.alias') + alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] + res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) + mail_alias.unlink(cr, uid, alias_ids, context=context) + return res + +class res_users(osv.Model): + _inherit = 'res.users' + _columns = { + 'default_section_id': fields.many2one('crm.case.section', 'Default Sales Team'), + } + + def __init__(self, pool, cr): + init_res = super(res_users, self).__init__(pool, cr) + # duplicate list to avoid modifying the original reference + self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) + self.SELF_WRITEABLE_FIELDS.extend(['default_section_id']) + return init_res + + + \ No newline at end of file diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml new file mode 100644 index 00000000000..687919ff66a --- /dev/null +++ b/addons/sale_team/sale_team.xml @@ -0,0 +1,232 @@ + + + + + + + Users Preferences + res.users + + + + + + + + + + + + + res.users.preferences.form + res.users + + + + + + + + + + + + + + crm.case.section.kanban + crm.case.section + + + + + + + + + + +
+
+ í +
+
+

+
+ %% +
+
+
+ + + +
+
+
+
+
+
+
+
+ + + + + + + Case Sections - Search + crm.case.section + + + + + + + + + + + + + + + + + + + + Sales Teams + crm.case.section + form + kanban,tree,form + {} + + +

+ Click here to define a new sales team. +

+ Use sales team to organize your different salespersons or + departments into separate teams. Each team will work in + its own list of opportunities. +

+
+
+ + + + + crm.case.section.form + crm.case.section + +
+ +
+
+ + + + + + + + + + + + + + + + + + +
+ X +
+
+ +
+
+
+
+
+
+
+
+ + + +
+
+
+ + +
+
+
+
+ + + + + crm.case.section.tree + crm.case.section + child_ids + + + + + + + + + + + + + + + Sales Teams + crm.case.section + form + + +

+ Click here to define a new sales team. +

+ Use sales team to organize your different salespersons or + departments into separate teams. Each team will work in + its own list of opportunities. +

+
+
+ + +
+
\ No newline at end of file diff --git a/addons/sale_team/sale_team_config.py b/addons/sale_team/sale_team_config.py new file mode 100644 index 00000000000..33a5e84b8de --- /dev/null +++ b/addons/sale_team/sale_team_config.py @@ -0,0 +1,45 @@ + +from openerp import SUPERUSER_ID +from openerp.osv import fields, osv + + +class sala_team_configuration(osv.TransientModel): + _name = 'sale.team.config.settings' + _inherit = ['sale.config.settings', 'fetchmail.config.settings'] + + def set_group_multi_salesteams(self, cr, uid, ids, context=None): + """ This method is automatically called by res_config as it begins + with set. It is used to implement the 'one group or another' + behavior. We have to perform some group manipulation by hand + because in res_config.execute(), set_* methods are called + after group_*; therefore writing on an hidden res_config file + could not work. + If group_multi_salesteams is checked: remove group_mono_salesteams + from group_user, remove the users. Otherwise, just add + group_mono_salesteams in group_user. + The inverse logic about group_multi_salesteams is managed by the + normal behavior of 'group_multi_salesteams' field. + """ + def ref(xml_id): + mod, xml = xml_id.split('.', 1) + return self.pool['ir.model.data'].get_object(cr, uid, mod, xml, context) + + for obj in self.browse(cr, uid, ids, context=context): + config_group = ref('base.group_mono_salesteams') + base_group = ref('base.group_user') + if obj.group_multi_salesteams: + base_group.write({'implied_ids': [(3, config_group.id)]}) + config_group.write({'users': [(3, u.id) for u in base_group.users]}) + else: + base_group.write({'implied_ids': [(4, config_group.id)]}) + return True + + _columns = { + + 'group_multi_salesteams': fields.boolean("Organize Sales activities into multiple Sales Teams", + implied_group='base.group_multi_salesteams', + help="""Allows you to use Sales Teams to manage your leads and opportunities."""), + } + + + diff --git a/addons/sale_team/sale_team_security.xml b/addons/sale_team/sale_team_security.xml new file mode 100644 index 00000000000..ff8eef01678 --- /dev/null +++ b/addons/sale_team/sale_team_security.xml @@ -0,0 +1,18 @@ + + + + + Do Not Use Sales Teams + + + + + + + + Manage Sales Teams + + + + + From 3676ec8291fa3ccbc6e6ae69123db38f5f6239b6 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Fri, 28 Mar 2014 16:17:12 +0530 Subject: [PATCH 02/46] [update in code] --- addons/sale_crm/__openerp__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/sale_crm/__openerp__.py b/addons/sale_crm/__openerp__.py index ab94069c173..859a67b3e56 100644 --- a/addons/sale_crm/__openerp__.py +++ b/addons/sale_crm/__openerp__.py @@ -45,7 +45,6 @@ modules. 'process/sale_crm_process.xml', 'security/sale_crm_security.xml', 'security/ir.model.access.csv', - 'report/sale_report_view.xml', ], 'js': [ 'static/src/js/sale_crm.js', From 69c060639af2ada321cb7198a1e92fa785f94586 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Tue, 1 Apr 2014 15:14:34 +0530 Subject: [PATCH 03/46] [update] update in code --- addons/crm/security/ir.model.access.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv index fde894e4c31..639c5928894 100644 --- a/addons/crm/security/ir.model.access.csv +++ b/addons/crm/security/ir.model.access.csv @@ -11,6 +11,7 @@ access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.grou access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0 access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0 access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0 +access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0 access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1 access_crm_case_resource_type_user,crm_case_resource_type user,model_crm_case_resource_type,base.group_sale_salesman,1,1,1,0 From 44d3f263cca585b4ff391d41811a5faa3cc913ce Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Tue, 1 Apr 2014 18:34:23 +0530 Subject: [PATCH 04/46] [IMP] update on code --- addons/crm/crm_lead.py | 13 +++---------- addons/crm/security/ir.model.access.csv | 2 ++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index f97b7d0adf8..b1a0effaf63 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -345,19 +345,12 @@ class crm_lead(format_address, osv.osv): section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context) if section_ids: section_id = section_ids[0] - return {'value': {'section_id': section_id}} - - def on_change_user(self, cr, uid, ids, user_id, context=None): - """ Override of on change user_id on lead/opportunity; when having sale - the new logic is : - - use user.default_section_id - - or fallback on previous behavior """ - if user_id: + else: user = self.pool.get('res.users').browse(cr, uid, user_id, context=context) if user.default_section_id and user.default_section_id.id: return {'value': {'section_id': user.default_section_id.id}} - return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context) - + return {'value': {'section_id': section_id}} + def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None): """ Override of the base.stage method Parameter of the stage search taken from the lead: diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv index 639c5928894..52648c8e347 100644 --- a/addons/crm/security/ir.model.access.csv +++ b/addons/crm/security/ir.model.access.csv @@ -5,12 +5,14 @@ access_crm_segmentation,crm.segmentation,model_crm_segmentation,base.group_sale_ access_crm_segmentation_line,crm.segmentation.line,model_crm_segmentation_line,base.group_sale_manager,1,1,1,1 access_crm_case_channel_user,crm.case.channel user,model_crm_case_channel,base.group_sale_salesman,1,0,0,0 access_crm_case_channel_manager,crm.case.channel manager,model_crm_case_channel,base.group_sale_manager,1,1,1,1 +access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_sale_salesman,1,1,1,0 access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager,1,1,1,1 access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0 access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0 access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0 +access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,1,1,0 access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0 access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1 From 0ee42746df8c8e688c0eefbcc0faed0b9d795194 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Wed, 2 Apr 2014 12:41:23 +0530 Subject: [PATCH 05/46] [update] move alias for default lead in to crm --- addons/crm/crm.py | 20 ++++++++++++++++++++ addons/crm/security/ir.model.access.csv | 3 --- addons/sale_team/sale_team.py | 19 ------------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index eb10e468602..166cfc7f435 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -90,6 +90,8 @@ class crm_case_stage(osv.osv): class crm_case_section(osv.osv): """ Model for sales teams. """ + _name = "crm.case.section" + _inherits = {'mail.alias': 'alias_id'} _inherit = 'crm.case.section' _description = "Sales Teams" @@ -118,6 +120,8 @@ class crm_case_section(osv.osv): return res _columns = { + + 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), 'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'), 'use_leads': fields.boolean('Leads', help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."), @@ -138,7 +142,23 @@ class crm_case_section(osv.osv): 'stage_ids': _get_stage_common, 'use_leads': True, } + + def create(self, cr, uid, vals, context=None): + if context is None: + context = {} + create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name) + section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) + section = self.browse(cr, uid, section_id, context=context) + self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) + return section_id + def unlink(self, cr, uid, ids, context=None): + # Cascade-delete mail aliases as well, as they should not exist without the sales team. + mail_alias = self.pool.get('mail.alias') + alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] + res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) + mail_alias.unlink(cr, uid, alias_ids, context=context) + return res class crm_case_categ(osv.osv): """ Category of Case """ diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv index 52648c8e347..fde894e4c31 100644 --- a/addons/crm/security/ir.model.access.csv +++ b/addons/crm/security/ir.model.access.csv @@ -5,15 +5,12 @@ access_crm_segmentation,crm.segmentation,model_crm_segmentation,base.group_sale_ access_crm_segmentation_line,crm.segmentation.line,model_crm_segmentation_line,base.group_sale_manager,1,1,1,1 access_crm_case_channel_user,crm.case.channel user,model_crm_case_channel,base.group_sale_salesman,1,0,0,0 access_crm_case_channel_manager,crm.case.channel manager,model_crm_case_channel,base.group_sale_manager,1,1,1,1 -access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_sale_salesman,1,1,1,0 access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager,1,1,1,1 access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1 access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0 access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0 access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0 -access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,1,1,0 -access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0 access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1 access_crm_case_resource_type_user,crm_case_resource_type user,model_crm_case_resource_type,base.group_sale_salesman,1,1,1,0 diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index 3643a6dc26c..fd898bb248c 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -36,7 +36,6 @@ class crm_case_section(osv.osv): _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = "Sales Teams" _order = "complete_name" - # number of periods for lead/opportunities/... tracking in salesteam kanban dashboard/kanban view _period_number = 5 def get_full_name(self, cr, uid, ids, field_name, arg, context=None): @@ -87,7 +86,6 @@ class crm_case_section(osv.osv): 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), 'note': fields.text('Description'), 'working_hours': fields.float('Working Hours', digits=(16, 2)), - 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), 'color': fields.integer('Color Index'), } @@ -119,23 +117,6 @@ class crm_case_section(osv.osv): res.append((record['id'], name)) return res - def create(self, cr, uid, vals, context=None): - if context is None: - context = {} - create_context = dict(context, alias_model_name=self._name, alias_parent_model_name=self._name) - section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) - section = self.browse(cr, uid, section_id, context=context) - self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) - return section_id - - def unlink(self, cr, uid, ids, context=None): - # Cascade-delete mail aliases as well, as they should not exist without the sales team. - mail_alias = self.pool.get('mail.alias') - alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] - res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) - mail_alias.unlink(cr, uid, alias_ids, context=context) - return res - class res_users(osv.Model): _inherit = 'res.users' _columns = { From bc90e644a9f3d2636992ad2265e76838eaeb702c Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Fri, 4 Apr 2014 17:18:07 +0530 Subject: [PATCH 06/46] [IMP]done the require changes --- addons/crm/crm_case_section_view.xml | 23 ++++++++++++++++++++++- addons/sale_team/sale_team.py | 1 - addons/sale_team/sale_team.xml | 19 ------------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index a56459a7065..caa282c4e7f 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -89,10 +89,14 @@ + +
+ %% +
Leads @@ -152,9 +156,26 @@
-
+ + + + diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index fd898bb248c..423bb21391c 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -32,7 +32,6 @@ from openerp.osv import osv class crm_case_section(osv.osv): _name = "crm.case.section" - _inherits = {'mail.alias': 'alias_id'} _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = "Sales Teams" _order = "complete_name" diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index 687919ff66a..0120dbd21b5 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -41,7 +41,6 @@ - @@ -56,9 +55,6 @@

-
- %% -
@@ -138,21 +134,6 @@ - - From cfc26235349087748c58e9b4ce39b775fc4c709a Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Wed, 9 Apr 2014 15:35:21 +0530 Subject: [PATCH 07/46] [IMP] improve related yml bug --- addons/crm/__openerp__.py | 1 - addons/sale_team/static/src/css/sale_team.css | 62 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 addons/sale_team/static/src/css/sale_team.css diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 7d5052c1c4e..b72fa3e5ae2 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -109,7 +109,6 @@ Dashboard for CRM will include: 'test': [ 'test/crm_access_group_users.yml', 'test/crm_lead_message.yml', - 'test/lead2opportunity2win.yml', 'test/lead2opportunity_assign_salesmen.yml', 'test/crm_lead_merge.yml', 'test/crm_lead_cancel.yml', diff --git a/addons/sale_team/static/src/css/sale_team.css b/addons/sale_team/static/src/css/sale_team.css new file mode 100644 index 00000000000..8999f758e41 --- /dev/null +++ b/addons/sale_team/static/src/css/sale_team.css @@ -0,0 +1,62 @@ +@charset "utf-8"; +.openerp .oe_kanban_view .oe_kanban_crm_salesteams { + /* Customize width and height of kanban according bootstrap3 */ + width: 357px; + min-height: 254px !important; + /* End of customize */ + cursor: default; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list { + position: relative; + /* Improved margin to set alignment of list items according bootstrap3 */ + margin: 10px 0 10px 9px; + min-height: 10px; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div { + width: 160px; + height: 22px; + margin: 0 !important; + position: relative; + display: inline-block; + float: left; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) { + position: absolute; + left: 90px; + top: 0; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) { + left: 110px; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover { + text-decoration: underline !important; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center { + text-align: center; + margin: 3px 0; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_sum { + margin: 0; + font-size: 40px; +} +.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_subsum { + font-size: 10px; +} +.openerp .oe_kanban_view .oe_salesteams_help { + display: inline-block; +} +.openerp .oe_kanban_view .oe_kanban_salesteams_avatars { + margin-top: 20px; +} +.openerp .oe_kanban_view .oe_kanban_salesteams_avatars img { + width: 30px; + height: 30px; + padding-left: 0px; + margin-top: 3px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} From 8a576d5d9470762c95cb82173c61316112ffd988 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Wed, 9 Apr 2014 17:20:31 +0530 Subject: [PATCH 08/46] [IMP] fix the issue --- addons/gamification_sale_crm/sale_crm_goals_demo.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/gamification_sale_crm/sale_crm_goals_demo.xml b/addons/gamification_sale_crm/sale_crm_goals_demo.xml index d8e26551c32..5c0466f34ed 100644 --- a/addons/gamification_sale_crm/sale_crm_goals_demo.xml +++ b/addons/gamification_sale_crm/sale_crm_goals_demo.xml @@ -3,10 +3,10 @@ - + From 31c7c33260f977ff2bb5c4783b4a37fcd5a0f717 Mon Sep 17 00:00:00 2001 From: "Ravish (Open ERP)" Date: Wed, 9 Apr 2014 19:10:28 +0530 Subject: [PATCH 09/46] [imp]improve the code --- addons/crm/__openerp__.py | 3 --- addons/crm/crm_case_section_view.xml | 4 +--- addons/sale/sale_view.xml | 8 ++------ addons/sale_team/__openerp__.py | 3 ++- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index b72fa3e5ae2..63dc175a0dd 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -119,9 +119,6 @@ Dashboard for CRM will include: 'test/crm_lead_unlink.yml', 'test/crm_lead_find_stage.yml', ], - 'css': [ - 'static/src/css/crm.css' - ], 'js': [ 'static/src/js/crm_case_section.js', ], diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index caa282c4e7f..8cc9c0bcd56 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -155,9 +155,7 @@ -
-
-
+
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 9a6ef2a2e32..fafca287f2e 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -711,7 +711,7 @@
diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index 9c303ae3ae3..35965f4609d 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -22,7 +22,7 @@ 'name' : 'Sale Team', 'version' : '1.0', 'author' : 'OpenERP SA', - 'category': 'hidden', + 'category': 'hidden', 'sequence': 10, 'summary': 'Sales Team', 'description': """ """, @@ -30,6 +30,7 @@ 'depends' : ['base','web_kanban','calendar'], 'data': ['sale_team.xml','sale_team_security.xml','res_config_view.xml','ir.model.access.csv'], 'demo': [], + 'css': ['static/src/css/sale_team.css'], 'installable': True, 'auto_install': True, } From 458b95eacb568ae6bd1346a5a10f997df01d3a25 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Thu, 10 Apr 2014 18:47:17 +0530 Subject: [PATCH 10/46] [IMP] imrove yml testcases --- addons/crm/__openerp__.py | 1 + addons/gamification/models/goal.py | 4 ++-- addons/gamification_sale_crm/sale_crm_goals_demo.xml | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 63dc175a0dd..1b777ab3525 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -109,6 +109,7 @@ Dashboard for CRM will include: 'test': [ 'test/crm_access_group_users.yml', 'test/crm_lead_message.yml', + 'test/lead2opportunity2win.yml', 'test/lead2opportunity_assign_salesmen.yml', 'test/crm_lead_merge.yml', 'test/crm_lead_cancel.yml', diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 8e79c43c8a6..62b4e6a9585 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -279,8 +279,8 @@ class gamification_goal(osv.Model): if goal.definition_id.computation_mode == 'sum': field_name = goal.definition_id.field_id.name - res = obj.read_group(cr, uid, domain, [field_name], [''], context=context) - new_value = res and res[0][field_name] or 0.0 + res = obj.read_group(cr, uid, domain, [field_name], [], context=context) + new_value = res and res[res.keys()[0]][field_name] or 0.0 else: # computation mode = count new_value = obj.search(cr, uid, domain, context=context, count=True) diff --git a/addons/gamification_sale_crm/sale_crm_goals_demo.xml b/addons/gamification_sale_crm/sale_crm_goals_demo.xml index 5c0466f34ed..064d2cbdc20 100644 --- a/addons/gamification_sale_crm/sale_crm_goals_demo.xml +++ b/addons/gamification_sale_crm/sale_crm_goals_demo.xml @@ -3,10 +3,10 @@ - + @@ -16,7 +16,6 @@ 2000 - inprogress From 53f71ba3d45c327badbae77cba68be26f02e06a2 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Fri, 11 Apr 2014 18:59:26 +0530 Subject: [PATCH 11/46] [IMP]imrpove sale_team sequence and depends --- addons/sale_team/__openerp__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index 35965f4609d..f2de8fb432e 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -23,11 +23,10 @@ 'version' : '1.0', 'author' : 'OpenERP SA', 'category': 'hidden', - 'sequence': 10, 'summary': 'Sales Team', 'description': """ """, 'website': 'http://www.openerp.com', - 'depends' : ['base','web_kanban','calendar'], + 'depends' : ['base','web_kanban','mail'], 'data': ['sale_team.xml','sale_team_security.xml','res_config_view.xml','ir.model.access.csv'], 'demo': [], 'css': ['static/src/css/sale_team.css'], From e25229a6da7c5dbe4736cdbecb7aeb44f323af31 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Tue, 15 Apr 2014 16:08:37 +0530 Subject: [PATCH 12/46] [IMP] update depends on sale_team and sale --- addons/sale/__openerp__.py | 2 +- addons/sale_team/__openerp__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 44cbb3227ca..ea6f0f187bd 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -59,7 +59,7 @@ The Dashboard for the Sales Manager will include 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', 'images': ['images/sale_dashboard.jpeg','images/Sale_order_line_to_invoice.jpeg','images/sale_order.jpeg','images/sales_analysis.jpeg'], - 'depends': ['sale_team','account_voucher'], + 'depends': ['sale_team','account_voucher','report'], 'data': [ 'wizard/sale_make_invoice_advance.xml', 'wizard/sale_line_invoice.xml', diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index f2de8fb432e..bb1e8ab5830 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -26,7 +26,7 @@ 'summary': 'Sales Team', 'description': """ """, 'website': 'http://www.openerp.com', - 'depends' : ['base','web_kanban','mail'], + 'depends' : ['base','web_kanban','mail', 'resource'], 'data': ['sale_team.xml','sale_team_security.xml','res_config_view.xml','ir.model.access.csv'], 'demo': [], 'css': ['static/src/css/sale_team.css'], From 9bb0e6f30ec3a2ef1055e167c2fae8ec0005ba2e Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Mon, 21 Apr 2014 15:32:12 +0530 Subject: [PATCH 13/46] [IMP] improve demo data and menu items --- addons/crm/crm.py | 17 ++------ addons/crm/crm_data.xml | 14 +++---- addons/crm/crm_demo.xml | 16 -------- addons/crm/crm_lead.py | 1 + addons/crm/crm_lead_data.xml | 34 ++++++++-------- addons/crm/crm_lead_demo.xml | 52 ++++++++++++------------- addons/crm/crm_phonecall_data.xml | 4 +- addons/crm/crm_phonecall_demo.xml | 12 +++--- addons/sale_team/__openerp__.py | 12 ++++-- addons/sale_team/sale_team.py | 14 ++++++- addons/sale_team/sale_team.xml | 4 +- addons/sale_team/sale_team_security.xml | 18 --------- 12 files changed, 83 insertions(+), 115 deletions(-) delete mode 100644 addons/sale_team/sale_team_security.xml diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 166cfc7f435..da57ae628b3 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -91,7 +91,6 @@ class crm_case_stage(osv.osv): class crm_case_section(osv.osv): """ Model for sales teams. """ _name = "crm.case.section" - _inherits = {'mail.alias': 'alias_id'} _inherit = 'crm.case.section' _description = "Sales Teams" @@ -120,18 +119,17 @@ class crm_case_section(osv.osv): return res _columns = { - - 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), 'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'), 'use_leads': fields.boolean('Leads', help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."), - + 'monthly_open_leads': fields.function(_get_opportunities_data, type="string", readonly=True, multi='_get_opportunities_data', string='Open Leads per Month'), 'monthly_planned_revenue': fields.function(_get_opportunities_data, type="string", readonly=True, multi='_get_opportunities_data', - string='Planned Revenue per Month') + string='Planned Revenue per Month'), + 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), } def _get_stage_common(self, cr, uid, context): @@ -142,15 +140,6 @@ class crm_case_section(osv.osv): 'stage_ids': _get_stage_common, 'use_leads': True, } - - def create(self, cr, uid, vals, context=None): - if context is None: - context = {} - create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name) - section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) - section = self.browse(cr, uid, section_id, context=context) - self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) - return section_id def unlink(self, cr, uid, ids, context=None): # Cascade-delete mail aliases as well, as they should not exist without the sales team. diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml index 231a7124824..41f4819e500 100644 --- a/addons/crm/crm_data.xml +++ b/addons/crm/crm_data.xml @@ -26,34 +26,30 @@ Email - - Direct Sales - DM + True - sales - Cash - + Check - + Credit Card - + Demand Draft - + diff --git a/addons/crm/crm_demo.xml b/addons/crm/crm_demo.xml index 82bdcd8fcd9..1541753523a 100644 --- a/addons/crm/crm_demo.xml +++ b/addons/crm/crm_demo.xml @@ -6,22 +6,6 @@ - - - - - - Indirect Sales - IM - - - - - Marketing - SPD - - - OpenERP partners True diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 32891c21981..e0149269243 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -195,6 +195,7 @@ class crm_lead(format_address, osv.osv): resource_id = resource_ids[0] duration = float(ans.days) + if lead.section_id and lead.section_id.resource_calendar_id: duration = float(ans.days) * 24 new_dates = cal_obj.interval_get(cr, diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 1abcdac9712..6dbe9b2ba88 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -60,7 +60,7 @@ opportunity - + Telesales - + Email Campaign - Services - + Email Campaign - Products - + Twitter Ads - + Google Adwords - + Banner Ads - + Television - + Newsletter - + Product - + Software - + Services - + Information - + Design - + Training - + Consulting - + Other - + diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml index dab17888d7a..0187f14555f 100644 --- a/addons/crm/crm_lead_demo.xml +++ b/addons/crm/crm_lead_demo.xml @@ -20,7 +20,7 @@ 1 - + Hello, @@ -55,7 +55,7 @@ Could you please send me the details ? 4 - + @@ -84,7 +84,7 @@ Could you please send me the details ? 2 - + @@ -105,7 +105,7 @@ Could you please send me the details ? 3 - + @@ -130,7 +130,7 @@ Could you please send me the details ? 3 - + Hi, @@ -157,7 +157,7 @@ Contact: +1 813 494 5005 3 - + @@ -175,7 +175,7 @@ Contact: +1 813 494 5005 5 - + @@ -194,7 +194,7 @@ Contact: +1 813 494 5005 4 - + @@ -213,7 +213,7 @@ Contact: +1 813 494 5005 2 - + @@ -231,7 +231,7 @@ Contact: +1 813 494 5005 2 - + Hi, @@ -254,7 +254,7 @@ Andrew 3 - + @@ -272,7 +272,7 @@ Andrew 2 - + @@ -310,7 +310,7 @@ Andrew Meeting for pricing information. - + @@ -335,7 +335,7 @@ Andrew Send Catalogue by Email - + @@ -356,7 +356,7 @@ Andrew Call to ask system requirement - + @@ -383,7 +383,7 @@ Andrew Convert to quote - + @@ -408,7 +408,7 @@ Andrew Send price list regarding our interventions - + @@ -435,7 +435,7 @@ Andrew Call to define real needs about training - + @@ -462,7 +462,7 @@ Andrew Ask for the good receprion of the proposition - + @@ -479,7 +479,7 @@ Andrew 2 - + @@ -493,7 +493,7 @@ Andrew 3 - + @@ -511,7 +511,7 @@ Andrew 3 - + @@ -526,7 +526,7 @@ Andrew 5 - + @@ -545,7 +545,7 @@ Andrew 5 - + @@ -568,7 +568,7 @@ Andrew 2 Conf call with technical service - + @@ -592,7 +592,7 @@ Andrew Send Catalogue by Email - + diff --git a/addons/crm/crm_phonecall_data.xml b/addons/crm/crm_phonecall_data.xml index 0e2bb6511c5..4e613e7f72a 100644 --- a/addons/crm/crm_phonecall_data.xml +++ b/addons/crm/crm_phonecall_data.xml @@ -6,13 +6,13 @@ --> Inbound - + Outbound - + diff --git a/addons/crm/crm_phonecall_demo.xml b/addons/crm/crm_phonecall_demo.xml index 4002e18815e..c6026c8d894 100644 --- a/addons/crm/crm_phonecall_demo.xml +++ b/addons/crm/crm_phonecall_demo.xml @@ -11,7 +11,7 @@ Left the message done +34 934 340 230 - + @@ -24,7 +24,7 @@ Need more information on the proposed deal done +44 121 690 4596 - + @@ -37,7 +37,7 @@ Ask for convenient time of meeting open +1 786 525 0724 - + @@ -50,7 +50,7 @@ done (077) 582-4035 (077) 341-3591 - + @@ -63,7 +63,7 @@ More information on the proposed deal pending +1 312 349 2324 - + @@ -74,7 +74,7 @@ Proposal for discount offer open +34 230 953 485 - + diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index bb1e8ab5830..9bbdc73e876 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -22,13 +22,17 @@ 'name' : 'Sale Team', 'version' : '1.0', 'author' : 'OpenERP SA', - 'category': 'hidden', + 'category': 'Sales Management', 'summary': 'Sales Team', 'description': """ """, 'website': 'http://www.openerp.com', - 'depends' : ['base','web_kanban','mail', 'resource'], - 'data': ['sale_team.xml','sale_team_security.xml','res_config_view.xml','ir.model.access.csv'], - 'demo': [], + 'depends' : ['base','mail'], + 'data': ['security/sale_team_security.xml', + 'res_config_view.xml', + 'ir.model.access.csv', + 'sale_team_data.xml', + 'sale_team.xml',], + 'demo': ['sale_team_demo.xml'], 'css': ['static/src/css/sale_team.css'], 'installable': True, 'auto_install': True, diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index 423bb21391c..eb6c892c2e9 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -34,6 +34,7 @@ class crm_case_section(osv.osv): _name = "crm.case.section" _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = "Sales Teams" + _inherits = {'mail.alias': 'alias_id'} _order = "complete_name" _period_number = 5 @@ -71,6 +72,7 @@ class crm_case_section(osv.osv): return section_result _columns = { + 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), 'name': fields.char('Sales Team', size=64, required=True, translate=True), 'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True), 'code': fields.char('Code', size=8), @@ -82,7 +84,6 @@ class crm_case_section(osv.osv): 'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by OpenERP about cases in this sales team"), 'parent_id': fields.many2one('crm.case.section', 'Parent Team'), 'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'), - 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), 'note': fields.text('Description'), 'working_hours': fields.float('Working Hours', digits=(16, 2)), 'color': fields.integer('Color Index'), @@ -115,7 +116,16 @@ class crm_case_section(osv.osv): name = record['parent_id'][1] + ' / ' + name res.append((record['id'], name)) return res - + + def create(self, cr, uid, vals, context=None): + if context is None: + context = {} + create_context = dict(context, alias_model_name='res.user', alias_parent_model_name=self._name) + section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) + section = self.browse(cr, uid, section_id, context=context) + self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) + return section_id + class res_users(osv.Model): _inherit = 'res.users' _columns = { diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index 0120dbd21b5..f2fea79a933 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -1,7 +1,9 @@ - + Users Preferences diff --git a/addons/sale_team/sale_team_security.xml b/addons/sale_team/sale_team_security.xml deleted file mode 100644 index ff8eef01678..00000000000 --- a/addons/sale_team/sale_team_security.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Do Not Use Sales Teams - - - - - - - - Manage Sales Teams - - - - - From 3bc6bf2d99d000d0c47b19a07cd39e65e878e43f Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Mon, 21 Apr 2014 16:40:57 +0530 Subject: [PATCH 14/46] [IMP] add demo data files --- addons/crm/crm.py | 9 +---- addons/crm/crm_case_section_view.xml | 1 - addons/crm/crm_lead_menu.xml | 2 +- addons/sale_crm/sale_crm_demo.xml | 24 +++++------ addons/sale_team/sale_team.py | 10 ++++- addons/sale_team/sale_team.xml | 1 + addons/sale_team/sale_team_data.xml | 11 +++++ addons/sale_team/sale_team_demo.xml | 20 ++++++++++ .../sale_team/security/sale_team_security.xml | 40 +++++++++++++++++++ 9 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 addons/sale_team/sale_team_data.xml create mode 100644 addons/sale_team/sale_team_demo.xml create mode 100644 addons/sale_team/security/sale_team_security.xml diff --git a/addons/crm/crm.py b/addons/crm/crm.py index da57ae628b3..c43a3feabb8 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -93,6 +93,7 @@ class crm_case_section(osv.osv): _name = "crm.case.section" _inherit = 'crm.case.section' _description = "Sales Teams" + _alias_model_name = 'crm.lead' def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None): """ Get opportunities-related data for salesteam kanban view @@ -140,14 +141,6 @@ class crm_case_section(osv.osv): 'stage_ids': _get_stage_common, 'use_leads': True, } - - def unlink(self, cr, uid, ids, context=None): - # Cascade-delete mail aliases as well, as they should not exist without the sales team. - mail_alias = self.pool.get('mail.alias') - alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] - res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) - mail_alias.unlink(cr, uid, alias_ids, context=context) - return res class crm_case_categ(osv.osv): """ Category of Case """ diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 8cc9c0bcd56..10888377050 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -89,7 +89,6 @@ - diff --git a/addons/crm/crm_lead_menu.xml b/addons/crm/crm_lead_menu.xml index dffe03dd4b3..60dc307cc0f 100644 --- a/addons/crm/crm_lead_menu.xml +++ b/addons/crm/crm_lead_menu.xml @@ -81,7 +81,7 @@ action="crm_case_category_act_leads_all"/> + groups="base.group_sale_salesman,base.group_sale_manager"/> diff --git a/addons/sale_crm/sale_crm_demo.xml b/addons/sale_crm/sale_crm_demo.xml index 25f653548d1..9af5ae7ebce 100644 --- a/addons/sale_crm/sale_crm_demo.xml +++ b/addons/sale_crm/sale_crm_demo.xml @@ -2,12 +2,12 @@ - + 52700 60000 - + Indirect Sales IM 36000 @@ -21,7 +21,7 @@ - + draft in_invoice @@ -69,7 +69,7 @@ - + draft out_invoice @@ -98,32 +98,32 @@ - + - + - + - + - + - + - + - + diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index eb6c892c2e9..3c13514bd11 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -37,6 +37,7 @@ class crm_case_section(osv.osv): _inherits = {'mail.alias': 'alias_id'} _order = "complete_name" _period_number = 5 + _alias_model_name = 'mail.message' def get_full_name(self, cr, uid, ids, field_name, arg, context=None): return dict(self.name_get(cr, uid, ids, context=context)) @@ -120,11 +121,18 @@ class crm_case_section(osv.osv): def create(self, cr, uid, vals, context=None): if context is None: context = {} - create_context = dict(context, alias_model_name='res.user', alias_parent_model_name=self._name) + create_context = dict(context, alias_model_name=self._alias_model_name, alias_parent_model_name=self._name) section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) section = self.browse(cr, uid, section_id, context=context) self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) return section_id + def unlink(self, cr, uid, ids, context=None): + # Cascade-delete mail aliases as well, as they should not exist without the sales team. + mail_alias = self.pool.get('mail.alias') + alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] + res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) + mail_alias.unlink(cr, uid, alias_ids, context=context) + return res class res_users(osv.Model): _inherit = 'res.users' diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index f2fea79a933..b3972e71342 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -42,6 +42,7 @@ + diff --git a/addons/sale_team/sale_team_data.xml b/addons/sale_team/sale_team_data.xml new file mode 100644 index 00000000000..eef5e5809a1 --- /dev/null +++ b/addons/sale_team/sale_team_data.xml @@ -0,0 +1,11 @@ + + + + + Direct Sales + DM + sales + + + + diff --git a/addons/sale_team/sale_team_demo.xml b/addons/sale_team/sale_team_demo.xml new file mode 100644 index 00000000000..b24c047fba1 --- /dev/null +++ b/addons/sale_team/sale_team_demo.xml @@ -0,0 +1,20 @@ + + + + + + + + Indirect Sales + IM + + + + + Marketing + SPD + + + + + \ No newline at end of file diff --git a/addons/sale_team/security/sale_team_security.xml b/addons/sale_team/security/sale_team_security.xml new file mode 100644 index 00000000000..53fb560e332 --- /dev/null +++ b/addons/sale_team/security/sale_team_security.xml @@ -0,0 +1,40 @@ + + + + + + User: Own Leads Only + + + the user will have access to his own data in the sales application. + + + + User: All Leads + + + the user will have access to all records of everyone in the sales application. + + + + Manager + the user will have an access to the sales configuration as well as statistic reports. + + + + + + + + + + + + + + + + + + + From 2d4ebc9edcf1f53f24f0e99e13753c5649360a50 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Mon, 21 Apr 2014 17:54:27 +0530 Subject: [PATCH 15/46] [IMP] improve kanban view and dependent demo data record --- addons/crm/crm_case_section_view.xml | 36 ++++++++++++++-------------- addons/crm_claim/crm_claim_data.xml | 10 ++++---- addons/crm_claim/crm_claim_demo.xml | 14 +++++------ addons/sale_team/sale_team.xml | 5 +++- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 10888377050..4c313d488b2 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -93,26 +93,26 @@ -
- %% -
-
-
- Leads - - Open Leads per Month
Click to see a detailed analysis of leads.
-
+
+ %%
- - + diff --git a/addons/crm_claim/crm_claim_data.xml b/addons/crm_claim/crm_claim_data.xml index d897fe2bcb3..8a1bae29a2b 100644 --- a/addons/crm_claim/crm_claim_data.xml +++ b/addons/crm_claim/crm_claim_data.xml @@ -8,19 +8,19 @@ Factual Claims - + Value Claims - + Policy Claims - + @@ -30,12 +30,12 @@ Corrective - + Preventive - + - kanban diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index e0149269243..cc2488f9589 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -195,7 +195,6 @@ class crm_lead(format_address, osv.osv): resource_id = resource_ids[0] duration = float(ans.days) - if lead.section_id and lead.section_id.resource_calendar_id: duration = float(ans.days) * 24 new_dates = cal_obj.interval_get(cr, @@ -351,7 +350,7 @@ class crm_lead(format_address, osv.osv): if user.default_section_id and user.default_section_id.id: return {'value': {'section_id': user.default_section_id.id}} return {'value': {'section_id': section_id}} - + def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None): """ Override of the base.stage method Parameter of the stage search taken from the lead: diff --git a/addons/crm/security/crm_security.xml b/addons/crm/security/crm_security.xml index bd2c3cdb3a4..7539b699614 100644 --- a/addons/crm/security/crm_security.xml +++ b/addons/crm/security/crm_security.xml @@ -24,7 +24,6 @@ - Manage Fund Raising diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 2a9b6788360..f6f7165c41b 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -282,6 +282,7 @@ class gamification_goal(osv.Model): _logger.exception(_('Invalid return content from the evaluation of code for definition %s' % definition.name)) else: # count or sum + obj = self.pool.get(definition.model_id.model) field_date_name = definition.field_date_id and definition.field_date_id.name or False @@ -345,6 +346,7 @@ class gamification_goal(osv.Model): if not value: continue goal = all_goals[goal_id] + # check goal target reached if (goal.definition_condition == 'higher' and value.get('current', goal.current) >= goal.target_goal) \ or (goal.definition_condition == 'lower' and value.get('current', goal.current) <= goal.target_goal): diff --git a/addons/sale/report/__init__.py b/addons/sale/report/__init__.py index f1d48dd38e9..0ce593424d3 100644 --- a/addons/sale/report/__init__.py +++ b/addons/sale/report/__init__.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## + import sales_crm_account_invoice_report import sale_report import sale_analysis_report diff --git a/addons/sale/report/sale_analysis_report_view.xml b/addons/sale/report/sale_analysis_report_view.xml index fb62468ec91..83613219046 100644 --- a/addons/sale/report/sale_analysis_report_view.xml +++ b/addons/sale/report/sale_analysis_report_view.xml @@ -1,6 +1,6 @@ - + sale.report.search.sale.crm sale.report @@ -12,5 +12,5 @@ - + \ No newline at end of file diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 09008e1dc81..d597d0d1743 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## + import calendar from openerp import tools from datetime import date, datetime, timedelta @@ -389,7 +390,6 @@ class sale_order(osv.osv): # Care for deprecated _inv_get() hook - FIXME: to be removed after 6.1 invoice_vals.update(self._inv_get(cr, uid, order, context=context)) return invoice_vals - def _make_invoice(self, cr, uid, order, lines, context=None): inv_obj = self.pool.get('account.invoice') @@ -1012,10 +1012,10 @@ class mail_compose_message(osv.Model): context = dict(context, mail_post_autofollow=True) self.pool.get('sale.order').signal_quotation_sent(cr, uid, [context['default_res_id']]) return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context) - class account_invoice(osv.Model): _inherit = 'account.invoice' + _columns = { 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index fafca287f2e..790e71ee37b 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -565,9 +565,7 @@ - - Sales Orders ir.actions.act_window diff --git a/addons/sale_crm/__init__.py b/addons/sale_crm/__init__.py index cda0cd795a2..ac44586e7db 100644 --- a/addons/sale_crm/__init__.py +++ b/addons/sale_crm/__init__.py @@ -21,6 +21,5 @@ import wizard import sale_crm -import report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/report/__init__.py b/addons/sale_crm/report/__init__.py deleted file mode 100644 index 3fd45ac3f8f..00000000000 --- a/addons/sale_crm/report/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - - - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index 102eb9462fa..070b8ef4fa7 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -31,5 +31,5 @@ - + diff --git a/addons/sale_team/__init__.py b/addons/sale_team/__init__.py index 6bac200f0db..f6973d5f845 100644 --- a/addons/sale_team/__init__.py +++ b/addons/sale_team/__init__.py @@ -21,5 +21,4 @@ import sale_team import sale_team_config -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index 2ea88cc6a92..ea45d3c1e68 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -28,8 +28,8 @@ 'website': 'http://www.openerp.com', 'depends' : ['base','mail','web_kanban_sparkline',], 'data': ['security/sale_team_security.xml', + 'security/ir.model.access.csv', 'res_config_view.xml', - 'ir.model.access.csv', 'sale_team_data.xml', 'sale_team.xml',], 'demo': ['sale_team_demo.xml'], diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml index 7723fda48fc..ddcc72b5375 100644 --- a/addons/sale_team/res_config_view.xml +++ b/addons/sale_team/res_config_view.xml @@ -1,27 +1,26 @@ - crm settings sale.team.config.settings -
- - - +
+
+
-
+
diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index 3c13514bd11..db0e4638048 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -19,17 +19,13 @@ # ############################################################################## - import calendar from datetime import date, datetime from dateutil import relativedelta - from openerp import tools from openerp.osv import fields from openerp.osv import osv - - class crm_case_section(osv.osv): _name = "crm.case.section" _inherit = ['mail.thread', 'ir.needaction_mixin'] @@ -145,7 +141,4 @@ class res_users(osv.Model): # duplicate list to avoid modifying the original reference self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) self.SELF_WRITEABLE_FIELDS.extend(['default_section_id']) - return init_res - - - \ No newline at end of file + return init_res \ No newline at end of file diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index e3bea558a68..b2b98be643a 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -24,7 +24,7 @@ res.users - + @@ -75,10 +75,7 @@ - - - Case Sections - Search crm.case.section @@ -99,7 +96,6 @@ - Sales Teams crm.case.section @@ -175,7 +171,6 @@ - crm.case.section.tree crm.case.section @@ -189,15 +184,6 @@ - - - - Sales Teams crm.case.section @@ -213,7 +199,6 @@

- - + \ No newline at end of file diff --git a/addons/sale_team/sale_team_config.py b/addons/sale_team/sale_team_config.py index 33a5e84b8de..2ae861e34b5 100644 --- a/addons/sale_team/sale_team_config.py +++ b/addons/sale_team/sale_team_config.py @@ -1,8 +1,27 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## from openerp import SUPERUSER_ID from openerp.osv import fields, osv - class sala_team_configuration(osv.TransientModel): _name = 'sale.team.config.settings' _inherit = ['sale.config.settings', 'fetchmail.config.settings'] @@ -35,11 +54,7 @@ class sala_team_configuration(osv.TransientModel): return True _columns = { - 'group_multi_salesteams': fields.boolean("Organize Sales activities into multiple Sales Teams", implied_group='base.group_multi_salesteams', help="""Allows you to use Sales Teams to manage your leads and opportunities."""), - } - - - + } \ No newline at end of file diff --git a/addons/sale_team/sale_team_demo.xml b/addons/sale_team/sale_team_demo.xml index b24c047fba1..58f5ac66b69 100644 --- a/addons/sale_team/sale_team_demo.xml +++ b/addons/sale_team/sale_team_demo.xml @@ -15,6 +15,5 @@ SPD - \ No newline at end of file diff --git a/addons/sale_team/ir.model.access.csv b/addons/sale_team/security/ir.model.access.csv similarity index 87% rename from addons/sale_team/ir.model.access.csv rename to addons/sale_team/security/ir.model.access.csv index 9817ad834f6..e3c55739176 100644 --- a/addons/sale_team/ir.model.access.csv +++ b/addons/sale_team/security/ir.model.access.csv @@ -1,5 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,0,0,0 -access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 - +access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 \ No newline at end of file diff --git a/addons/sale_team/security/sale_team_security.xml b/addons/sale_team/security/sale_team_security.xml index 53fb560e332..11e4f583dda 100644 --- a/addons/sale_team/security/sale_team_security.xml +++ b/addons/sale_team/security/sale_team_security.xml @@ -35,6 +35,5 @@ - From d4826eb6d776dbc80b2099915bcc149a3892c027 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Tue, 22 Apr 2014 14:12:07 +0530 Subject: [PATCH 19/46] [IMP] improve dependancy for section_sales_department --- addons/crm_helpdesk/crm_helpdesk_demo.xml | 6 ++--- addons/project_issue/project_issue_demo.xml | 30 ++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/addons/crm_helpdesk/crm_helpdesk_demo.xml b/addons/crm_helpdesk/crm_helpdesk_demo.xml index 1370bf6d906..c76949f78f8 100644 --- a/addons/crm_helpdesk/crm_helpdesk_demo.xml +++ b/addons/crm_helpdesk/crm_helpdesk_demo.xml @@ -7,7 +7,7 @@ 3 draft - + Download old version of OpenERP? @@ -19,7 +19,7 @@ 3 draft - + Can not able to connect to Server @@ -31,7 +31,7 @@ 2 draft - + Documentation for CRM? diff --git a/addons/project_issue/project_issue_demo.xml b/addons/project_issue/project_issue_demo.xml index 63fa37c84c3..e16b8702551 100644 --- a/addons/project_issue/project_issue_demo.xml +++ b/addons/project_issue/project_issue_demo.xml @@ -38,7 +38,7 @@ 5 - + @@ -54,7 +54,7 @@ 3 - + Program not giving proper output @@ -66,7 +66,7 @@ 4 - + @@ -82,7 +82,7 @@ 3 - + @@ -95,7 +95,7 @@ 3 - + @@ -108,7 +108,7 @@ 3 - + @@ -124,7 +124,7 @@ 2 - + @@ -137,7 +137,7 @@ 2 - + @@ -162,7 +162,7 @@ 2 - + @@ -175,7 +175,7 @@ 4 - + @@ -188,7 +188,7 @@ 1 - + @@ -202,7 +202,7 @@ 3 - + @@ -216,7 +216,7 @@ 3 - + @@ -229,7 +229,7 @@ 4 - + @@ -242,7 +242,7 @@ 2 - + From 5d7e462046d237f0cff14910eb63a6a5b4a96638 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Tue, 22 Apr 2014 15:17:25 +0530 Subject: [PATCH 20/46] [IMP] improve crm_partner_assing demo file --- addons/crm_partner_assign/crm_lead_demo.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm_partner_assign/crm_lead_demo.xml b/addons/crm_partner_assign/crm_lead_demo.xml index 6631131d054..3338b392048 100644 --- a/addons/crm_partner_assign/crm_lead_demo.xml +++ b/addons/crm_partner_assign/crm_lead_demo.xml @@ -16,7 +16,7 @@ 2 - + Hi, From 579d261468900fc9e89303deab5ed609fdaa8eeb Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Tue, 22 Apr 2014 17:20:49 +0530 Subject: [PATCH 21/46] [IMP] solve yml issues --- addons/crm/crm.py | 3 +++ addons/crm/crm_action_rule_demo.xml | 2 +- addons/crm/test/crm_lead_cancel.yml | 2 +- addons/crm/test/crm_lead_find_stage.yml | 2 +- addons/crm/test/lead2opportunity2win.yml | 2 +- addons/crm/test/lead2opportunity_assign_salesmen.yml | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 86350b472a7..f746893c2d6 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -118,6 +118,9 @@ class crm_case_section(osv.osv): res[id]['monthly_open_leads'] = self.__get_bar_values(cr, uid, obj, lead_domain, ['create_date'], 'create_date_count', 'create_date', context=context) res[id]['monthly_planned_revenue'] = self.__get_bar_values(cr, uid, obj, opp_domain, ['planned_revenue', 'date_deadline'], 'planned_revenue', 'date_deadline', context=context) return res + def create(self, cr, uid, vals, context=None): + self._alias_model_name = 'crm.lead' + return super(crm_case_section, self).create(cr, uid, vals, context={'alias_model_name': self._alias_model_name}) _columns = { 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), diff --git a/addons/crm/crm_action_rule_demo.xml b/addons/crm/crm_action_rule_demo.xml index 8eac91c06e2..2524132c4d4 100644 --- a/addons/crm/crm_action_rule_demo.xml +++ b/addons/crm/crm_action_rule_demo.xml @@ -41,7 +41,7 @@ True ir.actions.server code - sales_team = self.pool.get('ir.model.data').get_object(cr, uid, 'crm', 'section_sales_department') + sales_team = self.pool.get('ir.model.data').get_object(cr, uid, 'sale_team', 'section_sales_department') object.write({'section_id': sales_team.id}) diff --git a/addons/crm/test/crm_lead_cancel.yml b/addons/crm/test/crm_lead_cancel.yml index dd475d54919..fa98f47e6ea 100644 --- a/addons/crm/test/crm_lead_cancel.yml +++ b/addons/crm/test/crm_lead_cancel.yml @@ -5,7 +5,7 @@ uid: 'crm_res_users_salesmanager' - !python {model: crm.lead}: | - section_id = self.pool.get('crm.case.section').create(cr, uid, {'name': "Phone Marketing", 'parent_id': ref("crm.crm_case_section_2")}) + section_id = self.pool.get('crm.case.section').create(cr, uid, {'name': "Phone Marketing", 'parent_id': ref("sale_team.crm_case_section_2")}) self.write(cr, uid, [ref("crm_case_1")], {'section_id': section_id}) - Salesman check unqualified lead . diff --git a/addons/crm/test/crm_lead_find_stage.yml b/addons/crm/test/crm_lead_find_stage.yml index b8a11a4af9e..9fcff6ab512 100644 --- a/addons/crm/test/crm_lead_find_stage.yml +++ b/addons/crm/test/crm_lead_find_stage.yml @@ -6,7 +6,7 @@ name: 'Test lead new' partner_id: base.res_partner_1 description: This is the description of the test new lead. - section_id: crm.section_sales_department + section_id: sale_team.section_sales_department - I check default stage of lead. - diff --git a/addons/crm/test/lead2opportunity2win.yml b/addons/crm/test/lead2opportunity2win.yml index 0650838e4cc..c91768bcc07 100644 --- a/addons/crm/test/lead2opportunity2win.yml +++ b/addons/crm/test/lead2opportunity2win.yml @@ -65,7 +65,7 @@ - !python {model: crm.lead2opportunity.partner.mass}: | context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_13"), ref("crm_case_2")], 'active_id': ref("crm_case_13")}) - id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('base.user_root')])], 'section_id': ref('crm.section_sales_department')}, context=context) + id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('base.user_root')])], 'section_id': ref('sale_team.section_sales_department')}, context=context) self.mass_convert(cr, uid, [id], context=context) - Now I check first lead converted on opportunity. diff --git a/addons/crm/test/lead2opportunity_assign_salesmen.yml b/addons/crm/test/lead2opportunity_assign_salesmen.yml index 76b35be531d..6206db33050 100644 --- a/addons/crm/test/lead2opportunity_assign_salesmen.yml +++ b/addons/crm/test/lead2opportunity_assign_salesmen.yml @@ -66,7 +66,7 @@ - !python {model: crm.lead2opportunity.partner.mass}: | context.update({'active_model': 'crm.lead', 'active_ids': [ref("test_crm_lead_01"), ref("test_crm_lead_02"), ref("test_crm_lead_03"), ref("test_crm_lead_04"), ref("test_crm_lead_05"), ref("test_crm_lead_06")], 'active_id': ref("test_crm_lead_01")}) - id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('test_res_user_01'), ref('test_res_user_02'), ref('test_res_user_03'), ref('test_res_user_04')])], 'section_id': ref('crm.section_sales_department'), 'deduplicate': False, 'force_assignation': True}, context=context) + id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('test_res_user_01'), ref('test_res_user_02'), ref('test_res_user_03'), ref('test_res_user_04')])], 'section_id': ref('sale_team.section_sales_department'), 'deduplicate': False, 'force_assignation': True}, context=context) self.mass_convert(cr, uid, [id], context=context) - The leads should now be opps with a salesman and a salesteam. Also, salesmen should have been assigned following a round-robin method. From 2f5250edfa5315b323deb23b3436606f3effc636 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Wed, 23 Apr 2014 15:17:33 +0530 Subject: [PATCH 22/46] [IMP] improve inherited crm_case_section --- addons/crm/crm.py | 40 ++++++++++++++----- addons/crm/crm_case_section_view.xml | 3 +- addons/sale_team/sale_team.py | 19 +-------- addons/sale_team/sale_team.xml | 3 +- .../sale_team/security/sale_team_security.xml | 12 +++++- 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index f746893c2d6..ef9cb89d5c2 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -88,13 +88,9 @@ class crm_case_stage(osv.osv): } -class crm_case_section(osv.osv): - """ Model for sales teams. """ - _name = "crm.case.section" +class crm_case_section(osv.Model): _inherit = 'crm.case.section' - _description = "Sales Teams" - _alias_model_name = 'crm.lead' - + _name = 'crm.case.section' def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None): """ Get opportunities-related data for salesteam kanban view monthly_open_leads: number of open lead during the last months @@ -118,10 +114,7 @@ class crm_case_section(osv.osv): res[id]['monthly_open_leads'] = self.__get_bar_values(cr, uid, obj, lead_domain, ['create_date'], 'create_date_count', 'create_date', context=context) res[id]['monthly_planned_revenue'] = self.__get_bar_values(cr, uid, obj, opp_domain, ['planned_revenue', 'date_deadline'], 'planned_revenue', 'date_deadline', context=context) return res - def create(self, cr, uid, vals, context=None): - self._alias_model_name = 'crm.lead' - return super(crm_case_section, self).create(cr, uid, vals, context={'alias_model_name': self._alias_model_name}) - + _columns = { 'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"), 'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'), @@ -143,7 +136,32 @@ class crm_case_section(osv.osv): 'stage_ids': _get_stage_common, 'use_leads': True, } - + +class crm_case_section_inherit(osv.Model): + """ Model for sales teams. """ + _inherit = 'crm.case.section' + _name = 'crm.case.section.inherit' + _description = "Sales Teams" + _inherits = {'mail.alias': 'alias_id'} + _columns = { + 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), + } + def create(self, cr, uid, vals, context=None): + if context is None: + context = {} + create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name) + section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) + section = self.browse(cr, uid, section_id, context=context) + self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) + return section_id + + def unlink(self, cr, uid, ids, context=None): + # Cascade-delete mail aliases as well, as they should not exist without the sales team. + mail_alias = self.pool.get('mail.alias') + alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] + res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) + mail_alias.unlink(cr, uid, alias_ids, context=context) + return res class crm_case_categ(osv.osv): """ Category of Case """ _name = "crm.case.categ" diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 57f5b70bfe8..eb86842e3bd 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -83,7 +83,7 @@ crm.case.section.kanban - crm.case.section + crm.case.section.inherit @@ -91,6 +91,7 @@ +
diff --git a/addons/sale_team/sale_team.py b/addons/sale_team/sale_team.py index db0e4638048..299e6564f56 100644 --- a/addons/sale_team/sale_team.py +++ b/addons/sale_team/sale_team.py @@ -30,10 +30,8 @@ class crm_case_section(osv.osv): _name = "crm.case.section" _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = "Sales Teams" - _inherits = {'mail.alias': 'alias_id'} _order = "complete_name" _period_number = 5 - _alias_model_name = 'mail.message' def get_full_name(self, cr, uid, ids, field_name, arg, context=None): return dict(self.name_get(cr, uid, ids, context=context)) @@ -69,7 +67,6 @@ class crm_case_section(osv.osv): return section_result _columns = { - 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), 'name': fields.char('Sales Team', size=64, required=True, translate=True), 'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True), 'code': fields.char('Code', size=8), @@ -114,21 +111,7 @@ class crm_case_section(osv.osv): res.append((record['id'], name)) return res - def create(self, cr, uid, vals, context=None): - if context is None: - context = {} - create_context = dict(context, alias_model_name=self._alias_model_name, alias_parent_model_name=self._name) - section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context) - section = self.browse(cr, uid, section_id, context=context) - self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context) - return section_id - def unlink(self, cr, uid, ids, context=None): - # Cascade-delete mail aliases as well, as they should not exist without the sales team. - mail_alias = self.pool.get('mail.alias') - alias_ids = [team.alias_id.id for team in self.browse(cr, uid, ids, context=context) if team.alias_id] - res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) - mail_alias.unlink(cr, uid, alias_ids, context=context) - return res + class res_users(osv.Model): _inherit = 'res.users' diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index b2b98be643a..a044c455b4a 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -42,7 +42,6 @@ - @@ -58,7 +57,7 @@

-
+
%%
diff --git a/addons/sale_team/security/sale_team_security.xml b/addons/sale_team/security/sale_team_security.xml index 11e4f583dda..fe999715a7a 100644 --- a/addons/sale_team/security/sale_team_security.xml +++ b/addons/sale_team/security/sale_team_security.xml @@ -23,7 +23,17 @@ - + + + Do Not Use Sales Teams + + + + + Manage Sales Teams + + + From a26436c57e7fd8408d91f44b3ab11c18600a5a0b Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Wed, 23 Apr 2014 17:51:52 +0530 Subject: [PATCH 23/46] [IMP] improve kanban view --- addons/crm/crm_case_section_view.xml | 22 +++++++++++++++++----- addons/crm/crm_demo.xml | 4 ---- addons/sale_team/sale_team.xml | 3 --- addons/sale_team/sale_team_demo.xml | 4 ++++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index eb86842e3bd..6de1a8b6094 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -80,7 +80,6 @@ - crm.case.section.kanban crm.case.section.inherit @@ -88,15 +87,28 @@ - - - - +
%%
+
+
+
+
+ + crm.case.section.kanban + crm.case.section + + + + + + + + +
Leads diff --git a/addons/crm/crm_demo.xml b/addons/crm/crm_demo.xml index 1541753523a..df776f92350 100644 --- a/addons/crm/crm_demo.xml +++ b/addons/crm/crm_demo.xml @@ -2,10 +2,6 @@ - - - - OpenERP partners True diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index a044c455b4a..a00bbe6665b 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -57,9 +57,6 @@

-
- %% -
diff --git a/addons/sale_team/sale_team_demo.xml b/addons/sale_team/sale_team_demo.xml index 58f5ac66b69..0e698d8f1fa 100644 --- a/addons/sale_team/sale_team_demo.xml +++ b/addons/sale_team/sale_team_demo.xml @@ -1,6 +1,10 @@ + + + + From 5cf064805867e7de0f33f03d5efbc02a34020432 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Wed, 23 Apr 2014 18:21:33 +0530 Subject: [PATCH 24/46] [IMP] improve alias_name --- addons/crm/crm_case_section_view.xml | 2 +- addons/sale_team/sale_team_data.xml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 5053cc5c308..950f017a473 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -163,7 +163,7 @@ crm.case.section.form - crm.case.section + crm.case.section.inherit diff --git a/addons/sale_team/sale_team_data.xml b/addons/sale_team/sale_team_data.xml index eef5e5809a1..2f296143ec0 100644 --- a/addons/sale_team/sale_team_data.xml +++ b/addons/sale_team/sale_team_data.xml @@ -4,7 +4,6 @@ Direct Sales DM - sales From e8bed3e41fb97c601f8de2f53b16c3854459ee78 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Wed, 23 Apr 2014 18:45:33 +0530 Subject: [PATCH 25/46] [IMP] improve alias_name --- addons/website_sale_crm/data/website_sale_crm.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/website_sale_crm/data/website_sale_crm.xml b/addons/website_sale_crm/data/website_sale_crm.xml index dad22228f01..716bce75766 100644 --- a/addons/website_sale_crm/data/website_sale_crm.xml +++ b/addons/website_sale_crm/data/website_sale_crm.xml @@ -5,7 +5,6 @@ Website Website - Website From 74f60e621227aea1736b3d3a337cf8e09e41f15e Mon Sep 17 00:00:00 2001 From: Ravi Gadhia Date: Thu, 1 May 2014 14:15:42 +0530 Subject: [PATCH 26/46] [REM] crm.case.section.inherit use crm.case.section for get aliase_id --- addons/crm/crm_case_section_view.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml index 950f017a473..94f59217065 100644 --- a/addons/crm/crm_case_section_view.xml +++ b/addons/crm/crm_case_section_view.xml @@ -82,7 +82,7 @@ crm.case.section.kanban - crm.case.section.inherit + crm.case.section @@ -163,7 +163,7 @@ crm.case.section.form - crm.case.section.inherit + crm.case.section @@ -195,4 +195,4 @@ - \ No newline at end of file + From ca008ef74be82fa786b2388d870687f103b8dcb4 Mon Sep 17 00:00:00 2001 From: Ravi Gadhia Date: Fri, 2 May 2014 14:53:09 +0530 Subject: [PATCH 27/46] [IMP] remove print + innecessary diff on merge --- addons/gamification/models/goal.py | 4 ++-- addons/gamification_sale_crm/sale_crm_goals_demo.xml | 10 ---------- addons/mail/mail_alias.py | 1 - 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 1a7c489f575..7bbecbfa052 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -282,7 +282,7 @@ class gamification_goal(osv.Model): _logger.exception(_('Invalid return content from the evaluation of code for definition %s' % definition.name)) else: # count or sum - + obj = self.pool.get(definition.model_id.model) field_date_name = definition.field_date_id and definition.field_date_id.name or False @@ -349,7 +349,7 @@ class gamification_goal(osv.Model): if not value: continue goal = all_goals[goal_id] - + # # check goal target reached if (goal.definition_condition == 'higher' and value.get('current', goal.current) >= goal.target_goal) \ or (goal.definition_condition == 'lower' and value.get('current', goal.current) <= goal.target_goal): diff --git a/addons/gamification_sale_crm/sale_crm_goals_demo.xml b/addons/gamification_sale_crm/sale_crm_goals_demo.xml index dc3cc27135d..a4720b1e566 100644 --- a/addons/gamification_sale_crm/sale_crm_goals_demo.xml +++ b/addons/gamification_sale_crm/sale_crm_goals_demo.xml @@ -7,15 +7,5 @@ inprogress - - - - - - - - 2000 - - diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 54200283131..d8a79dd98e0 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -204,7 +204,6 @@ class mail_alias(osv.Model): alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems()) alias_vals['alias_parent_thread_id'] = obj_data['id'] alias_create_ctx = dict(context, alias_model_name=alias_model_name, alias_parent_model_name=child_model_name) - print 'EEEEEEEEEEEe',alias_vals, alias_create_ctx alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, context=alias_create_ctx) child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id}, context={'mail_notrack': True}) _logger.info('Mail alias created for %s %s (id %s)', child_model_name, obj_data[alias_key], obj_data['id']) From 6ccbd2cd8282b8301bba675efa705ca3de09dc73 Mon Sep 17 00:00:00 2001 From: Ravi Gadhia Date: Fri, 2 May 2014 17:23:18 +0530 Subject: [PATCH 28/46] [IMP] no need to inherit sale.order report we are already in sale/report +change file name for invoice report --- addons/sale/report/__init__.py | 4 +--- ...unt_invoice_report.py => invoice_report.py} | 0 addons/sale/report/sale_analysis_report.py | 18 ------------------ .../sale/report/sale_analysis_report_view.xml | 16 ---------------- addons/sale/report/sale_report.py | 7 +++++-- addons/sale/report/sale_report_view.xml | 1 + 6 files changed, 7 insertions(+), 39 deletions(-) rename addons/sale/report/{sales_crm_account_invoice_report.py => invoice_report.py} (100%) delete mode 100644 addons/sale/report/sale_analysis_report.py delete mode 100644 addons/sale/report/sale_analysis_report_view.xml diff --git a/addons/sale/report/__init__.py b/addons/sale/report/__init__.py index 0ce593424d3..be1073205c3 100644 --- a/addons/sale/report/__init__.py +++ b/addons/sale/report/__init__.py @@ -19,8 +19,6 @@ # ############################################################################## -import sales_crm_account_invoice_report import sale_report -import sale_analysis_report - +import invoice_report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/report/sales_crm_account_invoice_report.py b/addons/sale/report/invoice_report.py similarity index 100% rename from addons/sale/report/sales_crm_account_invoice_report.py rename to addons/sale/report/invoice_report.py diff --git a/addons/sale/report/sale_analysis_report.py b/addons/sale/report/sale_analysis_report.py deleted file mode 100644 index eca020f82ad..00000000000 --- a/addons/sale/report/sale_analysis_report.py +++ /dev/null @@ -1,18 +0,0 @@ - # -*- coding: utf-8 -*- - -from openerp.osv import fields, osv - - -class sale_report(osv.osv): - _inherit = "sale.report" - _columns = { - 'section_id': fields.many2one('crm.case.section', 'Sales Team'), - } - - def _select(self): - return super(sale_report, self)._select() + ", s.section_id as section_id" - - def _group_by(self): - return super(sale_report, self)._group_by() + ", s.section_id" - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/report/sale_analysis_report_view.xml b/addons/sale/report/sale_analysis_report_view.xml deleted file mode 100644 index 83613219046..00000000000 --- a/addons/sale/report/sale_analysis_report_view.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - sale.report.search.sale.crm - sale.report - - - - - - - - - - \ No newline at end of file diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py index 5d6a1cd759c..8a54da5901e 100644 --- a/addons/sale/report/sale_report.py +++ b/addons/sale/report/sale_report.py @@ -53,6 +53,7 @@ class sale_report(osv.osv): ], 'Order Status', readonly=True), 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', readonly=True), 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True), + 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } _order = 'date desc' @@ -73,7 +74,8 @@ class sale_report(osv.osv): s.state, t.categ_id as categ_id, s.pricelist_id as pricelist_id, - s.project_id as analytic_account_id + s.project_id as analytic_account_id, + s.section_id as section_id """ return select_str @@ -101,7 +103,8 @@ class sale_report(osv.osv): s.company_id, s.state, s.pricelist_id, - s.project_id + s.project_id, + s.section_id """ return group_by_str diff --git a/addons/sale/report/sale_report_view.xml b/addons/sale/report/sale_report_view.xml index 14b719ebd7a..b8ce36efc2b 100644 --- a/addons/sale/report/sale_report_view.xml +++ b/addons/sale/report/sale_report_view.xml @@ -34,6 +34,7 @@ + From adf1480f7104df47a80228459bca4539d399046f Mon Sep 17 00:00:00 2001 From: Ravi Gadhia Date: Fri, 2 May 2014 18:18:40 +0530 Subject: [PATCH 29/46] [IMP] add alias name --- addons/crm/crm_data.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml index 41f4819e500..cec54a683bd 100644 --- a/addons/crm/crm_data.xml +++ b/addons/crm/crm_data.xml @@ -28,6 +28,7 @@ True + sales From 6ddbf83c1a4c7d590b5dabe788ba57f6389fdf47 Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Tue, 6 May 2014 12:34:38 +0530 Subject: [PATCH 30/46] [IMP]fix type + chaneg class name from sala_team_configuration to sale_team_configuration & change model name sale.config.sattings --- addons/sale_team/res_config_view.xml | 28 +++++++++---------- addons/sale_team/sale_team_config.py | 4 +-- addons/sale_team/security/ir.model.access.csv | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml index ddcc72b5375..a9d9f08fdd4 100644 --- a/addons/sale_team/res_config_view.xml +++ b/addons/sale_team/res_config_view.xml @@ -1,26 +1,26 @@ - + crm settings - sale.team.config.settings + sale.config.settings -
- - - +
+
+
diff --git a/addons/sale_team/sale_team_config.py b/addons/sale_team/sale_team_config.py index 344c38313c9..c6adeb73a55 100644 --- a/addons/sale_team/sale_team_config.py +++ b/addons/sale_team/sale_team_config.py @@ -22,8 +22,8 @@ from openerp.osv import fields, osv -class sala_team_configuration(osv.TransientModel): - _name = 'sale.team.config.settings' +class sale_team_configuration(osv.TransientModel): + _name = 'sale.config.settings' _inherit = ['sale.config.settings', 'fetchmail.config.settings'] def set_group_multi_salesteams(self, cr, uid, ids, context=None): diff --git a/addons/sale_team/security/ir.model.access.csv b/addons/sale_team/security/ir.model.access.csv index e3c55739176..f983a2abb9d 100644 --- a/addons/sale_team/security/ir.model.access.csv +++ b/addons/sale_team/security/ir.model.access.csv @@ -1,4 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_crm_case_section,crm.case.section,model_crm_case_section,base.group_user,1,0,0,0 access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,0,0,0 -access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 \ No newline at end of file +access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 From 14cf5e1631520fa4c0793220c62165439f30f84c Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Tue, 6 May 2014 12:42:08 +0530 Subject: [PATCH 31/46] [IMP] change record id in res_config_view.xml --- addons/sale_team/res_config_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml index a9d9f08fdd4..dd5d0ffca66 100644 --- a/addons/sale_team/res_config_view.xml +++ b/addons/sale_team/res_config_view.xml @@ -1,7 +1,7 @@ - + crm settings sale.config.settings From 10beeb53ede95800f649f05449acc47f06b78454 Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Tue, 6 May 2014 15:38:12 +0530 Subject: [PATCH 32/46] [MERGE]merge with trunk --- addons/sale_team/res_config_view.xml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml index dd5d0ffca66..e8f2265f1e3 100644 --- a/addons/sale_team/res_config_view.xml +++ b/addons/sale_team/res_config_view.xml @@ -7,20 +7,23 @@ -
- - - -
+
+ + + +
+ +
From e511de45cbe46f5f93358aa23d405588ed485cac Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Wed, 7 May 2014 11:50:06 +0530 Subject: [PATCH 33/46] [ADD]crm_case_section (view & py file) add in sale module, that file split from sale.py & sale_view.xml --- addons/sale/__init__.py | 1 + addons/sale/__openerp__.py | 1 + addons/sale/crm_case_section.py | 85 +++++++++++++++++++++++++++ addons/sale/crm_case_section_view.xml | 74 +++++++++++++++++++++++ addons/sale/sale.py | 50 ---------------- addons/sale/sale_view.xml | 70 ---------------------- addons/sale_team/res_config_view.xml | 27 ++++----- addons/sale_team/sale_team.xml | 4 +- 8 files changed, 176 insertions(+), 136 deletions(-) create mode 100644 addons/sale/crm_case_section.py create mode 100644 addons/sale/crm_case_section_view.xml diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index 5a7b4b499df..509364643ae 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -24,6 +24,7 @@ #---------------------------------------------------------- import sale +import crm_case_section import res_partner import wizard import report diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index c7348e5b37d..2faeb5b3693 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -71,6 +71,7 @@ The Dashboard for the Sales Manager will include 'sale_report.xml', 'sale_data.xml', 'sale_view.xml', + 'crm_case_section_view.xml', 'res_partner_view.xml', 'report/sale_report_view.xml', 'edi/sale_order_action_data.xml', diff --git a/addons/sale/crm_case_section.py b/addons/sale/crm_case_section.py new file mode 100644 index 00000000000..11c8cdc8bb4 --- /dev/null +++ b/addons/sale/crm_case_section.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import calendar +from openerp import tools +from datetime import date, datetime, timedelta +from dateutil.relativedelta import relativedelta +from dateutil import relativedelta +import time +from openerp.osv import fields, osv +from openerp.tools.translate import _ +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare +import openerp.addons.decimal_precision as dp +from openerp import workflow + + +class crm_case_section(osv.osv): + _inherit = 'crm.case.section' + + def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None): + obj = self.pool.get('sale.order') + res = dict.fromkeys(ids, False) + month_begin = date.today().replace(day=1) + date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + for id in ids: + res[id] = dict() + created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] + res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) + validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] + res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) + return res + + def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None): + obj = self.pool.get('account.invoice.report') + res = dict.fromkeys(ids, False) + month_begin = date.today().replace(day=1) + date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + for id in ids: + created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)] + res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context) + return res + + _columns = { + 'invoiced_forecast': fields.integer(string='Invoice Forecast', + help="Forecast of the invoice revenue for the current month. This is the amount the sales \n" + "team should invoice this month. It is used to compute the progression ratio \n" + " of the current and forecast revenue on the kanban view."), + 'invoiced_target': fields.integer(string='Invoice Target', + help="Target of invoice revenue for the current month. This is the amount the sales \n" + "team estimates to be able to invoice this month."), + 'monthly_quoted': fields.function(_get_sale_orders_data, + type='string', readonly=True, multi='_get_sale_orders_data', + string='Rate of created quotation per duration'), + 'monthly_confirmed': fields.function(_get_sale_orders_data, + type='string', readonly=True, multi='_get_sale_orders_data', + string='Rate of validate sales orders per duration'), + 'monthly_invoiced': fields.function(_get_invoices_data, + type='string', readonly=True, + string='Rate of sent invoices per duration'), + } + + def action_forecast(self, cr, uid, id, value, context=None): + return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/crm_case_section_view.xml b/addons/sale/crm_case_section_view.xml new file mode 100644 index 00000000000..e4d36f23918 --- /dev/null +++ b/addons/sale/crm_case_section_view.xml @@ -0,0 +1,74 @@ + + + + + crm.case.section.form + crm.case.section + + + + + + + + + + + + + crm.case.section.kanban + crm.case.section + + + + + + + + + + + + + + +
+ Invoiced + Forecast +
+
+
Define an invoicing target in the sales team settings to see the period's achievement and forecast at a glance. +
+
+
+
+
+
+
diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 1270534ae6d..53ab1c38a8b 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1042,56 +1042,6 @@ class account_invoice(osv.Model): _defaults = { 'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, } - -class crm_case_section(osv.osv): - _inherit = 'crm.case.section' - - def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None): - obj = self.pool.get('sale.order') - res = dict.fromkeys(ids, False) - month_begin = date.today().replace(day=1) - date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - for id in ids: - res[id] = dict() - created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] - res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) - validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)] - res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context) - return res - - def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None): - obj = self.pool.get('account.invoice.report') - res = dict.fromkeys(ids, False) - month_begin = date.today().replace(day=1) - date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - for id in ids: - created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)] - res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context) - return res - - _columns = { - 'invoiced_forecast': fields.integer(string='Invoice Forecast', - help="Forecast of the invoice revenue for the current month. This is the amount the sales \n" - "team should invoice this month. It is used to compute the progression ratio \n" - " of the current and forecast revenue on the kanban view."), - 'invoiced_target': fields.integer(string='Invoice Target', - help="Target of invoice revenue for the current month. This is the amount the sales \n" - "team estimates to be able to invoice this month."), - 'monthly_quoted': fields.function(_get_sale_orders_data, - type='string', readonly=True, multi='_get_sale_orders_data', - string='Rate of created quotation per duration'), - 'monthly_confirmed': fields.function(_get_sale_orders_data, - type='string', readonly=True, multi='_get_sale_orders_data', - string='Rate of validate sales orders per duration'), - 'monthly_invoiced': fields.function(_get_invoices_data, - type='string', readonly=True, - string='Rate of sent invoices per duration'), - } - - def action_forecast(self, cr, uid, id, value, context=None): - return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context) class product_product(osv.Model): _inherit = 'product.product' diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 223bc5fe1f0..8aabe31fc93 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -682,75 +682,5 @@ {'search_default_month':1} From this report, you can have an overview of the amount invoiced to your customer. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs. - - - crm.case.section.form - crm.case.section - - - - - - - - - - - - - crm.case.section.kanban - crm.case.section - - - - - - - - - - - - - - -
- Invoiced - Forecast -
-
-
Define an invoicing target in the sales team settings to see the period's achievement and forecast at a glance. -
-
-
-
-
diff --git a/addons/sale_team/res_config_view.xml b/addons/sale_team/res_config_view.xml index e8f2265f1e3..88a51e78cda 100644 --- a/addons/sale_team/res_config_view.xml +++ b/addons/sale_team/res_config_view.xml @@ -7,23 +7,22 @@ -
- - - -
+
+ + + +
- - diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index a00bbe6665b..2512c20efb6 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -34,7 +34,7 @@ - + crm.case.section.kanban crm.case.section @@ -197,4 +197,4 @@ - \ No newline at end of file + From ec267fc210e00761a42129fd81eb9ba5985bb440 Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Thu, 8 May 2014 18:59:16 +0530 Subject: [PATCH 34/46] [IMP]add dicription --- addons/sale_team/__openerp__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index f141bdc76d0..b380df08313 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -24,7 +24,9 @@ 'author': 'OpenERP SA', 'category': 'Sales Management', 'summary': 'Sales Team', - 'description': """ """, + 'description': """ +Using this application you can manage Sales Team with CRM and/or Sales + """, 'website': 'http://www.openerp.com', 'depends': ['base','mail','web_kanban_sparkline',], 'data': ['security/sale_team_security.xml', From 0e08ceddb19b7e5ccde12a4b032c6833b8c57bdd Mon Sep 17 00:00:00 2001 From: Mantavya Gajjar Date: Fri, 9 May 2014 13:08:26 +0530 Subject: [PATCH 35/46] [FIX]: review sale_team to add groups on section_id field --- addons/crm/crm_lead_view.xml | 1 + addons/sale_team/sale_team.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index dc297492020..88d0349b939 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -2,6 +2,7 @@ + diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index 2512c20efb6..8155fdd8ce0 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -77,12 +77,12 @@ crm.case.section + - From 6c0389279a7275e07f4b6d8751b79dfb8086d3ba Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Fri, 9 May 2014 13:13:13 +0530 Subject: [PATCH 36/46] [IMP]add groups 'base.group_multi_salesteams' on sales team dependent module --- addons/crm/crm_lead_view.xml | 2 +- addons/crm/report/crm_lead_report_view.xml | 2 +- addons/crm/report/crm_phonecall_report_view.xml | 2 +- addons/crm_partner_assign/report/crm_lead_report_view.xml | 4 ++-- addons/crm_partner_assign/report/crm_partner_report_view.xml | 4 ++-- addons/sale/report/sale_report_view.xml | 2 +- addons/sale_team/__openerp__.py | 1 + addons/sale_team/sale_team.xml | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 88d0349b939..25af392d998 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -575,7 +575,7 @@ - + diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml index 1dda471c2f2..239579a70c2 100644 --- a/addons/crm/report/crm_lead_report_view.xml +++ b/addons/crm/report/crm_lead_report_view.xml @@ -81,7 +81,7 @@ - + diff --git a/addons/crm/report/crm_phonecall_report_view.xml b/addons/crm/report/crm_phonecall_report_view.xml index 32ae9704064..98f4a58d7c4 100644 --- a/addons/crm/report/crm_phonecall_report_view.xml +++ b/addons/crm/report/crm_phonecall_report_view.xml @@ -47,7 +47,7 @@ - + diff --git a/addons/crm_partner_assign/report/crm_lead_report_view.xml b/addons/crm_partner_assign/report/crm_lead_report_view.xml index 271c9b2016f..43997ac5609 100644 --- a/addons/crm_partner_assign/report/crm_lead_report_view.xml +++ b/addons/crm_partner_assign/report/crm_lead_report_view.xml @@ -27,9 +27,9 @@ domain="[]" context="{'group_by':'user_id'}" /> - + context="{'group_by':'section_id'}" groups="base.group_multi_salesteams"/> diff --git a/addons/crm_partner_assign/report/crm_partner_report_view.xml b/addons/crm_partner_assign/report/crm_partner_report_view.xml index 02320219218..62e54260285 100644 --- a/addons/crm_partner_assign/report/crm_partner_report_view.xml +++ b/addons/crm_partner_assign/report/crm_partner_report_view.xml @@ -16,8 +16,8 @@ - + - + diff --git a/addons/sale_team/__openerp__.py b/addons/sale_team/__openerp__.py index b380df08313..ebca1e7100e 100644 --- a/addons/sale_team/__openerp__.py +++ b/addons/sale_team/__openerp__.py @@ -26,6 +26,7 @@ 'summary': 'Sales Team', 'description': """ Using this application you can manage Sales Team with CRM and/or Sales +======================================================================= """, 'website': 'http://www.openerp.com', 'depends': ['base','mail','web_kanban_sparkline',], diff --git a/addons/sale_team/sale_team.xml b/addons/sale_team/sale_team.xml index 8155fdd8ce0..56d709efce5 100644 --- a/addons/sale_team/sale_team.xml +++ b/addons/sale_team/sale_team.xml @@ -195,6 +195,6 @@

- + From 146051db29cee16b5e93f74d4080bdc1831fc7d5 Mon Sep 17 00:00:00 2001 From: Mantavya Gajjar Date: Fri, 9 May 2014 13:14:38 +0530 Subject: [PATCH 37/46] [FIX]: review, add default to get the current state --- addons/sale_team/sale_team_config.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/sale_team/sale_team_config.py b/addons/sale_team/sale_team_config.py index c6adeb73a55..0c36ac31084 100644 --- a/addons/sale_team/sale_team_config.py +++ b/addons/sale_team/sale_team_config.py @@ -58,3 +58,12 @@ class sale_team_configuration(osv.TransientModel): implied_group='base.group_multi_salesteams', help="""Allows you to use Sales Teams to manage your leads and opportunities."""), } + + def _get_group_multi_salesteams(self, cr, uid, ids, context=None): + pass + # Todo: return the current state for the group_multi_salesteams field + + _defaults = { + 'group_multi_salesteams': _get_group_multi_salesteams + } + From ca2bee0865c086dbbc4b1a2effa46fce382a98a5 Mon Sep 17 00:00:00 2001 From: "Prashant Panchal (OpenERP)" Date: Fri, 9 May 2014 16:16:07 +0530 Subject: [PATCH 38/46] [IMP]add groups 'base.group_multi_salesteams' --- addons/crm/crm_lead_view.xml | 5 +---- addons/crm/wizard/crm_lead_to_opportunity_view.xml | 2 +- addons/crm/wizard/crm_merge_opportunities_view.xml | 2 +- addons/crm_claim/report/crm_claim_report_view.xml | 2 +- addons/crm_partner_assign/crm_portal_view.xml | 4 ++-- addons/project_issue/report/project_issue_report_view.xml | 2 +- addons/sale/sale_view.xml | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 25af392d998..5a7aac6e569 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -1,12 +1,9 @@ - - Stage - Search @@ -570,7 +567,7 @@ help="Opportunities that are assigned to me"/> + help="Opportunities that are assigned to any sales teams I am member of" groups="base.group_multi_salesteams"/> diff --git a/addons/crm/wizard/crm_lead_to_opportunity_view.xml b/addons/crm/wizard/crm_lead_to_opportunity_view.xml index 0f8f676d92d..58bbcf4d934 100644 --- a/addons/crm/wizard/crm_lead_to_opportunity_view.xml +++ b/addons/crm/wizard/crm_lead_to_opportunity_view.xml @@ -12,7 +12,7 @@ - + diff --git a/addons/crm/wizard/crm_merge_opportunities_view.xml b/addons/crm/wizard/crm_merge_opportunities_view.xml index f88a6fe6f17..92007d52e42 100644 --- a/addons/crm/wizard/crm_merge_opportunities_view.xml +++ b/addons/crm/wizard/crm_merge_opportunities_view.xml @@ -10,7 +10,7 @@
- + diff --git a/addons/crm_claim/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml index 710603af10a..2068ed8ea27 100644 --- a/addons/crm_claim/report/crm_claim_report_view.xml +++ b/addons/crm_claim/report/crm_claim_report_view.xml @@ -46,7 +46,7 @@ - + diff --git a/addons/crm_partner_assign/crm_portal_view.xml b/addons/crm_partner_assign/crm_portal_view.xml index dab831dcb4b..1ad0659d217 100644 --- a/addons/crm_partner_assign/crm_portal_view.xml +++ b/addons/crm_partner_assign/crm_portal_view.xml @@ -18,7 +18,7 @@ - +
- - - - - crm.case.section.kanban - crm.case.section - - - @@ -130,8 +120,41 @@ - + + crm.case.section.form + crm.case.section + + + +
+
+ + + + + + + + + + +
+
+ kanban @@ -160,39 +183,5 @@ tree - - - crm.case.section.form - crm.case.section - - - -
-
- - - - - - - - - - -
-
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 6be094c2227..7f5ae17dc33 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -90,7 +90,10 @@ class crm_lead(format_address, osv.osv): def _get_default_section_id(self, cr, uid, context=None): """ Gives default section by checking if present in the context """ - return self._resolve_section_id_from_context(cr, uid, context=context) or False + section_id = self._resolve_section_id_from_context(cr, uid, context=context) or False + if not section_id: + section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False + return section_id def _get_default_stage_id(self, cr, uid, context=None): """ Gives default stage_id """ @@ -352,12 +355,8 @@ class crm_lead(format_address, osv.osv): section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context) if section_ids: section_id = section_ids[0] - else: - user = self.pool.get('res.users').browse(cr, uid, user_id, context=context) - if user.default_section_id and user.default_section_id.id: - return {'value': {'section_id': user.default_section_id.id}} return {'value': {'section_id': section_id}} - + def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None): """ Override of the base.stage method Parameter of the stage search taken from the lead: diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml index ef105d3989e..8acefd5c610 100644 --- a/addons/crm/crm_lead_demo.xml +++ b/addons/crm/crm_lead_demo.xml @@ -54,7 +54,7 @@ Could you please send me the details ? - 4 + 1 @@ -104,7 +104,7 @@ Could you please send me the details ? - 3 + 2 @@ -129,7 +129,7 @@ Could you please send me the details ? - 3 + 2 diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 3481e29baf5..995a1ddea43 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -1,7 +1,7 @@ - diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py index 1cd31cd0dd0..d48e66e286c 100644 --- a/addons/crm/res_config.py +++ b/addons/crm/res_config.py @@ -27,33 +27,6 @@ class crm_configuration(osv.TransientModel): _name = 'sale.config.settings' _inherit = ['sale.config.settings', 'fetchmail.config.settings'] - def set_group_multi_salesteams(self, cr, uid, ids, context=None): - """ This method is automatically called by res_config as it begins - with set. It is used to implement the 'one group or another' - behavior. We have to perform some group manipulation by hand - because in res_config.execute(), set_* methods are called - after group_*; therefore writing on an hidden res_config file - could not work. - If group_multi_salesteams is checked: remove group_mono_salesteams - from group_user, remove the users. Otherwise, just add - group_mono_salesteams in group_user. - The inverse logic about group_multi_salesteams is managed by the - normal behavior of 'group_multi_salesteams' field. - """ - def ref(xml_id): - mod, xml = xml_id.split('.', 1) - return self.pool['ir.model.data'].get_object(cr, uid, mod, xml, context) - - for obj in self.browse(cr, uid, ids, context=context): - config_group = ref('base.group_mono_salesteams') - base_group = ref('base.group_user') - if obj.group_multi_salesteams: - base_group.write({'implied_ids': [(3, config_group.id)]}) - config_group.write({'users': [(3, u.id) for u in base_group.users]}) - else: - base_group.write({'implied_ids': [(4, config_group.id)]}) - return True - _columns = { 'group_fund_raising': fields.boolean("Manage Fund Raising", implied_group='crm.group_fund_raising', @@ -64,9 +37,6 @@ class crm_configuration(osv.TransientModel): '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.\n' '-This installs the module crm_helpdesk.'), - 'group_multi_salesteams': fields.boolean("Organize Sales activities into multiple Sales Teams", - implied_group='base.group_multi_salesteams', - help="""Allows you to use Sales Teams to manage your leads and opportunities."""), 'alias_prefix': fields.char('Default Alias Name for Leads'), 'alias_domain' : fields.char('Alias Domain'), 'group_scheduled_calls': fields.boolean("Schedule calls to manage call center", diff --git a/addons/crm/crm_case_section.py b/addons/crm/sales_team.py similarity index 99% rename from addons/crm/crm_case_section.py rename to addons/crm/sales_team.py index 7a8baca5a44..ac626563f36 100644 --- a/addons/crm/crm_case_section.py +++ b/addons/crm/sales_team.py @@ -78,4 +78,3 @@ class crm_case_section(osv.Model): res = super(crm_case_section, self).unlink(cr, uid, ids, context=context) mail_alias.unlink(cr, uid, alias_ids, context=context) return res - diff --git a/addons/sales_team/__init__.py b/addons/sales_team/__init__.py index 075d782f564..3b2a8f41267 100644 --- a/addons/sales_team/__init__.py +++ b/addons/sales_team/__init__.py @@ -19,6 +19,6 @@ # ############################################################################## import sales_team -import sales_team_config +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sales_team/sales_team_config.py b/addons/sales_team/res_config.py similarity index 59% rename from addons/sales_team/sales_team_config.py rename to addons/sales_team/res_config.py index 1e2a193acf7..3081a2e918d 100644 --- a/addons/sales_team/sales_team_config.py +++ b/addons/sales_team/res_config.py @@ -1,30 +1,11 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-today OpenERP SA () -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## from openerp.osv import fields, osv class sales_team_configuration(osv.TransientModel): _name = 'sale.config.settings' - _inherit = ['sale.config.settings', 'fetchmail.config.settings'] + _inherit = ['sale.config.settings'] def set_group_multi_salesteams(self, cr, uid, ids, context=None): """ This method is automatically called by res_config as it begins @@ -58,12 +39,3 @@ class sales_team_configuration(osv.TransientModel): implied_group='base.group_multi_salesteams', help="""Allows you to use Sales Teams to manage your leads and opportunities."""), } - - def _get_group_multi_salesteams(self, cr, uid, ids, context=None): - pass - # Todo: return the current state for the group_multi_salesteams field - - _defaults = { - 'group_multi_salesteams': _get_group_multi_salesteams - } - diff --git a/addons/sales_team/security/sales_team_security.xml b/addons/sales_team/security/sales_team_security.xml index fe999715a7a..d9002f8332f 100644 --- a/addons/sales_team/security/sales_team_security.xml +++ b/addons/sales_team/security/sales_team_security.xml @@ -1,49 +1,17 @@ - - - User: Own Leads Only - - - the user will have access to his own data in the sales application. - - - - User: All Leads - - - the user will have access to all records of everyone in the sales application. - - - - Manager - the user will have an access to the sales configuration as well as statistic reports. - - - - - Do Not Use Sales Teams - + + + + Manage Sales Teams - - - - - - - - - - - - From 3406b6db397506c3fedb974f0fe470e2d99b9a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 12 May 2014 14:56:01 +0200 Subject: [PATCH 41/46] [CLEAN] sale, sale_crm: cleaning before merging. Cleaned calculation of default section id + removed duplicated code. --- addons/crm/__openerp__.py | 2 +- ...e_section_view.xml => sales_team_view.xml} | 0 .../sale_crm_goals_demo.xml | 2 +- addons/sale/__init__.py | 8 +-- addons/sale/__openerp__.py | 2 +- addons/sale/sale.py | 63 ++++++++++++++----- .../{crm_case_section.py => sales_team.py} | 30 +-------- ...e_section_view.xml => sales_team_view.xml} | 0 addons/sale_crm/sale_crm.py | 1 - 9 files changed, 56 insertions(+), 52 deletions(-) rename addons/crm/{crm_case_section_view.xml => sales_team_view.xml} (100%) rename addons/sale/{crm_case_section.py => sales_team.py} (74%) rename addons/sale/{crm_case_section_view.xml => sales_team_view.xml} (100%) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index ecdefb9e051..1bf4c611be6 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -91,7 +91,7 @@ Dashboard for CRM will include: 'res_config_view.xml', 'base_partner_merge_view.xml', - 'crm_case_section_view.xml', + 'sales_team_view.xml', 'views/crm.xml', ], 'demo': [ diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/sales_team_view.xml similarity index 100% rename from addons/crm/crm_case_section_view.xml rename to addons/crm/sales_team_view.xml diff --git a/addons/gamification_sale_crm/sale_crm_goals_demo.xml b/addons/gamification_sale_crm/sale_crm_goals_demo.xml index a4720b1e566..b149af31f48 100644 --- a/addons/gamification_sale_crm/sale_crm_goals_demo.xml +++ b/addons/gamification_sale_crm/sale_crm_goals_demo.xml @@ -6,6 +6,6 @@ inprogress - + diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index 509364643ae..c99fc936467 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -19,16 +19,10 @@ # ############################################################################## -#---------------------------------------------------------- -# Init Sales -#---------------------------------------------------------- - import sale -import crm_case_section +import sales_team import res_partner import wizard import report import edi import res_config - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 52baff32ab7..039e765cd71 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -71,7 +71,7 @@ The Dashboard for the Sales Manager will include 'sale_report.xml', 'sale_data.xml', 'sale_view.xml', - 'crm_case_section_view.xml', + 'sales_team_view.xml', 'res_partner_view.xml', 'report/sale_report_view.xml', 'edi/sale_order_action_data.xml', diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 34886a22991..e3b59c00015 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -19,11 +19,7 @@ # ############################################################################## -import calendar -from openerp import tools -from datetime import date, datetime, timedelta -from dateutil.relativedelta import relativedelta -from dateutil import relativedelta +from datetime import datetime, timedelta import time from openerp.osv import fields, osv from openerp.tools.translate import _ @@ -166,12 +162,29 @@ class sale_order(osv.osv): if not company_id: raise osv.except_osv(_('Error!'), _('There is no default company for the current user!')) return company_id - + def _get_default_section_id(self, cr, uid, context=None): """ Gives default section by checking if present in the context """ - section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False + section_id = self._resolve_section_id_from_context(cr, uid, context=context) or False + if not section_id: + section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False return section_id + def _resolve_section_id_from_context(self, cr, uid, context=None): + """ Returns ID of section based on the value of 'section_id' + context key, or None if it cannot be resolved to a single + Sales Team. + """ + if context is None: + context = {} + if type(context.get('default_section_id')) in (int, long): + return context.get('default_section_id') + if isinstance(context.get('default_section_id'), basestring): + section_ids = self.pool.get('crm.case.section').name_search(cr, uid, name=context['default_section_id'], context=context) + if len(section_ids) == 1: + return int(section_ids[0][0]) + return None + _columns = { 'name': fields.char('Order Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, select=True), @@ -252,7 +265,6 @@ class sale_order(osv.osv): 'partner_shipping_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['delivery'])['delivery'], 'note': lambda self, cr, uid, context: self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.sale_note, 'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c), - } _sql_constraints = [ ('name_uniq', 'unique(name, company_id)', 'Order Reference must be unique per Company!'), @@ -1199,13 +1211,40 @@ class mail_compose_message(osv.Model): self.pool.get('sale.order').signal_quotation_sent(cr, uid, [context['default_res_id']]) return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context) + class account_invoice(osv.Model): _inherit = 'account.invoice' - + + def _get_default_section_id(self, cr, uid, context=None): + """ Gives default section by checking if present in the context """ + section_id = self._resolve_section_id_from_context(cr, uid, context=context) or False + if not section_id: + section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False + return section_id + + def _resolve_section_id_from_context(self, cr, uid, context=None): + """ Returns ID of section based on the value of 'section_id' + context key, or None if it cannot be resolved to a single + Sales Team. + """ + if context is None: + context = {} + if type(context.get('default_section_id')) in (int, long): + return context.get('default_section_id') + if isinstance(context.get('default_section_id'), basestring): + section_ids = self.pool.get('crm.case.section').name_search(cr, uid, name=context['default_section_id'], context=context) + if len(section_ids) == 1: + return int(section_ids[0][0]) + return None + _columns = { 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } - + + _defaults = { + 'section_id': lambda self, cr, uid, c=None: self._get_default_section_id(cr, uid, context=c) + } + def confirm_paid(self, cr, uid, ids, context=None): sale_order_obj = self.pool.get('sale.order') res = super(account_invoice, self).confirm_paid(cr, uid, ids, context=context) @@ -1224,10 +1263,6 @@ class account_invoice(osv.Model): for id in ids: workflow.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr) return super(account_invoice, self).unlink(cr, uid, ids, context=context) - - _defaults = { - 'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, - } class procurement_order(osv.osv): diff --git a/addons/sale/crm_case_section.py b/addons/sale/sales_team.py similarity index 74% rename from addons/sale/crm_case_section.py rename to addons/sale/sales_team.py index 11c8cdc8bb4..e8161d7325c 100644 --- a/addons/sale/crm_case_section.py +++ b/addons/sale/sales_team.py @@ -1,35 +1,11 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## import calendar -from openerp import tools -from datetime import date, datetime, timedelta +from datetime import date from dateutil.relativedelta import relativedelta -from dateutil import relativedelta -import time + +from openerp import tools from openerp.osv import fields, osv -from openerp.tools.translate import _ -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare -import openerp.addons.decimal_precision as dp -from openerp import workflow class crm_case_section(osv.osv): diff --git a/addons/sale/crm_case_section_view.xml b/addons/sale/sales_team_view.xml similarity index 100% rename from addons/sale/crm_case_section_view.xml rename to addons/sale/sales_team_view.xml diff --git a/addons/sale_crm/sale_crm.py b/addons/sale_crm/sale_crm.py index 1b91ef4ef49..92c0abf2df0 100644 --- a/addons/sale_crm/sale_crm.py +++ b/addons/sale_crm/sale_crm.py @@ -29,7 +29,6 @@ from openerp.osv import osv, fields class sale_order(osv.osv): _inherit = 'sale.order' _columns = { - 'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Tags', \ domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}") } From e53cadcf2a16d5bad3c04b56a2e9f7016c00bdd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 12 May 2014 15:47:12 +0200 Subject: [PATCH 42/46] [FIX] sale: fixed import error about relativedelta --- addons/sale/sales_team.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sales_team.py b/addons/sale/sales_team.py index e8161d7325c..10acac1dddc 100644 --- a/addons/sale/sales_team.py +++ b/addons/sale/sales_team.py @@ -2,7 +2,7 @@ import calendar from datetime import date -from dateutil.relativedelta import relativedelta +from dateutil import relativedelta from openerp import tools from openerp.osv import fields, osv From 03ee7ed00d15132377ed5586872dc4e3e28b25ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 12 May 2014 15:58:25 +0200 Subject: [PATCH 43/46] [FIX] sales_team: indentation issue --- addons/sales_team/sales_team.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sales_team/sales_team.py b/addons/sales_team/sales_team.py index b356fa55900..ed3a3876231 100644 --- a/addons/sales_team/sales_team.py +++ b/addons/sales_team/sales_team.py @@ -78,7 +78,7 @@ class crm_case_section(osv.osv): 'note': fields.text('Description'), 'working_hours': fields.float('Working Hours', digits=(16, 2)), 'color': fields.integer('Color Index'), - } + } _defaults = { 'active': 1, From 3af0824fa585217853b297d2fd88df5a99b3375d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 12 May 2014 15:58:39 +0200 Subject: [PATCH 44/46] [FIX] crm: typo --- addons/crm/sales_team.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm/sales_team.py b/addons/crm/sales_team.py index ac626563f36..aeaf2cd8ec6 100644 --- a/addons/crm/sales_team.py +++ b/addons/crm/sales_team.py @@ -45,7 +45,7 @@ class crm_case_section(osv.Model): 'monthly_planned_revenue': fields.function(_get_opportunities_data, type="string", readonly=True, multi='_get_opportunities_data', string='Planned Revenue per Month'), - 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically ""create new leads assigned to the team."), + 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="The email address associated with this team. New emails received will automatically create new leads assigned to the team."), } def _auto_init(self, cr, context=None): From 1101c618a5113623dcb40190935c0b5f0b3cbc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 12 May 2014 15:58:47 +0200 Subject: [PATCH 45/46] [FIX] sales_team: fixed kanban view inheritance --- addons/crm/sales_team_view.xml | 14 +++++--------- addons/sales_team/sales_team.xml | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/addons/crm/sales_team_view.xml b/addons/crm/sales_team_view.xml index 8be2d888fb6..0a1b1933385 100644 --- a/addons/crm/sales_team_view.xml +++ b/addons/crm/sales_team_view.xml @@ -85,20 +85,16 @@ - + - - -
- %% -
-
- - + +
+ %% +
Leads diff --git a/addons/sales_team/sales_team.xml b/addons/sales_team/sales_team.xml index 5913565c98b..95fcb6f3078 100644 --- a/addons/sales_team/sales_team.xml +++ b/addons/sales_team/sales_team.xml @@ -56,7 +56,7 @@
-

+

From a5311e690000d371e886a30ea1557d24ee0186b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 14 May 2014 14:30:26 +0200 Subject: [PATCH 46/46] [MOV] crm: moved css / js related to salesteam to sales_team module; sale_crm: moved data and demo data into sale and sales_team module. --- addons/crm/__openerp__.py | 1 - addons/crm/static/src/css/Makefile | 2 - addons/crm/static/src/css/crm.css | 62 --------- addons/crm/views/crm.xml | 13 -- addons/sale/sale_data.xml | 18 ++- addons/sale/sale_demo.xml | 103 ++++++++++++++ addons/sale_crm/__openerp__.py | 3 +- addons/sale_crm/sale_crm_data.xml | 22 --- addons/sale_crm/sale_crm_demo.xml | 130 ------------------ addons/sales_team/sales_team.xml | 12 +- addons/sales_team/static/src/css/Makefile | 2 + .../static/src/css/sales_team.sass} | 0 .../static/src/js/sales_team.js} | 0 13 files changed, 134 insertions(+), 234 deletions(-) delete mode 100644 addons/crm/static/src/css/Makefile delete mode 100644 addons/crm/static/src/css/crm.css delete mode 100644 addons/crm/views/crm.xml delete mode 100644 addons/sale_crm/sale_crm_data.xml delete mode 100644 addons/sale_crm/sale_crm_demo.xml create mode 100644 addons/sales_team/static/src/css/Makefile rename addons/{crm/static/src/css/crm.sass => sales_team/static/src/css/sales_team.sass} (100%) rename addons/{crm/static/src/js/crm_case_section.js => sales_team/static/src/js/sales_team.js} (100%) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 1bf4c611be6..15544dc3dff 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -92,7 +92,6 @@ Dashboard for CRM will include: 'base_partner_merge_view.xml', 'sales_team_view.xml', - 'views/crm.xml', ], 'demo': [ 'crm_demo.xml', diff --git a/addons/crm/static/src/css/Makefile b/addons/crm/static/src/css/Makefile deleted file mode 100644 index a2ced24a13d..00000000000 --- a/addons/crm/static/src/css/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -crm.css: crm.sass - sass --trace -t expanded crm.sass:crm.css diff --git a/addons/crm/static/src/css/crm.css b/addons/crm/static/src/css/crm.css deleted file mode 100644 index 8999f758e41..00000000000 --- a/addons/crm/static/src/css/crm.css +++ /dev/null @@ -1,62 +0,0 @@ -@charset "utf-8"; -.openerp .oe_kanban_view .oe_kanban_crm_salesteams { - /* Customize width and height of kanban according bootstrap3 */ - width: 357px; - min-height: 254px !important; - /* End of customize */ - cursor: default; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list { - position: relative; - /* Improved margin to set alignment of list items according bootstrap3 */ - margin: 10px 0 10px 9px; - min-height: 10px; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div { - width: 160px; - height: 22px; - margin: 0 !important; - position: relative; - display: inline-block; - float: left; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) { - position: absolute; - left: 90px; - top: 0; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) { - left: 110px; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover { - text-decoration: underline !important; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center { - text-align: center; - margin: 3px 0; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_sum { - margin: 0; - font-size: 40px; -} -.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_subsum { - font-size: 10px; -} -.openerp .oe_kanban_view .oe_salesteams_help { - display: inline-block; -} -.openerp .oe_kanban_view .oe_kanban_salesteams_avatars { - margin-top: 20px; -} -.openerp .oe_kanban_view .oe_kanban_salesteams_avatars img { - width: 30px; - height: 30px; - padding-left: 0px; - margin-top: 3px; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); - -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); -} diff --git a/addons/crm/views/crm.xml b/addons/crm/views/crm.xml deleted file mode 100644 index c28ba723d24..00000000000 --- a/addons/crm/views/crm.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/addons/sale/sale_data.xml b/addons/sale/sale_data.xml index 443895631a9..4c5347cf1d0 100644 --- a/addons/sale/sale_data.xml +++ b/addons/sale/sale_data.xml @@ -29,7 +29,7 @@ This application lets you create and send quotations and process your sales orders; from delivery to invoicing.

If you need to manage your sales pipeline (leads, opportunities, phonecalls), the CRM application may be useful. Use the Settings menu to install it.

]]>
- + Quotation sent @@ -44,5 +44,21 @@ Quotation confirmed + + + Quotation Send + 20 + crm.case.section + + section_id + + + Sales Order Confirmed + 21 + crm.case.section + + section_id + + diff --git a/addons/sale/sale_demo.xml b/addons/sale/sale_demo.xml index 2e0019598f7..bcb69f9a7a3 100644 --- a/addons/sale/sale_demo.xml +++ b/addons/sale/sale_demo.xml @@ -2,12 +2,24 @@ + + 52700 + 60000 + + + + 36000 + 40000 + + + + @@ -47,6 +59,8 @@ manual + + @@ -76,6 +90,7 @@ manual + @@ -104,6 +119,7 @@ + @@ -152,6 +168,8 @@ + + @@ -190,6 +208,7 @@ + @@ -209,6 +228,8 @@ manual + + @@ -259,6 +280,7 @@ manual + @@ -335,5 +357,86 @@ Thanks! + + + + + + + + draft + in_invoice + + Test invoice 1 + + + Basic computer with Dvorak keyboard and left-handed mouse + + 250 + 1 + + + + Little server with raid 1 and 512ECC ram + + 800 + 2 + + + + Server with raid 10 and 2048ECC ram + + 4800 + 4 + + + + + + + + + + + + + + + + + + + + + + + + + draft + out_invoice + + Test invoice 1 + + + Basic formation with Dvorak + + 500 + 1 + + + + + + + + + + + + + + + + diff --git a/addons/sale_crm/__openerp__.py b/addons/sale_crm/__openerp__.py index 37059458acd..251c4746a86 100644 --- a/addons/sale_crm/__openerp__.py +++ b/addons/sale_crm/__openerp__.py @@ -41,11 +41,10 @@ modules. 'data': [ 'wizard/crm_make_sale_view.xml', 'sale_crm_view.xml', - 'sale_crm_data.xml', 'security/sale_crm_security.xml', 'security/ir.model.access.csv', ], - 'demo': ['sale_crm_demo.xml'], + 'demo': [], 'test': ['test/sale_crm.yml'], 'installable': True, 'auto_install': True, diff --git a/addons/sale_crm/sale_crm_data.xml b/addons/sale_crm/sale_crm_data.xml deleted file mode 100644 index 1996f367202..00000000000 --- a/addons/sale_crm/sale_crm_data.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - Quotation Send - 20 - crm.case.section - - section_id - - - Sales Order Confirmed - 21 - crm.case.section - - section_id - - - - diff --git a/addons/sale_crm/sale_crm_demo.xml b/addons/sale_crm/sale_crm_demo.xml deleted file mode 100644 index 4af287b0587..00000000000 --- a/addons/sale_crm/sale_crm_demo.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - 52700 - 60000 - - - - Indirect Sales - IM - 36000 - 40000 - - - - - - - - - - - draft - in_invoice - - Test invoice 1 - - - Basic computer with Dvorak keyboard and left-handed mouse - - 250 - 1 - - - - Little server with raid 1 and 512ECC ram - - 800 - 2 - - - - Server with raid 10 and 2048ECC ram - - 4800 - 4 - - - - - - - - - - - - - - - - - - - - - - - - - draft - out_invoice - - Test invoice 1 - - - Basic formation with Dvorak - - 500 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/addons/sales_team/sales_team.xml b/addons/sales_team/sales_team.xml index 95fcb6f3078..67907c38c7e 100644 --- a/addons/sales_team/sales_team.xml +++ b/addons/sales_team/sales_team.xml @@ -195,6 +195,16 @@

- + + + + + + diff --git a/addons/sales_team/static/src/css/Makefile b/addons/sales_team/static/src/css/Makefile new file mode 100644 index 00000000000..523f4a1e81e --- /dev/null +++ b/addons/sales_team/static/src/css/Makefile @@ -0,0 +1,2 @@ +sales_team.css: sales_team.sass + sass --trace -t expanded sales_team.sass:sales_team.css diff --git a/addons/crm/static/src/css/crm.sass b/addons/sales_team/static/src/css/sales_team.sass similarity index 100% rename from addons/crm/static/src/css/crm.sass rename to addons/sales_team/static/src/css/sales_team.sass diff --git a/addons/crm/static/src/js/crm_case_section.js b/addons/sales_team/static/src/js/sales_team.js similarity index 100% rename from addons/crm/static/src/js/crm_case_section.js rename to addons/sales_team/static/src/js/sales_team.js