From 683cf35070c9723099fe3b90ddcbe7de2e0a57c9 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Tue, 14 Sep 2010 13:36:35 +0000 Subject: [PATCH 01/34] openerp local commit bzr revid: al@openerp.com-20100914133635-9yuqmkxqdkmde2ql --- .../report/account_aged_partner_balance.rml | 2 +- addons/account/report/invoice.rml | 2 -- .../account_report_aged_partner_balance.py | 6 +++--- addons/base_action_rule/base_action_rule.py | 19 +++++++++++++++---- .../base_action_rule_view.xml | 1 + addons/crm/report/crm_lead_report.py | 8 ++++---- addons/crm/wizard/crm_forward_to_partner.py | 16 ++++++++++++++-- addons/document/document.py | 1 + .../security/email_template_security.xml | 2 -- addons/mrp/mrp_view.xml | 2 +- addons/sale/report/sale_order.rml | 10 +++++----- 11 files changed, 45 insertions(+), 24 deletions(-) diff --git a/addons/account/report/account_aged_partner_balance.rml b/addons/account/report/account_aged_partner_balance.rml index bd52f9be4f5..5a74e46a115 100644 --- a/addons/account/report/account_aged_partner_balance.rml +++ b/addons/account/report/account_aged_partner_balance.rml @@ -168,7 +168,7 @@ Partners - [[ data['form']['direction_selection'] == 'future' and 'Due' or 'Not due' ]] [[ formatLang(data['form']['date1'],date=True) ]] + [[ data['form']['direction_selection'] == 'future' and 'Due' or 'Not Due' ]] [[ data['form']['4']['name'] ]] diff --git a/addons/account/report/invoice.rml b/addons/account/report/invoice.rml index f05198876b9..59342941829 100644 --- a/addons/account/report/invoice.rml +++ b/addons/account/report/invoice.rml @@ -239,8 +239,6 @@ - Tel. : [[ o.address_invoice_id.phone or removeParentNode('para') ]] - Fax : [[ o.address_invoice_id.fax or removeParentNode('para') ]] VAT : [[ o.partner_id.vat or removeParentNode('para') ]] diff --git a/addons/account/wizard/account_report_aged_partner_balance.py b/addons/account/wizard/account_report_aged_partner_balance.py index 29867f04d5b..0431bafacb2 100644 --- a/addons/account/wizard/account_report_aged_partner_balance.py +++ b/addons/account/wizard/account_report_aged_partner_balance.py @@ -75,9 +75,9 @@ class account_aged_trial_balance(osv.osv_memory): for i in range(5)[::-1]: stop = start - RelativeDateTime(days=period_length) res[str(i)] = { - 'name' : str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length), + 'name' : (i!=0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))), 'stop': start.strftime('%Y-%m-%d'), - 'start' : stop.strftime('%Y-%m-%d'), + 'start' : (i!=0 and stop.strftime('%Y-%m-%d') or time.strftime('01-01-1900')), } start = stop - RelativeDateTime(days=1) else: @@ -99,4 +99,4 @@ class account_aged_trial_balance(osv.osv_memory): account_aged_trial_balance() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index ff6321e599f..b4cd4f8ec00 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -113,6 +113,8 @@ the rule to mark CC(mail to any other person defined in actions)."), 'filter_id':fields.many2one('ir.filters', 'Filter', required=False), 'act_email_from' : fields.char('Email From', size=64, required=False, help="Use a python expression to specify the right field on which one than we will use for the 'From' field of the header"), + 'act_email_to' : fields.char('Email To', size=64, required=False, + help="Use a python expression to specify the right field on which one than we will use for the 'To' field of the header"), } _defaults = { @@ -356,13 +358,22 @@ the rule to mark CC(mail to any other person defined in actions)."), emails += (action.act_email_cc or '').split(',') if action.act_mail_to_email: emails += (action.act_mail_to_email or '').split(',') + import pdb + #pdb.set_trace() + + locals_for_emails = { + 'user' : self.pool.get('res.users').browse(cr, uid, uid, context=context), + 'obj' : obj, + } + + if action.act_email_to: + emails.append(safe_eval(action.act_email_to, {}, locals_for_emails)) + emails = filter(None, emails) + if len(emails) and action.act_mail_body: emails = list(set(emails)) - email_from = safe_eval(action.act_email_from, {}, { - 'user' : self.pool.get('res.users').browse(cr, uid, uid, context=context), - 'obj' : obj, - }) + email_from = safe_eval(action.act_email_from, {}, locals_for_emails) self.email_send(cr, uid, obj, emails, action.act_mail_body, emailfrom=email_from) return True diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml index 526fe55f4a3..76620f26fe1 100644 --- a/addons/base_action_rule/base_action_rule_view.xml +++ b/addons/base_action_rule/base_action_rule_view.xml @@ -65,6 +65,7 @@ + diff --git a/addons/crm/report/crm_lead_report.py b/addons/crm/report/crm_lead_report.py index 4f6f39e0690..09a80519cdb 100644 --- a/addons/crm/report/crm_lead_report.py +++ b/addons/crm/report/crm_lead_report.py @@ -127,9 +127,9 @@ class crm_lead_report(osv.osv): CREATE OR REPLACE VIEW crm_lead_report AS ( SELECT id, - to_char(c.create_date, 'YYYY') as name, - to_char(c.create_date, 'MM') as month, - to_char(c.create_date, 'YYYY-MM-DD') as day, + to_char(c.date_deadline, 'YYYY') as name, + to_char(c.date_deadline, 'MM') as month, + to_char(c.date_deadline, 'YYYY-MM-DD') as day, to_char(c.create_date, 'YYYY-MM-DD') as creation_date, to_char(c.date_open, 'YYYY-MM-DD') as opening_date, to_char(c.date_closed, 'YYYY-mm-dd') as date_closed, @@ -145,7 +145,7 @@ class crm_lead_report(osv.osv): c.partner_id, c.country_id, c.planned_revenue, - c.planned_revenue*(c.probability/100) as probable_revenue, + c.planned_revenue*(c.probability/100) as probable_revenue, 1 as nbr, 0 as avg_answers, 0.0 as perc_done, diff --git a/addons/crm/wizard/crm_forward_to_partner.py b/addons/crm/wizard/crm_forward_to_partner.py index aaa26c438b6..8f2d778c973 100644 --- a/addons/crm/wizard/crm_forward_to_partner.py +++ b/addons/crm/wizard/crm_forward_to_partner.py @@ -27,6 +27,18 @@ from osv import osv, fields import tools from tools.translate import _ +FWD_TEMPLATE="""Hello, + +OpenERP Leads are now forwarded to our trusted partners, through the CRM, we hope that they provide you with interesting projects, we know that they have shown keen interest in our software. +Below is an interesting lead for you. + +Please let us know about the advancements of this lead or if you are not able to answer to its requests by replying to this email. This way, we can keep track of closed leads or forward them to other partners. +Don't forget to propose our maintenance at the beginning of your implementation projects, together with your services quotation. The maintenance provides unlimited bugfixing that will avoid you waste time on bugs detected during the implementation. It also provides free migration services for the current stable version at the time of signature; otherwise if we released a new version during your implementation, the customer would not always be able to easily migrate to newer versions. + +Kind regards, OpenERP Team + +""" + class crm_lead_forward_to_partner(osv.osv_memory): """Forwards lead history""" _name = 'crm.lead.forward.to.partner' @@ -110,7 +122,7 @@ class crm_lead_forward_to_partner(osv.osv_memory): res_id = context.get('active_id') msg_val = self._get_case_history(cr, uid, history_type, res_id, context=context) if msg_val: - res = {'value': {'body' : '\n\n' + msg_val}} + res = {'value': {'body' : FWD_TEMPLATE + '\n\n' + msg_val}} return res def _get_case_history(self, cr, uid, history_type, res_id, context=None): @@ -268,7 +280,7 @@ class crm_lead_forward_to_partner(osv.osv_memory): body = self._get_case_history(cr, uid, defaults.get('history', 'latest'), lead.id, context=context) defaults.update({ 'subject' : '%s: %s' % (_('Fwd'), lead.name), - 'body' : body, + 'body' : FWD_TEMPLATE + '\n\n' + body, }) return defaults diff --git a/addons/document/document.py b/addons/document/document.py index 46cf6d189c1..f60531f40ef 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -144,6 +144,7 @@ class document_file(osv.osv): return super(document_file, self).copy(cr, uid, id, default, context) def write(self, cr, uid, ids, vals, context=None): + result = False if not isinstance(ids, list): ids = [ids] res = self.search(cr, uid, [('id', 'in', ids)]) diff --git a/addons/email_template/security/email_template_security.xml b/addons/email_template/security/email_template_security.xml index 7e6c1f4b560..9fcf47d94d8 100755 --- a/addons/email_template/security/email_template_security.xml +++ b/addons/email_template/security/email_template_security.xml @@ -1,10 +1,8 @@ - Marketing / User - diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index 4504de8a2cf..402d352c174 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -6,7 +6,7 @@ groups="group_mrp_user,group_mrp_manager,base.group_system" sequence="8"/> - + Shipping address : - [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] - [[ o.partner_shipping_id.title or '' ]] [[ o.partner_shipping_id.name ]] + [[ o.partner_id.title.name or '' ]] [[ o.partner_id.name ]] + [[ o.partner_shipping_id.title.name or '' ]] [[ o.partner_shipping_id.name ]] [[ o.partner_shipping_id.street ]] [[ o.partner_shipping_id.street2 or '' ]] [[ o.partner_shipping_id.zip or '' ]] [[ o.partner_shipping_id.city or '' ]] @@ -145,7 +145,7 @@ Invoice address : - [[ o.partner_invoice_id.title or '' ]] [[ o.partner_invoice_id.name or '' ]] + [[ o.partner_invoice_id.title.name or '' ]] [[ o.partner_invoice_id.name or '' ]] [[ o.partner_invoice_id.street ]] [[ o.partner_invoice_id.street2 and (', %s' % o.partner_invoice_id.street2 or '') ]] [[ o.partner_invoice_id.zip or '' ]] [[ o.partner_invoice_id.city or '' ]] [[ o.partner_invoice_id.state_id and o.partner_invoice_id.state_id.name or '' ]][[ o.partner_invoice_id.country_id and o.partner_invoice_id.country_id.name or '' ]] @@ -156,8 +156,8 @@ - [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] - [[ o.partner_order_id.title or '' ]] [[ o.partner_order_id.name ]] + [[ o.partner_id.title.name or '' ]] [[ o.partner_id.name ]] + [[ o.partner_order_id.title.name or '' ]] [[ o.partner_order_id.name ]] [[ o.partner_order_id.street ]] [[ o.partner_order_id.street2 or '' ]] [[ o.partner_order_id.zip or '' ]] [[ o.partner_order_id.city or '' ]] From 1837358d318d23f962ab8cb76243b0afdee53e66 Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Thu, 3 Feb 2011 12:26:14 +0530 Subject: [PATCH 02/34] [IMP] crm: Rewrite merge opportunities wizard. bzr revid: uco@tinyerp.com-20110203065614-6xq0c6qctl7pem85 --- addons/crm/wizard/crm_merge_opportunities.py | 163 +++++++++--------- .../wizard/crm_merge_opportunities_view.xml | 1 - 2 files changed, 80 insertions(+), 84 deletions(-) diff --git a/addons/crm/wizard/crm_merge_opportunities.py b/addons/crm/wizard/crm_merge_opportunities.py index 661180c0874..0b19ca6066f 100644 --- a/addons/crm/wizard/crm_merge_opportunities.py +++ b/addons/crm/wizard/crm_merge_opportunities.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## -from crm import crm from osv import osv, fields from tools.translate import _ @@ -28,35 +27,9 @@ class crm_merge_opportunity(osv.osv_memory): _name = 'crm.merge.opportunity' _description = 'Merge two Opportunities' - def view_init(self, cr, uid, fields, context=None): - """ - This function checks for precondition before wizard executes - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param fields: List of fields for default value - @param context: A standard dictionary for contextual values - - """ - record_id = context and context.get('active_id', False) or False - if record_id: - opp_obj = self.pool.get('crm.lead') - opp = opp_obj.browse(cr, uid, record_id, context=context) - if not opp.partner_id: - raise osv.except_osv(_('Warning!'), _('Opportunity must have Partner assigned before merging with other Opportunity.')) - #Search for Opportunity for the same partner - opp_ids = opp_obj.search(cr, uid, [('partner_id', '=', opp.partner_id.id), ('type', '=', 'opportunity'), ('state', 'in', ('open', 'pending'))]) - # Removing current opportunity - if record_id in opp_ids: - opp_ids.remove(record_id) - if not opp_ids: - raise osv.except_osv(_('Warning!'), _("There are no other 'Open' or 'Pending' Opportunities for the partner '%s'.") % (opp.partner_id.name)) - pass - - def action_merge(self, cr, uid, ids, context=None): """ - This function merges two opportunities + This function merges opportunities @param self: The object pointer @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @@ -65,54 +38,87 @@ class crm_merge_opportunity(osv.osv_memory): @return : Dictionary value for created Opportunity form """ - record_id = context and context.get('active_id', False) or False - if record_id: - opp_obj = self.pool.get('crm.lead') - message_obj = self.pool.get('mailgate.message') - current_opp = opp_obj.browse(cr, uid, record_id, context=context) + record_ids = context and context.get('active_ids') or False + if len(record_ids) <= 1: + return {'type': 'ir.actions.act_window_close'} + + obj_opportunity = self.browse(cr, uid, ids[0], context=context) + opp_obj = self.pool.get('crm.lead') + first_opp = obj_opportunity.opportunity_ids[0] + op_ids = obj_opportunity.opportunity_ids + first_opp_data = {} - for this in self.browse(cr, uid, ids, context=context): - for opp in this.opportunity_ids: - opp_obj.write(cr, uid, [opp.id], { - 'stage_id': opp.stage_id.id or current_opp.stage_id.id or False, - 'priority': opp.priority or current_opp.priority, - 'email_from': opp.email_from or current_opp.email_from, - 'phone': opp.phone or current_opp.phone, - 'section_id': opp.section_id.id or current_opp.section_id.id or False, - 'categ_id': opp.categ_id.id or current_opp.categ_id.id or False, - 'description': (opp.description or '') + '\n' + (current_opp.description or ''), - 'partner_name': opp.partner_name or current_opp.partner_name, - 'title': opp.title.id or current_opp.title.id or False, - 'function': opp.function or current_opp.function, - 'street': opp.street or current_opp.street, - 'street2': opp.street2 or current_opp.street2, - 'zip': opp.zip or current_opp.zip, - 'city': opp.city or current_opp.city, - 'country_id': opp.country_id.id or current_opp.country_id.id or False, - 'state_id': opp.state_id.id or current_opp.state_id.id or False, - 'fax': opp.fax or current_opp.fax, - 'mobile': opp.mobile or current_opp.mobile, - 'email_cc': ','.join(filter(lambda x: x, [opp.email_cc, current_opp.email_cc])) - }) - for history in current_opp.message_ids: - if history.history: - new_history = message_obj.copy(cr, uid, history.id, default={'res_id': opp.id}) - opp_obj._history(cr, uid, [current_opp], _('Merged into Opportunity: %s') % (opp.id)) + for opp in op_ids[1:]: + first_opp_data = { + 'partner_id': first_opp.partner_id.id or opp.partner_id.id, + 'stage_id': first_opp.stage_id.id or opp.stage_id.id, + 'section_id': first_opp.section_id.id or opp.section_id.id, + 'categ_id': first_opp.categ_id.id or opp.categ_id.id, + 'type_id': first_opp.type_id.id or opp.type_id.id, + 'channel_id': first_opp.channel_id.id or opp.channel_id.id, + 'user_id': first_opp.user_id.id or opp.user_id.id, + 'country_id': first_opp.country_id.id or opp.country_id.id, + 'state_id': first_opp.state_id.id or opp.state_id.id, + 'partner_address_id': first_opp.partner_address_id.id or opp.partner_address_id.id, + 'priority': first_opp.priority or opp.priority, + 'title': first_opp.title.id or opp.title.id, + 'function': first_opp.function or opp.function, + 'email_from': first_opp.email_from or opp.email_from, + 'phone': first_opp.phone or opp.phone, + 'description': first_opp.description or opp.description, + 'partner_name': first_opp.partner_name or opp.partner_name, + 'street': first_opp.street or opp.street, + 'street2': first_opp.street2 or opp.street2, + 'zip': first_opp.zip or opp.zip, + 'city': first_opp.city or opp.city, + 'fax': first_opp.fax or opp.fax, + 'mobile': first_opp.mobile or opp.mobile, + 'email_cc': ','.join(filter(lambda x: x, [opp.email_cc, first_opp.email_cc])), + 'state': 'open' + } + for history in opp.message_ids: + if history.history: + new_history = message_obj.copy(cr, uid, history.id, default={'res_id': opp.id}) + opp_obj._history(cr, uid, [first_opp], _('Merged from Opportunity: %s : Information lost : [Partner: %s, Stage: %s, Section: %s, Salesman: %s]') % (opp.name, opp.partner_id.name or '', opp.stage_id.name or '', opp.section_id.name or '', opp.user_id.name or '')) + - if this.state == 'unchanged': - pass - elif this.state == 'done': - opp_obj.case_close(cr, uid, [record_id]) - elif this.state == 'draft': - opp_obj.case_reset(cr, uid, [record_id]) - elif this.state in ['cancel', 'open', 'pending']: - act = 'case_' + this.state - getattr(opp_obj, act)(cr, uid, [record_id]) - return {'type': 'ir.actions.act_window_close'} + opp_obj.write(cr, uid, [first_opp.id], first_opp_data) + + unlink_ids = map(lambda x: x.id, op_ids[1:]) + opp_obj.unlink(cr, uid, unlink_ids) + + models_data = self.pool.get('ir.model.data') + + # Get Opportunity views + result = models_data._get_id( + cr, uid, 'crm', 'view_crm_case_opportunities_filter') + opportunity_view_form = models_data._get_id( + cr, uid, 'crm', 'crm_case_form_view_oppor') + opportunity_view_tree = models_data._get_id( + cr, uid, 'crm', 'crm_case_tree_view_oppor') + if opportunity_view_form: + opportunity_view_form = models_data.browse( + cr, uid, opportunity_view_form, context=context).res_id + if opportunity_view_tree: + opportunity_view_tree = models_data.browse( + cr, uid, opportunity_view_tree, context=context).res_id + + return { + 'name': _('Opportunity'), + 'view_type': 'form', + 'view_mode': 'tree, form', + 'res_model': 'crm.lead', + 'domain': [('type', '=', 'opportunity')], + 'res_id': int(first_opp.id), + 'view_id': False, + 'views': [(opportunity_view_form, 'form'), + (opportunity_view_tree, 'tree'), + (False, 'calendar'), (False, 'graph')], + 'type': 'ir.actions.act_window', + } _columns = { 'opportunity_ids' : fields.many2many('crm.lead', 'merge_opportunity_rel', 'merge_id', 'opportunity_id', 'Opportunities', domain=[('type', '=', 'opportunity')]), - 'state': fields.selection(crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')], string='Set State To', required=True), } def default_get(self, cr, uid, fields, context=None): @@ -126,21 +132,12 @@ class crm_merge_opportunity(osv.osv_memory): @return : default values of fields. """ - record_id = context and context.get('active_id', False) or False + record_ids = context and context.get('active_ids', False) or False res = super(crm_merge_opportunity, self).default_get(cr, uid, fields, context=context) - if record_id: - opp_obj = self.pool.get('crm.lead') - opp = opp_obj.browse(cr, uid, record_id, context=context) - opp_ids = opp_obj.search(cr, uid, [('partner_id', '=', opp.partner_id.id), ('type', '=', 'opportunity'), ('state', 'in', ('open', 'pending'))]) - # Removing current opportunity - if record_id in opp_ids: - opp_ids.remove(record_id) - + if record_ids: if 'opportunity_ids' in fields: - res.update({'opportunity_ids': opp_ids}) - if 'state' in fields: - res.update({'state': u'cancel'}) + res.update({'opportunity_ids': record_ids}) return res diff --git a/addons/crm/wizard/crm_merge_opportunities_view.xml b/addons/crm/wizard/crm_merge_opportunities_view.xml index 153267f0ad1..046cc37cd8f 100644 --- a/addons/crm/wizard/crm_merge_opportunities_view.xml +++ b/addons/crm/wizard/crm_merge_opportunities_view.xml @@ -14,7 +14,6 @@ -