Merge lp:~vrt-openerp/openobject-addons/6.1-trunk-bug-923440 into lp:openobject-addons/6.1

Proposed by Stuart Longland
Status: Needs review
Proposed branch: lp:~vrt-openerp/openobject-addons/6.1-trunk-bug-923440
Merge into: lp:openobject-addons/6.1
Diff against target: 548 lines (+284/-56)
3 files modified
base_contact/base_contact.py (+161/-25)
base_contact/base_contact_view.xml (+121/-30)
base_contact/security/ir.model.access.csv (+2/-1)
To merge this branch: bzr merge lp:~vrt-openerp/openobject-addons/6.1-trunk-bug-923440
Reviewer Review Type Date Requested Status
Amit Parik (community) Disapprove
OpenERP Core Team Pending
Review via email: mp+96493@code.launchpad.net

This proposal supersedes a proposal from 2012-03-07.

Description of the change

This branch contains the fixes presented in bug #923440 and bug #940264.

I'd like to thank Etienne Hirt for providing many of the patches which were used to construct this branch. All I did was tidy things up a bit, he did all the work. :-)

Note: I've updated the target branch and rebased off its head.

To post a comment you must log in.
6649. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6650. By Olivier Dony (Odoo)

[FIX] mail*: properly handle b64-encoding for attachments

When reading the datas property of an attachment,
a base64-encoded stream is expected.
The mail.message.schedule_with_attach() method OTOH
expects a binary file for attachments, so it should
be decoded if extracted from a binary field.

6651. By Olivier Dony (Odoo)

[FIX] crm: typo + duplicate line due to bad merge + bad hardcoded models

6652. By Olivier Dony (Odoo)

[FIX] crm_partner_assign: partial revert of recent commit, care for missing city/zip

6653. By Olivier Dony (Odoo)

[FIX] email_template: care for missing context

6654. By Olivier Dony (Odoo)

[FIX] marketing_campaign: correct search view, today should not be OR'ed with states

In 6.1 a group of filters in a search view are
OR'ed together if toggled when they are contained
within the same 'separator' group.

6655. By Olivier Dony (Odoo)

[FIX] crm_partner_assign: google map is confused by certain country names

6656. By Olivier Dony (Odoo)

[FIX] crm_partner_assign: geolocalization was bad for large countries e.g. US or Russia

Add one more step considering a slightly larger
range around the lead within the same country,
before considering the whole country at once.
Courtesy of Dhara Shah

6657. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6658. By Olivier Dony (Odoo)

[FIX] res.partner.bank: respect company restrictions when assign parent account for new bank GL account

6659. By Olivier Dony (Odoo)

[FIX] lunch: missing product description in list view

6660. By Olivier Dony (Odoo)

[FIX] portal: mark portal users as `share` to exclude from lists by default

6661. By Olivier Dony (Odoo)

[FIX] email.template: body_html should be translatable

6662. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6663. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6664. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6665. By Olivier Dony (Odoo)

[FIX] hr_holidays: Leaves calendar view should be filtered by users, not description

6666. By Olivier Dony (Odoo)

[FIX] project: project preference field must be editable

The user preferences screen is kind of a hack
because it lets the user modify fields on a
model that is normally read-only for her (res.users).
This is accomplished by a custom write() method
on res.users combined with a view on which some
fields are forced to be read-write using a
trick: @readonly=0.

6667. By Stephane Wirtel (OpenERP)

[FIX] In the case where the user has no signature, we set up a default value to avoid to have a body with 'False'.

6668. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6669. By Quentin (OpenERP) <email address hidden>

[FIX] account: qucik and dirty fix on the common wizard of reports to set the company_id by default in order to avoid having the name_search of fiscalyear processed before it is correctly set by the onchange of default value of chart account id. This bug is due to asynchronous calls of web client and will be solved asap, but in the meanwhile this little hack will localy solve the problem.

6670. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6671. By Olivier Dony (Odoo)

[FIX] project_issue: global CC fields contains email(s), not a URL

6672. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6673. By Olivier Dony (Odoo)

[FIX] email_template: attachments were not being sent due to programming error

6674. By Olivier Dony (Odoo)

[FIX] sale,sale_layout: avoid RML loop when printing SO with very long notes

