[MERGE]sync with trunk

bzr revid: sgo@tinyerp.com-20130411104746-3es0zngtda287wzb
This commit is contained in:
sgo@tinyerp.com
2013-04-11 16:17:46 +05:30
95 changed files with 1143 additions and 558 deletions
+1 -1
View File
@@ -3401,7 +3401,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
try:
tmp2 = obj_data.get_object_reference(cr, uid, *ref)
if tmp2:
self.pool.get(tmp2[0]).write(cr, uid, tmp2[1], {
self.pool[tmp2[0]].write(cr, uid, tmp2[1], {
'currency_id': obj_wizard.currency_id.id
})
except ValueError, e:
+1 -1
View File
@@ -313,7 +313,7 @@ class account_invoice(osv.osv):
context = {}
if context.get('active_model', '') in ['res.partner'] and context.get('active_ids', False) and context['active_ids']:
partner = self.pool.get(context['active_model']).read(cr, uid, context['active_ids'], ['supplier','customer'])[0]
partner = self.pool[context['active_model']].read(cr, uid, context['active_ids'], ['supplier','customer'])[0]
if not view_type:
view_id = self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'account.invoice.tree')])
view_type = 'tree'
+2 -1
View File
@@ -453,10 +453,11 @@
<filter name="invoices" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Proforma/Open/Paid Invoices"/>
<filter name="unpaid" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
<separator/>
<filter domain="[('user_id','=',uid)]" help="My Invoices" icon="terp-personal"/>
<field name="partner_id"/>
<field name="user_id" string="Salesperson"/>
<field name="period_id" string="Period"/>
<separator/>
<filter domain="[('user_id','=',uid)]" help="My Invoices"/>
<group expand="0" string="Group By...">
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+1 -1
View File
@@ -21,7 +21,7 @@ class CashBox(osv.osv_memory):
active_model = context.get('active_model', False) or False
active_ids = context.get('active_ids', []) or []
records = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)
records = self.pool[active_model].browse(cr, uid, active_ids, context=context)
return self._run(cr, uid, ids, records, context=None)
@@ -267,7 +267,7 @@
</field>
</record>
<menuitem id="base.menu_sales" name="Sales" parent="base.menu_base_partner" sequence="1"/>
<menuitem action="action_account_analytic_overdue_all" id="menu_action_account_analytic_overdue_all" sequence="7" parent="base.menu_sales"/>
<menuitem action="action_account_analytic_overdue_all" id="menu_action_account_analytic_overdue_all" sequence="8" parent="base.menu_sales"/>
<!-- Action Sales/Invoicing/Time and Material to Invoice -->
<record id="action_hr_tree_invoiced_all" model="ir.actions.act_window">
@@ -40,10 +40,10 @@ class one2many_mod2(fields.one2many):
plan = journal.plan_id
if plan and len(plan.plan_ids) > pnum:
acc_id = plan.plan_ids[pnum].root_analytic_id.id
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids),('analytic_account_id','child_of',[acc_id])], limit=self._limit)
ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids),('analytic_account_id','child_of',[acc_id])], limit=self._limit)
if ids2 is None:
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
for r in obj.pool[self._obj]._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
return res
+1 -1
View File
@@ -253,7 +253,7 @@
<para style="terp_default_Centre_9">[[ get_invoice_name(line.ml_inv_ref.id) or '-' ]]</para>
</td>
<td>
<para style="terp_default_Centre_9">[[line.date=='False' and '-' or formatLang(line.date,date=True) ]]</para>
<para style="terp_default_Centre_9">[[not line.date and '-' or formatLang(line.date,date=True) ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang(line.amount or '-', currency_obj=line.company_currency) ]] </para>
+2 -2
View File
@@ -411,7 +411,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
model_name = field.model_id.model
field_name = field.field_id.name
field_type = field.field_id.ttype
table_name = self.pool.get(model_name)._table
table_name = self.pool[model_name]._table
# get the current value
sql = "select id, %s from %s" % (field_name, table_name)
@@ -543,7 +543,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
fixes = group(fixes, ('model_name', 'field_name'))
for line in data:
table_name = self.pool.get(line['model_id'])._table if self.pool.get(line['model_id']) else None
table_name = self.pool[line['model_id']]._table if line['model_id'] in self.pool else None
# check if custom sql exists:
key = (line['model_id'], line['field_id'])
+8 -9
View File
@@ -70,8 +70,7 @@ class audittrail_rule(osv.osv):
obj_model = self.pool.get('ir.model.data')
#start Loop
for thisrule in self.browse(cr, uid, ids):
obj = self.pool.get(thisrule.object_id.model)
if not obj:
if thisrule.object_id.model not in self.pool:
raise osv.except_osv(
_('WARNING: audittrail is not part of the pool'),
_('Change audittrail depends -- Setting rule as DRAFT'))
@@ -131,7 +130,7 @@ class audittrail_log(osv.osv):
model_object = resname.object_id
res_id = resname.res_id
if model_object and res_id:
model_pool = self.pool.get(model_object.model)
model_pool = self.pool[model_object.model]
res = model_pool.read(cr, uid, res_id, ['name'])
data[resname.id] = res['name']
else:
@@ -190,7 +189,7 @@ def get_value_text(cr, uid, pool, resource_pool, method, field, value):
field_obj = (resource_pool._all_columns.get(field)).column
if field_obj._type in ('one2many','many2many'):
data = pool.get(field_obj._obj).name_get(cr, uid, value)
data = pool[field_obj._obj].name_get(cr, uid, value)
#return the modifications on x2many fields as a list of names
res = map(lambda x:x[1], data)
elif field_obj._type == 'many2one':
@@ -212,7 +211,7 @@ def create_log_line(cr, uid, log_id, model, lines=None):
if lines is None:
lines = []
pool = openerp.registry(cr.dbname)
obj_pool = pool.get(model.model)
obj_pool = pool[model.model]
model_pool = pool.get('ir.model')
field_pool = pool.get('ir.model.fields')
log_line_pool = pool.get('audittrail.log.line')
@@ -251,7 +250,7 @@ def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw):
@return: Returns result as per method of Object proxy
"""
pool = openerp.registry(cr.dbname)
resource_pool = pool.get(model)
resource_pool = pool[model]
model_pool = pool.get('ir.model')
model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)])
model_id = model_ids and model_ids[0] or False
@@ -321,7 +320,7 @@ def get_data(cr, uid, pool, res_ids, model, method):
}
"""
data = {}
resource_pool = pool.get(model.model)
resource_pool = pool[model.model]
# read all the fields of the given resources in super admin mode
for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids):
values = {}
@@ -390,7 +389,7 @@ def prepare_audittrail_log_line(cr, uid, pool, model, resource_id, method, old_v
key: []
}
# loop on all the fields
for field_name, field_definition in pool.get(model.model)._all_columns.items():
for field_name, field_definition in pool[model.model]._all_columns.items():
if field_name in ('__last_update', 'id'):
continue
#if the field_list param is given, skip all the fields not in that list
@@ -457,7 +456,7 @@ def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_val
# if at least one modification has been found
for model_id, resource_id in lines:
name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1]
name = pool[model.model].name_get(cr, uid, [resource_id])[0][1]
vals = {
'method': method,
'object_id': model_id,
+4 -4
View File
@@ -96,7 +96,7 @@ class base_action_rule(osv.osv):
""" filter the list record_ids that satisfy the action filter """
if record_ids and action_filter:
assert action.model == action_filter.model_id, "Filter model different from action rule model"
model = self.pool.get(action_filter.model_id)
model = self.pool[action_filter.model_id]
domain = [('id', 'in', record_ids)] + eval(action_filter.domain)
ctx = dict(context or {})
ctx.update(eval(action_filter.context))
@@ -106,7 +106,7 @@ class base_action_rule(osv.osv):
def _process(self, cr, uid, action, record_ids, context=None):
""" process the given action on the records """
# execute server actions
model = self.pool.get(action.model_id.model)
model = self.pool[action.model_id.model]
if action.server_action_ids:
server_action_ids = map(int, action.server_action_ids)
for record in model.browse(cr, uid, record_ids, context):
@@ -195,7 +195,7 @@ class base_action_rule(osv.osv):
ids = self.search(cr, SUPERUSER_ID, [])
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
model_obj = self.pool.get(model)
model_obj = self.pool[model]
if not hasattr(model_obj, 'base_action_ruled'):
model_obj.create = self._wrap_create(model_obj.create, model)
model_obj.write = self._wrap_write(model_obj.write, model)
@@ -232,7 +232,7 @@ class base_action_rule(osv.osv):
last_run = get_datetime(action.last_run) if action.last_run else False
# retrieve all the records that satisfy the action's condition
model = self.pool.get(action.model_id.model)
model = self.pool[action.model_id.model]
domain = []
ctx = dict(context)
if action.filter_id:
+4 -4
View File
@@ -591,7 +591,7 @@ property or property parameter."),
for vals in self.browse(cr, uid, ids, context=context):
if vals.ref and vals.ref.user_id:
mod_obj = self.pool.get(vals.ref._name)
mod_obj = self.pool[vals.ref._name]
res=mod_obj.read(cr,uid,[vals.ref.id],['duration','class'],context)
defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id,'duration':res[0]['duration'],'class':res[0]['class']}
mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
@@ -684,7 +684,7 @@ true, it will allow you to hide the event alarm information without removing it.
ir_obj = self.pool.get('ir.model')
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
model_obj = self.pool.get(model)
model_obj = self.pool[model]
for data in model_obj.browse(cr, uid, ids, context=context):
basic_alarm = data.alarm_id
@@ -754,7 +754,7 @@ true, it will allow you to hide the event alarm information without removing it.
alarm_obj = self.pool.get('calendar.alarm')
ir_obj = self.pool.get('ir.model')
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
model_obj = self.pool.get(model)
model_obj = self.pool[model]
for data in model_obj.browse(cr, uid, ids, context=context):
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', data.id)])
if alarm_ids:
@@ -853,7 +853,7 @@ class calendar_alarm(osv.osv):
for alarm in self.browse(cr, uid, alarm_ids, context=context):
next_trigger_date = None
update_vals = {}
model_obj = self.pool.get(alarm.model_id.model)
model_obj = self.pool[alarm.model_id.model]
res_obj = model_obj.browse(cr, uid, alarm.res_id, context=context)
re_dates = []
+1 -1
View File
@@ -135,7 +135,7 @@ class mail_message(osv.osv):
def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None):
if doc_model == 'crm.meeting':
for virtual_id in self.pool.get(doc_model).get_recurrent_ids(cr, uid, doc_dict.keys(), [], context=context):
for virtual_id in self.pool[doc_model].get_recurrent_ids(cr, uid, doc_dict.keys(), [], context=context):
doc_dict.setdefault(virtual_id, doc_dict[get_real_ids(virtual_id)])
return super(mail_message, self)._find_allowed_model_wise(cr, uid, doc_model, doc_dict, context=context)
+20 -1
View File
@@ -81,6 +81,8 @@ Dashboard for CRM will include:
'crm_lead_view.xml',
'crm_lead_menu.xml',
'crm_case_section_view.xml',
'crm_meeting_menu.xml',
'crm_phonecall_view.xml',
@@ -114,9 +116,26 @@ Dashboard for CRM will include:
'test/crm_lead_copy.yml',
'test/crm_lead_unlink.yml',
],
'css': [
'static/src/css/crm.css'
],
'js': [
'static/src/js/crm.js'
],
'installable': True,
'application': True,
'auto_install': False,
'images': ['images/crm_dashboard.png', 'images/customers.png','images/leads.png','images/opportunities_kanban.png','images/opportunities_form.png','images/opportunities_calendar.png','images/opportunities_graph.png','images/logged_calls.png','images/scheduled_calls.png','images/stages.png'],
'images': [
'images/crm_dashboard.png',
'images/customers.png',
'images/leads.png',
'images/opportunities_kanban.png',
'images/opportunities_form.png',
'images/opportunities_calendar.png',
'images/opportunities_graph.png',
'images/logged_calls.png',
'images/scheduled_calls.png',
'images/stages.png',
],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+21 -10
View File
@@ -98,6 +98,7 @@ class crm_case_stage(osv.osv):
'case_default': True,
}
class crm_case_section(osv.osv):
""" Model for sales teams. """
_name = "crm.case.section"
@@ -107,7 +108,7 @@ class crm_case_section(osv.osv):
_order = "complete_name"
def get_full_name(self, cr, uid, ids, field_name, arg, context=None):
return dict(self.name_get(cr, uid, ids, context=context))
return dict(self.name_get(cr, uid, ids, context=context))
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
@@ -117,27 +118,36 @@ class crm_case_section(osv.osv):
"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'),
'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 )),
'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="cascade", required=True,
help="The email address associated with this team. New emails received will automatically "
"create new leads assigned to the team."),
'open_lead_ids': fields.one2many('crm.lead', 'section_id',
string='Open Leads', readonly=True,
domain=['&', ('type', '!=', 'opportunity'), ('state', 'not in', ['done', 'cancel'])]),
'open_opportunity_ids': fields.one2many('crm.lead', 'section_id',
string='Open Opportunities', readonly=True,
domain=['&', '|', ('type', '=', 'opportunity'), ('type', '=', 'both'), ('state', 'not in', ['done', 'cancel'])]),
'color': fields.integer('Color Index'),
'use_leads': fields.boolean('Leads',
help="This enables the management of leads in the sales team. Otherwise the sales team manages only opportunities."),
}
def _get_stage_common(self, cr, uid, context):
ids = self.pool.get('crm.case.stage').search(cr, uid, [('case_default','=',1)], context=context)
ids = self.pool.get('crm.case.stage').search(cr, uid, [('case_default', '=', 1)], context=context)
return ids
_defaults = {
'active': 1,
'stage_ids': _get_stage_common,
'alias_domain': False, # always hide alias during creation
'use_leads': True,
}
_sql_constraints = [
@@ -150,7 +160,7 @@ class crm_case_section(osv.osv):
def name_get(self, cr, uid, ids, context=None):
"""Overrides orm name_get method"""
if not isinstance(ids, list) :
if not isinstance(ids, list):
ids = [ids]
res = []
if not ids:
@@ -167,20 +177,20 @@ class crm_case_section(osv.osv):
def create(self, cr, uid, vals, context=None):
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id'):
vals.pop('alias_name', None) # prevent errors during copy()
alias_name = vals.pop('alias_name', None) or vals.get('name') # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
{'alias_name': vals['name']},
{'alias_name': alias_name},
model_name="crm.lead",
context=context)
vals['alias_id'] = alias_id
res = super(crm_case_section, self).create(cr, uid, vals, context)
mail_alias.write(cr, uid, [vals['alias_id']], {'alias_defaults': {'section_id': res, 'type':'lead'}}, context)
mail_alias.write(cr, uid, [vals['alias_id']], {'alias_defaults': {'section_id': res, 'type': 'lead'}}, context)
return res
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 ]
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
@@ -230,4 +240,5 @@ class crm_payment_mode(osv.osv):
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+294
View File
@@ -0,0 +1,294 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- CRM lead search by Salesteams -->
<record model="ir.actions.act_window" id="crm_case_form_view_salesteams_lead">
<field name="name">Leads</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form</field>
<field name="domain">['|', ('type','=','lead'), ('type','=',False)]</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{
'search_default_section_id': [active_id],
'search_default_open': 1,
'default_section_id': active_id,
'default_type': 'lead',
'stage_type': 'lead',
}
</field>
<field name="help" type="html">
<p>
Use leads if you need a qualification step before creating an
opportunity or a customer. It can be a business card you received,
a contact form filled in your website, or a file of unqualified
prospects you import, etc.
</p><p>
Once qualified, the lead can be converted into a business
opportunity and/or a new customer in your address book.
</p>
</field>
</record>
<!-- CRM opportunity search by Salesteams -->
<record model="ir.actions.act_window" id="crm_case_form_view_salesteams_opportunity">
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,graph,form,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="view_id" ref="crm.crm_case_kanban_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="context">{
'search_default_section_id': [active_id],
'search_default_new': 1,
'search_default_open': 1,
'default_section_id': active_id,
'stage_type': 'opportunity',
'default_type': 'opportunity',
'default_user_id': uid,
}
</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new opportunity.
</p><p>
OpenERP helps you keep track of your sales pipeline to follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
</field>
</record>
<!-- Case Sections Salesteams kanban view -->
<record model="ir.ui.view" id="crm_case_section_salesteams_view_kanban">
<field name="name">crm.case.section.kanban</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<kanban version="7.0" class="oe_background_grey">
<field name="use_leads"/>
<field name="name"/>
<field name="user_id"/>
<field name="member_ids"/>
<field name="note"/>
<field name="alias_id"/>
<field name="color"/>
<field name="open_lead_ids"/>
<field name="open_opportunity_ids"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click oe_kanban_crm_salesteams">
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">
<li t-if="widget.view.is_action_enabled('edit')"><a type="edit">Sales Teams Settings</a></li>
<li t-if="widget.view.is_action_enabled('delete')"><a type="delete">Delete</a></li>
<li t-if="widget.view.is_action_enabled('edit')"><ul class="oe_kanban_colorpicker" data-field="color"/></li>
</ul>
</div>
<div class="oe_kanban_content">
<h4><field name="name"/></h4>
<div class="oe_kanban_alias" t-if="record.use_leads.raw_value and record.alias_id.value">
<span class="oe_e">%%</span><small><field name="alias_id"/></small>
</div>
<div class="oe_items_list">
<a t-if="record.use_leads.raw_value" name="%(crm_case_form_view_salesteams_lead)d" type="action">
<t t-raw="record.open_lead_ids.raw_value.length"/>
<t t-if="record.open_lead_ids.raw_value.length &gt;= 2">Leads</t>
<t t-if="record.open_lead_ids.raw_value.length &lt; 2">Lead</t></a>
<a name="%(crm_case_form_view_salesteams_opportunity)d" type="action">
<t t-raw="record.open_opportunity_ids.raw_value.length"/>
<t t-if="record.open_opportunity_ids.raw_value.length &gt;= 2">Opportunities</t>
<t t-if="record.open_opportunity_ids.raw_value.length &lt; 2">Opportunity</t></a>
</div>
<div class="oe_avatars">
<img t-if="record.user_id.raw_value" t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-data-member_id="record.user_id.raw_value"/>
<t t-foreach="record.member_ids.raw_value.slice(0,11)" t-as="member">
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
</t>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Case Sections Action -->
<record id="crm_case_section_salesteams_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="crm_case_section_salesteams_view_kanban"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click here to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<!-- Case Sections Form View -->
<record id="crm_case_section_view_form" model="ir.ui.view">
<field name="name">crm.case.section.form</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<form string="Sales Team" version="7.0">
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only" string="Project Name"/>
<h1>
<field name="name" string="Project Name"/>
</h1>
<div name="group_alias"
attrs="{'invisible': [('alias_domain', '=', False)]}">
<label for="alias_id" string="Email Alias"/>
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span name="edit_alias" class="oe_edit_only">
<field name="alias_name" class="oe_inline"
attrs="{'required': [('use_leads', '=', True), ('alias_id', '!=', False)]}"/>
@
<field name="alias_domain" class="oe_inline" readonly="1"/>
</span>
</div>
<div name="options_active">
<field name="use_leads" class="oe_inline"/><label for="use_leads"/>
</div>
</div>
<group>
<group>
<field name="parent_id"/>
<field name="resource_calendar_id"/>
<field name="active"/>
</group>
<group>
<field name="user_id"/>
<field name="code"/>
</group>
<group colspan="4" attrs="{'invisible': [('use_leads', '=', False)]}">
</group>
</group>
<notebook colspan="4">
<page string="Sales Team">
<group>
<field name="change_responsible"/>
</group>
<separator string="Team Members"/>
<field name="member_ids" widget="many2many_kanban">
<kanban quick_create="false" create="true">
<field name="name"/>
<templates>
<t t-name="kanban-box">
<div style="position: relative">
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
<div class="oe_module_vignette">
<div class="oe_module_desc">
<field name="name"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</page>
<page string="Stages">
<separator string="Select Stages for this Sales Team"/>
<field name="stage_ids"/>
</page>
<page string="Notes">
<field name="note"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Follow this salesteam to automatically track the events associated to users of this team."/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Case Sections Tree View -->
<record id="crm_case_section_view_tree" model="ir.ui.view">
<field name="name">crm.case.section.tree</field>
<field name="model">crm.case.section</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree string="Sales Team">
<field name="name"/>
<field name="code"/>
<field name="user_id"/>
</tree>
</field>
</record>
<!-- Case Sections Action -->
<record model="ir.actions.act_window.view" id="action_crm_tag_kanban_view_salesteams_oppor11">
<field name="sequence" eval="0"/>
<field name="view_mode">kanban</field>
<field name="view_id" ref="crm_case_kanban_view_leads"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_salesteams_oppor11">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_salesteams_oppor11">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_oppor"/>
<field name="act_window_id" ref="crm_case_form_view_salesteams_opportunity"/>
</record>
<record id="crm_case_section_act_tree" model="ir.actions.act_window">
<field name="name">Cases by Sales Team</field>
<field name="res_model">crm.case.section</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
</record>
<record id="crm_case_section_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click here to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<menuitem id="crm.menu_crm_case_section_act"
action="crm_case_section_salesteams_act"
sequence="1"
parent="base.menu_sales"
groups="base.group_multi_salesteams"/>
</data>
</openerp>
+3 -7
View File
@@ -27,8 +27,10 @@
</record>
<record model="crm.case.section" id="section_sales_department">
<field name="name">Sales Department</field>
<field name="name">Sales</field>
<field name="code">Sales</field>
<field name="use_leads">True</field>
<field name="member_ids" eval="[(4, ref('base.user_root'))]"/>
</record>
<!-- Payment Mode -->
@@ -64,12 +66,6 @@
<p>To manage quotations and sale orders, install the "Sales Management" application.</p>]]></field>
</record>
<record model="mail.alias" id="default_sales_alias">
<field name="alias_name">sales</field>
<field name="alias_model_id" ref="model_crm_lead"/>
<field name="alias_user_id" ref="base.user_root"/>
<field name="alias_defaults">{'type':'lead'}</field>
</record>
</data>
</openerp>
+16
View File
@@ -85,6 +85,22 @@ class crm_lead(base_stage, format_address, osv.osv):
},
}
def get_empty_list_help(self, cr, uid, help, context=None):
if context.get('default_type') == 'lead':
context['empty_list_help_model'] = 'crm.case.section'
context['empty_list_help_id'] = context.get('default_section_id')
context['empty_list_help_document_name'] = _("leads")
return super(crm_lead, self).get_empty_list_help(cr, uid, help, context=context)
def onchange_user_id(self, cr, uid, ids, section_id, user_id, context=None):
""" When changing the user, also set a section_id or restrict section id
to the ones user_id is member of. """
if user_id:
section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
if len(section_ids) > 0 and section_id not in section_ids:
section_id = section_ids[0]
return {'value': {'section_id': section_id}}
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
+1
View File
@@ -54,6 +54,7 @@
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Won</field>
<field eval="True" name="fold"/>
<field eval="1" name="case_default"/>
<field name="state">done</field>
<field eval="100" name="probability"/>
+39 -41
View File
@@ -9,34 +9,23 @@
<field name="domain">['|', ('type','=','lead'), ('type','=',False)]</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{'default_type':'lead', 'stage_type':'lead'}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create an unqualified lead.
</p><p>
Use leads if you need a qualification step before creating an
opportunity or a customer. It can be a business card you received,
a contact form filled in your website, or a file of unqualified
prospects you import, etc.
</p><p>
Once qualified, the lead can be converted into a business
opportunity and/or a new customer in your address book.
</p>
<field name="context">{
'default_type':'lead',
'stage_type':'lead',
'search_default_unassigned':1,
}
</field>
<field name="help" type="html">
<p>
Use leads if you need a qualification step before creating an
opportunity or a customer. It can be a business card you received,
a contact form filled in your website, or a file of unqualified
prospects you import, etc.
</p><p>
Once qualified, the lead can be converted into a business
opportunity and/or a new customer in your address book.
</p>
</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_leads_all">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="act_window_id" ref="crm_case_category_act_leads_all"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_leads_all">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_leads"/>
<field name="act_window_id" ref="crm_case_category_act_leads_all"/>
</record>
<record model="ir.actions.act_window" id="crm_case_category_act_oppor11">
@@ -44,20 +33,25 @@
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,graph,form,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'stage_type': 'opportunity', 'default_type': 'opportunity', 'default_user_id': uid}</field>
<field name="context">{
'stage_type': 'opportunity',
'default_type': 'opportunity',
'default_user_id': uid
}
</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new opportunity.
</p><p>
OpenERP helps you keep track of your sales pipeline to follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
<p class="oe_view_nocontent_create">
Click to create a new opportunity.
</p><p>
OpenERP helps you keep track of your sales pipeline to follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
</field>
</record>
@@ -82,9 +76,13 @@
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<menuitem name="Sales" id="base.menu_sales" parent="base.menu_base_partner" sequence="1" />
<menuitem name="Leads" id="menu_crm_leads" parent="base.menu_sales" action="crm_case_category_act_leads_all" sequence="2" />
<menuitem name="Opportunities" id="menu_crm_opportunities" parent="base.menu_sales" action="crm_case_category_act_oppor11" sequence="3" />
<menuitem name="Sales" id="base.menu_sales" parent="base.menu_base_partner" sequence="1"/>
<menuitem name="Leads" id="menu_crm_leads" parent="base.menu_sales" sequence="3"
action="crm_case_category_act_leads_all"
groups="base.group_mono_salesteams,base.group_sale_manager"/>
<menuitem name="Opportunities" id="menu_crm_opportunities" parent="base.menu_sales" sequence="4"
action="crm_case_category_act_oppor11"
groups="base.group_mono_salesteams,base.group_sale_manager"/>
</data>
</openerp>
+15 -14
View File
@@ -152,12 +152,13 @@
-->
</group>
<group>
<field name="user_id"
context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<label for="section_id"/>
<div>
<field name="user_id" on_change="onchange_user_id(section_id, user_id)"
context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads'] }"/>
<label for="section_id" groups="base.group_multi_salesteams"/>
<div groups="base.group_multi_salesteams">
<field name="section_id"/>
<button name="case_escalate" string="Escalate" type="object" attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
<button name="case_escalate" string="Escalate" type="object"
attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
</div>
<field name="type" invisible="1"/>
</group>
@@ -229,7 +230,7 @@
<field name="stage_id"/>
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="section_id" invisible="context.get('invisible_section', True)"/>
<field name="section_id" invisible="context.get('invisible_section', True)" groups="base.group_multi_salesteams"/>
<field name="state" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="referred" invisible="1"/>
@@ -327,7 +328,7 @@
<search string="Search Leads">
<field name="name" string="Lead / Customer" filter_domain="['|','|',('partner_name','ilike',self),('email_from','ilike',self),('name','ilike',self)]"/>
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike',self)]"/>
<field name="section_id" context="{'invisible_section': False, 'default_section_id': self}"/>
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="partner_id"/>
<field name="create_date"/>
@@ -335,7 +336,7 @@
<separator/>
<filter string="Open" name="open" domain="[('state','!=','cancel')]" help="Open Leads"/>
<filter string="Dead" name="dead" domain="[('state','=','cancel')]"/>
<filter string="Unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
@@ -428,9 +429,9 @@
</group>
<group>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<label for="section_id"/>
<div>
<field name="user_id" on_change="onchange_user_id(section_id, user_id)" context="{'default_groups_ref': ['base.group_user', 'base.group_sale_salesman_all_leads']}"/>
<label for="section_id" groups="base.group_multi_salesteams"/>
<div groups="base.group_multi_salesteams">
<field name="section_id" widget="selection"/>
<button name="case_escalate" string="Escalate" type="object" class="oe_link" attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
</div>
@@ -526,7 +527,7 @@
<field name="stage_id"/>
<field name="planned_revenue" sum="Expected Revenues"/>
<field name="probability" avg="Avg. of Probability"/>
<field name="section_id" invisible="context.get('invisible_section', True)"/>
<field name="section_id" invisible="context.get('invisible_section', True)" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="referred" invisible="1"/>
<field name="priority" invisible="1"/>
@@ -545,7 +546,7 @@
<search string="Search Opportunities">
<field name="name" string="Opportunity" filter_domain="['|','|','|',('partner_id','ilike',self),('partner_name','ilike',self),('email_from','ilike',self),('name', 'ilike', self)]"/>
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike', self)]"/>
<field name="section_id" context="{'invisible_section': False, 'default_section_id': self}"/>
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="partner_id"/>
<separator/>
@@ -553,7 +554,7 @@
<filter string="In Progress" name="open" domain="[('state','=','open')]" help="Open Opportunities"/>
<filter string="Won" name="won" domain="[('state','=','done')]"/>
<filter string="Lost" name="lost" domain="[('state','=','cancel')]"/>
<filter string="Unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
+4 -2
View File
@@ -103,7 +103,8 @@
<field name="date"/>
<field name="user_id"/>
<field name="duration" widget="float_time"/>
<field name="section_id" colspan="1" widget="selection"/>
<field name="section_id" colspan="1" widget="selection"
groups="base.group_multi_salesteams"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="email_from" invisible="1"/> <!--not needed because of the chatter, thus invisible, but must be in the view as it's returned by onchange_partner_id()-->
<field name="categ_id" widget="selection"
@@ -187,7 +188,8 @@
help="Phone Calls Assigned to the current user or with a team having the current user as team leader"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="section_id" string="Sales Team"/>
<field name="section_id" string="Sales Team"
groups="base.group_multi_salesteams"/>
<group expand="0" string="Group By...">
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+19 -16
View File
@@ -12,7 +12,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="category2_id"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
@@ -33,7 +33,8 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection"
groups="base.group_multi_salesteams"/>
<field name="category2_id" />
<field name="stage_id"/>
<field name="amount_revenue"/>
@@ -53,7 +54,8 @@
<graph string="Cases by Teams and Type" type="bar" orientation="horizontal">
<field name="category2_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
<field name="section_id" group="True"
groups="base.group_multi_salesteams"/>
</graph>
</field>
</record>
@@ -69,7 +71,7 @@
<field name="month"/>
<field name="nbr"/>
<field name="state"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="category2_id"/>
</search>
</field>
@@ -95,7 +97,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="nbr"/>
@@ -115,7 +117,8 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection"
groups="base.group_multi_salesteams"/>
<field name="stage_id"/>
<field name="amount_revenue"/>
<field name="nbr" />
@@ -134,7 +137,7 @@
<graph string="Cases by Team and Stage" type="bar" orientation="horizontal">
<field name="stage_id"/>
<field name="amount_revenue" operator="+"/>
<field name="section_id" group="True"/>
<field name="section_id" group="True" groups="base.group_multi_salesteams"/>
</graph>
</field>
</record>
@@ -150,7 +153,7 @@
<field name="month"/>
<field name="nbr"/>
<field name="state"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</search>
</field>
</record>
@@ -175,7 +178,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="categ_id"/>
<field name="stage_id"/>
<field name="nbr"/>
@@ -195,7 +198,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection" groups="base.group_multi_salesteams"/>
<field name="categ_id"/>
<field name="stage_id"/>
<field name="nbr" />
@@ -216,7 +219,7 @@
<field name="month"/>
<field name="nbr"/>
<field name="state"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</search>
</field>
</record>
@@ -230,7 +233,7 @@
<graph string="Cases by Section, Category and Stage" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
<field name="section_id" group="True" groups="base.group_multi_salesteams"/>
</graph>
</field>
</record>
@@ -255,7 +258,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="categ_id"/>
<field name="category2_id"/>
<field name="stage_id"/>
@@ -276,7 +279,7 @@
<field name="name"/>
<field name="month"/>
<field name="user_id"/>
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection" groups="base.group_multi_salesteams"/>
<field name="categ_id"/>
<field name="category2_id"/>
<field name="stage_id"/>
@@ -298,7 +301,7 @@
<field name="month"/>
<field name="nbr"/>
<field name="state"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</search>
</field>
</record>
@@ -312,7 +315,7 @@
<graph string="Cases by Section, Category and Type" type="bar" orientation="horizontal">
<field name="category2_id"/>
<field name="nbr" operator="+"/>
<field name="section_id" group="True"/>
<field name="section_id" group="True" groups="base.group_multi_salesteams"/>
</graph>
</field>
</record>
+6 -116
View File
@@ -70,109 +70,6 @@
<menuitem action="crm_case_channel_action" id="menu_crm_case_channel" parent="base.menu_crm_config_lead" sequence="4" groups="base.group_no_one"/>
<!-- Case Sections Form View -->
<record id="crm_case_section_view_form" model="ir.ui.view">
<field name="name">crm.case.section.form</field>
<field name="model">crm.case.section</field>
<field name="arch" type="xml">
<form string="Sales Team" version="7.0">
<group>
<group>
<field name="name" colspan="2"/>
<field name="parent_id"/>
<field name="code"/>
</group>
<group>
<field name="user_id"/>
<field name="resource_calendar_id"/>
<field name="active"/>
</group>
</group>
<notebook colspan="4">
<page string="Sales Team">
<group>
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
<div attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" class="oe_inline"/>
</div>
<field name="change_responsible"/>
</group>
<separator string="Team Members"/>
<field name="member_ids" widget="many2many_kanban">
<kanban quick_create="false" create="true">
<field name="name"/>
<templates>
<t t-name="kanban-box">
<div style="position: relative">
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
<div class="oe_module_vignette">
<div class="oe_module_desc">
<field name="name"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</page>
<page string="Stages">
<separator string="Select Stages for this Sales Team"/>
<field name="stage_ids"/>
</page>
<page string="Notes">
<field name="note"/>
</page>
</notebook>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Follow this salesteam to automatically track the events associated to users of this team."/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Case Sections Tree View -->
<record id="crm_case_section_view_tree" model="ir.ui.view">
<field name="name">crm.case.section.tree</field>
<field name="model">crm.case.section</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree string="Sales Team">
<field name="name"/>
<field name="code"/>
<field name="user_id"/>
</tree>
</field>
</record>
<!-- Case Sections Action -->
<record id="crm_case_section_act" model="ir.actions.act_window">
<field name="name">Sales Teams</field>
<field name="res_model">crm.case.section</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new sales team.
</p><p>
Use sales team to organize your different salespersons or
departments into separate teams. Each team will work in
its own list of opportunities.
</p>
</field>
</record>
<menuitem action="crm_case_section_act"
id="menu_crm_case_section_act" sequence="15"
parent="base.menu_base_config" groups="base.group_sale_manager"/>
<!-- CRM Stage Tree View -->
<record model="ir.ui.view" id="crm_case_stage_tree">
@@ -233,7 +130,7 @@
<form string="Case Category" version="7.0">
<group>
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="object_id" invisible="1"/>
</group>
</form>
@@ -248,7 +145,7 @@
<field name="arch" type="xml">
<tree string="Case Category">
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
@@ -261,7 +158,7 @@
<field name="arch" type="xml">
<tree string="Campaign">
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
@@ -275,7 +172,7 @@
<form string="Campaign" version="7.0">
<group>
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</group>
</form>
</field>
@@ -295,13 +192,6 @@
groups="base.group_no_one"
parent="base.menu_crm_config_lead"/>
<record id="crm_case_section_act_tree" model="ir.actions.act_window">
<field name="name">Cases by Sales Team</field>
<field name="res_model">crm.case.section</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="crm_case_section_view_tree"/>
</record>
<!-- Segmentation line Tree View -->
@@ -434,7 +324,7 @@
<field name="arch" type="xml">
<tree string="Payment Mode">
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
@@ -448,7 +338,7 @@
<form string="Payment Mode" version="7.0">
<group>
<field name="name"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</group>
</form>
</field>
+6 -3
View File
@@ -19,7 +19,8 @@
<field name="channel_id" invisible="1"/>
<field name="type" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1"
groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
@@ -77,7 +78,8 @@
help="Leads/Opportunities that are assigned to one of the sale teams I manage"/>
<separator/>
<filter icon="terp-personal" string="My Case(s)" help="Leads/Opportunities that are assigned to me" domain="[('user_id','=',uid)]"/>
<field name="section_id" context="{'invisible_section': False}"/>
<field name="section_id" context="{'invisible_section': False}"
groups="base.group_multi_salesteams"/>
<field name="user_id" string="Salesperson"/>
<group expand="0" string="Extended Filters...">
<field name="partner_id"/>
@@ -134,7 +136,8 @@
<field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/>
<field name="deadline_month" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1"
groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
@@ -11,7 +11,8 @@
<tree string="Phone calls" create="false">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1"
groups="base.group_multi_salesteams"/>
<field name="priority" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
@@ -59,7 +60,8 @@
help="Phone calls that are assigned to one of the sale teams I manage"/>
<separator/>
<filter icon="terp-personal" string="My Phone Calls" help="Phone Calls that are assigned to me" domain="[('user_id','=',uid)]" />
<field name="section_id" string="Sales Team" context="{'invisible_section': False}"/>
<field name="section_id" string="Sales Team" context="{'invisible_section': False}"
groups="base.group_multi_salesteams"/>
<field name="user_id" string="Salesperson"/>
<group expand="0" string="Extended Filters...">
<field name="partner_id"/>
+37 -10
View File
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
# Copyright (C) 2004-TODAY OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -21,24 +21,51 @@
from openerp.osv import fields, osv
class crm_configuration(osv.osv_memory):
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 = {
'fetchmail_lead': fields.boolean("Create leads from incoming mails",
fetchmail_model='crm.lead', fetchmail_name='Incoming Leads',
help="""Allows you to configure your incoming mail server, and create leads from incoming emails."""),
'group_fund_raising': fields.boolean("Manage Fund Raising",
implied_group='crm.group_fund_raising',
help="""Allows you to trace and manage your activities for fund raising."""),
'module_crm_claim':fields.boolean("Manage Customer Claims",
'module_crm_claim': fields.boolean("Manage Customer Claims",
help="""Allows you to track your customers/suppliers claims and grievances.
This installs the module crm_claim."""),
'module_crm_helpdesk':fields.boolean("Manage Helpdesk and Support",
help="""Allows you to communicate with Customer, process Customer query, and provide better help and support. This installs the module crm_helpdesk."""),
'module_crm_helpdesk': fields.boolean("Manage Helpdesk and Support",
help="""Allows you to communicate with Customer, process Customer query, and provide better help and support. This installs the module crm_helpdesk."""),
'group_multi_salesteams': fields.boolean("Organize Sales activities into multiple Sales Teams",
implied_group='base.group_multi_salesteams',
help="""Allows you to use Sales Teams to manage your leads and opportunities."""),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+5 -10
View File
@@ -22,20 +22,15 @@
</div>
</div>
</group>
</div>
<group name="On Mail Client" version="7.0" position="after">
<separator string="Sales Teams Configuration"/>
<group>
<label for="id" string="On Mail Server"/>
<label for="id" string="Use Sales Teams"/>
<div>
<div name="fetchmail_lead">
<field name="fetchmail_lead" class="oe_inline"/>
<label for="fetchmail_lead"/>
<button name="configure_fetchmail_lead" type="object" string="Configure" icon="gtk-go-forward"
attrs="{'invisible': [('fetchmail_lead','=',False)]}" class="oe_link"/>
</div>
<field name="group_multi_salesteams" class="oe_inline"/>
<label for="group_multi_salesteams"/>
</div>
</group>
</group>
</div>
</field>
</record>
+6 -3
View File
@@ -10,7 +10,7 @@
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="section_id" completion="1"/>
<field name="section_id" completion="1" groups="base.group_multi_salesteams"/>
</field>
</field>
</record>
@@ -30,8 +30,11 @@
<field name="res_model">crm.lead</field>
<field name="view_mode">kanban,tree,form,graph,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_partner_id': active_id,
'stage_type': 'opportunity', 'default_type': 'opportunity'}</field>
<field name="context">{
'search_default_partner_id': active_id,
'stage_type': 'opportunity',
'default_type': 'opportunity'
}</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help" type="html">
+13
View File
@@ -22,6 +22,19 @@
<field name="implied_ids" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="base.group_mono_salesteams" model="res.groups">
<field name="name">Do Not Use Sales Teams</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record id="base.group_user" model="res.groups">
<field name="implied_ids" eval="[(4, ref('base.group_mono_salesteams'))]"/>
</record>
<record id="base.group_multi_salesteams" model="res.groups">
<field name="name">Manage Sales Teams</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record id="group_fund_raising" model="res.groups">
<field name="name">Manage Fund Raising</field>
+42
View File
@@ -0,0 +1,42 @@
.openerp .oe_kanban_view .oe_kanban_crm_salesteams {
width: 345px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_avatars {
text-align: right;
margin: -5px 0 -10px 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_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);
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list {
margin: 10px 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a {
width: 110px;
display: inline-block;
}
.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;
}
+11
View File
@@ -0,0 +1,11 @@
openerp.crm = function(openerp) {
openerp.web_kanban.KanbanRecord.include({
on_card_clicked: function() {
if (this.view.dataset.model === 'crm.case.section') {
this.$('.oe_kanban_crm_salesteams_list a').first().click();
} else {
this._super.apply(this, arguments);
}
},
});
};
@@ -22,7 +22,7 @@
<field name="phone"/>
<field name="stage_id"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</group>
@@ -68,13 +68,13 @@
<field name="phone"/>
<field name="stage_id"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</group>
<group string="Assign opportunities to" attrs="{'invisible': [('name', '=', '')]}">
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="user_ids" widget="many2many_tags"/>
</group>
@@ -19,7 +19,7 @@
<field name="phone"/>
<field name="stage_id"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
<footer>
@@ -23,7 +23,7 @@
<field name="partner_id" readonly="True"/>
<field name="phone"/>
<field name="user_id" attrs="{'invisible': [('action','=','log')]}"/>
<field name="section_id" widget="selection" attrs="{'invisible': [('action','=','log')]}"/>
<field name="section_id" widget="selection" attrs="{'invisible': [('action','=','log')]}" groups="base.group_multi_salesteams"/>
</group>
</group>
<field name="note" placeholder="Call Description" />
@@ -15,7 +15,7 @@
<field name="date" string="Planned Date" attrs="{'invisible': [('action','=','log')]}"/>
<field name="partner_id" readonly="True"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</group>
<footer>
<button name="action_schedule" type="object" string="Log Call" attrs="{'invisible' : [('action', '!=', 'log')]}" class="oe_highlight"/>
-1
View File
@@ -21,7 +21,6 @@
import crm_claim
import report
import res_config
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-1
View File
@@ -41,7 +41,6 @@ automatically new claims based on incoming emails.
'crm_claim_menu.xml',
'security/ir.model.access.csv',
'report/crm_claim_report_view.xml',
'res_config_view.xml',
'crm_claim_data.xml',
],
'demo': ['crm_claim_demo.xml'],
+1 -1
View File
@@ -116,7 +116,7 @@
<group colspan="4" col="4" groups="base.group_user">
<field name="user_id"/>
<field name="priority"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="date_deadline"/>
<field name="state" groups="base.group_no_one"/>
</group>
@@ -11,7 +11,8 @@
<tree string="Claims" create="false">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1"
groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
@@ -61,7 +62,8 @@
<filter icon="terp-personal" string="My Case(s)" help="My Case(s)" domain="[('user_id','=',uid)]" />
<field name="company_id" groups="base.group_multi_company"/>
<field name="user_id" string="Salesperson"/>
<field name="section_id" string="Sales Team" context="{'invisible_section': False}"/>
<field name="section_id" string="Sales Team" context="{'invisible_section': False}"
groups="base.group_multi_salesteams"/>
<group expand="0" string="Extended Filters...">
<field name="partner_id"/>
<field name="stage_id" domain="[('section_ids', '=', 'section_id')]"/>
-32
View File
@@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
class crm_claim_settings(osv.osv_memory):
_name = 'sale.config.settings'
_inherit = ['sale.config.settings', 'fetchmail.config.settings']
_columns = {
'fetchmail_claim': fields.boolean("Create claims from incoming mails",
fetchmail_model='crm.claim', fetchmail_name='Incoming Claims',
help="""Allows you to configure your incoming mail server, and create claims from incoming emails."""),
}
-23
View File
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_project_config_claim" model="ir.ui.view">
<field name="name">crm_claim settings</field>
<field name="model">sale.config.settings</field>
<field name="inherit_id" ref="base_setup.view_sale_config_settings"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<div name="fetchmail_lead" position="after">
<div>
<field name="fetchmail_claim" class="oe_inline"/>
<label for="fetchmail_claim"/>
<button type="object" name="configure_fetchmail_claim" string="Configure" icon="gtk-go-forward"
attrs="{'invisible': [('fetchmail_claim','=',False)]}" class="oe_link"/>
</div>
</div>
</field>
</record>
</data>
</openerp>
+3 -3
View File
@@ -48,7 +48,7 @@
<sheet string="Helpdesk Support">
<group col="4" class="oe_header">
<field name="name" string="Query"/>
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="date"/>
<field name="date_deadline"/>
@@ -115,7 +115,7 @@
<field name="date" string="Date"/>
<field name="date_deadline"/>
<field name="user_id"/>
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="priority"/>
<field name="state"/>
</tree>
@@ -154,7 +154,7 @@
help="Helpdesk requests that are assigned to me or to one of the sale teams I manage" />
<field name="partner_id" />
<field name="user_id"/>
<field name="section_id" string="Sales Team"/>
<field name="section_id" string="Sales Team" groups="base.group_multi_salesteams"/>
<group expand="0" string="Group By...">
<filter string="Partner" icon="terp-partner" domain="[]" help="Partner" context="{'group_by':'partner_id'}" />
<filter string="Responsible" icon="terp-personal" domain="[]" help="Responsible User" context="{'group_by':'user_id'}" />
@@ -11,7 +11,7 @@
<tree string="Helpdesk" create="false">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1" groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
@@ -60,7 +60,7 @@
<separator/>
<filter string="My Company" icon="terp-go-home" context="{'invisible_section': False}" domain="[('section_id.user_id.company_id','=',uid)]" help="My company"/>
<field name="user_id" string="Salesperson"/>
<field name="section_id" string="Sales Team" context="{'invisible_section': False}"/>
<field name="section_id" string="Sales Team" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="company_id" groups="base.group_multi_company"/>
<group expand="0" string="Extended Filters..." groups="base.group_no_one">
<field name="priority" string="Priority"/>
@@ -10,7 +10,7 @@
<search string="Leads Analysis">
<filter icon="terp-check" string="Current" domain="[('state','in',('draft','open'))]"/>
<filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]"/>
<field name="section_id" context="{'invisible_section': False}"/>
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="grade_id"/>
<field name="user_id"/>
<field name="partner_assigned_id"/>
@@ -69,7 +69,7 @@
<field name="year" invisible="1"/>
<field name="month" invisible="1"/>
<field name="date_assign" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1" groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="grade_id" invisible="1" widget="selection"/>
<field name="partner_assigned_id" invisible="1"/>
@@ -8,7 +8,7 @@
<field name="model">crm.partner.report.assign</field>
<field name="arch" type="xml">
<search string="Partner assigned Analysis">
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="grade_id"/>
<field name="activation"/>
@@ -49,7 +49,7 @@
<field name="date_review" invisible="1"/>
<field name="date_partnership" invisible="1"/>
<field name="period_id" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1" groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="opp"/>
<field name="turnover"/>
+16 -15
View File
@@ -140,30 +140,31 @@
<field name="type"/>
<field name="stage_id"/>
<button name="stage_previous" string="Previous"
states="open,pending" type="object" icon="gtk-go-back" />
states="open,pending" type="object" icon="gtk-go-back" />
<button name="stage_next" string="Next"
states="open,pending" type="object"
icon="gtk-go-forward" />
states="open,pending" type="object"
icon="gtk-go-forward" />
<field name="section_id"
invisible="context.get('invisible_section', True)" />
invisible="context.get('invisible_section', True)"
groups="base.group_multi_salesteams"/>
<field name="user_id" />
<field name="state" />
<button name="case_cancel" string="Cancel"
states="draft,open,pending" type="object"
icon="gtk-cancel" />
states="draft,open,pending" type="object"
icon="gtk-cancel" />
<button name="case_open" string="Open"
states="draft,pending" type="object"
icon="gtk-go-forward" />
states="draft,pending" type="object"
icon="gtk-go-forward" />
<button name="case_close" string="Close"
states="open,draft,pending" type="object"
icon="gtk-close" />
states="open,draft,pending" type="object"
icon="gtk-close" />
<button string="Convert to Opportunity"
name="convert_opportunity"
states="draft,open,pending" icon="gtk-index"
type="object" attrs="{'invisible':[('type','=','opportunity')]}" />
name="convert_opportunity"
states="draft,open,pending" icon="gtk-index"
type="object" attrs="{'invisible':[('type','=','opportunity')]}" />
<button name="case_escalate" string="Escalate"
states="open,draft,pending" type="object"
icon="gtk-go-up" />
states="open,draft,pending" type="object"
icon="gtk-go-up" />
</tree>
</field>
</page>
@@ -86,7 +86,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
if context is None:
context = {}
if model and model == 'crm.lead' and res_id:
lead = self.pool.get(model).browse(cr, uid, res_id, context=context)
lead = self.pool[model].browse(cr, uid, res_id, context=context)
context['history_mode'] = history_mode
body = self.get_record_data(cr, uid, 'crm.lead', res_id, context=context)['body']
return {'value': {'body': body}}
@@ -110,7 +110,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
if wizard.model not in ('crm.lead'):
return res
lead = self.pool.get(wizard.model)
lead = self.pool[wizard.model]
lead_ids = wizard.res_id and [wizard.res_id] or []
if wizard.composition_mode == 'mass_mail':
@@ -61,7 +61,7 @@ class open_questionnaire(osv.osv_memory):
for d in data.question_ans_ids:
if d.answer_id:
answers.append(d.answer_id.id)
self.pool.get(model)._questionnaire_compute(cr, uid, answers, context=context)
self.pool[model]._questionnaire_compute(cr, uid, answers, context=context)
return {'type': 'ir.actions.act_window_close'}
+4 -5
View File
@@ -52,11 +52,10 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,gantt,graph,kanban</field>
</record>
<menuitem
id="menu_crm_todo"
parent="base.menu_sales"
action="crm_todo_action"
sequence="6"/>
<menuitem id="menu_crm_todo"
parent="base.menu_sales"
action="crm_todo_action"
sequence="7"/>
</data>
+6 -7
View File
@@ -137,7 +137,7 @@ class document_file(osv.osv):
It is a hack that will try to discover if the mentioned record is
clearly associated with a partner record.
"""
obj_model = self.pool.get(res_model)
obj_model = self.pool[res_model]
if obj_model._name == 'res.partner':
return res_id
elif 'partner_id' in obj_model._columns and obj_model._columns['partner_id']._obj == 'res.partner':
@@ -422,7 +422,6 @@ class document_directory_content(osv.osv):
tname = ''
if content.include_name:
record_name = node.displayname or ''
# obj = node.context._dirobj.pool.get(model)
if record_name:
tname = (content.prefix or '') + record_name + (content.suffix or '') + (content.extension or '')
else:
@@ -1296,9 +1295,9 @@ class node_res_dir(node_class):
Note that many objects use NULL for a name, so we should
better call the name_search(),name_get() set of methods
"""
obj = self.context._dirobj.pool.get(self.res_model)
if not obj:
if self.res_model not in self.context._dirobj.pool:
return []
obj = self.context._dirobj.pool[self.res_model]
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
@@ -1333,7 +1332,7 @@ class node_res_dir(node_class):
if self.ressource_tree:
object2 = False
if self.resm_id:
object2 = dirobj.pool.get(self.res_model).browse(cr, uid, self.resm_id) or False
object2 = dirobj.pool[self.res_model].browse(cr, uid, self.resm_id) or False
if obj._parent_name in obj.fields_get(cr, uid):
where.append((obj._parent_name,'=',object2 and object2.id or False))
@@ -1504,7 +1503,7 @@ class node_res_obj(node_class):
ctx = self.context.context.copy()
ctx.update(self.dctx)
directory = dirobj.browse(cr, uid, self.dir_id)
obj = dirobj.pool.get(self.res_model)
obj = dirobj.pool[self.res_model]
where = []
res = []
if name:
@@ -1590,7 +1589,7 @@ class node_res_obj(node_class):
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
res_obj = dirobj.pool.get(self.res_model)
res_obj = dirobj.pool[self.res_model]
object2 = res_obj.browse(cr, uid, self.res_id) or False
+3 -3
View File
@@ -67,7 +67,7 @@ class node_acl_mixin(object):
"""
ret = par_class.get_dav_props(self, cr)
if prop_model:
propobj = self.context._dirobj.pool.get(prop_model)
propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
@@ -105,7 +105,7 @@ class node_acl_mixin(object):
if ret is not None:
return ret
if prop_model:
propobj = self.context._dirobj.pool.get(prop_model)
propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
@@ -151,7 +151,7 @@ class node_acl_mixin(object):
assert prop_model
assert res_id
assert isinstance(lock_data, dict), '%r' % lock_data
propobj = self.context._dirobj.pool.get(prop_model)
propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
+8 -8
View File
@@ -106,8 +106,8 @@ class edi(osv.AbstractModel):
"""
edi_list = []
for record in records:
record_model_obj = self.pool.get(record._name)
edi_list += record_model_obj.edi_export(cr, uid, [record], context=context)
record_model = record._model
edi_list += record_model.edi_export(cr, uid, [record], context=context)
return self.serialize(edi_list)
def load_edi(self, cr, uid, edi_documents, context=None):
@@ -131,9 +131,9 @@ class edi(osv.AbstractModel):
"You can install it by connecting as the administrator and opening the configuration assistant.")%(module,))
model = edi_document.get('__import_model') or edi_document.get('__model')
assert model, 'a `__model` or `__import_model` attribute is required in each EDI document.'
model_obj = self.pool.get(model)
assert model_obj, 'model `%s` cannot be found, despite module `%s` being available - '\
assert model in self.pool, 'model `%s` cannot be found, despite module `%s` being available - '\
'this EDI document seems invalid or unsupported.' % (model,module)
model_obj = self.pool[model]
record_id = model_obj.edi_import(cr, uid, edi_document, context=context)
record_action = model_obj._edi_record_display_action(cr, uid, record_id, context=context)
res.append((model, record_id, record_action))
@@ -400,7 +400,7 @@ class EDIMixin(object):
return results
def _edi_get_object_by_name(self, cr, uid, name, model_name, context=None):
model = self.pool.get(model_name)
model = self.pool[model_name]
search_results = model.name_search(cr, uid, name, operator='=', context=context)
if len(search_results) == 1:
return model.browse(cr, uid, search_results[0][0], context=context)
@@ -483,7 +483,7 @@ class EDIMixin(object):
('name','=',ext_id),
('module','in',modules)])
if data_ids:
model = self.pool.get(model)
model = self.pool[model]
data = ir_model_data.browse(cr, uid, data_ids[0], context=context)
if model.exists(cr, uid, [data.res_id]):
return model.browse(cr, uid, data.res_id, context=context)
@@ -519,7 +519,7 @@ class EDIMixin(object):
_logger.debug("%s: Importing EDI relationship [%r,%r] - name not found, creating it.",
self._name, external_id, value)
# also need_new_ext_id here, but already been set above
model = self.pool.get(model)
model = self.pool[model]
res_id, _ = model.name_create(cr, uid, value, context=context)
target = model.browse(cr, uid, res_id, context=context)
else:
@@ -592,7 +592,7 @@ class EDIMixin(object):
# process o2m values, connecting them to their parent on-the-fly
for o2m_field, o2m_value in o2m_todo.iteritems():
field = self._all_columns[o2m_field].column
dest_model = self.pool.get(field._obj)
dest_model = self.pool[field._obj]
for o2m_line in o2m_value:
# link to parent record: expects an (ext_id, name) pair
o2m_line[field._fields_id] = (ext_id_members['full'], record_display[1])
+1 -1
View File
@@ -89,7 +89,7 @@ class email_template(osv.osv):
template = tools.ustr(template)
record = None
if res_id:
record = self.pool.get(model).browse(cr, uid, res_id, context=context)
record = self.pool[model].browse(cr, uid, res_id, context=context)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
variables = {
'object': record,
@@ -40,7 +40,7 @@ class email_template_preview(osv.osv_memory):
email_template = self.pool.get('email.template')
template = email_template.browse(cr, uid, int(template_id), context=context)
template_object = template.model_id
model = self.pool.get(template_object.model)
model = self.pool[template_object.model]
record_ids = model.search(cr, uid, [], 0, 10, 'id', context=context)
default_id = context.get('default_res_id')
+1 -1
View File
@@ -155,7 +155,7 @@ class google_docs_ir_attachment(osv.osv):
pool_ir_attachment = self.pool.get('ir.attachment')
pool_gdoc_config = self.pool.get('google.docs.config')
name_gdocs = ''
model_fields_dic = self.pool.get(res_model).read(cr, uid, res_id, [], context=context)
model_fields_dic = self.pool[res_model].read(cr, uid, res_id, [], context=context)
# check if a model is configured with a template
google_docs_config = pool_gdoc_config.search(cr, uid, [('model_id', '=', res_model)], context=context)
+2 -1
View File
@@ -341,7 +341,8 @@
</group>
<group>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="department_id"/> </group>
<field name="department_id"/>
</group>
</group>
<div>
<label for="description"/>
+2 -2
View File
@@ -202,8 +202,8 @@ class one2many_mod2(fields.one2many):
res = {}
for id in ids:
res[id] = []
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids), ('appears_on_payslip', '=', True)], limit=self._limit)
for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids), ('appears_on_payslip', '=', True)], limit=self._limit)
for r in obj.pool[self._obj]._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
return res
+6
View File
@@ -487,6 +487,12 @@ class hr_applicant(base_stage, osv.Model):
"""
return self.set_priority(cr, uid, ids, '3')
def get_empty_list_help(self, cr, uid, help, context=None):
context['empty_list_help_model'] = 'hr.job'
context['empty_list_help_id'] = context.get('default_job_id', None)
context['empty_list_help_document_name'] = _("job applicants")
return super(hr_applicant, self).get_empty_list_help(cr, uid, help, context=context)
class hr_job(osv.osv):
_inherit = "hr.job"
@@ -10,17 +10,13 @@
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="view_crm_case_jobs_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a new job applicant.
</p><p>
<p>
OpenERP helps you track applicants in the recruitment
process and follow up all operations: meetings, interviews, etc.
</p><p>
If you setup the email gateway, applicants and their attached
CV are created automatically when an email is sent to
jobs@yourcompany.com. If you install the document management
modules, all resumes are indexed automatically, so that you can
easily search through their content.
Applicants and their attached CV are created automatically when an email is sent.
If you install the document management modules, all resumes are indexed automatically,
so that you can easily search through their content.
</p>
</field>
</record>
+11 -5
View File
@@ -312,11 +312,17 @@
attrs="{'invisible':[('survey_id','=',False)]}"/>
</div>
</field>
<xpath expr="//div[@class='oe_title']" version="7.0" position="after">
<div attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only"/>
<field name="alias_name" nolabel="1" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" nolabel="1" class="oe_inline"/>
<xpath expr="//div[@class='oe_title']//h1" position="after">
<div name="group_alias"
attrs="{'invisible': [('alias_domain', '=', False)]}">
<label for="alias_id" string="Email Alias"/>
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span name="edit_alias" class="oe_edit_only">
<field name="alias_name" class="oe_inline"
attrs="{'required': [('alias_id', '!=', False)]}"/>
@
<field name="alias_domain" class="oe_inline" readonly="1"/>
</span>
</div>
</xpath>
</field>
@@ -389,7 +389,7 @@ class account_coda_import(osv.osv_memory):
if statement['coda_note'] != '':
self.pool.get('account.bank.statement').write(cr, uid, [statement['id']], {'coda_note': statement['coda_note']}, context=context)
model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_bank_statement_tree')
action = self.pool.get(model).browse(cr, uid, action_id, context=context)
action = self.pool[model].browse(cr, uid, action_id, context=context)
return {
'name': action.name,
'view_type': action.view_type,
+1 -1
View File
@@ -78,7 +78,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
else:
#replace the value in the destination object only if it's the user lang
if context.get('lang') == lang:
self.pool.get(out_obj._name).write(cr, uid, out_ids[j], {in_field: value[in_id]})
self.pool[out_obj._name].write(cr, uid, out_ids[j], {in_field: value[in_id]})
else:
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' %(lang, src[in_id]))#out_obj._name))
return True
+8 -3
View File
@@ -117,8 +117,13 @@ class mail_alias(osv.Model):
mail catchall domain from config.
e.g. `jobs@openerp.my.openerp.com` or `sales@openerp.my.openerp.com`
"""
return [(record['id'], "%s@%s" % (record['alias_name'], record['alias_domain']))
for record in self.read(cr, uid, ids, ['alias_name', 'alias_domain'], context=context)]
res = []
for record in self.browse(cr, uid, ids, context=context):
if record.alias_name and record.alias_domain:
res.append((record['id'], "%s@%s" % (record.alias_name, record.alias_domain)))
else:
res.append((record['id'], False))
return res
def _find_unique(self, cr, uid, name, context=None):
"""Find a unique alias name similar to ``name``. If ``name`` is
@@ -159,7 +164,7 @@ class mail_alias(osv.Model):
registry = RegistryManager.get(cr.dbname)
mail_alias = registry.get('mail.alias')
child_class_model = registry.get(child_model_name)
child_class_model = registry[child_model_name]
no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test':False})
# Use read() not browse(), to avoid prefetching uninitialized inherited fields
for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]):
+33 -25
View File
@@ -29,6 +29,7 @@
<field name="message_is_follower"/>
<field name="message_summary"/>
<field name="description"/>
<field name="alias_id"/>
<templates>
<t t-name="kanban-description">
<div class="oe_group_description" t-if="record.description.raw_value">
@@ -42,6 +43,9 @@
</div>
<div class="oe_group_details">
<h4><a type="open"><field name="name"/></a></h4>
<div class="oe_kanban_alias" t-if="record.alias_id.value">
<span class="oe_e">%%</span><small><field name="alias_id"/></small>
</div>
<div class="oe_grey">
<field name="description"/>
</div>
@@ -68,39 +72,43 @@
<field name="arch" type="xml">
<form string="Group Form" version="7.0">
<sheet class="openerp_mail_group_sheet">
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/>
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_small"}'/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" string="Group Name"/>
</div>
<h1><field name="name" readonly="0"/></h1>
<div name="alias_box" colspan="4" attrs="{'invisible': [('alias_domain', '=', False)]}">
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only"/>
<field name="alias_name" nolabel="1" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" nolabel="1" class="oe_inline"/>
<div name="group_alias"
attrs="{'invisible': [('alias_domain', '=', False)]}">
<label for="alias_id" string="Email Alias"/>
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span name="edit_alias" class="oe_edit_only">
<field name="alias_name" class="oe_inline"
attrs="{'required': [('alias_id', '!=', False)]}"/>
@
<field name="alias_domain" class="oe_inline" readonly="1"/>
</span>
</div>
<field name="description" placeholder="Topics discussed in this group..."/>
</div>
<field name="description" placeholder="Topics discussed in this group..."/>
<div class="oe_clear"/>
<group>
<group class="oe_edit_only">
<field name="public"/>
<field name="group_public_id"
attrs="{'invisible': [('public','&lt;&gt;','groups')], 'required': [('public','=','groups')]}"
/>
<field name="group_ids" widget="many2many_tags"/>
</group>
<group>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','public')]}">
This group is visible by everyone,
including your customers if you installed
the portal module.
</div>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','private')]}">
Only the invited followers can read the
discussions on this group.
</div>
</group>
<group class="oe_edit_only">
<field name="public"/>
<field name="group_public_id"
attrs="{'invisible': [('public','&lt;&gt;','groups')], 'required': [('public','=','groups')]}"
/>
<field name="group_ids" widget="many2many_tags"/>
</group>
<group attrs="{'invisible': [('public', 'not in', ['public', 'private'])]}">
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','public')]}">
This group is visible by everyone,
including your customers if you installed
the portal module.
</div>
<div class="oe_grey" attrs="{'invisible': [('public','&lt;&gt;','private')]}">
Only the invited followers can read the
discussions on this group.
</div>
</group>
</sheet>
<div class="oe_chatter">
+4 -4
View File
@@ -108,8 +108,8 @@ class mail_mail(osv.Model):
res_id = message.res_id
# if model and res_id: try to use ``message_get_reply_to`` that returns the document alias
if model and res_id and hasattr(self.pool.get(model), 'message_get_reply_to'):
email_reply_to = self.pool.get(model).message_get_reply_to(cr, uid, [res_id], context=context)[0]
if model and res_id and hasattr(self.pool[model], 'message_get_reply_to'):
email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0]
# no alias reply_to -> reply_to will be the email_from, only the email part
if not email_reply_to and values.get('email_from'):
emails = tools.email_split(values.get('email_from'))
@@ -118,7 +118,7 @@ class mail_mail(osv.Model):
# format 'Document name <email_address>'
if email_reply_to and model and res_id:
document_name = self.pool.get(model).name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
if document_name:
# sanitize document name
sanitized_doc_name = re.sub(r'[^\w+.]+', '-', document_name[1])
@@ -217,7 +217,7 @@ class mail_mail(osv.Model):
and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False):
related_user = partner.user_ids[0]
try:
self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
self.pool[mail.model].check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
# the parameters to encode for the query and fragment part of url
query = {'db': cr.dbname}
+4 -4
View File
@@ -76,9 +76,9 @@ class mail_message(osv.Model):
# TDE note: regroup by model/ids, to have less queries to perform
result = dict.fromkeys(ids, False)
for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context):
if not message.get('model') or not message.get('res_id') or not self.pool.get(message['model']):
if not message.get('model') or not message.get('res_id') or message['model'] not in self.pool:
continue
result[message['id']] = self.pool.get(message['model']).name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1]
result[message['id']] = self.pool[message['model']].name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1]
return result
def _get_to_read(self, cr, uid, ids, name, arg, context=None):
@@ -569,7 +569,7 @@ class mail_message(osv.Model):
def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None):
doc_ids = doc_dict.keys()
allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context)
allowed_doc_ids = self.pool[doc_model].search(cr, uid, [('id', 'in', doc_ids)], context=context)
return set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]])
def _find_allowed_doc_ids(self, cr, uid, model_ids, context=None):
@@ -717,7 +717,7 @@ class mail_message(osv.Model):
model_record_ids = _generate_model_record_ids(message_values, other_ids)
document_related_ids = []
for model, doc_dict in model_record_ids.items():
model_obj = self.pool.get(model)
model_obj = self.pool[model]
mids = model_obj.exists(cr, uid, doc_dict.keys())
if operation in ['create', 'write', 'unlink']:
model_obj.check_access_rights(cr, uid, 'write')
+50 -10
View File
@@ -89,6 +89,46 @@ class mail_thread(osv.AbstractModel):
# :param function lambda: returns whether the tracking should record using this subtype
_track = {}
def get_empty_list_help(self, cr, uid, help, context=None):
""" Override of BaseModel.get_empty_list_help() to generate an help message
that adds alias information. """
model = context.get('empty_list_help_model')
res_id = context.get('empty_list_help_id')
ir_config_parameter = self.pool.get("ir.config_parameter")
catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context)
document_name = context.get('empty_list_help_document_name', _('document'))
alias = None
if catchall_domain and model and res_id: # specific res_id -> find its alias (i.e. section_id specified)
object_id = self.pool.get(model).browse(cr, uid, res_id, context=context)
alias = object_id.alias_id
elif catchall_domain and model: # no specific res_id given -> generic help message, take an example alias (i.e. alias of some section_id)
model_id = self.pool.get('ir.model').search(cr, uid, [("model", "=", self._name)], context=context)[0]
alias_obj = self.pool.get('mail.alias')
alias_ids = alias_obj.search(cr, uid, [("alias_model_id", "=", model_id)], context=context, limit=1, order='id ASC')
if alias_ids:
alias = alias_obj.browse(cr, uid, alias_ids[0], context=context)
if alias:
alias_email = alias.name_get()[0][1]
return _("""<p class='oe_view_nocontent_create'>
Click here to add a new %(document)s or send an email to: <a href='mailto:%(email)s'>%(email)s</a>
</p>
%(static_help)s"""
) % {
'document': document_name,
'email': alias_email,
'static_help': help or ''
}
if document_name != 'document' and help and help.find("oe_view_nocontent_create") == -1:
return _("<p class='oe_view_nocontent_create'>Click here to add a new %(document)s</p>%(static_help)s") % {
'document': document_name,
'static_help': help or '',
}
return help
def _get_message_data(self, cr, uid, ids, name, args, context=None):
""" Computes:
- message_unread: has uid unread message for the document
@@ -409,7 +449,7 @@ class mail_thread(osv.AbstractModel):
""" Used by the plugin addon, based for plugin_outlook and others. """
ret_dict = {}
for model_name in self.pool.obj_list():
model = self.pool.get(model_name)
model = self.pool[model_name]
if 'mail.thread' in getattr(model, '_inherit', []):
ret_dict[model_name] = model._description
return ret_dict
@@ -480,12 +520,12 @@ class mail_thread(osv.AbstractModel):
if ref_match:
thread_id = int(ref_match.group(1))
model = ref_match.group(2) or model
model_pool = self.pool.get(model)
if thread_id and model and model_pool and model_pool.exists(cr, uid, thread_id) \
and hasattr(model_pool, 'message_update'):
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, model, thread_id, custom_values, uid)
return [(model, thread_id, custom_values, uid)]
if thread_id and model in self.pool:
model_obj = self.pool[model]
if model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, model, thread_id, custom_values, uid)
return [(model, thread_id, custom_values, uid)]
# Verify whether this is a reply to a private message
if in_reply_to:
@@ -626,7 +666,7 @@ class mail_thread(osv.AbstractModel):
if self._name == 'mail.thread':
context.update({'thread_model': model})
if model:
model_pool = self.pool.get(model)
model_pool = self.pool[model]
assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \
"Undeliverable mail with Message-Id %s, model %s does not accept incoming emails" % \
(msg['message_id'], model)
@@ -680,7 +720,7 @@ class mail_thread(osv.AbstractModel):
if isinstance(custom_values, dict):
data = custom_values.copy()
model = context.get('thread_model') or self._name
model_pool = self.pool.get(model)
model_pool = self.pool[model]
fields = model_pool.fields_get(cr, uid, context=context)
if 'name' in fields and not data.get('name'):
data['name'] = msg_dict.get('subject', '')
@@ -957,7 +997,7 @@ class mail_thread(osv.AbstractModel):
model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name
if model != self._name:
del context['thread_model']
return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
return self.pool[model].message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
# 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails
email_from = kwargs.get('email_from')
-1
View File
@@ -568,7 +568,6 @@
text-shadow: none;
width: 100%;
}
.openerp .oe_followers button.oe_invite,
.openerp .oe_followers button.oe_follower.oe_following{
color: white;
background-color: #3465A4;
+5 -1
View File
@@ -14,6 +14,10 @@
padding: 0px 18px;
}
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_avatar {
padding-top: 3px;
}
/* Resize footer width */
.openerp .oe_form div.oe_mail_group_footer {
max-width: 80%;
@@ -21,7 +25,7 @@
/* Resize group description */
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_text > textarea {
height: 40px;
height: 60px;
}
/* ------------------------------ */
+3 -3
View File
@@ -37,10 +37,10 @@ class invite_wizard(osv.osv_memory):
res_id = result.get('res_id')
if 'message' in fields and model and res_id:
ir_model = self.pool.get('ir.model')
model_ids = ir_model.search(cr, uid, [('model', '=', self.pool.get(model)._name)], context=context)
model_ids = ir_model.search(cr, uid, [('model', '=', self.pool[model]._name)], context=context)
model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1]
document_name = self.pool.get(model).name_get(cr, uid, [res_id], context=context)[0][1]
document_name = self.pool[model].name_get(cr, uid, [res_id], context=context)[0][1]
message = _('<div><p>Hello,</p><p>%s invited you to follow %s document: %s.<p></div>') % (user_name, model_name, document_name)
result['message'] = message
elif 'message' in fields:
@@ -63,7 +63,7 @@ class invite_wizard(osv.osv_memory):
def add_followers(self, cr, uid, ids, context=None):
for wizard in self.browse(cr, uid, ids, context=context):
model_obj = self.pool.get(wizard.res_model)
model_obj = self.pool[wizard.res_model]
document = model_obj.browse(cr, uid, wizard.res_id, context=context)
# filter partner_ids to get the new followers, to avoid sending email to already following partners
+3 -3
View File
@@ -174,7 +174,7 @@ class mail_compose_message(osv.TransientModel):
related to.
:param int res_id: id of the document record this mail is related to
"""
doc_name_get = self.pool.get(model).name_get(cr, uid, [res_id], context=context)
doc_name_get = self.pool[model].name_get(cr, uid, [res_id], context=context)
record_name = False
if doc_name_get:
record_name = doc_name_get[0][1]
@@ -237,7 +237,7 @@ class mail_compose_message(osv.TransientModel):
mass_mail_mode = wizard.composition_mode == 'mass_mail'
if mass_mail_mode: # mass mail: avoid any auto subscription because this could lead to people being follower of plenty of documents
context['mail_create_nosubscribe'] = True
active_model_pool = self.pool.get(wizard.model if wizard.model else 'mail.thread')
active_model_pool = self.pool[wizard.model if wizard.model else 'mail.thread']
# wizard works in batch mode: [res_id] or active_ids
res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
@@ -319,7 +319,7 @@ class mail_compose_message(osv.TransientModel):
exp = str(match.group()[2:-1]).strip()
result = eval(exp, {
'user': self.pool.get('res.users').browse(cr, uid, uid, context=context),
'object': self.pool.get(model).browse(cr, uid, res_id, context=context),
'object': self.pool[model].browse(cr, uid, res_id, context=context),
'context': dict(context), # copy context to prevent side-effects of eval
})
return result and tools.ustr(result) or ''
@@ -165,7 +165,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
# dead code
def signal(self, cr, uid, model, res_id, signal, run_existing=True, context=None):
record = self.pool.get(model).browse(cr, uid, res_id, context)
record = self.pool[model].browse(cr, uid, res_id, context)
return self._signal(cr, uid, record, signal, run_existing, context)
#dead code
@@ -228,7 +228,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
if unique_value:
if unique_field.ttype == 'many2one':
unique_value = unique_value.id
similar_res_ids = self.pool.get(campaign_rec.object_id.model).search(cr, uid,
similar_res_ids = self.pool[campaign_rec.object_id.model].search(cr, uid,
[(unique_field.name, '=', unique_value)], context=context)
if similar_res_ids:
duplicate_workitem_domain = [('res_id','in', similar_res_ids),
@@ -349,7 +349,7 @@ class marketing_campaign_segment(osv.osv):
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
uid, [('start', '=', True), ('campaign_id', '=', segment.campaign_id.id)], context=context)
model_obj = self.pool.get(segment.object_id.model)
model_obj = self.pool[segment.object_id.model]
criteria = []
if segment.sync_last_date and segment.sync_mode != 'all':
criteria += [(segment.sync_mode, '>', segment.sync_last_date)]
@@ -594,7 +594,7 @@ class marketing_campaign_workitem(osv.osv):
if not wi.res_id:
continue
proxy = self.pool.get(wi.object_id.model)
proxy = self.pool[wi.object_id.model]
if not proxy.exists(cr, uid, [wi.res_id]):
continue
ng = proxy.name_get(cr, uid, [wi.res_id], context=context)
@@ -628,7 +628,7 @@ class marketing_campaign_workitem(osv.osv):
for id, res_id, model in res:
workitem_map.setdefault(model,{}).setdefault(res_id,set()).add(id)
for model, id_map in workitem_map.iteritems():
model_pool = self.pool.get(model)
model_pool = self.pool[model]
condition_name[0] = model_pool._rec_name
condition = [('id', 'in', id_map.keys()), condition_name]
for res_id in model_pool.search(cr, uid, condition, context=context):
@@ -676,7 +676,7 @@ class marketing_campaign_workitem(osv.osv):
return False
activity = workitem.activity_id
proxy = self.pool.get(workitem.object_id.model)
proxy = self.pool[workitem.object_id.model]
object_id = proxy.browse(cr, uid, workitem.res_id, context=context)
eval_context = {
+1 -1
View File
@@ -42,7 +42,7 @@ class pad_common(osv.osv_memory):
myPad.createPad(path)
#get attr on the field model
model = self.pool.get(context["model"])
model = self.pool[context["model"]]
field = model._all_columns[context['field_name']]
real_field = field.column.pad_content_field
+3 -3
View File
@@ -58,7 +58,7 @@ class plugin_handler(osv.osv_memory):
res_id = msg.res_id
model = msg.model
url = self._make_url(cr, uid, res_id, model)
name = self.pool.get(model).name_get(cr, uid, [res_id])[0][1]
name = self.pool[model].name_get(cr, uid, [res_id])[0][1]
return (model, res_id, url, name)
def document_type(self, cr, uid, context=None):
@@ -82,7 +82,7 @@ class plugin_handler(osv.osv_memory):
@return : the result of name_search a list of tuple
[(id, 'name')]
"""
return self.pool.get(model).name_search(cr, uid, name)
return self.pool[model].name_search(cr, uid, name)
def push_message(self, cr, uid, model, email, res_id=0):
"""
@@ -92,7 +92,7 @@ class plugin_handler(osv.osv_memory):
@return Dictionary which contain model , url and resource id.
"""
mail_message = self.pool.get('mail.message')
model_obj = self.pool.get(model)
model_obj = self.pool[model]
msg = self.pool.get('mail.thread').message_parse(cr, uid, email)
message_id = msg.get('message-id')
mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)])
+1 -1
View File
@@ -1279,7 +1279,7 @@ class ean_wizard(osv.osv_memory):
ean13 = openerp.addons.product.product.sanitize_ean13(r.ean13_pattern)
m = context.get('active_model')
m_id = context.get('active_id')
self.pool.get(m).write(cr,uid,[m_id],{'ean13':ean13})
self.pool[m].write(cr,uid,[m_id],{'ean13':ean13})
return { 'type' : 'ir.actions.act_window_close' }
class product_product(osv.osv):
@@ -430,6 +430,7 @@
<field name="available_in_pos">True</field>
<field name="list_price">1.49</field>
<field name="name">Coca-Cola Regular 1L</field>
<field name="ean13">5449000054227</field>
<field name="pos_categ_id" ref="coke"/>
<field name="image">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</field>
</record>
@@ -716,6 +717,7 @@
<record id="chaudfontaine_50cl" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">0.44</field>
<field name="ean13">5449000111715</field>
<field name="name">Chaudfontaine 50cl</field>
<field name="pos_categ_id" ref="plain_water"/>
<field name="image">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</field>
@@ -830,6 +832,7 @@
<record id="jupiler_33cl" model="product.product">
<field name="available_in_pos">True</field>
<field name="list_price">0.77</field>
<field name="ean13">5410228142027</field>
<field name="name">Jupiler 33cl</field>
<field name="pos_categ_id" ref="pils"/>
<field name="image">/9j/4AAQSkZJRgABAAEBLAEsAAD/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9PjsBCwoKDg0OHBYWHCgoKCgoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAGQAPQMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APZqYGdqet2+myJE6tJK4yFXgAepNACJqrPD5reTEvbc+aVwKU2vyR7mDx7FOCxUj+dMC3Z61bzxF5LuFAOu4hcfnQBZmv444fNSSKVc4+Vuv40gH2l7Hdq20FXX7yt1FMCduq/X+hrCs7Tp6/a/9tf9df1TXUWtxHlnjvxjFDrotYbWG6jiUBw5Iyc+oNc1XEckrI9vA5OsRS5pNrsT6ZrM2q2izw6LdqgGP9HuQR+RIq41m1sYYjK1Slb2i+af/BM+58UwaTcukkWqW7scssipyfzxSdeK3TFDJ681eLi/n/wCH/hOLa/22wtbmY9gIkGfxzmhYiL2uOWT14q7cV/XoQax4pvbWJ3fT3O8/wDLWXp+A/xode3QKWVqb1kbPwv8YG/1G6sL3y0lmw0RGecdsk06VXm3IxuCVGKcT05vvJ9f6GprtKdP/F/7bLz/AM/TqvPWzKmsySQ6PdyRNtdYjg1tLYuik6kU+58838N4buSW5Us7sSWHIry5KV9T7yg6fIlE9M8JXsen+H4kKHcFy2EJH5gV2UmlE+fzCnKdZtHCeM9QF/rDPECwAxjpzWNWze56GB56VKzgzM0afyNRjlcbcHpmpgkpbmuIc50n7up0Wul9TtnjghZnK/KAh6/lW7SaPLp88HrZfMx9K8O+ILO4g1EW0losci/vJPl6kDp170owknew8RiqDg4tpu3Q+homZoYWJySASfXitat+aFv5v/bX56/j3t1Xz3cr60M6Ld/9cjWstmXQ/iR9TxS6P71vrXDI+upbGTqSkBJF4PQkVnJaHXRe6MwmoNGy3owDa7YqwyDcICD3+YVrRXvo4ce2qEj2Hw8Uj8L6YzFUBtYuTxztFejT+Beh8ljP48/8T/Mi190bTmQMCyzRbh6fOKU/hIpb/I7WH/UQf7o/lWVX46f+L/21+f8An6dVK6kGsDOkXQ/6ZGtpbF0vjXqeXaZ4f1K71CC7TTftNoJfnDFQrKDg9T9a5I05N3sfQVcZShTceazsdhqWhaBoqTakdKNwXQQpaxoH3seyqe5/kK6lSgnseJLHYiUbOTOZ8PQ21zo+owaX4PvLO8jjkMU2pxKMyH7qhm5wM+nQeppRpQjsgqY7EVLc02YGl/D3xDY6nZzSwR+XDKjM3nKTgEZNYRoz57nq1cwoPDezTbdkburo1z8MrAQW0106Jb/u4SQxKldwyBkdDz2rpirRR4uIkp1pNbNsWHUtW1Pw9LcarZRWZNxH5KRybyU3DknJ759OlKfwip7v0PUIR+4i/wB0fyqZptxt3/R+a/X06qSDVf8AkFXX/XI/yq5bFU/jXqeY6tPdJHYQQ3j2sCWrSyuHKqo8x8scdew9+BXM1JtJHuUp0qcJzmk9f0RVXSfEGsWC3OnWV89rIuY557tAz88OEJ4/M8d619k0tGcX1+M5WcUtdLLb17nHajNr2l3T292buKVeShmYE/nXLKLT1bR7sainDmjTjJeVv1sbPgDWLyfxbaRS3VwyP5iPHJITg7CeQT64rSkpRqJNnBjJUK+EnKEbNNdLNanRatb3E3w/ms4LaW4KX8kbwxEgui3DZGe3A611vY+e6lLw1Hcx+D5Eu3jEsd1FGIo5Ffy1XbgEgnBPJx71MvhNIbv0PYoT+4i91H8qUpNOPm/0ZJDqn/ILuf8Ark38qp7Dh8SPJ/EsTXel2VvE+17tUtwScLxLITk+nCn8Kzprr5HbjJWjy/3r/gjF/wCElN5pVroOq2Yc2JKQXK3PkFAOMHPB6Y5x0FanCVNZ8aXceiadp+o6ba3v+jbkmuA/nINzAHII4KhSCRzU1KfMjpweKeHldX+T/wCAxvw/lF740tLhE27mAK5zjbERn8cGs7WlFHWqiqUa89rtafM3NY0qLUXurlrPUrsxySukMEmyJs3Eg5O089z7YrZnlFvQ7c23hSbdY21mjXiYjgm80nkZ3NuPze3H0qJfCaQ+J+h69EMwxc9FB/SpnTcpRd9nf8GvluRfcS72/ZJdy7l2HK+taivY8f8AEjJNbQadE2xlvrhY+efu/uxn/eJH41nT6rzO3Gp+4+8UcncPZalCj30/2K8OS8phJSYdmOOQ3XoMHj3NaI4zIuYF1rWb+5UMIHaTyAeMsQxjTH0XAHtincVjp/hParFqF5qk3ENjAzsfQ4I/kT+VRb3jojLloyXdr/M63V4vtPw8s4xazXLS+TI0UOdzksGb6ZyeardGEo8smjI0611Kz0+7VtOj0/TmuIylv5xkkWT5Ov1HPOOtRPYunu/Q9oh/1Ef+6P5VZmNu/wDj0lz/AHDQB5JNHZ3Pis219lYnaZRMT/qpXOFb8MD8zWF46q+7PWUKzcJqN1GK+fcxNa0ud/EHkajClvDZKwIUZLrlm4Hc/Mfr+NNztp1M44duXtOW8fLr8vzMfyZ7283xwt9onYBIkB+QfwoBWdWbbsj08twsKdN1Zqzf4I7O/wDJ8MaTa6CRG2papKkt+V7LkcH3OMe/zHvW6fKknueNVjGtVnOCtFFzUvL/AOEBsvOe8SPyoQfsY/eNwOBVR+FHPW/iS9WZ+nW32XwpdqlhcWSNfRskdy2ZCMKMngdSD2qanwhT3foewwf6iP8A3R/KrM2Nuji0lPohoA8W17jVrv8A67P/AOhGuGp8TPrcD/Bj6I1LTV9L1uyjsPEJaOWJdsN8n3gPRvX/AD9auMozVpfec1bD1cPJzo6p7x/yIZfEPh7w0jjw7aSXt8wx9ruV+VPp0P5AfWrUqdPY55Ucbi/j91djlbFp9R8R29xeytLLNcKXYnk81EZ80zorYRUsO0tEdwNF1XVf7Nt4dWudP08aZE2Lfgu/RhnIxwR611Q+Feh4GI0qy9WR3nhyPw/bTrbSTSQTmAs0r7maQO2SfwIqanwipbv0PUrf/j2i/wBwfyqzNjpE3xsp/iGKAPHfEqyWus3aXNu2Gkcpu9CSQQT1riqpqTPp8DaVGPK+xjEQvKRuKR46kZNZna3NR7spSQQszE3IHJH3fyoKdSaXwk2kRxrq1kwlDN56ZXB45q6fxI5cbKToyTX9XPXNGH/Eh0//AK9Y/wD0EV2w+FHzGJ/jT/xP8yvr1jcajZx2tsm+Rpk/AZ5NE1dEUmk36HXRp5capnO0AZpkjqAKt/p1tqEJjuIY5R6SKGFJpMuFSUHeLaOUvvAmkuWJtJ4Ae9vJkfrmsnRh2O2nmuIj1T9TDn+H+kBj/p92nsyg/wBKn2MfM6Fndb+VDLXwZpFldxXC3t5K8ThgoQDJH4U404p31M6+bVasHFxSudbYwXn2WG1tLORYoY1jWS5O3gDAPv8AhWqemh5s5OcnJ9Wb9naC1j+Zt8h+82MfkPSqJLFABQAUAFAAQD1GaACgAoAKACgA/9k=</field>
+3 -3
View File
@@ -16,7 +16,7 @@ class PosBox(CashBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
records = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)
records = self.pool[active_model].browse(cr, uid, active_ids, context=context)
bank_statements = [record.cash_register_id for record in records if record.cash_register_id]
if not bank_statements:
@@ -41,7 +41,7 @@ class PosBoxIn(PosBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0]
session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0]
values['ref'] = session.name
return values
@@ -57,7 +57,7 @@ class PosBoxOut(PosBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0]
session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0]
values['ref'] = session.name
return values
+1 -1
View File
@@ -45,7 +45,7 @@ class mail_mail(osv.Model):
and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False):
related_user = partner.user_ids[0]
try:
self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
self.pool[mail.model].check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
url = partner_obj._get_signup_url_for_action(cr, related_user.id, [partner.id], action='', res_id=mail.res_id, model=mail.model, context=context)[partner.id]
text = _("""<small>Access this document <a style='color:inherit' href="%s">directly in OpenERP</a></small>""") % url
except except_orm, e:
+25
View File
@@ -0,0 +1,25 @@
# Russian translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
"PO-Revision-Date: 2013-04-09 13:04+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-04-10 05:21+0000\n"
"X-Generator: Launchpad (build 16550)\n"
#. module: portal_anonymous
#. openerp-web
#: code:addons/portal_anonymous/static/src/xml/portal_anonymous.xml:8
#, python-format
msgid "Login"
msgstr "Вход"
+9 -5
View File
@@ -286,7 +286,6 @@ class project(osv.osv):
'type_ids': _get_type_common,
'alias_model': 'project.task',
'privacy_visibility': 'public',
'alias_domain': False, # always hide alias during creation
}
# TODO: Why not using a SQL contraints ?
@@ -531,11 +530,11 @@ def Project():
context = dict(context, project_creation_in_progress=True)
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id') and vals.get('name', False):
vals.pop('alias_name', None) # prevent errors during copy()
alias_name = vals.pop('alias_name', None) # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
{'alias_name': "project+"+short_name(vals['name'])},
{'alias_name': alias_name or "project+"+short_name(vals['name'])},
model_name=vals.get('alias_model', 'project.task'),
context=context)
vals['alias_id'] = alias_id
@@ -605,8 +604,7 @@ class task(base_stage, osv.osv):
search_domain = []
project_id = self._resolve_project_id_from_context(cr, uid, context=context)
if project_id:
search_domain += ['|', ('project_ids', '=', project_id)]
search_domain += [('id', 'in', ids)]
search_domain += [('project_ids', '=', project_id)]
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search
@@ -889,6 +887,12 @@ class task(base_stage, osv.osv):
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
return res
def get_empty_list_help(self, cr, uid, help, context=None):
context['empty_list_help_id'] = context.get('default_project_id')
context['empty_list_help_model'] = 'project.project'
context['empty_list_help_document_name'] = _("tasks")
return super(task, self).get_empty_list_help(cr, uid, help, context=context)
# ----------------------------------------
# Case management
# ----------------------------------------
+28 -24
View File
@@ -50,16 +50,17 @@
<field name="name">Tasks</field>
<field name="res_model">project.task</field>
<field name="view_mode">kanban,tree,form,calendar,gantt,graph</field>
<field name="context">{'search_default_project_id': [active_id], 'default_project_id': active_id}</field>
<field name="context">{
'search_default_project_id': [active_id],
'default_project_id': active_id,
}</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new task.
</p><p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.
</p>
<p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.
</p>
</field>
</record>
@@ -87,6 +88,17 @@
<h1>
<field name="name" string="Project Name"/>
</h1>
<div name="group_alias"
attrs="{'invisible': [('alias_domain', '=', False)]}">
<label for="alias_id" string="Email Alias"/>
<field name="alias_id" class="oe_inline oe_read_only" required="0" nolabel="1"/>
<span name="edit_alias" class="oe_edit_only">
<field name="alias_name" class="oe_inline"
attrs="{'required': [('alias_id', '!=', False)]}"/>
@
<field name="alias_domain" class="oe_inline" readonly="1"/>
</span>
</div>
<div name="options_active">
<field name="use_tasks" class="oe_inline"/>
<label for="use_tasks"/>
@@ -133,13 +145,6 @@
</page>
<page string="Other Info">
<group>
<group string="Email Interface" attrs="{'invisible': [('alias_domain', '=', False)]}">
<div>
<field name="alias_id" invisible="1" required="0"/>
<label for="alias_name" class="oe_edit_only "/>
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>@<field name="alias_domain" class="oe_inline"/>
</div>
</group>
<group string="Administration" groups="project.group_time_work_estimation_tasks">
<field name="planned_hours" widget="float_time"/>
<field name="effective_hours" widget="float_time"/>
@@ -231,7 +236,6 @@
<field name="color"/>
<field name="task_count"/>
<field name="alias_id"/>
<field name="alias_domain"/>
<field name="doc_count"/>
<templates>
<t t-name="kanban-box">
@@ -245,8 +249,10 @@
</ul>
</div>
<div class="oe_kanban_content">
<h4><field name="name"/></h4>
<div class="oe_kanban_alias" t-if="record.alias_id.value">
<span class="oe_e">%%</span><small><field name="alias_id"/></small>
</div>
<div class="oe_kanban_project_list">
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px">
<span t-if="record.task_count.raw_value gt 1"><field name="task_count"/> Tasks</span>
@@ -622,13 +628,11 @@
<field name="view_mode">kanban,tree,form,calendar,gantt,graph</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new task.
</p><p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.
</p>
<p>
OpenERP's project management allows you to manage the pipeline
of tasks in order to get things done efficiently. You can
track progress, discuss on tasks, attach documents, etc.
</p>
</field>
</record>
<record id="open_view_task_list_kanban" model="ir.actions.act_window.view">
@@ -125,7 +125,7 @@ class project_task_delegate(osv.osv_memory):
action_model, action_id = models_data.get_object_reference(cr, uid, 'project', 'action_view_task')
view_model, task_view_form_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_form2')
view_model, task_view_tree_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_tree2')
action = self.pool.get(action_model).read(cr, uid, action_id, context=context)
action = self.pool[action_model].read(cr, uid, action_id, context=context)
action['res_id'] = delegated_tasks[task_id]
action['view_id'] = False
action['views'] = [(task_view_form_id, 'form'), (task_view_tree_id, 'tree')]
+34 -8
View File
@@ -416,6 +416,12 @@ class project_issue(base_stage, osv.osv):
self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
return res
def get_empty_list_help(self, cr, uid, help, context=None):
context['empty_list_help_model'] = 'project.project'
context['empty_list_help_id'] = context.get('default_project_id')
context['empty_list_help_document_name'] = _("issues")
return super(project_issue, self).get_empty_list_help(cr, uid, help, context=context)
# -------------------------------------------------------
# Stage management
# -------------------------------------------------------
@@ -563,7 +569,8 @@ class project_issue(base_stage, osv.osv):
return res
class project(osv.osv):
class project(osv.Model):
_inherit = "project.project"
def _get_alias_models(self, cr, uid, context=None):
@@ -578,7 +585,9 @@ class project(osv.osv):
return res
_columns = {
'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'project_escalation_id': fields.many2one('project.project', 'Project Escalation',
help='If any issue is escalated from the current Project, it will be listed under the project selected here.',
states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}),
'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues"),
}
@@ -593,14 +602,13 @@ class project(osv.osv):
(_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
]
project()
class account_analytic_account(osv.osv):
class account_analytic_account(osv.Model):
_inherit = 'account.analytic.account'
_description = 'Analytic Account'
_columns = {
'use_issues' : fields.boolean('Issues', help="Check this field if this project manages issues"),
'use_issues': fields.boolean('Issues', help="Check this field if this project manages issues"),
}
def on_change_template(self, cr, uid, ids, template_id, context=None):
@@ -611,16 +619,34 @@ class account_analytic_account(osv.osv):
return res
def _trigger_project_creation(self, cr, uid, vals, context=None):
if context is None: context = {}
if context is None:
context = {}
res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
return res or (vals.get('use_issues') and not 'project_creation_in_progress' in context)
account_analytic_account()
class project_project(osv.osv):
class project_project(osv.Model):
_inherit = 'project.project'
_defaults = {
'use_issues': True
}
def _check_create_write_values(self, cr, uid, vals, context=None):
""" Perform some check on values given to create or write. """
# Handle use_tasks / use_issues: if only one is checked, alias should take the same model
if vals.get('use_tasks') and not vals.get('use_issues'):
vals['alias_model'] = 'project.task'
elif vals.get('use_issues') and not vals.get('use_tasks'):
vals['alias_model'] = 'project.issue'
def create(self, cr, uid, vals, context=None):
self._check_create_write_values(cr, uid, vals, context=context)
return super(project_project, self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
self._check_create_write_values(cr, uid, vals, context=context)
return super(project_project, self).write(cr, uid, ids, vals, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+5 -7
View File
@@ -14,13 +14,11 @@
<field name="domain" eval=""/>
<field name="search_view_id" ref="view_project_issue_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to report a new issue.
</p><p>
The OpenERP issues tacker allows you to efficiantly manage things
like internal requests, software development bugs, customer
complaints, project troubles, material breakdowns, etc.
</p>
<p>
The OpenERP issues tacker allows you to efficiantly manage things
like internal requests, software development bugs, customer
complaints, project troubles, material breakdowns, etc.
</p>
</field>
</record>
+24 -4
View File
@@ -302,7 +302,18 @@
<field name="view_type">form</field>
<field name="name">Issues</field>
<field name="view_mode">kanban,tree,form,calendar,graph</field>
<field name="context">{'search_default_project_id': [active_id], 'default_project_id': active_id}</field>
<field name="context">{
'search_default_project_id': [active_id],
'default_project_id': active_id,
}
</field>
<field name="help" type="html">
<p>
The OpenERP issues tacker allows you to efficiantly manage things
like internal requests, software development bugs, customer
complaints, project troubles, material breakdowns, etc.
</p>
</field>
</record>
<!-- Project -->
@@ -324,9 +335,18 @@
<field name="priority" position="before">
<field name="project_escalation_id"/>
</field>
<field name="alias_domain" position="after">
<label for="alias_model" class="oe_edit_only" string="creates"/><field name="alias_model" class="oe_edit_only oe_inline"/>
</field>
<xpath expr='//span[@name="edit_alias"]' position='replace'>
<span class="oe_edit_only" name="edit_alias">
<field name="alias_name" class="oe_inline" attrs="{'required': [('alias_id', '!=', False)]}"/>
@
<field class="oe_inline" name="alias_domain"/>
<span class="oe_inline"
attrs="{'invisible': ['|', ('use_issues', '!=', True), ('use_tasks', '!=', True)]}">
<label for="alias_model" string="creates"/>
<field name="alias_model" class="oe_inline"/>
</span>
</span>
</xpath>
</field>
</record>
@@ -14,7 +14,7 @@
<field name="version_id" string="Version" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="company_id" invisible="1" groups="base.group_multi_company"/>
<field name="section_id" invisible="1"/>
<field name="section_id" invisible="1" groups="base.group_multi_salesteams"/>
<field name="user_id" invisible="1"/>
<field name="channel_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
+1 -1
View File
@@ -371,7 +371,7 @@ class purchase_order(osv.osv):
pick_ids += [picking.id for picking in po.picking_ids]
action_model, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree4'))
action = self.pool.get(action_model).read(cr, uid, action_id, context=context)
action = self.pool[action_model].read(cr, uid, action_id, context=context)
ctx = eval(action['context'])
ctx.update({
'search_default_purchase_id': ids[0]
+18 -13
View File
@@ -328,19 +328,24 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="search_view_id" ref="view_sales_order_filter"/>
<field name="context">{'show_address': 1}</field>
<field name="domain">[('state','not in',('draft','sent','cancel'))]</field>
<field name="context">{
'show_address': 1,
'search_default_my_sale_orders_filter': 1
}
</field>
<field name="domain">[('state', 'not in', ('draft', 'sent', 'cancel'))]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a quotation that can be converted into a sales
order.
</p><p>
OpenERP will help you efficiently handle the complete sales flow:
quotation, sales order, delivery, invoicing and payment.
</p>
<p class="oe_view_nocontent_create">
Click to create a quotation that can be converted into a sales
order.
</p><p>
OpenERP will help you efficiently handle the complete sales flow:
quotation, sales order, delivery, invoicing and payment.
</p>
</field>
</record>
<menuitem action="action_orders" id="menu_sale_order" parent="base.menu_sales" sequence="5" groups="base.group_sale_salesman,base.group_sale_manager"/>
<menuitem action="action_orders" id="menu_sale_order" parent="base.menu_sales" sequence="6" groups="base.group_sale_salesman,base.group_sale_manager"/>
<record id="action_orders_exception" model="ir.actions.act_window">
<field name="name">Sales in Exception</field>
@@ -371,7 +376,7 @@
<field name="view_type">form</field>
<field name="view_id" ref="view_quotation_tree"/>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="context">{'show_address': 1}</field>
<field name="context">{'show_address': 1, 'search_default_my_sale_orders_filter': 1}</field>
<field name="domain">[('state','in',('draft','sent','cancel'))]</field>
<field name="search_view_id" ref="view_sales_order_filter"/>
<field name="help" type="html">
@@ -390,8 +395,8 @@
</record>
<menuitem id="menu_sale_quotations"
action="action_quotations" parent="base.menu_sales"
sequence="4"/>
action="action_quotations" parent="base.menu_sales"
sequence="5"/>
<record id="action_order_tree" model="ir.actions.act_window">
<field name="name">Old Quotations</field>
@@ -10,7 +10,7 @@
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='date']" position="after">
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</xpath>
</data>
</field>
+33 -1
View File
@@ -19,8 +19,10 @@
#
##############################################################################
from datetime import datetime
from openerp.osv import osv, fields
class sale_order(osv.osv):
_inherit = 'sale.order'
_columns = {
@@ -30,19 +32,49 @@ class sale_order(osv.osv):
}
class crm_case_section(osv.osv):
_inherit = 'crm.case.section'
def _get_sum_month_invoice(self, cr, uid, ids, field_name, arg, context=None):
res = dict.fromkeys(ids, 0)
obj = self.pool.get('account.invoice.report')
when = datetime.today()
for section_id in ids:
invoice_ids = obj.search(cr, uid, [("section_id", "=", section_id), ('state', 'not in', ['draft', 'cancel']), ('year', '=', when.year), ('month', '=', when.month > 9 and when.month or "0%s" % when.month)], context=context)
for invoice in obj.browse(cr, uid, invoice_ids, context=context):
res[section_id] += invoice.price_total
return res
_columns = {
'quotation_ids': fields.one2many('sale.order', 'section_id',
string='Quotations', readonly=True,
domain=[('state', 'in', ['draft', 'sent', 'cancel'])]),
'sale_order_ids': fields.one2many('sale.order', 'section_id',
string='Sale Orders', readonly=True,
domain=[('state', 'not in', ['draft', 'sent', 'cancel'])]),
'invoice_ids': fields.one2many('account.invoice', 'section_id',
string='Invoices', readonly=True,
domain=[('state', 'not in', ['draft', 'cancel'])]),
'sum_month_invoice': fields.function(_get_sum_month_invoice,
string='Total invoiced this month',
type='integer', readonly=True),
}
class res_users(osv.Model):
_inherit = 'res.users'
_columns = {
'default_section_id': fields.many2one('crm.case.section', 'Default Sales Team'),
}
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: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False,
'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:
+136 -5
View File
@@ -22,7 +22,7 @@
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="section_id" widget="selection"/>
<field name="section_id" widget="selection" groups="base.group_multi_salesteams"/>
<field name="categ_ids" widget="many2many_tags"/>
</field>
</field>
@@ -41,7 +41,7 @@
help="My Sales Team(s)"/>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<field name="section_id" string="Sales Team"/>
<field name="section_id" string="Sales Team" groups="base.group_multi_salesteams"/>
</xpath>
</field>
</record>
@@ -53,18 +53,22 @@
<field name="inherit_id" ref="account.invoice_tree"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='date_invoice']" position="after">
<field name="section_id" invisible="1"/>
<xpath expr="//field[@name='user_id']" position="after">
<field name="section_id" string="Sales Team" groups="base.group_multi_salesteams"/>
</xpath>
</data>
</field>
</record>
<!-- Update account invoice search view!-->
<record id="account_invoice_groupby_inherit" model="ir.ui.view">
<field name="name">account.invoice.groupby</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='user_id']" position="after">
<field name="section_id"/>
</xpath>
<xpath expr="//group/filter[@string='Due Date']" position="after">
<filter string="Sales Team" domain="[]" context="{'group_by':'section_id'}"/>
</xpath>
@@ -79,7 +83,7 @@
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='user_id']" position="after">
<field name="section_id"/>
<field name="section_id" groups="base.group_multi_salesteams"/>
</xpath>
</data>
</field>
@@ -113,5 +117,132 @@
</field>
</record>
<!-- search by Salesteams -->
<record id="action_orders_salesteams" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="domain">[('state','not in',('draft','sent','cancel'))]</field>
<field name="context">{
'search_default_section_id': [active_id],
'default_section_id': active_id,
'search_default_my_sale_orders_filter': 1,
}
</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a quotation that can be converted into a sales
order.
</p><p>
OpenERP will help you efficiently handle the complete sales flow:
quotation, sales order, delivery, invoicing and payment.
</p>
</field>
</record>
<record id="action_quotations_salesteams" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="context">{
'search_default_section_id': [active_id],
'default_section_id': active_id, 'show_address': 1,
'search_default_my_sale_orders_filter': 1
}
</field>
<field name="domain">[('state','in',('draft','sent','cancel'))]</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a quotation, the first step of a new sale.
</p><p>
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.
</p><p>
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.
</p>
</field>
</record>
<record id="action_invoice_salesteams" model="ir.actions.act_window">
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="view_id" ref="account.invoice_tree"/>
<field name="domain">[
('state', 'not in', ['draft', 'cancel']),
('type', '=', 'out_invoice')]</field>
<field name="context">{
'search_default_section_id': [active_id],
'default_section_id': active_id},
'default_type':'out_invoice',
'type':'out_invoice',
'journal_type': 'sale',
}
</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
</record>
<record id="action_invoice_salesteams_view_tree" model="ir.actions.act_window.view">
<field name="sequence">1</field>
<field name="view_mode">tree</field>
<field name="act_window_id" ref="sale_crm.action_invoice_salesteams"/>
</record>
<record id="action_invoice_salesteams_view_form" model="ir.actions.act_window.view">
<field name="sequence">2</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account.invoice_form"/>
<field name="act_window_id" ref="sale_crm.action_invoice_salesteams"/>
</record>
<record id="crm_case_section_salesteams_view_kanban" model="ir.ui.view">
<field name="name">crm.case.section.kanban</field>
<field name="model">crm.case.section</field>
<field name="inherit_id" ref="crm.crm_case_section_salesteams_view_kanban"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='open_opportunity_ids']" position="after">
<field name="quotation_ids"/>
<field name="sale_order_ids"/>
<field name="invoice_ids"/>
</xpath>
<xpath expr="//div[@class='oe_items_list']" position="inside">
<a name="%(action_quotations_salesteams)d" type="action">
<t t-raw="record.quotation_ids.raw_value.length"/>
<t t-if="record.quotation_ids.raw_value.length &gt;= 2">Quotations</t>
<t t-if="record.quotation_ids.raw_value.length &lt; 2">Quotation</t>
</a>
<a name="%(action_orders_salesteams)d" type="action">
<t t-raw="record.sale_order_ids.raw_value.length"/>
<t t-if="record.sale_order_ids.raw_value.length &gt;= 2">Sales Orders</t>
<t t-if="record.sale_order_ids.raw_value.length &lt; 2">Sales Order</t>
</a>
<a name="%(action_invoice_salesteams)d" type="action" groups="account.group_account_invoice">
<t t-raw="record.invoice_ids.raw_value.length"/>
<t t-if="record.invoice_ids.raw_value.length &gt;= 2">Invoices</t>
<t t-if="record.invoice_ids.raw_value.length &lt; 2">Invoice</t>
</a>
</xpath>
<xpath expr="//div[@class='oe_items_list']" position="after">
<div class="oe_center">
<div class="oe_sum"><field name="sum_month_invoice"/></div>
<div class="oe_subsum">Invoiced this month</div>
</div>
</xpath>
</data>
</field>
</record>
</data>
</openerp>
+7 -7
View File
@@ -205,7 +205,7 @@ class share_wizard(osv.TransientModel):
raise osv.except_osv(_('No email address configured'),
_('You must configure your email address in the user preferences before using the Share button.'))
model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'action_share_wizard_step1')
action = self.pool.get(model).read(cr, uid, res_id, context=context)
action = self.pool[model].read(cr, uid, res_id, context=context)
action['res_id'] = ids[0]
action.pop('context', '')
return action
@@ -404,7 +404,7 @@ class share_wizard(osv.TransientModel):
local_rel_fields = []
models = [x[1].model for x in relation_fields]
model_obj = self.pool.get('ir.model')
model_osv = self.pool.get(model.model)
model_osv = self.pool[model.model]
for colinfo in model_osv._all_columns.itervalues():
coldef = colinfo.column
coltype = coldef._type
@@ -412,7 +412,7 @@ class share_wizard(osv.TransientModel):
if coltype in ttypes and colinfo.column._obj not in models:
relation_model_id = model_obj.search(cr, UID_ROOT, [('model','=',coldef._obj)])[0]
relation_model_browse = model_obj.browse(cr, UID_ROOT, relation_model_id, context=context)
relation_osv = self.pool.get(coldef._obj)
relation_osv = self.pool[coldef._obj]
if coltype == 'one2many':
# don't record reverse path if it's not a real m2o (that happens, but rarely)
dest_model_ci = relation_osv._all_columns
@@ -422,7 +422,7 @@ class share_wizard(osv.TransientModel):
local_rel_fields.append((relation_field, relation_model_browse))
for parent in relation_osv._inherits:
if parent not in models:
parent_model = self.pool.get(parent)
parent_model = self.pool[parent]
parent_colinfos = parent_model._all_columns
parent_model_browse = model_obj.browse(cr, UID_ROOT,
model_obj.search(cr, UID_ROOT, [('model','=',parent)]))[0]
@@ -458,7 +458,7 @@ class share_wizard(osv.TransientModel):
"""
# obj0 class and its parents
obj0 = [(None, model)]
model_obj = self.pool.get(model.model)
model_obj = self.pool[model.model]
ir_model_obj = self.pool.get('ir.model')
for parent in model_obj._inherits:
parent_model_browse = ir_model_obj.browse(cr, UID_ROOT,
@@ -777,7 +777,7 @@ class share_wizard(osv.TransientModel):
# Record id not found: issue
if res_id <= 0:
raise osv.except_osv(_('Record id not found'), _('The share engine has not been able to fetch a record_id for your invitation.'))
self.pool.get(model.model).message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context)
self.pool[model.model].message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context)
# self.send_invite_email(cr, uid, wizard_data, context=context)
# self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context)
@@ -823,7 +823,7 @@ class share_wizard(osv.TransientModel):
elif tmp_idx == len(wizard_data.result_line_ids)-2:
body += ' and'
body += '.'
return self.pool.get(model_name).message_post(cr, uid, [res_id], body=body, context=context)
return self.pool[model_name].message_post(cr, uid, [res_id], body=body, context=context)
def send_invite_email(self, cr, uid, wizard_data, context=None):
# TDE Note: not updated because will disappear
@@ -39,7 +39,7 @@ class stock_invoice_onshipping(osv.osv_memory):
if not model or 'stock.picking' not in model:
return []
model_pool = self.pool.get(model)
model_pool = self.pool[model]
journal_obj = self.pool.get('account.journal')
res_ids = context and context.get('active_ids', [])
vals = []
@@ -119,7 +119,7 @@ class stock_invoice_onshipping(osv.osv_memory):
elif inv_type == "in_refund":
action_model,action_id = data_pool.get_object_reference(cr, uid, 'account', "action_invoice_tree4")
if action_model:
action_pool = self.pool.get(action_model)
action_pool = self.pool[action_model]
action = action_pool.read(cr, uid, action_id, context=context)
action['domain'] = "[('id','in', ["+','.join(map(str,invoice_ids))+"])]"
return action
+2 -2
View File
@@ -115,7 +115,7 @@ class subscription_subscription(osv.osv):
try:
(model_name, id) = row['doc_source'].split(',')
id = int(id)
model = self.pool.get(model_name)
model = self.pool[model_name]
except:
raise osv.except_osv(_('Wrong Source Document !'), _('Please provide another source document.\nThis one does not exist !'))
@@ -136,7 +136,7 @@ class subscription_subscription(osv.osv):
# the subscription is over and we mark it as being done
if remaining == 1:
state = 'done'
id = self.pool.get(model_name).copy(cr, uid, id, default, context)
id = self.pool[model_name].copy(cr, uid, id, default, context)
self.pool.get('subscription.subscription.history').create(cr, uid, {'subscription_id': row['id'], 'date':time.strftime('%Y-%m-%d %H:%M:%S'), 'document_id': model_name+','+str(id)})
self.write(cr, uid, [row['id']], {'state':state})
return True
+7 -6
View File
@@ -402,9 +402,10 @@ class survey_question_wiz(osv.osv_memory):
sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
# mark the survey request as done; call 'survey_req_done' on its actual model
survey_req_obj = self.pool.get(context.get('active_model'))
if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
if context.get('active_model') in self.pool:
survey_req_obj = self.pool[context.get('active_model')]
if hasattr(survey_req_obj, 'survey_req_done'):
survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
if sur_rec.send_response:
survey_data = survey_obj.browse(cr, uid, survey_id)
@@ -609,10 +610,10 @@ class survey_question_wiz(osv.osv_memory):
survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
if context.has_key('cur_id'):
if context.has_key('request') and context.get('request',False):
self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
self.pool[context.get('object')].survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
else:
self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict:
sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans'])
for key,val in sur_name_read['store_ans'].items():