openerp-community-reviewer team mailing list archive
-
openerp-community-reviewer team
-
Mailing list archive
-
Message #01043
[Merge] lp:~hirt/ocb-addons/6.1_base_contact_finalize into lp:ocb-addons/6.1
Etienne Hirt has proposed merging lp:~hirt/ocb-addons/6.1_base_contact_finalize into lp:ocb-addons/6.1.
Requested reviews:
OpenERP Community Backports Team (ocb)
Related bugs:
Bug #923440 in OpenERP Addons: "Base_contact: Missing Fields in new design [6.1]"
https://bugs.launchpad.net/openobject-addons/+bug/923440
For more details, see:
https://code.launchpad.net/~hirt/ocb-addons/6.1_base_contact_finalize/+merge/193941
Finalising the base contact 6.1 desig by adding the missing fields as described in https://bugs.launchpad.net/openobject-addons/+bug/923440
--
https://code.launchpad.net/~hirt/ocb-addons/6.1_base_contact_finalize/+merge/193941
Your team OpenERP Community Backports Team is requested to review the proposed merge of lp:~hirt/ocb-addons/6.1_base_contact_finalize into lp:ocb-addons/6.1.
=== modified file 'base_contact/__openerp__.py' (properties changed: -x to +x)
--- base_contact/__openerp__.py 2012-01-31 13:36:57 +0000
+++ base_contact/__openerp__.py 2013-11-05 15:41:30 +0000
@@ -21,7 +21,7 @@
{
'name': 'Contacts Management',
- 'version': '1.0',
+ 'version': '1.1',
'category': 'Customer Relationship Management',
'complexity': "expert",
'description': """
@@ -35,12 +35,17 @@
It also adds new menu items located in
Purchases / Address Book / Contacts
- Sales / Address Book / Contacts
-
-Pay attention that this module converts the existing addresses into "addresses + contacts". It means that some fields of the addresses will be missing (like the contact name), since these are supposed to be defined in an other object.
+ Sales / Address Book / Contacts and Locations
+
+Pay attention that this module converts the existing addresses into "addresses + contacts".
+It means that some fields of the addresses will be missing (the contact name is copied into
+addresses to be compatible with other modules contact name). Others are supposed to be defined in an other object.
+
+All UI work with lastname(s) firstname. Firstnames are possible but do not use them together with
+any lastname for search. Also when entering a new contact add the additional firstnames later
""",
- 'author': 'OpenERP SA',
- 'website': 'http://www.openerp.com',
+ 'author': 'OpenERP SA, Art of Technology AG',
+ 'website': 'http://www.openerp.com, http://www.aotag.ch',
'depends': ['base','process'],
'init_xml': [],
'update_xml': [
=== modified file 'base_contact/base_contact.py' (properties changed: -x to +x)
--- base_contact/base_contact.py 2013-10-28 11:57:54 +0000
+++ base_contact/base_contact.py 2013-11-05 15:41:30 +0000
@@ -21,18 +21,65 @@
from osv import fields, osv
import addons
+import pdb
class res_partner_contact(osv.osv):
""" Partner Contact """
_name = "res.partner.contact"
_description = "Contact"
+
+ _rec_name = 'last_name'
+
def _name_get_full(self, cr, uid, ids, prop, unknow_none, context=None):
result = {}
for rec in self.browse(cr, uid, ids, context=context):
- result[rec.id] = rec.last_name+' '+(rec.first_name or '')
+ #use firstname lastname as in the demo data of base/res/res_partner_demo.xml was not a good idea
+ # change back to lastname firstname throughout the UI
+ if(rec.first_name):
+ #last_name is a required field. Therefore always available
+ result[rec.id] = rec.last_name+' '+rec.first_name
+ else:
+ result[rec.id] = rec.last_name
+
return result
+
+ def _main_job(self, cr, uid, ids, fields, arg, context=None):
+ """
+ @summary: Returns partner_id and function of job with the lowest 'sequence_contact'
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of partner contact’s IDs
+ @fields: Get Fields
+ @param context: A standard dictionary for contextual values
+ @param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """
+
+ res = dict.fromkeys(ids, False)
+
+ all_ids = self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)], order='sequence_contact')
+ #pdb.set_trace()
+ addresses = self.pool.get('res.partner.address').browse(cr, uid, all_ids)
+ for addr in addresses:
+ #@todo: How to handle past jobs. Not main job if others are available? Or same as sorting?
+ if(res[addr.contact_id.id] == False):
+ res[addr.contact_id.id] = {'partner_id': addr.partner_id.id, 'function': addr.function}
+
+ for id in res:
+ if (res[id]==False):
+ res[id] = {'partner_id': False, 'function': False}
+
+ return res
+
+ def _get_contact_id_from_address(self, cr, uid, ids, context=None):
+ #@todo: remove obsolete function
+ result = {}
+ for addr in self.pool.get('res.partner.address').browse(cr, uid, ids, context=context):
+ result[addr.contact_id.id] = True
+ return result.keys()
+
+
_columns = {
'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=True, select=True),
@@ -40,18 +87,17 @@
'first_name': fields.char('First Name', size=64),
'mobile': fields.char('Mobile', size=64),
'title': fields.many2one('res.partner.title','Title', domain=[('domain','=','contact')]),
- 'website': fields.char('Website', size=120),
+ 'website': fields.char('Private Website', size=120),
'lang_id': fields.many2one('res.lang', 'Language'),
'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'),
'country_id': fields.many2one('res.country','Nationality'),
'birthdate': fields.char('Birthdate', size=64),
'active': fields.boolean('Active', help="If the active field is set to False,\
it will allow you to hide the partner contact without removing it."),
- 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
- relation='res.partner', string='Main Employer'),
- 'function': fields.related('job_ids', 'function', type='char', \
- string='Main Function'),
- 'email': fields.char('E-Mail', size=240),
+ #Storage for partner_id and function not fully worked and not required -> removed
+ 'partner_id': fields.function(_main_job, type='many2one', relation='res.partner', string='Main Employer', store = False, multi='mainjob'),
+ 'function': fields.function(_main_job, type='char', size=128, string='Main Function', store = False, multi='mainjob'),
+ 'email': fields.char('Private E-Mail', size=240),
'comment': fields.text('Notes', translate=True),
'photo': fields.binary('Photo'),
}
@@ -65,15 +111,28 @@
'active' : lambda *a: True,
}
- _order = "name"
+ _order = "last_name, first_name"
def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None):
+ """
+ Search function searches for firstname or lastname or lastname(s) followed by firstname(s)
+ """
if not args:
args = []
if context is None:
context = {}
if name:
- ids = self.search(cr, uid, ['|',('name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
+ names = name.split(' ')
+ length = len(names)
+ if length == 1:
+ ids = self.search(cr, uid, ['|',('last_name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
+ else:
+ #assume lastnames firstname
+ last_name = names[0]
+ #range does not take upper limit as for i <
+ for i in range(1,length-1):
+ last_name = last_name + ' ' + names[i]
+ ids = self.search(cr, uid, ['|','|',('last_name', operator, name),('first_name', operator, name),'&',('last_name', operator, last_name),('first_name', operator, names[length-1])] + args, limit=limit, context=context)
else:
ids = self.search(cr, uid, args, limit=limit, context=context)
return self.name_get(cr, uid, ids, context=context)
@@ -85,6 +144,33 @@
if obj.partner_id:
result[obj.id] = result[obj.id] + ', ' + obj.partner_id.name
return result.items()
+
+ def view_init(self, cr, uid, fields, context=None):
+ """
+ This function shall fill the last_name and first_name if empty from context default_name
+ It assumes entry of lastnames Firstname or lastname only. Entry of multiple
+ firstnames has to be adjusted afterwards
+ """
+
+ if context is None:
+ context = {}
+ else:
+ default_name = context.get('default_name')
+ if default_name:
+ split = default_name.split(' ')
+ length = len(split)
+ if length > 1:
+ context.update({'default_first_name': split[length-1]})
+ #join again
+ default_name = split[0]
+ #range does not take upper limit!
+ for i in range(1,length-1):
+ default_name = default_name + ' ' + split[i]
+
+ #either fill joined rest or original text into context for last name
+ context.update({'default_last_name': default_name})
+ pass
+
def _auto_init(self, cr, context=None):
def table_exists(view_name):
@@ -99,7 +185,7 @@
cr.execute("""
INSERT INTO
res_partner_contact
- (id,name,last_name,title,active,email,mobile,birthdate)
+ (id,last_name,first_name,title,active,email,mobile,birthdate)
SELECT
id,COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate
FROM
@@ -123,9 +209,11 @@
'state_id': fields.many2one("res.country.state", 'Fed. State', domain="[('country_id','=',country_id)]"),
'country_id': fields.many2one('res.country', 'Country'),
'company_id': fields.many2one('res.company', 'Company',select=1),
- 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'),
+ 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Addresses'),
'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
relation='res.partner', string='Main Partner'),
+ 'contact_id': fields.related('job_ids', 'contact_id', type='many2one',\
+ relation='res.partner.contact', string='First Contact'),
}
_defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c),
@@ -168,6 +256,29 @@
class res_partner_address(osv.osv):
_inherit = 'res.partner.address'
+
+ def _get_address_from_location_ids(self, cr, uid, ids, context=None):
+ result = {}
+ #if self._name=="res.partner.location":
+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('location_id','in',ids)]):
+ result[addr] = True
+ #else:
+ #raise osv.except_osv(_('getAddressFromLocation'), self._name)
+
+ return result.keys()
+
+ def _get_address_from_contact_ids(self, cr, uid, ids, context=None):
+ result = {}
+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)]):
+ result[addr] = True
+ return result.keys()
+
+ def _get_own_addresses(self, cr, uid, ids, context=None):
+ result = {}
+ for id in ids:
+ result[id] = True
+ return result.keys()
+
def _default_location_id(self, cr, uid, context=None):
if context is None:
@@ -177,6 +288,23 @@
ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context)
return ids and ids[0] or False
+ def onchange_contact_id(self,cr, uid, ids, contact_id=False, context={}):
+ if not contact_id:
+ return {'value':{
+ 'mobile': False,
+ #setting of name is not followed. If no contact_id it is set to False by the relation
+ 'name': '/',
+ 'title': False,
+ }
+ }
+ contact = self.pool.get('res.partner.contact').browse(cr, uid, contact_id, context=context)
+ return {'value':{
+ 'mobile': contact.mobile,
+ 'name': contact.name,
+ 'title': contact.title and contact.title.id or False,
+ }}
+
+
def onchange_location_id(self,cr, uid, ids, location_id=False, context={}):
if not location_id:
return {}
@@ -193,23 +321,52 @@
_columns = {
'location_id' : fields.many2one('res.partner.location', 'Location'),
'contact_id' : fields.many2one('res.partner.contact', 'Contact'),
+
+ #add private type
+ 'type': fields.selection( [ ('default','Default'),('invoice','Invoice'), ('delivery','Delivery'), ('contact','Contact'), ('other','Other'), ('private', 'Private') ],'Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."),
+
+
+ #field for administer functions
+ 'sequence_contact': fields.integer('Contact Seq.',help='Order of\
+ importance of this address in the list of addresses of the linked contact'),
+ 'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"),
+ 'date_stop': fields.date('Date Stop', help="Last date of job"),
+ 'state': fields.selection([('past', 'Past'),('current', 'Current')], \
+ 'State', required=True, help="Status of Address"),
# fields from location
- 'street': fields.related('location_id', 'street', string='Street', type="char", store=True, size=128),
- 'street2': fields.related('location_id', 'street2', string='Street2', type="char", store=True, size=128),
- 'zip': fields.related('location_id', 'zip', string='Zip', type="char", store=True, change_default=True, size=24),
- 'city': fields.related('location_id', 'city', string='City', type="char", store=True, size=128),
- 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", store=True, domain="[('country_id','=',country_id)]"),
- 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', store=True, relation='res.country'),
+ #Trigger for change of location id of self is not required because this is handled by onchange_location_id triggered in the only form!
+ 'street': fields.related('location_id', 'street', string='Street', type="char", size=128,
+ store = {'res.partner.location': (_get_address_from_location_ids, ['street'], 10),}),
+ 'street2': fields.related('location_id', 'street2', string='Street2', type="char", size=128,
+ store = {'res.partner.location': (_get_address_from_location_ids, ['street2'], 10),}),
+ 'zip': fields.related('location_id', 'zip', string='Zip', type="char", change_default=True, size=24,
+ store = {'res.partner.location': (_get_address_from_location_ids, ['zip'], 10),}),
+ 'city': fields.related('location_id', 'city', string='City', type="char", size=128,
+ store = {'res.partner.location': (_get_address_from_location_ids, ['city'], 10),}),
+ 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", domain="[('country_id','=',country_id)]",
+ store = {'res.partner.location': (_get_address_from_location_ids, ['state_id'], 10),}),
+ 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', relation='res.country',
+ store = {'res.partner.location': (_get_address_from_location_ids, ['country_id'], 10),}),
- 'phone': fields.char('Phone', size=64),
- 'fax': fields.char('Fax', size=64),
- 'email': fields.char('E-Mail', size=240),
+ #These fields exists
+ #'phone': fields.char('Phone', size=64),
+ #'fax': fields.char('Fax', size=64),
+ #'email': fields.char('E-Mail', size=240),
+ #this field is missing
+ 'other': fields.char('Other Phone', size=64, help='Additional phone field'),
# fields from contact
+
'mobile' : fields.related('contact_id', 'mobile', type='char', size=64, string='Mobile'),
- 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", store=True),
- 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title", store=True),
+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['mobile'], 10),
+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}), @bug: query wants to store in crm_lead!!!!
+ 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name",
+ store = {'res.partner.contact': (_get_address_from_contact_ids, ['last_name', 'first_name'], 10),
+ 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
+ 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title"),
+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['title'], 10),
+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
}
def create(self, cr, uid, data, context={}):
if not data.get('location_id', False):
@@ -229,10 +386,10 @@
result = {}
for rec in self.browse(cr,uid, ids, context=context):
res = []
+ if rec.contact_id and rec.contact_id.name:
+ res.append(rec.contact_id.name)
if rec.partner_id:
res.append(rec.partner_id.name_get()[0][1])
- if rec.contact_id and rec.contact_id.name:
- res.append(rec.contact_id.name)
if rec.location_id:
if rec.location_id.city: res.append(rec.location_id.city)
if rec.location_id.country_id: res.append(rec.location_id.country_id.name_get()[0][1])
@@ -240,8 +397,17 @@
return result.items()
_defaults = {
- 'location_id': _default_location_id
+ 'location_id': _default_location_id,
+ 'sequence_contact' : lambda *a: 0,
+ 'state': lambda *a: 'current',
+ #default for name is not followed as related field
+ 'name': lambda *a: '/',
}
+ #order by name. default addresses are assumed to have no name = empty -> are last entry!
+ #@todo: how to move empty entry to front
+ _order='state, name, sequence_contact'
+
+
def default_get(self, cr, uid, fields=[], context=None):
if context is None:
@@ -252,3 +418,46 @@
res_partner_address()
+class res_partner(osv.osv):
+ _inherit = 'res.partner'
+
+ """def _get_address_from_partner_ids(self, cr, uid, ids, context=None):
+ result = {}
+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('partner_id','in',ids)]):
+ result[addr] = True
+ return result.keys() @todo: somehow trigger is not required"""
+
+ def _default_address_id(self, cr, uid, ids, prop, unknow_none, context=None):
+ #pdb.set_trace()
+ #res = super(res_partner,self).address_get(cr, uid, ids)
+
+ res = dict.fromkeys(ids, False)
+
+ all_ids = self.pool.get('res.partner.address').search(cr, uid, [('partner_id','in',ids), ('type','=','default')])
+
+ addresses = self.pool.get('res.partner.address').browse(cr, uid, all_ids)
+ for addr in addresses:
+ if(res[addr.partner_id.id] == False):
+ res[addr.partner_id.id] = addr.id
+
+ """for id in res:
+ if (res[id]==False):
+ res[id] = [] """
+
+ #pdb.set_trace()
+ return res
+
+
+ _columns = {#default_address_id has to be stored to enable search of the related fields!!! Somehow trigger is not required!
+ 'default_address_id': fields.function(_default_address_id, type='many2one', obj='res.partner.address', string='address_id', store = True),
+ 'phone': fields.related('default_address_id', 'phone', type='char', string='Phone'),
+ 'fax': fields.related('default_address_id', 'fax', type='char', string='Fax', store = False),
+ 'email': fields.related('default_address_id', 'email', type='char', size=240, string='E-mail', store = False),
+ 'street': fields.related('default_address_id', 'street', type='char', string='Street', store = False),
+ 'city': fields.related('default_address_id', 'city', type='char', string='City', store = False),
+ 'country': fields.related('default_address_id','country_id', type='many2one', relation='res.country', string='Country'),
+ }
+
+res_partner()
+
+
=== modified file 'base_contact/base_contact_view.xml' (properties changed: -x to +x)
--- base_contact/base_contact_view.xml 2012-01-31 13:36:57 +0000
+++ base_contact/base_contact_view.xml 2013-11-05 15:41:30 +0000
@@ -1,6 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
+
+ <!-- Address views -->
+
+ <record id="view_partner_address_tree" model="ir.ui.view">
+ <field name="name">res.partner.address.tree</field>
+ <field name="model">res.partner.address</field>
+ <field name="inherit_id" ref="base.view_partner_address_tree"/>
+ <field name="type">tree</field>
+ <field name="context">{"search_default_state": "current"}</field>
+ <field name="arch" type="xml">
+ <tree string="Partner Addresses" position="replace">
+ <tree string="Addresses" colors="gray:state in ('past')">
+ <field name="name"/>
+ <field name="partner_id"/>
+ <field name="function"/>
+ <field name="email"/>
+ <field name="phone"/>
+ <field name="mobile"/>
+ <field name="country_id"/>
+ <field name="type"/>
+ <field name="state" />
+ </tree>
+ </tree>
+ </field>
+ </record>
+
+ <record id="view_res_partner_address_filter" model="ir.ui.view">
+ <field name="name">res.partner.address.select</field>
+ <field name="model">res.partner.address</field>
+ <field name="inherit_id" ref="base.view_res_partner_address_filter"/>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Search Contact" position="replace" >
+ <search string="Search Address">
+ <group>
+ <field name="partner_id" string="Partner"/>
+ <field name="name" string="Contact" />
+ <field name="function"/>
+ <field name="location_id" />
+ <field name="type" />
+ <field name="state" />
+ </group>
+ <newline/>
+ <group expand="0" string="Group By...">
+ <filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by' : 'partner_id'}" />
+ <filter string="Function" icon="terp-go-home" domain="[]" context="{'group_by' : 'function'}" />
+ <filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}" />
+ <filter string="State" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'state'}" />
+ </group>
+ </search>
+ </search>
+ </field>
+ </record>
+
+ <!-- Address Tree view for Contact -->
+ <record id="view_partner_address_tree_contact" model="ir.ui.view">
+ <field name="name">res.partner.address.tree.contact</field>
+ <field name="model">res.partner.address</field>
+ <field name="type">tree</field>
+ <field eval="17" name="priority"/>
+ <field name="arch" type="xml">
+ <tree string="Functions and Addresses" colors="gray:state in ('past')">
+ <field name="location_id"/>
+ <field name="function"/>
+ <field name="email" widget="email"/>
+ <field name="phone"/>
+ <field name="other" />
+ <field name="fax"/>
+ <field name="type"/>
+ <field name="state" />
+ <field name="sequence_contact" string="Seq."/>
+ </tree>
+ </field>
+ </record>
+
+ <!-- Adress Tree view for Partner -->
+ <record id="view_partner_address_tree_partner" model="ir.ui.view">
+ <field name="name">res.partner.address.tree.partner</field>
+ <field name="model">res.partner.address</field>
+ <field name="type">tree</field>
+ <field eval="18" name="priority"/>
+ <field name="arch" type="xml">
+ <tree string="Functions and Addresses" colors="gray:state in ('past')" >
+ <field name="name"/>
+ <field name="location_id"/>
+ <field name="function"/>
+ <field name="email" widget="email"/>
+ <field name="phone"/>
+ <field name="mobile"/>
+ <field name="other" />
+ <field name="fax"/>
+ <field name="type"/>
+ <field name="state" />
+ </tree>
+ </field>
+ </record>
<!-- Views for Contacts Tree View -->
@@ -9,8 +105,8 @@
<field name="model">res.partner.contact</field>
<field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Partner Contact">
- <field name="name"/>
+ <tree string="Contact">
+ <field name="last_name"/>
<field name="first_name"/>
<field name="mobile"/>
<field name="email"/>
@@ -28,7 +124,7 @@
<field name="model">res.partner.contact</field>
<field name="type">form</field>
<field name="arch" type="xml">
- <form string="Partner Contact">
+ <form string="Contact">
<group colspan="4" col="6">
<field name="last_name" select="1"/>
<field name="first_name" select="1"/>
@@ -48,22 +144,8 @@
<field name="photo" widget='image' nolabel="1"/>
</group>
</group>
- <field name="job_ids" colspan="4" nolabel="1" mode="tree,form">
- <form string="Functions and Addresses">
- <field name="partner_id" />
- <field name="location_id" domain="[('partner_id', '=', partner_id)]"/>
- <field name="function" />
- <separator string="Professional Info" colspan="4"/>
- <field name="phone"/>
- <field name="fax"/>
- <field name="email" widget="email"/>
- </form>
- <tree string="Functions and Addresses">
- <field name="location_id"/>
- <field name="function"/>
- <field name="phone"/>
- <field name="email"/>
- </tree>
+ <!-- default_type is not followed! -->
+ <field name="job_ids" colspan="4" nolabel="1" mode="tree,form" context="{'tree_view_ref' : 'base_contact.view_partner_address_tree_contact', 'default_contact_id': active_id, 'default_type': 'contact'}">
</field>
</page>
<page string="Extra Information">
@@ -90,10 +172,10 @@
<field name="model">res.partner.contact</field>
<field name="type">search</field>
<field name="arch" type="xml">
- <search string="Partner Contact">
+ <search string="Contact">
<field name="name" string="First/Lastname"
filter_domain="['|', ('first_name','ilike', self), ('last_name', 'ilike', self)]"/>
- <field name="partner_id" string="Partner"/>
+ <field name="job_ids" string="Partner"/>
</search>
</field>
</record>
@@ -113,6 +195,7 @@
<!-- Rename menuitem for partner addresses -->
<record model="ir.ui.menu" id="base.menu_partner_address_form">
<field name="name">Addresses</field>
+ <!-- does not work <field name="context">{"search_default_state": "current"}</field> -->
</record>
<!--
@@ -127,7 +210,9 @@
<menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form"
parent = "base.menu_procurement_management_supplier" sequence="2"/>
- <!-- Views for Partners Form View -->
+ <!-- @todo: Menu addresses to be added in purchase module?! -->
+
+ <!-- Views for Partner -->
<record model="ir.ui.view" id="view_partner_form_inherit">
<field name="name">Partner form inherited</field>
@@ -135,17 +220,50 @@
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
- <separator string="Postal Address" position="after">
- <field name="location_id" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', parent.id)]"/>
- </separator>
- <xpath expr="//field[@string='Contact Name']" position="replace">
- <field name="contact_id"/>
- </xpath>
- <field name="title" position="replace"/>
+ <field name="address" position="replace" >
+ <field colspan="4" mode="tree,form" name="address" nolabel="1" select="1" height="260" context="{'tree_view_ref' : 'base_contact.view_partner_address_tree_partner', 'default_partner_id': active_id, 'default_type': 'contact'}">
+ </field>
+ </field>
+
</field>
</record>
-
- <!-- Views for Addresses -->
+
+ <record id="view_partner_tree" model="ir.ui.view">
+ <field name="name">res.partner.tree</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_partner_tree"/>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+
+ <field name="phone" position="after" >
+ <field name="fax"/>
+ </field>
+
+ <field name="city" position="before" >
+ <field name="street"/>
+ </field>
+
+ </field>
+ </record>
+
+ <record id="view_res_partner_filter" model="ir.ui.view">
+ <field name="name">res.partner.select</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_res_partner_filter"/>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+
+
+ <field name="country" position="before">
+ <field name="street" select="1"/>
+ <field name="city" select="1"/>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Views for Location -->
<record model="ir.ui.view" id="view_partner_location_form">
<field name="name">res.partner.location.form</field>
@@ -153,12 +271,24 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Locations">
+ <field name="partner_id" readonly="1" />
<field name="street" colspan="4"/>
<field name="street2" colspan="4"/>
<field name="zip"/>
<field name="city"/>
<field name="country_id" />
<field name="state_id"/>
+ <newline />
+ <separator string="Addresses" colspan="4" />
+ <field name="job_ids" nolabel="1" colspan="4" readonly="1" mode="tree">
+ <tree string="Address">
+ <field name = "contact_id" />
+ <field name = "partner_id" />
+ <field name = "function" />
+ <field name = "type" />
+ <field name = "state" />
+ </tree>
+ </field>
</form>
</field>
</record>
@@ -170,6 +300,9 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Locations">
+ <field name="partner_id" string="Partner" />
+ <field name="contact_id" />
+ <field name="street" />
<field name="city"/>
<field name="country_id" />
<field name="state_id"/>
@@ -177,19 +310,66 @@
</field>
</record>
+ <record model="ir.ui.view" id="view_partner_location_search">
+ <field name="name">res.partner.location.search</field>
+ <field name="model">res.partner.location</field>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Partner Location">
+ <field name="partner_id" string="Partner"/>
+ <field name="street" />
+ </search>
+ </field>
+ </record>
+
+
+ <record model="ir.actions.act_window" id="action_partner_location_form">
+ <field name="name">Locations</field>
+ <field name="res_model">res.partner.location</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">tree,form</field>
+ <field name="view_id" ref="view_partner_location_tree"/>
+ <field name="search_view_id" ref="view_partner_location_search"/>
+ </record>
+ <!-- sequence=30 is because 11 is not enough for beeing below addresses to be checked further -->
+ <menuitem name="Locations" id="menu_partner_location_form" action="action_partner_location_form" parent = "base.menu_address_book" sequence="30"/>
+ <menuitem name="Locations" id="menu_purchase_partner_location_form" action="action_partner_location_form" parent = "base.menu_procurement_management_supplier" sequence="30"/>
+
+
+ <!-- Update default address view -->
+
<record model="ir.ui.view" id="view_partner_address_form_inherited0">
<field name='name'>res.partner.address.form.inherited0</field>
<field name='model'>res.partner.address</field>
<field name="inherit_id" ref="base.view_partner_address_form1"/>
<field name='type'>form</field>
<field name='arch' type='xml'>
+
+ <field name="partner_id" position="replace">
+ <field name="partner_id" colspan="2" attrs="{'required':[('contact_id','=', False)]}"/>
+ </field>
+
<field name="name" position="replace">
- <field name="contact_id"/>
- </field>
+ <field name="contact_id" on_change="onchange_contact_id(contact_id)" attrs="{'required':[('partner_id','=', False)]}"/>
+ <!-- <field name="name" string="use this field for initial name only" /> would require adaption of create-->
+ </field>
+
+ <field name="type" position="replace">
+ <field name="type" required="1"/>
+ </field>
+
<separator string="Postal Address" position="after">
- <field name="location_id" on_change="onchange_location_id(location_id)"/>
+ <field name="location_id" required="1" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', partner_id)]"/>
</separator>
<field name="title" position="replace"/>
+ <field name="function" position="after">
+ <separator string="Status" colspan="6"/>
+ <field name="state" />
+ <field name="date_start" />
+ <field name="date_stop" />
+ <separator string="Sequence" colspan="6" col="2"/>
+ <field name="sequence_contact" string="Contact Seq."/>
+ </field>
</field>
</record>
=== modified file 'base_contact/security/ir.model.access.csv' (properties changed: -x to +x)
--- base_contact/security/ir.model.access.csv 2012-01-31 13:36:57 +0000
+++ base_contact/security/ir.model.access.csv 2013-11-05 15:41:30 +0000
@@ -1,7 +1,8 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1
"access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0
-"access_res_partner_location","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
+"access_res_partner_location_manager","res.partner.location","model_res_partner_location","base.group_partner_manager",1,1,1,1
+"access_res_partner_location_all","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
"access_res_partner_location_sale_salesman","res.partner.location","model_res_partner_location","base.group_sale_salesman",1,1,1,0
"access_res_partner_address_sale_salesman","res.partner.address.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0
"access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0
Follow ups