Forward port of revision 5001 from the
6.0 branch. Apparently very long SO
notes (above 2200 characters) will cause
an endless loop while trying to render
inside a blockTable

6675. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6676. By Christophe Simonis (OpenERP)

[FIX] email_template: report_name must be rendered

6677. By Quentin (OpenERP) <email address hidden>

[MERGE] opw-381937. Stock: don't set an arbitrary value of 1 when valuating a stock move of a product with 0 as unit amount

6678. By Olivier Dony (Odoo)

[FIX] mail.message: when auto-deleting a message, only delete attachments it owns

There's a peculiar way to manage attachments on
mail messages, as there is an explicit many2many
on top of regular attachments like for any
record, so it is possible to link a mail
to attachments that are owned by other records.
Such attachments must not be deleted along with
the message when the auto-delete flag is set.

6679. By Olivier Dony (Odoo)

[MERGE] base.action.rule: better handle non-ASCII data

Also fixes the `regex_history` expression
that should search on the `subject` field
now (it was renamed in 6.1).

6680. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6681. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6682. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6683. By Quentin (OpenERP) <email address hidden>

[FIX] account: build_ctx_period must always return a list of ids

6684. By Olivier Dony (Odoo)

[FIX] mail.message: allow reading msg even if author belongs to another company

6685. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6686. By Raphael Collet (OpenERP)

