[MERGE] from trunk

bzr revid: fva@openerp.com-20140127130136-905xxex6cfsbfwjs
bzr revid: fva@openerp.com-20140127132925-9bvrpfaaxp17pq58
This commit is contained in:
Frédéric van der Essen 2014-01-27 14:29:25 +01:00
commit 9d85d0c25f
15 changed files with 893 additions and 57 deletions

View File

@ -105,6 +105,9 @@ class account_config_settings(osv.osv_memory):
'module_account_followup': fields.boolean('Manage customer payment follow-ups',
help='This allows to automate letters for unpaid invoices, with multi-level recalls.\n'
'-This installs the module account_followup.'),
'module_product_email_template': fields.boolean('Send products tools and information at the invoice confirmation',
help='With this module, link your products to a template to send complete information and tools to your customer.\n'
'For instance when invoicing a training, the training agenda and materials will automatically be send to your customers.'),
'group_proforma_invoices': fields.boolean('Allow pro-forma invoices',
implied_group='account.group_proforma_invoices',
help="Allows you to put invoices in pro-forma state."),

View File

@ -183,6 +183,10 @@
<field name="module_account_followup" class="oe_inline"/>
<label for="module_account_followup"/>
</div>
<div>
<field name="module_product_email_template" class="oe_inline"/>
<label for="module_product_email_template"/>
</div>
</div>
</group>
<group>

View File

@ -761,24 +761,6 @@ class crm_lead(format_address, osv.osv):
)
return partner_id
def _lead_set_partner(self, cr, uid, lead, partner_id, context=None):
"""
Assign a partner to a lead.
:param object lead: browse record of the lead to process
:param int partner_id: identifier of the partner to assign
:return bool: True if the partner has properly been assigned
"""
res = False
res_partner = self.pool.get('res.partner')
if partner_id:
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id and lead.section_id.id or False})
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
res = lead.write({'partner_id': partner_id}, context=context)
message = _("<b>Partner</b> set to <em>%s</em>." % (lead.partner_id.name))
self.message_post(cr, uid, [lead.id], body=message, context=context)
return res
def handle_partner_assignation(self, cr, uid, ids, action='create', partner_id=False, context=None):
"""
Handle partner assignation during a lead conversion.
@ -792,13 +774,16 @@ class crm_lead(format_address, osv.osv):
"""
#TODO this is a duplication of the handle_partner_assignation method of crm_phonecall
partner_ids = {}
# If a partner_id is given, force this partner for all elements
force_partner_id = partner_id
for lead in self.browse(cr, uid, ids, context=context):
# If the action is set to 'create' and no partner_id is set, create a new one
if action == 'create':
partner_id = force_partner_id or self._create_lead_partner(cr, uid, lead, context)
self._lead_set_partner(cr, uid, lead, partner_id, context=context)
if lead.partner_id:
partner_ids[lead.id] = lead.partner_id.id
continue
if not partner_id and action == 'create':
partner_id = self._create_lead_partner(cr, uid, lead, context)
self.pool['res.partner'].write(cr, uid, partner_id, {'section_id': lead.section_id and lead.section_id.id or False})
if partner_id:
lead.write({'partner_id': partner_id}, context=context)
partner_ids[lead.id] = partner_id
return partner_ids

View File

@ -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')}, 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('crm.section_sales_department'), 'deduplicate': False}, 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.

View File

