openerp-community team mailing list archive
-
openerp-community team
-
Mailing list archive
-
Message #00918
Re: lp:~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1 into lp:openobject-addons/6.1
Dear Reviewers,
Please find attached the diff vs. trunk 6480
Best Regards
Etienne
On 04.03.2012 14:05, Etienne Hirt wrote:
> Etienne Hirt has proposed merging lp:~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1 into lp:openobject-addons/6.1.
>
> Requested reviews:
> OpenERP Core Team (openerp)
> 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/~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1/+merge/95777
>
> This branch is intended to update the new base_contact V6.1 with the functionality of V6.0 and to perform corrections (see also bug923440):
> * Triggers for storage and redefine only fields that are not available already
> * state field and date_from/to
> * Sequence for partner and contact view, corresponding sorting and correct selection of main function/partner and main address
> * Other phone in res_partner_address
> * Obsolete: Use field name for last_name in res_partner_contact to enable auto filling when creating a new contact
> ** use name again and setting _rec_name = 'last_name' but not followed for "create and edit"
> * Defining address tree view for partner and for contact and select them instead of defining the tree within the form
> * search for contacts connected to job_ids to search for all partners and partner is in name!
> * store firstname lastname in name as in the in the demo data of base/res/res_partner_demo.xml
--
https://code.launchpad.net/~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1/+merge/95777
Your team OpenERP Community is subscribed to branch lp:~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1.
#. module: base_contact
#: field:res.partner.location,city:0
Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv
===================================================================
--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv (revision 12877)
+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv (revision 13001)
@@ -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
Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py
===================================================================
--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py (revision 12877)
+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py (revision 13001)
@@ -21,37 +21,80 @@
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
+ if(rec.first_name):
+ result[rec.id] = rec.first_name+' '+rec.last_name
+ else:
+ result[rec.id] = rec.last_name
+
return result
+
+ def _main_job(self, cr, uid, ids, fields, arg, context=None):
+ """
+ @summary: Returns 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:
+ 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),
+ 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=False, select=True),
'last_name': fields.char('Last Name', size=64, required=True),
'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.date('Birth Date'),
+ '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,7 +108,7 @@
'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):
if not args:
@@ -73,7 +116,7 @@
if context is None:
context = {}
if name:
- ids = self.search(cr, uid, ['|',('name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
+ ids = self.search(cr, uid, ['|',('last_name', operator, name),('first_name', operator, name)] + 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 +128,22 @@
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 first and last name if empty from context
+ """
+
+ if context is None:
+ context = {}
+ else:
+ default_name = context.get('default_name')
+ #if default_name:
+ #pdb.set_trace()
+ #The following does not work
+ #self._columns['last_name'] = default_name
+ pass
+
def _auto_init(self, cr, context=None):
def table_exists(view_name):
@@ -99,9 +158,9 @@
cr.execute("""
INSERT INTO
res_partner_contact
- (id,name,last_name,title,active)
+ (id,last_name,first_name,title,active,email,mobile,birthdate)
SELECT
- id,COALESCE(name, '/'),COALESCE(name, '/'),title,true
+ id,COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate
FROM
res_partner_address""")
cr.execute("alter table res_partner_address add contact_id int references res_partner_contact")
@@ -124,6 +183,8 @@
'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'),
'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),
@@ -166,6 +227,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:
@@ -175,6 +259,17 @@
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 {}
+ 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 {}
@@ -191,23 +286,49 @@
_columns = {
'location_id' : fields.many2one('res.partner.location', 'Location'),
'contact_id' : fields.many2one('res.partner.contact', 'Contact'),
+
+ #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'),
+ 'sequence_partner': fields.integer('Partner Seq.',help='Order of importance\
+ of this job title in the list of job title of the linked partner'),
+ '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):
@@ -238,9 +359,16 @@
return result.items()
_defaults = {
- 'location_id': _default_location_id
+ 'location_id': _default_location_id,
+ 'sequence_contact' : lambda *a: 0,
+ 'sequence_partner' : lambda *a: 10,
+ 'state': lambda *a: 'current',
}
+
+ _order='sequence_partner, type, name'
+
+
def default_get(self, cr, uid, fields=[], context=None):
if context is None:
context = {}
Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml
===================================================================
--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml (revision 12877)
+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml (revision 13001)
@@ -1,6 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
+
+ <!-- Address views -->
+
+ <!-- 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="Partner Contacts" 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" />
+ <field name="sequence_partner" string="Seq."/>
+ </tree>
+ </field>
+ </record>
<!-- Views for Contacts Tree View -->
@@ -10,7 +56,7 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Partner Contact">
- <field name="name"/>
+ <field name="last_name"/>
<field name="first_name"/>
<field name="mobile"/>
<field name="email"/>
@@ -48,22 +94,7 @@
<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>
+ <field name="job_ids" colspan="4" nolabel="1" mode="tree,form" context="{'tree_view_ref' : 'base_contact.view_partner_address_tree_contact'}">
</field>
</page>
<page string="Extra Information">
@@ -93,7 +124,7 @@
<search string="Partner 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>
@@ -127,6 +158,8 @@
<menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form"
parent = "base.menu_procurement_management_supplier" sequence="2"/>
+ <!-- @todo: Menu addresses to be added in purchase module?! -->
+
<!-- Views for Partners Form View -->
<record model="ir.ui.view" id="view_partner_form_inherit">
@@ -135,30 +168,37 @@
<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'}">
+ </field>
+ </field>
+
</field>
</record>
+
+
+ <!-- Views for Location -->
- <!-- Views for Addresses -->
-
<record model="ir.ui.view" id="view_partner_location_form">
<field name="name">res.partner.location.form</field>
<field name="model">res.partner.location</field>
<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="Contacts" colspan="4" />
+ <field name="job_ids" nolabel="1" colspan="4" readonly="1" mode="tree">
+ <tree>
+ <field name = "contact_id" />
+ </tree>
+ </field>
</form>
</field>
</record>
@@ -170,6 +210,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,6 +220,34 @@
</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>
@@ -184,12 +255,22 @@
<field name='type'>form</field>
<field name='arch' type='xml'>
<field name="name" position="replace">
- <field name="contact_id"/>
+ <field name="contact_id" on_change="onchange_contact_id(contact_id)" />
+ <!-- <field name="name" string="use this field for initial name only" /> would require adaption of create-->
</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="4"/>
+ <field name="sequence_contact" string="Contact Seq."/>
+ <field name="sequence_partner" string="Partner Seq."/>
+ </field>
</field>
</record>
References