[FIX] backport of branch trunk-bug-937194-nco (mail: remove character &#13; from message)

6687. By Olivier Dony (Odoo)

[FIX] edi: company logo appears truncated on EDI preview in Firefox

6688. By Olivier Dony (Odoo)

[FIX] edi: avoid disprupting EDI preview layout with wide notes

6689. By Olivier Dony (Odoo)

[FIX] edi: care for missing invoice fields in EDI preview (instead of displaying `false`)

6690. By Olivier Dony (Odoo)

[MERGE] procurement: Fix typo (bug 956234), courtesy of Guewen Baconnier @ Camptocamp

6691. By Olivier Dony (Odoo)

[MERGE] Update l10n_it account types, courtesy of Lorenzo Battistini (Agile BG - Domsense)

6692. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6693. By Xavier ALT

[MERGE] OPW 573035: fetchmail: UnboundLocalError: local variable imap_server referenced before assignment

6694. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6695. By Olivier Dony (Odoo)

[FIX] mail: default permissions should allow write for everyone

Mail messages are created in multiple steps that
usually involve calling write() at some point, so
giving all users write access is necessary.

6696. By Olivier Dony (Odoo)

[MERGE] Properly pass context when incrementing sequences, courtesy of Stefan Rijnhart (Therp)

6697. By Rucha Patel <email address hidden>

[FIX] email_template: don't re-encode attachments copied from template'

6698. By Rucha Patel <email address hidden>

[FIX] email_template: ensure non-empty context when rendering template'

6699. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6700. By Xavier ALT

[MERGE] OPW 573037: audittrail: force admin for subscribe/unsubscribe op - fix 'admin/access rights' members access

6701. By Olivier Dony (Odoo)

[FIX] email.template: properly propagate res_id over context reloads in composition wizard

6702. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6703. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6704. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6705. By Xavier ALT

[MERGE] OPW 381582: stock: on inventory, product qty should be computed up to 'inventory date', not after

6706. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6707. By Xavier ALT

[MERGE] OPW 573041: crm: for crm.lead, force orm 'default_get' to avoid misbehaviour when 'base_contact' is installed

6708. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6709. By Xavier ALT

[MERGE] OPW 381524: stock: on picking invoicing, do not invoice scrapped products

6710. By Xavier ALT

[MERGE] OPW 573244: account: manually unreconcilling move line doesn't switch invoice back to 'open' state

6711. By Xavier ALT

[MERGE] OPW 51189: account: on invoice 'refund', keep original salesman and fiscal position

6712. By Xavier ALT

[MERGE] OPW 16328: account.move.line: do not create writeoff entries when called from fy closing wizard

6713. By Xavier ALT

[MERGE] OPW 50804: stock: fix search_default_available on 'internal move' search view

6714. By Xavier ALT

[MERGE] OPW 381927: project: when copying the project, analytic lines of the related analytic account should not be copied

6715. By Xavier ALT

[MERGE] OPW 381848: purchase_requisition: fix action context as create_uid is not present in the search view

6716. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6717. By Xavier ALT

[MERGE] OWP 572921: account_voucher: fix computation of paid_amount_in_company_currency field

6718. By Olivier Dony (Odoo)

[FIX] Trunk backport: properly record UTC login date, courtesy of Ian Beardslee

6719. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6720. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6721. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6722. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6723. By Xavier ALT

[MERGE] project_issue: by default, convert issue to bug only if there is no provided category

6724. By Christophe Simonis (OpenERP)

[FIX] auth_openid: allow login from direct http request

6725. By Christophe Simonis (OpenERP)

[FIX] auth_openid: use correct api for login users

6726. By Antony Lesuisse (OpenERP)

[MERGE] point_of_sale barcode scanning (manual merge)

6727. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6728. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6729. By Xavier ALT

[MERGE] project_issue: issue analysis have to use 'AVG' group operator for AVG Working Hours fields

6730. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6731. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6732. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6733. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6734. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6735. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6736. By Xavier ALT

[MERGE] report_webkit: remove deprecated 'lib_path' field on company

6737. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6738. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6739. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6740. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6741. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6742. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

6743. By Xavier ALT

[MERGE] report_webkit: handle more gracefull remove of 'lib_path' + fix test in l10n_ch

6749. By Stuart Longland

base_contact: Add support for private addresses

This patch adds support for private contact addresses and allows for the UI to
pick out addresses of a given type by default based on the context.

Credit: Etienne Hirt

6750. By Stuart Longland

Rebase off upstream tree

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Stuart,

This is a big improvement for 6.1, Sorry to say this but we have consider only blocking point as well as small bug fixes for the 6.1 branch . So we can not consider this type of big improvement for 6.1

Thanks for the contribution!

review: Disapprove

Unmerged revisions

6750. By Stuart Longland

Rebase off upstream tree

6749. By Stuart Longland

base_contact: Add support for private addresses

This patch adds support for private contact addresses and allows for the UI to
pick out addresses of a given type by default based on the context.

Credit: Etienne Hirt

6748. By Stuart Longland

Rebase and merge with upstream

6747. By Stuart Longland

base_contact: Make contact_id OR partner_id required

Source and credit: Etienne Hirt
https://bugs.launchpad.net/openobject-addons/+bug/940264/comments/4

This patch mandates that at least one of contact_id OR partner_id (or both)
must be filled in for the object to be valid.

6746. By Stuart Longland

base_contact: Tweak order of address "names"

Tweak name_get so that it returns a string of the form:
 FirstName LastName, Partner, City, Country
rather than the default:
 Partner, FirstName, LastName, City, Country

IMO this should be locale dependent.

6745. By Stuart Longland

base_contact: Remove erronious security/base_contact_security.xml

Seems this is one of many rabbit droppings from the 6.0-branch of OpenERP.

6744. By Stuart Longland

Rebase and merge with upstream 6.1 branch

Credit goes to Etienne Hirt for putting the contributions together. Please see
https://code.launchpad.net/~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1

for the original commit log.

I tried to add these changes individually, but ran into numerous snags due to
the way the original branch was constructed (bzr merge won't work as the
branches do not share a common ancestor).

So all changes have been folded into one commit here, with the updates to .po
files filtered out as these seemed to be mostly noise.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'base_contact/base_contact.py'
2--- base_contact/base_contact.py 2012-02-15 13:22:13 +0000
3+++ base_contact/base_contact.py 2012-04-18 04:27:19 +0000
4@@ -21,37 +21,80 @@
5
6 from osv import fields, osv
7 import addons
8+import pdb
9
10 class res_partner_contact(osv.osv):
11 """ Partner Contact """
12
13 _name = "res.partner.contact"
14 _description = "Contact"
15+
16+ _rec_name = 'last_name'
17
18+
19 def _name_get_full(self, cr, uid, ids, prop, unknow_none, context=None):
20 result = {}
21 for rec in self.browse(cr, uid, ids, context=context):
22- result[rec.id] = rec.last_name+' '+(rec.first_name or '')
23+ #use firstname lastname as in the demo data of base/res/res_partner_demo.xml
24+ if(rec.first_name):
25+ result[rec.id] = rec.first_name+' '+rec.last_name
26+ else:
27+ result[rec.id] = rec.last_name
28+
29 return result
30+
31+ def _main_job(self, cr, uid, ids, fields, arg, context=None):
32+ """
33+ @summary: Returns id and function of job with the lowest 'sequence_contact'
34+ @param self: The object pointer
35+ @param cr: the current row, from the database cursor,
36+ @param uid: the current user’s ID for security checks,
37+ @param ids: List of partner contact’s IDs
38+ @fields: Get Fields
39+ @param context: A standard dictionary for contextual values
40+ @param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """
41+
42+ res = dict.fromkeys(ids, False)
43+
44+ all_ids = self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)], order='sequence_contact')
45+ #pdb.set_trace()
46+ addresses = self.pool.get('res.partner.address').browse(cr, uid, all_ids)
47+ for addr in addresses:
48+ if(res[addr.contact_id.id] == False):
49+ res[addr.contact_id.id] = {'partner_id': addr.partner_id.id, 'function': addr.function}
50+
51+ for id in res:
52+ if (res[id]==False):
53+ res[id] = {'partner_id': False, 'function': False}
54+
55+ return res
56+
57+ def _get_contact_id_from_address(self, cr, uid, ids, context=None):
58+ #@todo: remove obsolete function
59+ result = {}
60+ for addr in self.pool.get('res.partner.address').browse(cr, uid, ids, context=context):
61+ result[addr.contact_id.id] = True
62+ return result.keys()
63+
64+
65
66 _columns = {
67- 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=True, select=True),
68+ 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=False, select=True),
69 'last_name': fields.char('Last Name', size=64, required=True),
70 'first_name': fields.char('First Name', size=64),
71 'mobile': fields.char('Mobile', size=64),
72 'title': fields.many2one('res.partner.title','Title', domain=[('domain','=','contact')]),
73- 'website': fields.char('Website', size=120),
74+ 'website': fields.char('Private Website', size=120),
75 'lang_id': fields.many2one('res.lang', 'Language'),
76 'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'),
77 'country_id': fields.many2one('res.country','Nationality'),
78 'birthdate': fields.char('Birthdate', size=64),
79 'active': fields.boolean('Active', help="If the active field is set to False,\
80 it will allow you to hide the partner contact without removing it."),
81- 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
82- relation='res.partner', string='Main Employer'),
83- 'function': fields.related('job_ids', 'function', type='char', \
84- string='Main Function'),
85- 'email': fields.char('E-Mail', size=240),
86+ #Storage for partner_id and function not fully worked and not required -> removed
87+ 'partner_id': fields.function(_main_job, type='many2one', relation='res.partner', string='Main Employer', store = False, multi='mainjob'),
88+ 'function': fields.function(_main_job, type='char', size=128, string='Main Function', store = False, multi='mainjob'),
89+ 'email': fields.char('Private E-Mail', size=240),
90 'comment': fields.text('Notes', translate=True),
91 'photo': fields.binary('Photo'),
92 }
93@@ -65,7 +108,7 @@
94 'active' : lambda *a: True,
95 }
96
97- _order = "name"
98+ _order = "last_name, first_name"
99
100 def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None):
101 if not args:
102@@ -73,7 +116,7 @@
103 if context is None:
104 context = {}
105 if name:
106- ids = self.search(cr, uid, ['|',('name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
107+ ids = self.search(cr, uid, ['|',('last_name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
108 else:
109 ids = self.search(cr, uid, args, limit=limit, context=context)
110 return self.name_get(cr, uid, ids, context=context)
111@@ -85,6 +128,22 @@
112 if obj.partner_id:
113 result[obj.id] = result[obj.id] + ', ' + obj.partner_id.name
114 return result.items()
115+
116+ def view_init(self, cr, uid, fields, context=None):
117+ """
118+ This function shall fill the first and last name if empty from context
119+ """
120+
121+ if context is None:
122+ context = {}
123+ else:
124+ default_name = context.get('default_name')
125+ #if default_name:
126+ #pdb.set_trace()
127+ #The following does not work
128+ #self._columns['last_name'] = default_name
129+ pass
130+
131
132 def _auto_init(self, cr, context=None):
133 def table_exists(view_name):
134@@ -99,7 +158,7 @@
135 cr.execute("""
136 INSERT INTO
137 res_partner_contact
138- (id,name,last_name,title,active,email,mobile,birthdate)
139+ (id,last_name,first_name,title,active,email,mobile,birthdate)
140 SELECT
141 id,COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate
142 FROM
143@@ -124,6 +183,8 @@
144 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'),
145 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
146 relation='res.partner', string='Main Partner'),
147+ 'contact_id': fields.related('job_ids', 'contact_id', type='many2one',\
148+ relation='res.partner.contact', string='First Contact'),
149 }
150 _defaults = {
151 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c),
152@@ -166,6 +227,29 @@
153
154 class res_partner_address(osv.osv):
155 _inherit = 'res.partner.address'
156+
157+ def _get_address_from_location_ids(self, cr, uid, ids, context=None):
158+ result = {}
159+ #if self._name=="res.partner.location":
160+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('location_id','in',ids)]):
161+ result[addr] = True
162+ #else:
163+ #raise osv.except_osv(_('getAddressFromLocation'), self._name)
164+
165+ return result.keys()
166+
167+ def _get_address_from_contact_ids(self, cr, uid, ids, context=None):
168+ result = {}
169+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)]):
170+ result[addr] = True
171+ return result.keys()
172+
173+ def _get_own_addresses(self, cr, uid, ids, context=None):
174+ result = {}
175+ for id in ids:
176+ result[id] = True
177+ return result.keys()
178+
179
180 def _default_location_id(self, cr, uid, context=None):
181 if context is None:
182@@ -175,6 +259,17 @@
183 ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context)
184 return ids and ids[0] or False
185
186+ def onchange_contact_id(self,cr, uid, ids, contact_id=False, context={}):
187+ if not contact_id:
188+ return {}
189+ contact = self.pool.get('res.partner.contact').browse(cr, uid, contact_id, context=context)
190+ return {'value':{
191+ 'mobile': contact.mobile,
192+ 'name': contact.name,
193+ 'title': contact.title and contact.title.id or False,
194+ }}
195+
196+
197 def onchange_location_id(self,cr, uid, ids, location_id=False, context={}):
198 if not location_id:
199 return {}
200@@ -191,23 +286,57 @@
201 _columns = {
202 'location_id' : fields.many2one('res.partner.location', 'Location'),
203 'contact_id' : fields.many2one('res.partner.contact', 'Contact'),
204+
205+ #add private type
206+ '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."),
207+
208+
209+ #field for administer functions
210+ 'sequence_contact': fields.integer('Contact Seq.',help='Order of\
211+ importance of this address in the list of addresses of the linked contact'),
212+ 'sequence_partner': fields.integer('Partner Seq.',help='Order of importance\
213+ of this job title in the list of job title of the linked partner'),
214+ 'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"),
215+ 'date_stop': fields.date('Date Stop', help="Last date of job"),
216+ 'state': fields.selection([('past', 'Past'),('current', 'Current')], \
217+ 'State', required=True, help="Status of Address"),
218+
219+ #add private type
220+ '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."),
221
222 # fields from location
223- 'street': fields.related('location_id', 'street', string='Street', type="char", store=True, size=128),
224- 'street2': fields.related('location_id', 'street2', string='Street2', type="char", store=True, size=128),
225- 'zip': fields.related('location_id', 'zip', string='Zip', type="char", store=True, change_default=True, size=24),
226- 'city': fields.related('location_id', 'city', string='City', type="char", store=True, size=128),
227- 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", store=True, domain="[('country_id','=',country_id)]"),
228- 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', store=True, relation='res.country'),
229+ #Trigger for change of location id of self is not required because this is handled by onchange_location_id triggered in the only form!
230+ 'street': fields.related('location_id', 'street', string='Street', type="char", size=128,
231+ store = {'res.partner.location': (_get_address_from_location_ids, ['street'], 10),}),
232+ 'street2': fields.related('location_id', 'street2', string='Street2', type="char", size=128,
233+ store = {'res.partner.location': (_get_address_from_location_ids, ['street2'], 10),}),
234+ 'zip': fields.related('location_id', 'zip', string='Zip', type="char", change_default=True, size=24,
235+ store = {'res.partner.location': (_get_address_from_location_ids, ['zip'], 10),}),
236+ 'city': fields.related('location_id', 'city', string='City', type="char", size=128,
237+ store = {'res.partner.location': (_get_address_from_location_ids, ['city'], 10),}),
238+ 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", domain="[('country_id','=',country_id)]",
239+ store = {'res.partner.location': (_get_address_from_location_ids, ['state_id'], 10),}),
240+ 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', relation='res.country',
241+ store = {'res.partner.location': (_get_address_from_location_ids, ['country_id'], 10),}),
242
243- 'phone': fields.char('Phone', size=64),
244- 'fax': fields.char('Fax', size=64),
245- 'email': fields.char('E-Mail', size=240),
246+ #These fields exists
247+ #'phone': fields.char('Phone', size=64),
248+ #'fax': fields.char('Fax', size=64),
249+ #'email': fields.char('E-Mail', size=240),
250+ #this field is missing
251+ 'other': fields.char('Other Phone', size=64, help='Additional phone field'),
252
253 # fields from contact
254+
255 'mobile' : fields.related('contact_id', 'mobile', type='char', size=64, string='Mobile'),
256- 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", store=True),
257- 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title", store=True),
258+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['mobile'], 10),
259+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}), @bug: query wants to store in crm_lead!!!!
260+ 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name",
261+ store = {'res.partner.contact': (_get_address_from_contact_ids, ['last_name', 'first_name'], 10),
262+ 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
263+ 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title"),
264+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['title'], 10),
265+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
266 }
267 def create(self, cr, uid, data, context={}):
268 if not data.get('location_id', False):
269@@ -227,10 +356,10 @@
270 result = {}
271 for rec in self.browse(cr,uid, ids, context=context):
272 res = []
273+ if rec.contact_id and rec.contact_id.name:
274+ res.append(rec.contact_id.name)
275 if rec.partner_id:
276 res.append(rec.partner_id.name_get()[0][1])
277- if rec.contact_id and rec.contact_id.name:
278- res.append(rec.contact_id.name)
279 if rec.location_id:
280 if rec.location_id.city: res.append(rec.location_id.city)
281 if rec.location_id.country_id: res.append(rec.location_id.country_id.name_get()[0][1])
282@@ -238,8 +367,15 @@
283 return result.items()
284
285 _defaults = {
286- 'location_id': _default_location_id
287+ 'location_id': _default_location_id,
288+ 'sequence_contact' : lambda *a: 0,
289+ 'sequence_partner' : lambda *a: 10,
290+ 'state': lambda *a: 'current',
291 }
292+
293+ _order='sequence_partner, type, name'
294+
295+
296
297 def default_get(self, cr, uid, fields=[], context=None):
298 if context is None:
299
300=== modified file 'base_contact/base_contact_view.xml'
301--- base_contact/base_contact_view.xml 2012-01-31 13:36:57 +0000
302+++ base_contact/base_contact_view.xml 2012-04-18 04:27:19 +0000
303@@ -1,6 +1,52 @@
304 <?xml version="1.0" encoding="utf-8"?>
305 <openerp>
306 <data>
307+
308+ <!-- Address views -->
309+
310+ <!-- Address Tree view for Contact -->
311+ <record id="view_partner_address_tree_contact" model="ir.ui.view">
312+ <field name="name">res.partner.address.tree.contact</field>
313+ <field name="model">res.partner.address</field>
314+ <field name="type">tree</field>
315+ <field eval="17" name="priority"/>
316+ <field name="arch" type="xml">
317+ <tree string="Functions and Addresses" colors="gray:state in ('past')">
318+ <field name="location_id"/>
319+ <field name="function"/>
320+ <field name="email" widget="email"/>
321+ <field name="phone"/>
322+ <field name="other" />
323+ <field name="fax"/>
324+ <field name="type"/>
325+ <field name="state" />
326+ <field name="sequence_contact" string="Seq."/>
327+ </tree>
328+ </field>
329+ </record>
330+
331+ <!-- Adress Tree view for Partner -->
332+ <record id="view_partner_address_tree_partner" model="ir.ui.view">
333+ <field name="name">res.partner.address.tree.partner</field>
334+ <field name="model">res.partner.address</field>
335+ <field name="type">tree</field>
336+ <field eval="18" name="priority"/>
337+ <field name="arch" type="xml">
338+ <tree string="Partner Contacts" colors="gray:state in ('past')" >
339+ <field name="name"/>
340+ <field name="location_id"/>
341+ <field name="function"/>
342+ <field name="email" widget="email"/>
343+ <field name="phone"/>
344+ <field name="mobile"/>
345+ <field name="other" />
346+ <field name="fax"/>
347+ <field name="type"/>
348+ <field name="state" />
349+ <field name="sequence_partner" string="Seq."/>
350+ </tree>
351+ </field>
352+ </record>
353
354 <!-- Views for Contacts Tree View -->
355
356@@ -10,7 +56,7 @@
357 <field name="type">tree</field>
358 <field name="arch" type="xml">
359 <tree string="Partner Contact">
360- <field name="name"/>
361+ <field name="last_name"/>
362 <field name="first_name"/>
363 <field name="mobile"/>
364 <field name="email"/>
365@@ -48,22 +94,8 @@
366 <field name="photo" widget='image' nolabel="1"/>
367 </group>
368 </group>
369- <field name="job_ids" colspan="4" nolabel="1" mode="tree,form">
370- <form string="Functions and Addresses">
371- <field name="partner_id" />
372- <field name="location_id" domain="[('partner_id', '=', partner_id)]"/>
373- <field name="function" />
374- <separator string="Professional Info" colspan="4"/>
375- <field name="phone"/>
376- <field name="fax"/>
377- <field name="email" widget="email"/>
378- </form>
379- <tree string="Functions and Addresses">
380- <field name="location_id"/>
381- <field name="function"/>
382- <field name="phone"/>
383- <field name="email"/>
384- </tree>
385+ <!-- default_type is not followed! -->
386+ <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'}">
387 </field>
388 </page>
389 <page string="Extra Information">
390@@ -93,7 +125,7 @@
391 <search string="Partner Contact">
392 <field name="name" string="First/Lastname"
393 filter_domain="['|', ('first_name','ilike', self), ('last_name', 'ilike', self)]"/>
394- <field name="partner_id" string="Partner"/>
395+ <field name="job_ids" string="Partner"/>
396 </search>
397 </field>
398 </record>
399@@ -127,6 +159,8 @@
400 <menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form"
401 parent = "base.menu_procurement_management_supplier" sequence="2"/>
402
403+ <!-- @todo: Menu addresses to be added in purchase module?! -->
404+
405 <!-- Views for Partners Form View -->
406
407 <record model="ir.ui.view" id="view_partner_form_inherit">
408@@ -135,17 +169,15 @@
409 <field name="inherit_id" ref="base.view_partner_form"/>
410 <field name="type">form</field>
411 <field name="arch" type="xml">
412- <separator string="Postal Address" position="after">
413- <field name="location_id" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', parent.id)]"/>
414- </separator>
415- <xpath expr="//field[@string='Contact Name']" position="replace">
416- <field name="contact_id"/>
417- </xpath>
418- <field name="title" position="replace"/>
419+ <field name="address" position="replace" >
420+ <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'}">
421+ </field>
422+ </field>
423 </field>
424 </record>
425-
426- <!-- Views for Addresses -->
427+
428+
429+ <!-- Views for Location -->
430
431 <record model="ir.ui.view" id="view_partner_location_form">
432 <field name="name">res.partner.location.form</field>
433@@ -153,12 +185,20 @@
434 <field name="type">form</field>
435 <field name="arch" type="xml">
436 <form string="Locations">
437+ <field name="partner_id" readonly="1" />
438 <field name="street" colspan="4"/>
439 <field name="street2" colspan="4"/>
440 <field name="zip"/>
441 <field name="city"/>
442 <field name="country_id" />
443 <field name="state_id"/>
444+ <newline />
445+ <separator string="Contacts" colspan="4" />
446+ <field name="job_ids" nolabel="1" colspan="4" readonly="1" mode="tree">
447+ <tree>
448+ <field name = "contact_id" />
449+ </tree>
450+ </field>
451 </form>
452 </field>
453 </record>
454@@ -170,6 +210,9 @@
455 <field name="type">tree</field>
456 <field name="arch" type="xml">
457 <tree string="Locations">
458+ <field name="partner_id" string="Partner" />
459+ <field name="contact_id" />
460+ <field name="street" />
461 <field name="city"/>
462 <field name="country_id" />
463 <field name="state_id"/>
464@@ -177,19 +220,67 @@
465 </field>
466 </record>
467
468+ <record model="ir.ui.view" id="view_partner_location_search">
469+ <field name="name">res.partner.location.search</field>
470+ <field name="model">res.partner.location</field>
471+ <field name="type">search</field>
472+ <field name="arch" type="xml">
473+ <search string="Partner Location">
474+ <field name="partner_id" string="Partner"/>
475+ <field name="street" />
476+ </search>
477+ </field>
478+ </record>
479+
480+
481+ <record model="ir.actions.act_window" id="action_partner_location_form">
482+ <field name="name">Locations</field>
483+ <field name="res_model">res.partner.location</field>
484+ <field name="view_type">form</field>
485+ <field name="view_mode">tree,form</field>
486+ <field name="view_id" ref="view_partner_location_tree"/>
487+ <field name="search_view_id" ref="view_partner_location_search"/>
488+ </record>
489+ <!-- sequence=30 is because 11 is not enough for beeing below addresses to be checked further -->
490+ <menuitem name="Locations" id="menu_partner_location_form" action="action_partner_location_form" parent = "base.menu_address_book" sequence="30"/>
491+ <menuitem name="Locations" id="menu_purchase_partner_location_form" action="action_partner_location_form" parent = "base.menu_procurement_management_supplier" sequence="30"/>
492+
493+
494+ <!-- Update default address view -->
495+
496 <record model="ir.ui.view" id="view_partner_address_form_inherited0">
497 <field name='name'>res.partner.address.form.inherited0</field>
498 <field name='model'>res.partner.address</field>
499 <field name="inherit_id" ref="base.view_partner_address_form1"/>
500 <field name='type'>form</field>
501 <field name='arch' type='xml'>
502+
503+ <field name="partner_id" position="replace">
504+ <field name="partner_id" colspan="2" attrs="{'required':[('contact_id','=', False)]}"/>
505+ </field>
506+
507 <field name="name" position="replace">
508- <field name="contact_id"/>
509- </field>
510+ <field name="contact_id" on_change="onchange_contact_id(contact_id)" attrs="{'required':[('partner_id','=', False)]}"/>
511+ <!-- <field name="name" string="use this field for initial name only" /> would require adaption of create-->
512+ </field>
513+
514+ <field name="type" position="replace">
515+ <field name="type" required="1"/>
516+ </field>
517+
518 <separator string="Postal Address" position="after">
519- <field name="location_id" on_change="onchange_location_id(location_id)"/>
520+ <field name="location_id" required="1" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', partner_id)]"/>
521 </separator>
522 <field name="title" position="replace"/>
523+ <field name="function" position="after">
524+ <separator string="Status" colspan="6"/>
525+ <field name="state" />
526+ <field name="date_start" />
527+ <field name="date_stop" />
528+ <separator string="Sequence" colspan="6" col="4"/>
529+ <field name="sequence_contact" string="Contact Seq."/>
530+ <field name="sequence_partner" string="Partner Seq."/>
531+ </field>
532 </field>
533 </record>
534
535
536=== modified file 'base_contact/security/ir.model.access.csv'
537--- base_contact/security/ir.model.access.csv 2012-01-31 13:36:57 +0000
538+++ base_contact/security/ir.model.access.csv 2012-04-18 04:27:19 +0000
539@@ -1,7 +1,8 @@
540 "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
541 "access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1
542 "access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0
543-"access_res_partner_location","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
544+"access_res_partner_location_manager","res.partner.location","model_res_partner_location","base.group_partner_manager",1,1,1,1
545+"access_res_partner_location_all","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
546 "access_res_partner_location_sale_salesman","res.partner.location","model_res_partner_location","base.group_sale_salesman",1,1,1,0
547 "access_res_partner_address_sale_salesman","res.partner.address.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0
548 "access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0