@ -41,6 +41,22 @@ class crm_lead2opportunity_partner(osv.osv_memory):
def onchange_action(self, cr, uid, ids, action, context=None):
return {'value': {'partner_id': False if action != 'exist' else self._find_matching_partner(cr, uid, context=context)}}
def _get_duplicated_leads(self, cr, uid, partner_id, email, context=None):
lead_obj = self.pool.get('crm.lead')
results = []
if partner_id:
# Search for opportunities that have the same partner and that arent done or cancelled
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), '|', ('probability', '=', False), ('probability', '<', '100')])
for id in ids:
results.append(id)
email = re.findall(r'([^ ,<@]+@[^> ,]+)', email or '')
if email:
ids = lead_obj.search(cr, uid, [('email_from', '=ilike', email[0]), '|', ('probability', '=', False), ('probability', '<', '100')])
for id in ids:
results.append(id)
return list(set(results))
def default_get(self, cr, uid, fields, context=None):
"""
Default get for name, opportunity_ids.
@ -51,24 +67,15 @@ class crm_lead2opportunity_partner(osv.osv_memory):
res = super(crm_lead2opportunity_partner, self).default_get(cr, uid, fields, context=context)
if context.get('active_id'):
tomerge = set([int(context['active_id'])])
tomerge = [int(context['active_id'])]
email = False
partner_id = res.get('partner_id')
lead = lead_obj.browse(cr, uid, int(context['active_id']), context=context)
#TOFIX: use mail.mail_message.to_mail
email = re.findall(r'([^ ,<@]+@[^> ,]+)', lead.email_from or '')
if partner_id:
# Search for opportunities that have the same partner and that arent done or cancelled
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), '|', ('probability', '=', False), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
if email:
ids = lead_obj.search(cr, uid, [('email_from', '=ilike', email[0]), '|', ('probability', '=', False), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
tomerge.extend(self._get_duplicated_leads(cr, uid, partner_id, email))
tomerge = list(set(tomerge))
if 'action' in fields:
res.update({'action' : partner_id and 'exist' or 'create'})
@ -77,7 +84,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
if 'name' in fields:
res.update({'name' : len(tomerge) >= 2 and 'merge' or 'convert'})
if 'opportunity_ids' in fields and len(tomerge) >= 2:
res.update({'opportunity_ids': list(tomerge)})
res.update({'opportunity_ids': tomerge})
if lead.user_id:
res.update({'user_id': lead.user_id.id})
if lead.section_id:
@ -116,11 +123,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
context = {}
lead = self.pool.get('crm.lead')
res = False
partner_ids_map = self._create_partner(cr, uid, ids, context=context)
lead_ids = vals.get('lead_ids', [])
team_id = vals.get('section_id', False)
data = self.browse(cr, uid, ids, context=context)[0]
for lead_id in lead_ids:
partner_id = partner_ids_map.get(lead_id, False)
partner_id = self._create_partner(cr, uid, lead_id, data.action, data.partner_id, context=context)
# FIXME: cannot pass user_ids as the salesman allocation only works in batch
res = lead.convert_opportunity(cr, uid, [lead_id], partner_id, [], team_id, context=context)
# FIXME: must perform salesman allocation in batch separately here
@ -152,7 +159,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
return self.pool.get('crm.lead').redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
def _create_partner(self, cr, uid, ids, context=None):
def _create_partner(self, cr, uid, lead_id, action, partner_id, context=None):
"""
Create partner based on action.
:return dict: dictionary organized as followed: {lead_id: partner_assigned_id}
@ -163,10 +170,14 @@ class crm_lead2opportunity_partner(osv.osv_memory):
if context is None:
context = {}
lead = self.pool.get('crm.lead')
lead_ids = context.get('active_ids', [])
data = self.browse(cr, uid, ids, context=context)[0]
partner_id = data.partner_id and data.partner_id.id or False
return lead.handle_partner_assignation(cr, uid, lead_ids, data.action, partner_id, context=context)
if action == 'each_exist_or_create':
ctx = dict(context)
ctx['active_id'] = lead_id
partner_id = self._find_matching_partner(cr, uid, context=ctx)
action = 'create'
print partner_id
res = lead.handle_partner_assignation(cr, uid, [lead_id], action, partner_id, context=context)
return res.get(lead_id)
class crm_lead2opportunity_mass_convert(osv.osv_memory):
_name = 'crm.lead2opportunity.partner.mass'
@ -176,6 +187,15 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
_columns = {
'user_ids': fields.many2many('res.users', string='Salesmen'),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'deduplicate': fields.boolean('Apply deduplication', help='Merge with existing leads/opportunities of each partner'),
'action': fields.selection([
('each_exist_or_create', 'Use existing partner or create'),
('nothing', 'Do not link to a customer')
], 'Related Customer', required=True),
}
_defaults = {
'deduplicate': True,
}
def default_get(self, cr, uid, fields, context=None):
@ -184,13 +204,37 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
# avoid forcing the partner of the first lead as default
res['partner_id'] = False
if 'action' in fields:
res['action'] = 'create'
res['action'] = 'each_exist_or_create'
if 'name' in fields:
res['name'] = 'convert'
if 'opportunity_ids' in fields:
res['opportunity_ids'] = False
return res
def on_change_action(self, cr, uid, ids, action, context=None):
vals = {}
if action != 'exist':
vals = {'value': {'partner_id': False}}
return vals
def on_change_deduplicate(self, cr, uid, ids, deduplicate, context=None):
if context is None:
context = {}
active_leads = self.pool['crm.lead'].browse(cr, uid, context['active_ids'], context=context)
partner_ids = [(lead.partner_id.id, lead.partner_id and lead.partner_id.email or lead.email_from) for lead in active_leads]
partners_duplicated_leads = {}
for partner_id, email in partner_ids:
duplicated_leads = self._get_duplicated_leads(cr, uid, partner_id, email)
if len(duplicated_leads) > 1:
partners_duplicated_leads.setdefault((partner_id, email), []).extend(duplicated_leads)
leads_with_duplicates = []
for lead in active_leads:
lead_tuple = (lead.partner_id.id, lead.partner_id.email if lead.partner_id else lead.email_from)
if len(partners_duplicated_leads.get(lead_tuple, [])) > 1:
leads_with_duplicates.append(lead.id)
return {'value': {'opportunity_ids': leads_with_duplicates}}
def _convert_opportunity(self, cr, uid, ids, vals, context=None):
"""
When "massively" (more than one at a time) converting leads to
@ -208,6 +252,21 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
return super(crm_lead2opportunity_mass_convert, self)._convert_opportunity(cr, uid, ids, vals, context=context)
def mass_convert(self, cr, uid, ids, context=None):
return self.action_apply(cr, uid, ids, context=context)
data = self.browse(cr, uid, ids, context=context)[0]
ctx = dict(context)
if data.name == 'convert' and data.deduplicate:
merged_lead_ids = []
remaining_lead_ids = []
for lead in self.pool['crm.lead'].browse(cr, uid, context.get('active_ids', []), context=context):
duplicated_lead_ids = self._get_duplicated_leads(cr, uid, lead.partner_id.id, lead.partner_id and lead.partner_id.email or lead.email_from)
if len(duplicated_lead_ids) > 1:
lead_id = self.pool.get('crm.lead').merge_opportunity(cr, uid, duplicated_lead_ids, False, False, context=context)
merged_lead_ids.extend(duplicated_lead_ids)
remaining_lead_ids.append(lead_id)
active_ids = set(context.get('active_ids', []))
active_ids = active_ids.difference(merged_lead_ids)
active_ids = active_ids.union(remaining_lead_ids)
ctx['active_ids'] = list(active_ids)
return self.action_apply(cr, uid, ids, context=ctx)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -52,21 +52,17 @@
<form string="Convert to Opportunity" version="7.0">
<separator string="Conversion Options"/>
<group>
<field name="name" class="oe_inline"/>
<field name="action" class="oe_inline" on_change="on_change_action(action)"/>
<field name="deduplicate" class="oe_inline" on_change="on_change_deduplicate(deduplicate, context)"/>
</group>
<group attrs="{'invisible': [('name', '!=', 'convert')]}">
<field name="action" class="oe_inline"/>
<field name="partner_id"
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
class="oe_inline"/>
</group>
<group string="Assign opportunities to" attrs="{'invisible': [('name', '=', '')]}">
<group string="Assign opportunities to">
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="user_ids" widget="many2many_tags"/>
</group>
<group string="Select Opportunities" attrs="{'invisible': [('name', '!=', 'merge')]}">
<field name="opportunity_ids" colspan="4" nolabel="1" attrs="{'invisible': [('name', '=', 'convert')]}">
<tree>
<label for="opportunity_ids" string="Leads with existing duplicates (for information)" help="Leads that you selected that have duplicates. If the list is empty, it means that no duplicates were found" attrs="{'invisible': [('deduplicate', '=', False)]}"/>
<group attrs="{'invisible': [('deduplicate', '=', False)]}">
<field name="opportunity_ids" colspan="4" nolabel="1" readonly="1">
<tree create="false" delete="false">
<field name="create_date"/>
<field name="name"/>
<field name="type"/>

View File

@ -76,6 +76,12 @@ class email_template(osv.osv):
_description = 'Email Templates'
_order = 'name'
def default_get(self, cr, uid, fields, context=None):
res = super(email_template, self).default_get(cr, uid, fields, context)
if res.get('model'):
res['model_id'] = self.pool['ir.model'].search(cr, uid, [('model', '=', res.pop('model'))], context=context)[0]
return res
def render_template_batch(self, cr, uid, template, model, res_ids, context=None):
"""Render the given template text, replace mako expressions ``${expr}``
with the result of evaluating these expressions with

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import models

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
{
'name': 'Product Email Template',
'depends': ['account'],
'author': 'OpenERP SA',
'category': 'Accounting & Finance',
'description': """
Add email templates to products to be send on invoice confirmation
==================================================================
With this module, link your products to a template to send complete information and tools to your customer.
For instance when invoicing a training, the training agenda and materials will automatically be send to your customers.'
""",
'website': 'http://www.openerp.com',
'demo': [
'data/product_demo.xml',
],
'data': [
'views/product_view.xml',
'views/email_template_view.xml',
],
'installable': True,
'auto_install': False,
}

View File

@ -0,0 +1,648 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="product_online_training_email_template" model="email.template">
<field name="name">Online Training</field>
<field name="subject">Online Training</field>
<field name="model_id" ref="product.model_product_template"/>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<div style="height:auto;text-align: center;font-size : 40px;color: #333333;margin-top:30px;font-weight: 300;">
Online Training + Certification
</div>
<div style="height:auto;text-left: center;font-size : 16px;color: #646464;margin-top:30px;margin-left:15px;margin-right:5px;">
These courses feature the same high quality course content found in our traditional classroom trainings, supplemented with
modular sessions and cloud-based labs. Many of our online learning courses also include dozens of recorded webinars and live
sessions by our senior instructors. At the end of the training, you can pass the OpenERP Certification exam in one of the 5000+
Pearson VUE test centers worldwide.
</div>
<div style="height: auto;margin-top:30px;margin-bottom:10px;margin-left:20px;color: #646464;font-size:16px;">
<strong>Your advantages</strong>
<ul>
<li>Modular approach applied to the learning method</li>
<li>New interactive learning experience</li>
<li>Lower training budget for the same quality courses</li>
<li>Better comfort to facilitate your learning process</li>
<li>OpenERP <a href="https://www.openerp.com/certification">Certification Exam</a> included (Pre-Ordered, available as of November 1st, 2013)</li>
</ul>
</div>
<hr color="DCDCFB"/>
<div style="height:auto;text-align: center;font-size : 40px;color: #333333;margin-top:30px;font-weight: 300;">
Structure of the Training
</div>
<div>
<table>
<tr>
<td>
<img src="https://www.openerp.com/saas_master/static/site_new/img/layout/online_training.png"/>
</td>
<td style="height: auto;margin-top:10px;margin-bottom:10px;font-size:18px;color: #646464;">
<strong>There are three components to the training</strong>
<ul>
<li>Videos with detailed demos</li>
<li>Hands-on exercises and their solutions</li>
<li>Live Q&A sessions with a trainer</li>
</ul>
</td>
</tr>
</table>
</div>
<div style="height:auto;text-align: left;font-size : 14px;color: #646464;margin-top:10px;margin-left:15px;">
The 5-day training is modular, which means that you can choose to participate in the full training or to just 1 or 2 modules.
Nevertheless, <b>the first day of the training is compulsory</b> for everyone. The Monday is compulsory because the
introduction of OpenERP is important before going through the other modules.<br/><br/>
Each day of the week starts from 9 AM (CEST/PST) to 12 PM (CEST/PST). A Q&A session will be hosted by an OpenERP trainer.
Each day, the participants are expected to have done the following <b>BEFORE</b> attending the Q&A session:
<ul>
<li>Watch the videos for this day</li>
<li>Do the related exercises (written solutions will be provided upfront as well)</li>
<li>Send their questions by email before 5PM (CEST/PST) on the previous business day</li>
</ul><br/>
The Q&A session will be hosted on a web conference service.<b> A stable internet connection is required.</b> The trainer will
screen the questions for the day and select the most relevant ones to be answered during the session. The purpose of the
<b>Q&A session is not to cover questions related to a specific implementation project </b>or company-specific business
workflows. The <b>questions should be about the material covered in the videos </b>and the exercises and should benefit
the other participants of the training as well.<br/>
Each day of the week is dedicated to specific applications in OpenERP as per the following planning:
<ul style="color: #6d57e0">
<li>
<strong><a href="https://www.openerp.com/online-training#Monday" style="text-decoration:none;" target=_new>Monday: </a></strong>
<a href="https://www.openerp.com/online-training#Monday_1" style="text-decoration:none;" target=_new>Introduction</a>,
<a href="https://www.openerp.com/online-training#Monday_2" style="text-decoration:none;" target=_new>CRM</a>,
<a href="https://www.openerp.com/online-training#Monday_3" style="text-decoration:none;" target=_new>Sales Management</a>
</li>
<li>
<strong><a href="https://www.openerp.com/online-training#Tuesday" style="text-decoration:none;" target=_new>Tuesday: </a></strong>
<a href="https://www.openerp.com/online-training#Tuesday_1" style="text-decoration:none;" target=_new>Access rights</a>,
<a href="https://www.openerp.com/online-training#Tuesday_2" style="text-decoration:none;" target=_new>Purchase</a>,
<a href="https://www.openerp.com/online-training#Tuesday_2" style="text-decoration:none;" target=_new>Sales &amp; Purchase management</a>,
<a href="https://www.openerp.com/online-training#Tuesday_4" style="text-decoration:none;" target=_new>Financial accounting</a>
</li>
<li>
<strong><a href="https://www.openerp.com/online-training#Wednesday" style="text-decoration:none;" target=_new>Wednesday: </a></strong>
<a href="https://www.openerp.com/online-training#Wednesday_1" style="text-decoration:none;" target=_new>Project management</a>,
<a href="https://www.openerp.com/online-training#Wednesday_2" style="text-decoration:none;" target=_new>Human resources</a>,
<a href="https://www.openerp.com/online-training#Wednesday_3" style="text-decoration:none;" target=_new>Contract management</a>
</li>
<li>
<strong><a href="https://www.openerp.com/online-training#Thursday" style="text-decoration:none;" target=_new>Thursday: </a></strong>
<a href="https://www.openerp.com/online-training#Thursday_1" style="text-decoration:none;" target=_new>Warehouse management</a>,
<a href="https://www.openerp.com/online-training#Thursday_2" style="text-decoration:none;" target=_new>Manufacturing (MRP) &amp; Sales</a>,
<a href="https://www.openerp.com/online-training#Thursday_4" style="text-decoration:none;" target=_new>Import/Export</a>
</li>
<li>
<strong><a href="https://www.openerp.com/online-training#Friday" style="text-decoration:none;" target=_new>Friday: </a></strong>
<a href="https://www.openerp.com/online-training#Friday_1" style="text-decoration:none;" target=_new>Pricelists</a>,
<a href="https://www.openerp.com/online-training#Friday_2" style="text-decoration:none;" target=_new>Point of Sale (POS)</a>,
<a href="https://www.openerp.com/online-training#Friday_3" style="text-decoration:none;" target=_new>Introduction to report customization</a>
</li>
</ul>
</div>
<div style="text-align: center;margin-top:30px;" >
<table cellspacing="5" align="center" cellpadding="5">
<tr style="font-size : 20px;color: #333333;margin-top:30px;">
<td>English</td></td>
<td>English</td></td>
<td>Spanish</td>
</tr>
<tr style="font-size : 10px;color: #646464;">
<td>Europe</td>
<td>USA & Canada</td>
<td>USA & Latin America</td>
</tr>
<tr style="font-size : 10px;color: #FFFFFF;background-color:#8b5bdd;">
<td><a href="http://onlinetrainingencet.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
<td><a href="http://onlinetrainingenpst.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
<td><a href="http://onlinetrainingespst.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
</tr>
</table>
</div>
<hr color="DCDCFB"/>
<div style="height:auto;text-align: center;font-size : 40px;color: #333333;margin-top:40px;font-weight: 300;">
Content of the Training
</div>
<div style="height:auto;text-align: center;font-size : 24px;color: #646464;margin-top:30px;">
<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-right: 25px;" />Monday<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-left: 25px;" /><br/><br/>
Introduction, CRM & Sales
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Introduction: Get familiar with the V7.</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>OpenERPs architecture</li>
<li>How to create an OpenERP Online instance</li>
<li>List and form views, search and filter features</li>
<li>Tooltips and drill-downs</li>
<li>Advanced navigation</li>
<li>Calendar, Graph, Kanban and Gantt views</li>
<li>Social network features: emailing, internal communication</li>
</ul>
</td>
<td style="width:50%;">
The introduction exercises have been created to help you discover OpenERP in an easy way. Their main objective is to present the different applications, menus, view types, shortcuts, field types, wizards, actions, etc. It will help you to discover how to navigate in OpenERP!<br/></br>
Therefore, the Introduction is compulsory for everyone, even if you need to learn a specific module given on an other date. This obligation has been made to make sure that you are not lost if you arrive in the middle of the training for another module.
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">CRM Module</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Manage Lead & Opportunities</li>
<li>Call, Meeting</li>
<li>Partners & contacts</li>
<li>Automated actions</li>
<li>Import partners and contacts from LinkedIn</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Track all leads coming in and push them to real opportunities</li>
<li>Improve the productivity of the sales force</li>
<li>Access all documents and messages related to one lead/opportunity in one place</li>
<li>Track the sales pipeline by month and stage to produce
accurate sales forecasts at the individual and group
levels</li>
<li>Track individual performance of sales people</li>
</ul>
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Sales Module</div>
<table>
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Customers</li>
<li>Products to sell</li>
<li>Manual discounts</li>
<li>Margins</li>
<li>Sales & Warehouse: Invoicing control (On demand / On
Delivery Order), Shipping policy (At once / Each product
when available)</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Register orders from customers and create invoices</li>
<li>Schedule deliveries (for products) or tasks (for service)</li>
<li>Ensure that sales orders are properly invoiced by tracking pending sales orders</li>
</ul>
</td>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<strong>CRM & Sales management:</strong>
<ul>
<li>From an opportunity to a sale order</li>
<li>Claims</li>
<li>Aftersale communication</li>
</ul>
</td>
<td style="width:50%;">
OpenERP can work with independent applications, so the
whole commercial process can be integrated together in
order to accomplish complete business flows.
</td>
</tr>
</table>
</div>
<div style="height:auto;text-align: center;font-size : 24px;color: #646464;margin-top:30px;">
<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-right: 25px;" />Tuesday<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-left: 25px;" /><br/><br/>
Access rights, Sales & Purchase, Financial accounting
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Access rights</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Users</li>
<li>Groups</li>
<li>Access rights and access rules</li>
<li>Modules configuration</li>
</ul>
</td>
<td style="width:50%;">
Thanks to the integrated access rights management integrated, each user has an access to its relevant information. No overloaded screen with a lot of irrelevant data, no unwanted menu, etc. Only a clean interface!
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Purchase</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Suppliers</li>
<li>Products</li>
<li>Request for Quotation</li>
<li>Purchase order</li>
<li>Invoicing & Invoice control</li>
<li>Incoming order (Complete/partial reception)</li>
<li>Purchase requisition</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Better negotiate volumes and prices based on historical data</li>
<li>Centralize all the data to be able to build reporting and statistics</li>
<li>Control the invoicing process</li>
<li>Work with purchase requisitions to ask different suppliers to submit quotations</li>
</ul>
</td>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<strong>Sales & Purchase management</strong>
<ul>
<li>Make to order product</li>
<li>Retailer process: buy a product and sell it without any customization/manufacturing</li>
</ul>
</td>
<td style="width:50%;">
Keep control of the replenishment process based on sales demands! Thanks to this integration, you will be able to automate the ordering for the missing units ordered by a customer
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Financial accounting</div>
<table>
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Invoices</li>
<li>Refunds</li>
<li>Journal Entries & Reconciliations</li>
<li>Reports / Closing of fiscal year</li>
<li>Accounts</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Rapidly encode your financial operations or accounting transactions</li>
<li>Carry out payments easily and adequately reconcile these payments with invoices</li>
<li>Quick creation of invoices with pre-set defaults on debtor/creditor and income/expense accounts</li>
<li>Multiple manners to reconcile</li>
<li>Configuration of accounts to ensure correct display in balance sheet and profit & loss statement</li>
<li>Apply correct deferral methods to ensure the close of the fiscal year</li>
</ul>
</td>
</tr>
</table>
</div>
<div style="height:auto;text-align: center;font-size : 24px;color: #646464;margin-top:30px;">
<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-right: 25px;" />Wednesday<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-left: 25px;" /><br/><br/>
Project management, Human resources, Contract management
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Project Management</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Projects</li>
<li>Tasks and tasks delegation</li>
<li>Issues and issues escalation</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Manage and follow your projects, tasks and issues</li>
<li>Discover the Kanban view to quickly operate some actions and to quickly detect any bottlenecks in your projects flows</li>
<li>Discover the Gantt view to see how your project has been planned and adapt it according to new elements or to the people agenda</li>
<li>Define project members & delegate tasks</li>
<li>Register issues and escalate them</li>
<li>Create automatically timesheet lines in the Human Resources menu from recorded work activities</li>
<li>Track and invoice (to customers) the costs associated to a project</li>
<li>Manage a support ticket system</li>
</ul>
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Human Resources</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Employees</li>
<li>Recruitment</li>
<li>Expenses</li>
<li>Allocations and leaves requests</li>
<li>Time management: timesheet and timesheet lines</li>
</ul>
</td>
<td style="width:50%;">
<strong>About Recruiting:</strong>
<ul>
<li>Better negotiate volumes and prices based on historical data</li>
<li>Centralize all the data to be able to build reporting and statistics</li>
<li>Control the invoicing process</li>
<li>Work with purchase requisitions to ask different suppliers to submit quotations</li>
</ul>
<strong>About Holidays:</strong>
<ul>
<li>Track the number of vacation days accrued by each employee</li>
<li>Allow managers to approve leave requests and plan backups for their teams</li>
</ul>
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Contract management</div>
<table>
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Contracts</li>
<li>Invoicing methods
<li>Sale orders</li>
<li>Timesheets</li>
<li>Expenses</li>
</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Centralize the data related to a specific contract in one single point</li>
<li>Perform the invoicing from one single place (Sales order / Timesheet / Expenses)</li>
<li>Follow the renewal process</li>
<li>Compute statistics based on expected revenues</li>
</ul>
</td>
</tr>
</table>
</div>
<div style="height:auto;text-align: center;font-size : 24px;color: #646464;margin-top:30px;">
<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-right: 25px;" />Thursday<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-left: 25px;" /><br/><br/>
Warehouse management, Manufacturing (MRP) & Sales, Import/Export
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Warehouse management</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Stock moves</li>
<li>Inventory</li>
<li>Partial delivery / receipt</li>
<li>Units of measure</li>
</ul>
</td>
<td style="width:50%;">
OpenERP Warehouse Management is at once very simple, flexible and complete. It is based on the concept of double entry that revolutionized accounting: Nothing lost, everything moved. In OpenERP, we dont talk about disappearance, consumption or loss of products: instead we speak only of stock moves from one place to another.
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Manufacturing (MRP)</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Bill of materials</li>
<li>Multi-level BoM</li>
<li>Routings</li>
<li>Work center operations</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Manage the production planning</li>
<li>Organize the different manufacturing orders to optimize the workload of the different resources</li>
<li>From an operational perspective, track which products and quantities need to be manufactured</li>
</ul>
<strong>As a manager:</strong>
<ul>
<li>Define products to be assembled or to be sold as a kit</li>
<li>Organize the pipeline of the production</li>
<li>Track the cost of a manufacturing order and measure the efficiency of the department</li>
</ul>
</td>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<strong>MRP & Sales</strong>
<ul>
<li>Product configuration Make to Stock / to Order</li>
<li>Commercial BoM (kit)</li>
<li>Just in Time</li>
</ul>
</td>
<td style="width:50%;">
From the sales perspective, you will have a manufacturing order generated based on a request coming from a customer without any manual operation. This integration of those two aplications allows you to perform the following flow in an automated way: Sale order > Stock level verification > Production of the missing units > Reception in stock of the finished goods > Delivery to the customer.
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Import/Export</div>
<table>
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Import from CSV files</li>
<li>Export as CSV or as Excel file</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Transfer data from one system to OpenERP.</li>
</ul>
OpenERP offers a simple way to import and export data. OpenERP will guide you for this phase thanks to a FAQ directly integrated into the import screen
</td>
</tr>
</table>
</div>
<div style="height:auto;text-align: center;font-size : 24px;color: #646464;margin-top:30px;">
<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-right: 25px;" />Friday<hr style="display: inline-block; width: 15%; margin-bottom: 4px;margin-left: 25px;" /><br/><br/>
Pricelists, Point of Sale (POS), Introduction to report customization
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Pricelists</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Prices for returning customers</li>
<li>Prices in foreign currencies (with exchange fees)</li>
<li>Retailer prices (based on a minimal margin)</li>
</ul>
</td>
<td style="width:50%;">
<ul>
<li>Keep control on the pricing policy</li>
<li>Allow discounts for some periods</li>
<li>Ensure your margins even when you define discounts</li>
<li>Allow different pricing by customer and/or supplier</li>
<li>Update the prices in an easy way</li>
</ul>
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Point of Sale (POS)</div>
<table cellspacing="5">
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Payment methods (journals)</li>
<li>POS Configuration</li>
<li>POS front-end</li>
<li>POS back-end</li>
<li>Shops</li>
<li>Sessions</li>
<li>POS Orders</li>
<li>Re-Invoicing</li>
<li>Scanning / Self-scanning</li>
</ul>
</td>
<td style="width:50%;">
OpenERP POS is the first POS running in a 100% web based environment, which means any computer with a browser can host the POS. The POS is a two-part system with a front-end (interaction with the client) and a back-end (managers can configure the system, print reports, analyse, ...)<br/><br/>
<strong>About the front-end:</strong>
<ul>
<li>Offline mode. Imagine several cases were having an offline mode is of prime interest: Connexion to server shutdown at a big supermarket / Use in environments that requires mobility but without wifi / Use in large environments like restaurants and gardens / Use in low tech environments</li>
</ul>
<strong>About the back-end:</strong>
<ul>
<li>Configure the products being sold in the POS</li>
<li>Configure the payments methods</li>
<li>Print daily sales report</li>
<li>Analyze sales</li>
</ul>
</td>
</tr>
</table>
<div style="text-align: left;font-size : 24px;color: #646464;margin-top:30px;">Introduction to report customization</div>
<table>
<tr style="text-align: center;font-size : 20px;color: #FFFFFF;background-color:#969696;">
<th>Content</th>
<th>What will you learn?</th>
</tr>
<tr style="text-align: left;font-size : 16px;color: #646464;">
<td style="width:50%;">
<ul>
<li>Customize the layout of your invoices</li>
<li>Change the footer/header of documents</li>
<li>Add a field in a standard document / report</li>
</ul>
</td>
<td style="width:50%;">
This features will help you to fully customize the standard documents made from OpenERP.
</td>
</tr>
</table>
</div>
<div style="text-align: center;background-color:#FFFFFF;margin-top:30px;" >
<table cellspacing="5" align="center" cellpadding="5">
<tr style="font-size : 20px;color: #333333;margin-top:30px;">
<td>English</td>
<td>English</td>
<td>Spanish</td>
</tr>
<tr style="font-size : 10px;color: #646464;">
<td>Europe</td>
<td>USA & Canada</td>
<td>USA & Latin America</td>
</tr>
<tr style="font-size : 10px;color: #FFFFFF;background-color:#8b5bdd;">
<td><a href="http://onlinetrainingencet.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
<td><a href="http://onlinetrainingenpst.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
<td><a href="http://onlinetrainingespst.eventbrite.com" style="text-decoration:none;color:#FFFFFF;" target=_new>Register</a></td>
</tr>
</table>
</div>
<hr color="DCDCFB"/>
<div style="height:auto;text-align: center;font-size : 30px;color: #333333;margin-top:10px;">
Training Material
</div>
<div style="height:auto;text-align: left;font-size : 16px;color: #646464;margin-top:30px;">
As soon as registration will be finalized (ie. payment confirmation), the participants will be provided with the material listed
below:
<ul>
<li>Access to online videos with detailed demos</li>
<li>Training material with exercises</li>
<li>Written solutions to the exercises</li>
</ul>
Therefore, there is an advantage to registering early to the training if you are interested in preparing your live sessions ahead of time. Moreover, the number of participants is limited per online session which is another reason to consider registering early and securing your seat.
</div>
<div style="text-align: center;background-color:#FFFFFF;margin-top:30px;font-size:20px;color:#4e66e7">
<table cellspacing="5">
<tr>
<td>
With the live sessions, we learned a lot more than what was covered in the videos. Definitely a good start for building up a solid base of working knowledge of OpenERP.
</td>
<td>
The trainer did a wonderful job with the training! He was well informed and interactive online and offline. Thank you so much for the experience!
</td>
</tr>
<tr>
<td>
It would be very difficult to cover all of the possibilities of OpenERP and I believe the major aspects were covered very well
</td>
<td>
The trainer has a very good knowledge of the subject, he understands the issues of the trainees very fast and provided answers with the right level of illustration.
</td>
</tr>
</table>
</div>
</div>
]]>
</field>
</record>
<record id="product_online_training" model="product.product">
<field name="name">Online Training</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="standard_price">500</field>
<field name="list_price">900</field>
<field name="type">service</field>
<field name="uom_id" ref="product.product_uom_hour"/>
<field name="uom_po_id" ref="product.product_uom_hour"/>
<field name="email_template_id" ref="product_online_training_email_template"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
import product
import invoice

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
from openerp.osv import osv
class account_invoice(osv.Model):
_inherit = 'account.invoice'
def invoice_validate_send_email(self, cr, uid, ids, context=None):
Composer = self.pool['mail.compose.message']
for invoice in self.browse(cr, uid, ids, context=context):
# send template only on customer invoice
if invoice.type != 'out_invoice':
continue
# subscribe the partner to the invoice
if invoice.partner_id.id not in invoice.message_follower_ids:
self.message_subscribe(cr, uid, [invoice.id], [invoice.partner_id.id], context=context)
for line in invoice.invoice_line:
if line.product_id.email_template_id:
# CLEANME: should define and use a clean API: message_post with a template
composer_id = Composer.create(cr, uid, {
'model': 'account.invoice',
'res_id': invoice.id,
'template_id': line.product_id.email_template_id.id,
'composition_mode': 'comment',
}, context=context)
template_values = Composer.onchange_template_id(
cr, uid, composer_id, line.product_id.email_template_id.id, 'comment', 'account.invoice', invoice.id
)['value']
template_values['attachment_ids'] = [(4, id) for id in template_values.get('attachment_ids', '[]')]
Composer.write(cr, uid, [composer_id], template_values, context=context)
Composer.send_mail(cr, uid, [composer_id], context=context)
return True
def invoice_validate(self, cr, uid, ids, context=None):
res = super(account_invoice, self).invoice_validate(cr, uid, ids, context=context)
self.invoice_validate_send_email(cr, uid, ids, context=context)
return res

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from openerp.osv import fields, osv
class product_template(osv.Model):
""" Product Template inheritance to add an optional email.template to a
product.template. When validating an invoice, an email will be send to the
customer based on this template. The customer will receive an email for each
product linked to an email template. """
_inherit = "product.template"
_columns = {
'email_template_id': fields.many2one(
'email.template', 'Product Email Template',
help='When validating an invoice, an email will be send to the customer'
'based on this template. The customer will receive an email for each'
'product linked to an email template.'),
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="email_template_form_simplified">
<field name="name">email.template.form.simplified</field>
<field name="model">email.template</field>
<field name="priority">100</field>
<field name="arch" type="xml">
<form string="Email Template" version="7.0">
<group>
<field name="subject" invisible="1"/>
<field name="name" invisible="1"/>
<field name="model" invisible="1"/>
<h3 colspan="2">Body</h3>
<field name="body_html" nolabel="1" colspan="2"
placeholder="Rich-text/HTML content of the message (placeholders may be used here)"/>
<field name="attachment_ids" nolabel="1" colspan="2"
widget="many2many_binary"/>
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="product_normal_form_view_template" model="ir.ui.view">
<field name="name">product.normal.procurement.locations.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="list_price" position="after">
<field name="email_template_id"
domain="[('model','=','product.template')]"
context="{
'form_view_ref':'product_email_template.email_template_form_simplified',
'default_model': 'product.template',
'default_subject': name,
'default_name': name,
}"/>
</field>
</field>
</record>
</data>
</openerp>