Merge lp:~hirt/ocb-addons/6.1_base_contact_finalize into lp:ocb-addons/6.1
- 6.1_base_contact_finalize
- Merge into 6.1
Status: | Needs review |
---|---|
Proposed branch: | lp:~hirt/ocb-addons/6.1_base_contact_finalize |
Merge into: | lp:ocb-addons/6.1 |
Diff against target: |
973 lines (+559/-100) 4 files modified
base_contact/__openerp__.py (+11/-6) base_contact/base_contact.py (+294/-53) base_contact/base_contact_view.xml (+252/-40) base_contact/security/ir.model.access.csv (+2/-1) |
To merge this branch: | bzr merge lp:~hirt/ocb-addons/6.1_base_contact_finalize |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Omar (Pexego) | code review, no test | Needs Fixing | |
Review via email: mp+193941@code.launchpad.net |
Commit message
Description of the change
Finalising the base contact 6.1 desig by adding the missing fields as described in https:/
Etienne Hirt (hirt) wrote : | # |
Dear Pedro,
Thanks for your offer to check it.
Somehow the redesign of the base_contact module for 6.1 was never
finished as it was abandoned by openerp. I prepared the fixes some time
ago to have the function available at Art of Technology. This
functionality is also the main reason for us not considering Version 7
(yet).
The effort now is to have others being able to profit from it, too and
also to profit from the community.
Best Regards
Etienne
On 05.11.2013 17:09, Pedro Manuel Baeza wrote:
> Hi, Etienne, thank you for making again the MP properly. I will check it, but it's a huge diff for only a bugfix. I'm not sure if this is going to fit into OCB project and goals.
>
> Let's see what others reviewers say.
>
> Regards.
Omar (Pexego) (omar7r) wrote : | # |
At first sight, you should remove pdb import and the commented lines, on the other hand, you convert the partner_id field, from related to function field without search function, this field could be used in several addons as filter, with function field will not work anymore at least without search function.
IMHO I prefer name_search as works now, because your way don't support, for example, with compound first names or more than one last name, this is applyable to view_init function too.
It's a huge diff as Pedro said and I think that isn't the best way to complete this addon but we can wait for opinion of other reviewers, for now, I will mark it as needs fixing, for the up things.
Regards
Etienne Hirt (hirt) wrote : | # |
Dear Omar,
thanks for the review and your valuable comments. Please check my
answers below.
Best Regards
Etienne
On 20.11.2013 01:19, Omar (Pexego) wrote:
> Review: Needs Fixing code review, no test
>
> At first sight, you should remove pdb import and the commented lines, on the other hand,
mostly done
> you convert the partner_id field, from related to function field without search function, this field could be used in several addons as filter, with function field will not work anymore at least without search function.
With the related field you have no real control what partner is selected
as main partner.
Originally I wanted to have conditional storage but this somehow did not
work. I removed it then because contacts are nowhere searched for
partners as far as I know. Also IMHO the related fields can not be
searched if not stored.
What do you propose?
> IMHO I prefer name_search as works now, because your way don't support, for example, with compound first names or more than one last name, this is applyable to view_init function too.
Please check again the proposed search function. Because it's intention
is to extend the original function instead of limit it. Should we also
consider one lastname with multiple/compound first names?
Without the view_init function all newly entered contacts are filled
into lastname only. Thus the proposed function is an extension but not
perfect as it can not guess that multiple Firstnames are used.
>
> It's a huge diff as Pedro said and I think that isn't the best way to complete this addon but we can wait for opinion of other reviewers, for now, I will mark it as needs fixing, for the up things.
>
> Regards
Omar (Pexego) (omar7r) wrote : | # |
Hi Etienne,
Thanks for updating. Related fields can not be grouped but, searched yes. Other solution, you could have a search function defined in your function field.
At Spain for example, everyone have two last names and one or two first names, like Jose Antonio or Diego Armando, we could not have limitation in that.
Regards
Etienne Hirt (hirt) wrote : | # |
Hi Omar,
Thanks for insisting. With your inputs I found now a solution that supports any number of first and lastname for all searches. This was not the case in the baseline I started with.
Also the partner_id I could change back to related as the sorting of the address_id fits the requirements for the main job.
The view_init is a helper function that is a 90% solution but helps the user even if the remaining 10% when there is more than one firstname.
The partner_contact class is ready for re-reviewing. But the partner_address requires some further work. I therefore set the state to WIP.
Best Regards
- 6817. By Etienne Hirt
-
remove the executable flag that wrongly added in last commit
- 6818. By Etienne Hirt
-
* store partner_id in location directly to solve usability issue of having
locations assigned to partners if any and to view it while using.
Attention: this commit does not store the partner_ids yet at updating
but for install the module it is added.
* override copy method for res.partner.location to avoid copying the
related addresses's - 6819. By Etienne Hirt
-
add auto_init for partner_id in res_partner_
location - 6820. By Etienne Hirt
-
* streamline location editing
* enhance and streamline search - 6821. By Etienne Hirt
-
delete action as menu deletion did not work for upgrade contact/address with new action
- 6822. By Etienne Hirt
-
*further streamlining location editing
*restrict deletion of partner when there are assigned addresses - 6823. By Etienne Hirt
-
* changes of partner of address does still not fully update the location partner_id
to be continued - 6824. By Etienne Hirt
-
* use storage triggers for partner_id in res_partner_
location
* minor UI adjustments:
** group extended for location menu but not addresses
** add partner to functions/addresses in contact form - 6825. By Etienne Hirt
-
* enhance contact and location search
* fix length of name in contact to allow full lenght of last_name + first_name - 6826. By Etienne Hirt
-
void delection of assigned locations
- 6827. By Etienne Hirt
-
commit files no longer executable
- 6828. By Etienne Hirt
-
do merge
- 6829. By Etienne Hirt
-
add street to res_partner_address displayname
- 6830. By Etienne Hirt
-
add other phone to address tree and form
- 6831. By Etienne Hirt
-
* store all related fields from location if one changes
* add trigger on change_location_id also because the on_change function does not store all changes!
Unmerged revisions
- 6831. By Etienne Hirt
-
* store all related fields from location if one changes
* add trigger on change_location_id also because the on_change function does not store all changes! - 6830. By Etienne Hirt
-
add other phone to address tree and form
- 6829. By Etienne Hirt
-
add street to res_partner_address displayname
- 6828. By Etienne Hirt
-
do merge
- 6827. By Etienne Hirt
-
commit files no longer executable
- 6826. By Etienne Hirt
-
void delection of assigned locations
- 6825. By Etienne Hirt
-
* enhance contact and location search
* fix length of name in contact to allow full lenght of last_name + first_name - 6824. By Etienne Hirt
-
* use storage triggers for partner_id in res_partner_
location
* minor UI adjustments:
** group extended for location menu but not addresses
** add partner to functions/addresses in contact form - 6823. By Etienne Hirt
-
* changes of partner of address does still not fully update the location partner_id
to be continued - 6822. By Etienne Hirt
-
*further streamlining location editing
*restrict deletion of partner when there are assigned addresses
Preview Diff
1 | === modified file 'account_asset/i18n/ca.po' (properties changed: +x to -x) | |||
2 | === modified file 'account_asset/i18n/de.po' (properties changed: +x to -x) | |||
3 | === modified file 'account_asset/i18n/es.po' (properties changed: +x to -x) | |||
4 | === modified file 'account_asset/i18n/es_CR.po' (properties changed: +x to -x) | |||
5 | === modified file 'account_asset/i18n/fr.po' (properties changed: +x to -x) | |||
6 | === modified file 'account_asset/i18n/fr_BE.po' (properties changed: +x to -x) | |||
7 | === modified file 'account_asset/i18n/pl.po' (properties changed: +x to -x) | |||
8 | === modified file 'account_asset/i18n/pt.po' (properties changed: +x to -x) | |||
9 | === modified file 'account_asset/i18n/sv.po' (properties changed: +x to -x) | |||
10 | === modified file 'account_asset/security/ir.model.access.csv' (properties changed: +x to -x) | |||
11 | === modified file 'account_asset/wizard/__init__.py' (properties changed: +x to -x) | |||
12 | === modified file 'account_asset/wizard/account_asset_change_duration.py' (properties changed: +x to -x) | |||
13 | === modified file 'account_asset/wizard/wizard_asset_compute.py' (properties changed: +x to -x) | |||
14 | === modified file 'base_contact/__openerp__.py' | |||
15 | --- base_contact/__openerp__.py 2012-01-31 13:36:57 +0000 | |||
16 | +++ base_contact/__openerp__.py 2015-01-16 20:04:03 +0000 | |||
17 | @@ -21,7 +21,7 @@ | |||
18 | 21 | 21 | ||
19 | 22 | { | 22 | { |
20 | 23 | 'name': 'Contacts Management', | 23 | 'name': 'Contacts Management', |
22 | 24 | 'version': '1.0', | 24 | 'version': '1.1', |
23 | 25 | 'category': 'Customer Relationship Management', | 25 | 'category': 'Customer Relationship Management', |
24 | 26 | 'complexity': "expert", | 26 | 'complexity': "expert", |
25 | 27 | 'description': """ | 27 | 'description': """ |
26 | @@ -35,12 +35,17 @@ | |||
27 | 35 | 35 | ||
28 | 36 | It also adds new menu items located in | 36 | It also adds new menu items located in |
29 | 37 | Purchases / Address Book / Contacts | 37 | Purchases / Address Book / Contacts |
33 | 38 | Sales / Address Book / Contacts | 38 | Sales / Address Book / Contacts and Locations |
34 | 39 | 39 | ||
35 | 40 | 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. | 40 | Pay attention that this module converts the existing addresses into "addresses + contacts". |
36 | 41 | It means that some fields of the addresses will be missing (the contact name is copied into | ||
37 | 42 | addresses to be compatible with other modules contact name). Others are supposed to be defined in an other object. | ||
38 | 43 | |||
39 | 44 | All UI work with lastname(s) firstname(s) but the order has to be observed. | ||
40 | 45 | When entering a new contact only one firstname is assumed. You migh add the additional firstname(s) later | ||
41 | 41 | """, | 46 | """, |
44 | 42 | 'author': 'OpenERP SA', | 47 | 'author': 'OpenERP SA, Art of Technology AG', |
45 | 43 | 'website': 'http://www.openerp.com', | 48 | 'website': 'http://www.openerp.com, http://www.aotag.ch', |
46 | 44 | 'depends': ['base','process'], | 49 | 'depends': ['base','process'], |
47 | 45 | 'init_xml': [], | 50 | 'init_xml': [], |
48 | 46 | 'update_xml': [ | 51 | 'update_xml': [ |
49 | 47 | 52 | ||
50 | === modified file 'base_contact/base_contact.py' | |||
51 | --- base_contact/base_contact.py 2013-09-10 15:12:35 +0000 | |||
52 | +++ base_contact/base_contact.py 2015-01-16 20:04:03 +0000 | |||
53 | @@ -27,31 +27,36 @@ | |||
54 | 27 | 27 | ||
55 | 28 | _name = "res.partner.contact" | 28 | _name = "res.partner.contact" |
56 | 29 | _description = "Contact" | 29 | _description = "Contact" |
58 | 30 | 30 | ||
59 | 31 | def _name_get_full(self, cr, uid, ids, prop, unknow_none, context=None): | 31 | def _name_get_full(self, cr, uid, ids, prop, unknow_none, context=None): |
60 | 32 | result = {} | 32 | result = {} |
61 | 33 | for rec in self.browse(cr, uid, ids, context=context): | 33 | for rec in self.browse(cr, uid, ids, context=context): |
63 | 34 | result[rec.id] = rec.last_name+' '+(rec.first_name or '') | 34 | if(rec.first_name): |
64 | 35 | #last_name is a required field. Therefore always available | ||
65 | 36 | result[rec.id] = rec.last_name+' '+rec.first_name | ||
66 | 37 | else: | ||
67 | 38 | result[rec.id] = rec.last_name | ||
68 | 39 | |||
69 | 35 | return result | 40 | return result |
70 | 36 | 41 | ||
71 | 37 | _columns = { | 42 | _columns = { |
73 | 38 | 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=True, select=True), | 43 | 'name': fields.function(_name_get_full, string='Name', size=128, type="char", store=True, select=True), |
74 | 39 | 'last_name': fields.char('Last Name', size=64, required=True), | 44 | 'last_name': fields.char('Last Name', size=64, required=True), |
75 | 40 | 'first_name': fields.char('First Name', size=64), | 45 | 'first_name': fields.char('First Name', size=64), |
76 | 41 | 'mobile': fields.char('Mobile', size=64), | 46 | 'mobile': fields.char('Mobile', size=64), |
79 | 42 | 'title': fields.many2one('res.partner.title','Title', domain=[('domain','=','contact')]), | 47 | 'title': fields.many2one('res.partner.title','Title', domain=[('domain','=','contact')], required=True), |
80 | 43 | 'website': fields.char('Website', size=120), | 48 | 'website': fields.char('Private Website', size=120), |
81 | 44 | 'lang_id': fields.many2one('res.lang', 'Language'), | 49 | 'lang_id': fields.many2one('res.lang', 'Language'), |
82 | 45 | 'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'), | 50 | 'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'), |
83 | 46 | 'country_id': fields.many2one('res.country','Nationality'), | 51 | 'country_id': fields.many2one('res.country','Nationality'), |
84 | 47 | 'birthdate': fields.char('Birthdate', size=64), | 52 | 'birthdate': fields.char('Birthdate', size=64), |
85 | 48 | 'active': fields.boolean('Active', help="If the active field is set to False,\ | 53 | 'active': fields.boolean('Active', help="If the active field is set to False,\ |
87 | 49 | it will allow you to hide the partner contact without removing it."), | 54 | it will allow you to hide the partner contact without removing it."), |
88 | 50 | 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\ | 55 | 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\ |
89 | 51 | relation='res.partner', string='Main Employer'), | 56 | relation='res.partner', string='Main Employer'), |
90 | 52 | 'function': fields.related('job_ids', 'function', type='char', \ | 57 | 'function': fields.related('job_ids', 'function', type='char', \ |
91 | 53 | string='Main Function'), | 58 | string='Main Function'), |
93 | 54 | 'email': fields.char('E-Mail', size=240), | 59 | 'email': fields.char('Private E-Mail', size=240), |
94 | 55 | 'comment': fields.text('Notes', translate=True), | 60 | 'comment': fields.text('Notes', translate=True), |
95 | 56 | 'photo': fields.binary('Photo'), | 61 | 'photo': fields.binary('Photo'), |
96 | 57 | } | 62 | } |
97 | @@ -67,17 +72,6 @@ | |||
98 | 67 | 72 | ||
99 | 68 | _order = "name" | 73 | _order = "name" |
100 | 69 | 74 | ||
101 | 70 | def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None): | ||
102 | 71 | if not args: | ||
103 | 72 | args = [] | ||
104 | 73 | if context is None: | ||
105 | 74 | context = {} | ||
106 | 75 | if name: | ||
107 | 76 | ids = self.search(cr, uid, ['|',('name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context) | ||
108 | 77 | else: | ||
109 | 78 | ids = self.search(cr, uid, args, limit=limit, context=context) | ||
110 | 79 | return self.name_get(cr, uid, ids, context=context) | ||
111 | 80 | |||
112 | 81 | def name_get(self, cr, uid, ids, context=None): | 75 | def name_get(self, cr, uid, ids, context=None): |
113 | 82 | result = {} | 76 | result = {} |
114 | 83 | for obj in self.browse(cr, uid, ids, context=context): | 77 | for obj in self.browse(cr, uid, ids, context=context): |
115 | @@ -85,6 +79,32 @@ | |||
116 | 85 | if obj.partner_id: | 79 | if obj.partner_id: |
117 | 86 | result[obj.id] = result[obj.id] + ', ' + obj.partner_id.name | 80 | result[obj.id] = result[obj.id] + ', ' + obj.partner_id.name |
118 | 87 | return result.items() | 81 | return result.items() |
119 | 82 | |||
120 | 83 | def view_init(self, cr, uid, fields, context=None): | ||
121 | 84 | """ | ||
122 | 85 | This function shall fill the last_name and first_name if empty from context default_name | ||
123 | 86 | It assumes entry of lastnames Firstname or lastname only. Entry of multiple | ||
124 | 87 | firstnames has to be adjusted afterwards | ||
125 | 88 | """ | ||
126 | 89 | |||
127 | 90 | if context is None: | ||
128 | 91 | context = {} | ||
129 | 92 | else: | ||
130 | 93 | default_name = context.get('default_name') | ||
131 | 94 | if default_name: | ||
132 | 95 | split = default_name.split(' ') | ||
133 | 96 | length = len(split) | ||
134 | 97 | if length > 1: | ||
135 | 98 | context.update({'default_first_name': split[length-1]}) | ||
136 | 99 | #join again | ||
137 | 100 | default_name = split[0] | ||
138 | 101 | for i in range(1,length-1): | ||
139 | 102 | default_name = default_name + ' ' + split[i] | ||
140 | 103 | |||
141 | 104 | #either fill joined rest or original text into context for last name | ||
142 | 105 | context.update({'default_last_name': default_name}) | ||
143 | 106 | pass | ||
144 | 107 | |||
145 | 88 | 108 | ||
146 | 89 | def _auto_init(self, cr, context=None): | 109 | def _auto_init(self, cr, context=None): |
147 | 90 | def table_exists(view_name): | 110 | def table_exists(view_name): |
148 | @@ -99,9 +119,9 @@ | |||
149 | 99 | cr.execute(""" | 119 | cr.execute(""" |
150 | 100 | INSERT INTO | 120 | INSERT INTO |
151 | 101 | res_partner_contact | 121 | res_partner_contact |
153 | 102 | (id,name,last_name,title,active,email,mobile,birthdate) | 122 | (id,name, last_name,first_name,title,active,email,mobile,birthdate) |
154 | 103 | SELECT | 123 | SELECT |
156 | 104 | id,COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate | 124 | id,name, COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate |
157 | 105 | FROM | 125 | FROM |
158 | 106 | res_partner_address""") | 126 | res_partner_address""") |
159 | 107 | cr.execute("alter table res_partner_address add contact_id int references res_partner_contact") | 127 | cr.execute("alter table res_partner_address add contact_id int references res_partner_contact") |
160 | @@ -115,6 +135,14 @@ | |||
161 | 115 | class res_partner_location(osv.osv): | 135 | class res_partner_location(osv.osv): |
162 | 116 | _name = 'res.partner.location' | 136 | _name = 'res.partner.location' |
163 | 117 | _rec_name = 'street' | 137 | _rec_name = 'street' |
164 | 138 | |||
165 | 139 | def _get_location_from_address_ids(self, cr, uid, ids, context=None): | ||
166 | 140 | result = {} | ||
167 | 141 | |||
168 | 142 | for location in self.pool.get('res.partner.location').search(cr, uid, [('job_ids','in',ids)]): | ||
169 | 143 | result[location] = True | ||
170 | 144 | |||
171 | 145 | return result.keys() | ||
172 | 118 | _columns = { | 146 | _columns = { |
173 | 119 | 'street': fields.char('Street', size=128), | 147 | 'street': fields.char('Street', size=128), |
174 | 120 | 'street2': fields.char('Street2', size=128), | 148 | 'street2': fields.char('Street2', size=128), |
175 | @@ -123,13 +151,55 @@ | |||
176 | 123 | 'state_id': fields.many2one("res.country.state", 'Fed. State', domain="[('country_id','=',country_id)]"), | 151 | 'state_id': fields.many2one("res.country.state", 'Fed. State', domain="[('country_id','=',country_id)]"), |
177 | 124 | 'country_id': fields.many2one('res.country', 'Country'), | 152 | 'country_id': fields.many2one('res.country', 'Country'), |
178 | 125 | 'company_id': fields.many2one('res.company', 'Company',select=1), | 153 | 'company_id': fields.many2one('res.company', 'Company',select=1), |
180 | 126 | 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'), | 154 | 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Addresses'), |
181 | 155 | #storage triggers are important if an address is changed to another partner etc. | ||
182 | 127 | 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\ | 156 | 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\ |
184 | 128 | relation='res.partner', string='Main Partner'), | 157 | relation='res.partner', string='Main Partner', |
185 | 158 | store = { | ||
186 | 159 | 'res.partner.location': (lambda self,cr,uid,ids,c=None: ids, ['job_ids'], 10), | ||
187 | 160 | 'res.partner.address': (_get_location_from_address_ids, ['partner_id'], 10), | ||
188 | 161 | }), | ||
189 | 162 | 'contact_id': fields.related('job_ids', 'contact_id', type='many2one',\ | ||
190 | 163 | relation='res.partner.contact', string='First Contact'), | ||
191 | 129 | } | 164 | } |
192 | 130 | _defaults = { | 165 | _defaults = { |
193 | 131 | 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c), | 166 | 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c), |
194 | 132 | } | 167 | } |
195 | 168 | |||
196 | 169 | def copy(self, cr, uid, id, default=None, context=None): | ||
197 | 170 | """ | ||
198 | 171 | Overrides orm copy method in order to avoid copying of related objects such as | ||
199 | 172 | * job_ids | ||
200 | 173 | @param self: the object pointer | ||
201 | 174 | @param cr: the current row, from the database cursor, | ||
202 | 175 | @param uid: the current user’s ID for security checks, | ||
203 | 176 | @param id: Id of crm_lead | ||
204 | 177 | @param default: Dictionary of default values for copy. | ||
205 | 178 | @param context: A standard dictionary for contextual values | ||
206 | 179 | """ | ||
207 | 180 | if context is None: | ||
208 | 181 | context = {} | ||
209 | 182 | if default is None: | ||
210 | 183 | default = {} | ||
211 | 184 | |||
212 | 185 | default.update({ | ||
213 | 186 | 'job_ids': [], | ||
214 | 187 | }) | ||
215 | 188 | return super(osv.osv, self).copy(cr, uid, id, default, context=context) | ||
216 | 189 | |||
217 | 190 | def view_init(self, cr, uid, fields, context=None): | ||
218 | 191 | """ | ||
219 | 192 | This function shall fill the street from the entry | ||
220 | 193 | """ | ||
221 | 194 | |||
222 | 195 | if context is None: | ||
223 | 196 | context = {} | ||
224 | 197 | else: | ||
225 | 198 | default_name = context.get('default_name') | ||
226 | 199 | if default_name: | ||
227 | 200 | context.update({'default_street': default_name}) | ||
228 | 201 | pass | ||
229 | 202 | |||
230 | 133 | def _auto_init(self, cr, context=None): | 203 | def _auto_init(self, cr, context=None): |
231 | 134 | def table_exists(view_name): | 204 | def table_exists(view_name): |
232 | 135 | cr.execute('SELECT count(relname) FROM pg_class WHERE relname = %s', (view_name,)) | 205 | cr.execute('SELECT count(relname) FROM pg_class WHERE relname = %s', (view_name,)) |
233 | @@ -144,21 +214,32 @@ | |||
234 | 144 | INSERT INTO | 214 | INSERT INTO |
235 | 145 | res_partner_location | 215 | res_partner_location |
236 | 146 | (id,street,street2,zip,city, | 216 | (id,street,street2,zip,city, |
238 | 147 | state_id,country_id,company_id) | 217 | state_id,country_id,company_id,partner_id) |
239 | 148 | SELECT | 218 | SELECT |
240 | 149 | id,street,street2,zip,city, | 219 | id,street,street2,zip,city, |
242 | 150 | state_id,country_id,company_id | 220 | state_id,country_id,company_id,partner_id |
243 | 151 | FROM | 221 | FROM |
244 | 152 | res_partner_address""") | 222 | res_partner_address""") |
245 | 153 | cr.execute("alter table res_partner_address add location_id int references res_partner_location") | 223 | cr.execute("alter table res_partner_address add location_id int references res_partner_location") |
246 | 154 | cr.execute("update res_partner_address set location_id=id") | 224 | cr.execute("update res_partner_address set location_id=id") |
247 | 155 | cr.execute("select setval('res_partner_location_id_seq', (select max(id)+1 from res_partner_address))") | 225 | cr.execute("select setval('res_partner_location_id_seq', (select max(id)+1 from res_partner_address))") |
248 | 226 | else: | ||
249 | 227 | cr.execute(""" | ||
250 | 228 | UPDATE | ||
251 | 229 | res_partner_location l | ||
252 | 230 | SET | ||
253 | 231 | partner_id = addr.partner_id | ||
254 | 232 | FROM | ||
255 | 233 | res_partner_address addr INNER JOIN res_partner_location loc ON (loc.id = addr.location_id) | ||
256 | 234 | WHERE | ||
257 | 235 | l.id = loc.id and l.partner_id is null and addr.partner_id is not null """) | ||
258 | 236 | |||
259 | 156 | 237 | ||
260 | 157 | def name_get(self, cr, uid, ids, context=None): | 238 | def name_get(self, cr, uid, ids, context=None): |
261 | 158 | result = {} | 239 | result = {} |
262 | 159 | for obj in self.browse(cr, uid, ids, context=context): | 240 | for obj in self.browse(cr, uid, ids, context=context): |
263 | 160 | res = [] | 241 | res = [] |
265 | 161 | if obj.partner_id: res.append(obj.partner_id.name_get()[0][1]) | 242 | if obj.street: res.append(obj.street) |
266 | 162 | if obj.city: res.append(obj.city) | 243 | if obj.city: res.append(obj.city) |
267 | 163 | if obj.country_id: res.append(obj.country_id.name_get()[0][1]) | 244 | if obj.country_id: res.append(obj.country_id.name_get()[0][1]) |
268 | 164 | result[obj.id] = ', '.join(res) | 245 | result[obj.id] = ', '.join(res) |
269 | @@ -168,15 +249,83 @@ | |||
270 | 168 | 249 | ||
271 | 169 | class res_partner_address(osv.osv): | 250 | class res_partner_address(osv.osv): |
272 | 170 | _inherit = 'res.partner.address' | 251 | _inherit = 'res.partner.address' |
273 | 252 | |||
274 | 253 | def _get_address_from_location_ids(self, cr, uid, ids, context=None): | ||
275 | 254 | result = {} | ||
276 | 255 | |||
277 | 256 | for addr in self.pool.get('res.partner.address').search(cr, uid, [('location_id','in',ids)]): | ||
278 | 257 | result[addr] = True | ||
279 | 258 | |||
280 | 259 | return result.keys() | ||
281 | 260 | |||
282 | 261 | def _get_address_from_contact_ids(self, cr, uid, ids, context=None): | ||
283 | 262 | result = {} | ||
284 | 263 | for addr in self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)]): | ||
285 | 264 | result[addr] = True | ||
286 | 265 | return result.keys() | ||
287 | 266 | |||
288 | 267 | def _get_own_addresses(self, cr, uid, ids, context=None): | ||
289 | 268 | result = {} | ||
290 | 269 | for id in ids: | ||
291 | 270 | result[id] = True | ||
292 | 271 | return result.keys() | ||
293 | 272 | |||
294 | 171 | 273 | ||
295 | 172 | def _default_location_id(self, cr, uid, context=None): | 274 | def _default_location_id(self, cr, uid, context=None): |
296 | 173 | if context is None: | 275 | if context is None: |
297 | 174 | context = {} | 276 | context = {} |
298 | 175 | if not context.get('default_partner_id',False): | 277 | if not context.get('default_partner_id',False): |
299 | 176 | return False | 278 | return False |
301 | 177 | ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context) | 279 | #if a default location is available than this is the default location |
302 | 280 | address_pool = self.pool.get('res.partner.address') | ||
303 | 281 | address_ids = address_pool.search(cr, uid, [('partner_id','=',context['default_partner_id']),('type','=','default')], context=context) | ||
304 | 282 | ids=[] | ||
305 | 283 | if address_ids: | ||
306 | 284 | addresses = address_pool.browse(cr, uid, address_ids) | ||
307 | 285 | for address in addresses: | ||
308 | 286 | if address and address.location_id: | ||
309 | 287 | ids.append(address.location_id.id) | ||
310 | 288 | break | ||
311 | 289 | if not ids: | ||
312 | 290 | ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context) | ||
313 | 291 | |||
314 | 178 | return ids and ids[0] or False | 292 | return ids and ids[0] or False |
315 | 293 | |||
316 | 294 | def onchange_partner_id(self,cr, uid, ids, partner_id=False, context={}): | ||
317 | 295 | #if this address is the only one that points to its location then keep the location | ||
318 | 296 | if ids: | ||
319 | 297 | address = self.pool.get('res.partner.address').browse(cr, uid, ids[0], context=context) | ||
320 | 298 | if address.location_id: | ||
321 | 299 | location = self.pool.get('res.partner.location').browse(cr, uid, address.location_id.id, context=context) | ||
322 | 300 | if len(location.job_ids) <=1: | ||
323 | 301 | return {} | ||
324 | 302 | |||
325 | 303 | if partner_id: | ||
326 | 304 | context['default_partner_id'] = partner_id | ||
327 | 305 | location_id = self._default_location_id(cr, uid, context) | ||
328 | 306 | else: | ||
329 | 307 | location_id = False | ||
330 | 308 | return {'value':{ | ||
331 | 309 | 'location_id': location_id, | ||
332 | 310 | } | ||
333 | 311 | } | ||
334 | 179 | 312 | ||
335 | 313 | def onchange_contact_id(self,cr, uid, ids, contact_id=False, context={}): | ||
336 | 314 | if not contact_id: | ||
337 | 315 | return {'value':{ | ||
338 | 316 | 'mobile': False, | ||
339 | 317 | #setting of name is not required. If no contact_id it is set to False by the relation | ||
340 | 318 | 'title': False, | ||
341 | 319 | } | ||
342 | 320 | } | ||
343 | 321 | contact = self.pool.get('res.partner.contact').browse(cr, uid, contact_id, context=context) | ||
344 | 322 | return {'value':{ | ||
345 | 323 | 'mobile': contact.mobile, | ||
346 | 324 | 'name': contact.name, | ||
347 | 325 | 'title': contact.title and contact.title.id or False, | ||
348 | 326 | }} | ||
349 | 327 | |||
350 | 328 | |||
351 | 180 | def onchange_location_id(self,cr, uid, ids, location_id=False, context={}): | 329 | def onchange_location_id(self,cr, uid, ids, location_id=False, context={}): |
352 | 181 | if not location_id: | 330 | if not location_id: |
353 | 182 | return {} | 331 | return {} |
354 | @@ -191,37 +340,73 @@ | |||
355 | 191 | }} | 340 | }} |
356 | 192 | 341 | ||
357 | 193 | _columns = { | 342 | _columns = { |
359 | 194 | 'location_id' : fields.many2one('res.partner.location', 'Location'), | 343 | #do not allow to delete a partner as long as jobs are related to it |
360 | 344 | 'partner_id': fields.many2one('res.partner', 'Partner Name', ondelete='restrict', select=True, help="Keep empty for a private address, not related to partner."), | ||
361 | 345 | 'location_id' : fields.many2one('res.partner.location', 'Location', ondelete='restrict',), | ||
362 | 195 | 'contact_id' : fields.many2one('res.partner.contact', 'Contact'), | 346 | 'contact_id' : fields.many2one('res.partner.contact', 'Contact'), |
363 | 347 | |||
364 | 348 | #add private type | ||
365 | 349 | '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."), | ||
366 | 350 | |||
367 | 351 | |||
368 | 352 | #field for administer functions | ||
369 | 353 | 'sequence_contact': fields.integer('Contact Seq.',help='Order of\ | ||
370 | 354 | importance of this address in the list of addresses of the linked contact'), | ||
371 | 355 | 'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"), | ||
372 | 356 | 'date_stop': fields.date('Date Stop', help="Last date of job"), | ||
373 | 357 | 'state': fields.selection([('past', 'Past'),('current', 'Current')], \ | ||
374 | 358 | 'State', required=True, help="Status of Address"), | ||
375 | 196 | 359 | ||
376 | 197 | # fields from location | 360 | # fields from location |
383 | 198 | 'street': fields.related('location_id', 'street', string='Street', type="char", store=True, size=128), | 361 | #Trigger for change of location id of self seems not required because this is handled by onchange_location_id |
384 | 199 | 'street2': fields.related('location_id', 'street2', string='Street2', type="char", store=True, size=128), | 362 | # triggered in the form, but this does not properly store the values!. None looks at any fields for change |
385 | 200 | 'zip': fields.related('location_id', 'zip', string='Zip', type="char", store=True, change_default=True, size=24), | 363 | 'street': fields.related('location_id', 'street', string='Street', |
386 | 201 | 'city': fields.related('location_id', 'city', string='City', type="char", store=True, size=128), | 364 | type="char", size=128, readonly=True, |
387 | 202 | 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", store=True, domain="[('country_id','=',country_id)]"), | 365 | store = { 'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), |
388 | 203 | 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', store=True, relation='res.country'), | 366 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), |
389 | 367 | 'street2': fields.related('location_id', 'street2', string='Street2', | ||
390 | 368 | type="char", size=128, readonly=True, | ||
391 | 369 | store = {'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), | ||
392 | 370 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), | ||
393 | 371 | 'zip': fields.related('location_id', 'zip', string='Zip', | ||
394 | 372 | type="char", change_default=True, size=24, readonly=True, | ||
395 | 373 | store = {'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), | ||
396 | 374 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), | ||
397 | 375 | 'city': fields.related('location_id', 'city', string='City', | ||
398 | 376 | type="char", size=128, readonly=True, | ||
399 | 377 | store = {'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), | ||
400 | 378 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), | ||
401 | 379 | 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", | ||
402 | 380 | string='Fed. State', type="many2one", | ||
403 | 381 | domain="[('country_id','=',country_id)]", readonly=True, | ||
404 | 382 | store = {'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), | ||
405 | 383 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), | ||
406 | 384 | 'country_id': fields.related('location_id', 'country_id', type='many2one', | ||
407 | 385 | string='Country', relation='res.country', readonly=True, | ||
408 | 386 | store = {'res.partner.address': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 5), | ||
409 | 387 | 'res.partner.location': (_get_address_from_location_ids, None, 10),}), | ||
410 | 204 | 388 | ||
414 | 205 | 'phone': fields.char('Phone', size=64), | 389 | #this field is missing compared to 6.0 implementation |
415 | 206 | 'fax': fields.char('Fax', size=64), | 390 | 'other': fields.char('Other Phone', size=64, help='Additional phone field'), |
413 | 207 | 'email': fields.char('E-Mail', size=240), | ||
416 | 208 | 391 | ||
417 | 209 | # fields from contact | 392 | # fields from contact |
418 | 210 | 'mobile' : fields.related('contact_id', 'mobile', type='char', size=64, string='Mobile'), | 393 | 'mobile' : fields.related('contact_id', 'mobile', type='char', size=64, string='Mobile'), |
421 | 211 | 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", store=True), | 394 | #store = {'res.partner.contact': (_get_address_from_contact_ids, ['mobile'], 10), |
422 | 212 | 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title", store=True), | 395 | # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}), @bug: query wants to store in crm_lead!!!! |
423 | 396 | 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", | ||
424 | 397 | store = {'res.partner.contact': (_get_address_from_contact_ids, ['last_name', 'first_name'], 10), | ||
425 | 398 | 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}), | ||
426 | 399 | 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title"), | ||
427 | 213 | } | 400 | } |
428 | 214 | def create(self, cr, uid, data, context={}): | 401 | def create(self, cr, uid, data, context={}): |
439 | 215 | if not data.get('location_id', False): | 402 | if data.get('location_id', False): |
440 | 216 | loc_id = self.pool.get('res.partner.location').create(cr, uid, { | 403 | location = self.pool.get('res.partner.location').browse(cr, uid, [data['location_id']])[0] |
441 | 217 | 'street': data.get('street',''), | 404 | data['street'] = location.street or False |
442 | 218 | 'street2': data.get('street2',''), | 405 | data['street2'] = location.street2 or False |
443 | 219 | 'zip': data.get('zip',''), | 406 | data['zip'] = location.zip or False |
444 | 220 | 'city': data.get('city',''), | 407 | data['city'] = location.city or False |
445 | 221 | 'country_id': data.get('country_id',False), | 408 | data['country_id'] = location.country_id and location.country_id.id or False |
446 | 222 | 'state_id': data.get('state_id',False) | 409 | data['state_id'] = location.state_id and location.state_id.id or False |
437 | 223 | }, context=context) | ||
438 | 224 | data['location_id'] = loc_id | ||
447 | 225 | result = super(res_partner_address, self).create(cr, uid, data, context=context) | 410 | result = super(res_partner_address, self).create(cr, uid, data, context=context) |
448 | 226 | return result | 411 | return result |
449 | 227 | 412 | ||
450 | @@ -229,26 +414,82 @@ | |||
451 | 229 | result = {} | 414 | result = {} |
452 | 230 | for rec in self.browse(cr,uid, ids, context=context): | 415 | for rec in self.browse(cr,uid, ids, context=context): |
453 | 231 | res = [] | 416 | res = [] |
454 | 417 | if rec.contact_id and rec.contact_id.name: | ||
455 | 418 | res.append(rec.contact_id.name) | ||
456 | 232 | if rec.partner_id: | 419 | if rec.partner_id: |
457 | 233 | res.append(rec.partner_id.name_get()[0][1]) | 420 | res.append(rec.partner_id.name_get()[0][1]) |
458 | 234 | if rec.contact_id and rec.contact_id.name: | ||
459 | 235 | res.append(rec.contact_id.name) | ||
460 | 236 | if rec.location_id: | 421 | if rec.location_id: |
461 | 422 | if rec.location_id.street: res.append(rec.location_id.street) | ||
462 | 237 | if rec.location_id.city: res.append(rec.location_id.city) | 423 | if rec.location_id.city: res.append(rec.location_id.city) |
463 | 238 | if rec.location_id.country_id: res.append(rec.location_id.country_id.name_get()[0][1]) | 424 | if rec.location_id.country_id: res.append(rec.location_id.country_id.name_get()[0][1]) |
464 | 239 | result[rec.id] = ', '.join(res) | 425 | result[rec.id] = ', '.join(res) |
465 | 240 | return result.items() | 426 | return result.items() |
466 | 241 | 427 | ||
467 | 242 | _defaults = { | 428 | _defaults = { |
469 | 243 | 'location_id': _default_location_id | 429 | 'location_id': _default_location_id, |
470 | 430 | 'sequence_contact' : lambda *a: 0, | ||
471 | 431 | 'state': lambda *a: 'current', | ||
472 | 244 | } | 432 | } |
473 | 433 | |||
474 | 434 | def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None): | ||
475 | 435 | """ | ||
476 | 436 | Search function searches in (contact) name and partner_id depending on context | ||
477 | 437 | while using otherwise the standard implementation | ||
478 | 438 | """ | ||
479 | 439 | if not args: | ||
480 | 440 | args = [] | ||
481 | 441 | if context is None: | ||
482 | 442 | context = {} | ||
483 | 443 | |||
484 | 444 | if name and context.get('contact_display', 'contact') == 'partner': | ||
485 | 445 | ids = self.search(cr, uid, ['|',('name', operator, name),('partner_id', operator, name)] + args, limit=limit, context=context) | ||
486 | 446 | return self.name_get(cr, uid, ids, context=context) | ||
487 | 447 | else: | ||
488 | 448 | return super(res_partner_address, self).name_search(cr, uid, name, args, operator, context, limit) | ||
489 | 449 | |||
490 | 450 | |||
491 | 451 | |||
492 | 452 | #order by name. default addresses are assumed to have no name = empty -> are last entry! | ||
493 | 453 | _order='state, name, sequence_contact' | ||
494 | 454 | |||
495 | 455 | |||
496 | 245 | 456 | ||
497 | 246 | def default_get(self, cr, uid, fields=[], context=None): | 457 | def default_get(self, cr, uid, fields=[], context=None): |
498 | 247 | if context is None: | 458 | if context is None: |
499 | 248 | context = {} | 459 | context = {} |
502 | 249 | if 'default_type' in context: | 460 | #if 'default_type' in context: |
503 | 250 | del context['default_type'] | 461 | # del context['default_type'] |
504 | 251 | return super(res_partner_address, self).default_get(cr, uid, fields, context) | 462 | return super(res_partner_address, self).default_get(cr, uid, fields, context) |
505 | 252 | 463 | ||
506 | 253 | res_partner_address() | 464 | res_partner_address() |
507 | 254 | 465 | ||
508 | 466 | class res_partner(osv.osv): | ||
509 | 467 | _inherit = 'res.partner' | ||
510 | 468 | |||
511 | 469 | def _default_address_id(self, cr, uid, ids, prop, unknow_none, context=None): | ||
512 | 470 | |||
513 | 471 | res = dict.fromkeys(ids, False) | ||
514 | 472 | |||
515 | 473 | all_ids = self.pool.get('res.partner.address').search(cr, uid, [('partner_id','in',ids), ('type','=','default')]) | ||
516 | 474 | |||
517 | 475 | addresses = self.pool.get('res.partner.address').browse(cr, uid, all_ids) | ||
518 | 476 | for addr in addresses: | ||
519 | 477 | if(res[addr.partner_id.id] == False): | ||
520 | 478 | res[addr.partner_id.id] = addr.id | ||
521 | 479 | |||
522 | 480 | return res | ||
523 | 481 | |||
524 | 482 | |||
525 | 483 | _columns = {#default_address_id has to be stored to enable search of the related fields!!! Somehow trigger is not required! | ||
526 | 484 | 'default_address_id': fields.function(_default_address_id, type='many2one', obj='res.partner.address', string='address_id', store = True), | ||
527 | 485 | 'phone': fields.related('default_address_id', 'phone', type='char', string='Phone'), | ||
528 | 486 | 'fax': fields.related('default_address_id', 'fax', type='char', string='Fax', store = False), | ||
529 | 487 | 'email': fields.related('default_address_id', 'email', type='char', size=240, string='E-mail', store = False), | ||
530 | 488 | 'street': fields.related('default_address_id', 'street', type='char', string='Street', store = False), | ||
531 | 489 | 'city': fields.related('default_address_id', 'city', type='char', string='City', store = False), | ||
532 | 490 | 'country': fields.related('default_address_id','country_id', type='many2one', relation='res.country', string='Country'), | ||
533 | 491 | } | ||
534 | 492 | |||
535 | 493 | res_partner() | ||
536 | 494 | |||
537 | 495 | |||
538 | 255 | 496 | ||
539 | === modified file 'base_contact/base_contact_view.xml' | |||
540 | --- base_contact/base_contact_view.xml 2012-01-31 13:36:57 +0000 | |||
541 | +++ base_contact/base_contact_view.xml 2015-01-16 20:04:03 +0000 | |||
542 | @@ -1,6 +1,106 @@ | |||
543 | 1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
544 | 2 | <openerp> | 2 | <openerp> |
545 | 3 | <data> | 3 | <data> |
546 | 4 | |||
547 | 5 | <!-- Address views --> | ||
548 | 6 | |||
549 | 7 | <record id="view_partner_address_tree" model="ir.ui.view"> | ||
550 | 8 | <field name="name">res.partner.address.tree</field> | ||
551 | 9 | <field name="model">res.partner.address</field> | ||
552 | 10 | <field name="inherit_id" ref="base.view_partner_address_tree"/> | ||
553 | 11 | <field name="type">tree</field> | ||
554 | 12 | <field name="context">{"search_default_state": "current"}</field> | ||
555 | 13 | <field name="arch" type="xml"> | ||
556 | 14 | <tree string="Partner Addresses" position="replace"> | ||
557 | 15 | <tree string="Addresses" colors="gray:state in ('past')"> | ||
558 | 16 | <field name="name"/> | ||
559 | 17 | <field name="partner_id"/> | ||
560 | 18 | <field name="function"/> | ||
561 | 19 | <field name="email"/> | ||
562 | 20 | <field name="phone"/> | ||
563 | 21 | <field name="mobile"/> | ||
564 | 22 | <field name="other" /> | ||
565 | 23 | <field name="country_id"/> | ||
566 | 24 | <field name="type"/> | ||
567 | 25 | <field name="state" /> | ||
568 | 26 | </tree> | ||
569 | 27 | </tree> | ||
570 | 28 | </field> | ||
571 | 29 | </record> | ||
572 | 30 | |||
573 | 31 | <record id="view_res_partner_address_filter" model="ir.ui.view"> | ||
574 | 32 | <field name="name">res.partner.address.select</field> | ||
575 | 33 | <field name="model">res.partner.address</field> | ||
576 | 34 | <field name="inherit_id" ref="base.view_res_partner_address_filter"/> | ||
577 | 35 | <field name="type">search</field> | ||
578 | 36 | <field name="arch" type="xml"> | ||
579 | 37 | <search string="Search Contact" position="replace" > | ||
580 | 38 | <search string="Search Address"> | ||
581 | 39 | <group> | ||
582 | 40 | <field name="partner_id" string="Partner"/> | ||
583 | 41 | <field name="name" string="Contact (Lastname(s) Firstname(s))" /> | ||
584 | 42 | <field name="function"/> | ||
585 | 43 | <field name="street" /> | ||
586 | 44 | <field name="city" /> | ||
587 | 45 | <field name="country_id" /> | ||
588 | 46 | <field name="type" /> | ||
589 | 47 | <field name="state" /> | ||
590 | 48 | </group> | ||
591 | 49 | <newline/> | ||
592 | 50 | <group expand="0" string="Group By..."> | ||
593 | 51 | <filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by' : 'partner_id'}" /> | ||
594 | 52 | <filter string="Function" icon="terp-go-home" domain="[]" context="{'group_by' : 'function'}" /> | ||
595 | 53 | <filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}" /> | ||
596 | 54 | <filter string="State" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'state'}" /> | ||
597 | 55 | </group> | ||
598 | 56 | </search> | ||
599 | 57 | </search> | ||
600 | 58 | </field> | ||
601 | 59 | </record> | ||
602 | 60 | |||
603 | 61 | <!-- Address Tree view for Contact --> | ||
604 | 62 | <record id="view_partner_address_tree_contact" model="ir.ui.view"> | ||
605 | 63 | <field name="name">res.partner.address.tree.contact</field> | ||
606 | 64 | <field name="model">res.partner.address</field> | ||
607 | 65 | <field name="type">tree</field> | ||
608 | 66 | <field eval="17" name="priority"/> | ||
609 | 67 | <field name="arch" type="xml"> | ||
610 | 68 | <tree string="Functions and Addresses" colors="gray:state in ('past')"> | ||
611 | 69 | <field name="partner_id"/> | ||
612 | 70 | <field name="location_id"/> | ||
613 | 71 | <field name="function"/> | ||
614 | 72 | <field name="email" widget="email"/> | ||
615 | 73 | <field name="phone"/> | ||
616 | 74 | <field name="other" /> | ||
617 | 75 | <field name="fax"/> | ||
618 | 76 | <field name="type"/> | ||
619 | 77 | <field name="state" /> | ||
620 | 78 | <field name="sequence_contact" string="Seq."/> | ||
621 | 79 | </tree> | ||
622 | 80 | </field> | ||
623 | 81 | </record> | ||
624 | 82 | |||
625 | 83 | <!-- Adress Tree view for Partner --> | ||
626 | 84 | <record id="view_partner_address_tree_partner" model="ir.ui.view"> | ||
627 | 85 | <field name="name">res.partner.address.tree.partner</field> | ||
628 | 86 | <field name="model">res.partner.address</field> | ||
629 | 87 | <field name="type">tree</field> | ||
630 | 88 | <field eval="18" name="priority"/> | ||
631 | 89 | <field name="arch" type="xml"> | ||
632 | 90 | <tree string="Functions and Addresses" colors="gray:state in ('past')" > | ||
633 | 91 | <field name="name"/> | ||
634 | 92 | <field name="location_id"/> | ||
635 | 93 | <field name="function"/> | ||
636 | 94 | <field name="email" widget="email"/> | ||
637 | 95 | <field name="phone"/> | ||
638 | 96 | <field name="mobile"/> | ||
639 | 97 | <field name="other" /> | ||
640 | 98 | <field name="fax"/> | ||
641 | 99 | <field name="type"/> | ||
642 | 100 | <field name="state" /> | ||
643 | 101 | </tree> | ||
644 | 102 | </field> | ||
645 | 103 | </record> | ||
646 | 4 | 104 | ||
647 | 5 | <!-- Views for Contacts Tree View --> | 105 | <!-- Views for Contacts Tree View --> |
648 | 6 | 106 | ||
649 | @@ -9,8 +109,8 @@ | |||
650 | 9 | <field name="model">res.partner.contact</field> | 109 | <field name="model">res.partner.contact</field> |
651 | 10 | <field name="type">tree</field> | 110 | <field name="type">tree</field> |
652 | 11 | <field name="arch" type="xml"> | 111 | <field name="arch" type="xml"> |
655 | 12 | <tree string="Partner Contact"> | 112 | <tree string="Contact"> |
656 | 13 | <field name="name"/> | 113 | <field name="last_name"/> |
657 | 14 | <field name="first_name"/> | 114 | <field name="first_name"/> |
658 | 15 | <field name="mobile"/> | 115 | <field name="mobile"/> |
659 | 16 | <field name="email"/> | 116 | <field name="email"/> |
660 | @@ -28,7 +128,7 @@ | |||
661 | 28 | <field name="model">res.partner.contact</field> | 128 | <field name="model">res.partner.contact</field> |
662 | 29 | <field name="type">form</field> | 129 | <field name="type">form</field> |
663 | 30 | <field name="arch" type="xml"> | 130 | <field name="arch" type="xml"> |
665 | 31 | <form string="Partner Contact"> | 131 | <form string="Contact"> |
666 | 32 | <group colspan="4" col="6"> | 132 | <group colspan="4" col="6"> |
667 | 33 | <field name="last_name" select="1"/> | 133 | <field name="last_name" select="1"/> |
668 | 34 | <field name="first_name" select="1"/> | 134 | <field name="first_name" select="1"/> |
669 | @@ -48,22 +148,7 @@ | |||
670 | 48 | <field name="photo" widget='image' nolabel="1"/> | 148 | <field name="photo" widget='image' nolabel="1"/> |
671 | 49 | </group> | 149 | </group> |
672 | 50 | </group> | 150 | </group> |
689 | 51 | <field name="job_ids" colspan="4" nolabel="1" mode="tree,form"> | 151 | <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'}"> |
674 | 52 | <form string="Functions and Addresses"> | ||
675 | 53 | <field name="partner_id" /> | ||
676 | 54 | <field name="location_id" domain="[('partner_id', '=', partner_id)]"/> | ||
677 | 55 | <field name="function" /> | ||
678 | 56 | <separator string="Professional Info" colspan="4"/> | ||
679 | 57 | <field name="phone"/> | ||
680 | 58 | <field name="fax"/> | ||
681 | 59 | <field name="email" widget="email"/> | ||
682 | 60 | </form> | ||
683 | 61 | <tree string="Functions and Addresses"> | ||
684 | 62 | <field name="location_id"/> | ||
685 | 63 | <field name="function"/> | ||
686 | 64 | <field name="phone"/> | ||
687 | 65 | <field name="email"/> | ||
688 | 66 | </tree> | ||
690 | 67 | </field> | 152 | </field> |
691 | 68 | </page> | 153 | </page> |
692 | 69 | <page string="Extra Information"> | 154 | <page string="Extra Information"> |
693 | @@ -90,15 +175,15 @@ | |||
694 | 90 | <field name="model">res.partner.contact</field> | 175 | <field name="model">res.partner.contact</field> |
695 | 91 | <field name="type">search</field> | 176 | <field name="type">search</field> |
696 | 92 | <field name="arch" type="xml"> | 177 | <field name="arch" type="xml"> |
700 | 93 | <search string="Partner Contact"> | 178 | <search string="Contact"> |
701 | 94 | <field name="name" string="First/Lastname" | 179 | <field name="last_name" /> |
702 | 95 | filter_domain="['|', ('first_name','ilike', self), ('last_name', 'ilike', self)]"/> | 180 | <field name="first_name" /> |
703 | 96 | <field name="partner_id" string="Partner"/> | 181 | <field name="partner_id" string="Partner"/> |
704 | 97 | </search> | 182 | </search> |
705 | 98 | </field> | 183 | </field> |
706 | 99 | </record> | 184 | </record> |
707 | 100 | 185 | ||
709 | 101 | <!-- Views for Contacts Action --> | 186 | <!-- Views for Contacts Action and menu --> |
710 | 102 | 187 | ||
711 | 103 | <record model="ir.actions.act_window" id="action_partner_contact_form"> | 188 | <record model="ir.actions.act_window" id="action_partner_contact_form"> |
712 | 104 | <field name="name">Contacts</field> | 189 | <field name="name">Contacts</field> |
713 | @@ -110,11 +195,27 @@ | |||
714 | 110 | </record> | 195 | </record> |
715 | 111 | <menuitem name="Contacts" id="menu_partner_contact_form" action="action_partner_contact_form" parent = "base.menu_address_book" sequence="2"/> | 196 | <menuitem name="Contacts" id="menu_partner_contact_form" action="action_partner_contact_form" parent = "base.menu_address_book" sequence="2"/> |
716 | 112 | 197 | ||
720 | 113 | <!-- Rename menuitem for partner addresses --> | 198 | <!-- Views for Address Action and menu --> |
721 | 114 | <record model="ir.ui.menu" id="base.menu_partner_address_form"> | 199 | <record id="action_partner_address_form" model="ir.actions.act_window"> |
722 | 115 | <field name="name">Addresses</field> | 200 | <field name="name">Addresses</field> |
723 | 201 | <field name="type">ir.actions.act_window</field> | ||
724 | 202 | <field name="res_model">res.partner.address</field> | ||
725 | 203 | <field name="view_type">form</field> | ||
726 | 204 | <field name="view_mode">tree,form,kanban</field> | ||
727 | 205 | <field name="context"> {"search_default_state": "current"}</field> | ||
728 | 206 | <field name="search_view_id" ref="view_res_partner_address_filter"/> | ||
729 | 207 | <field name="help">Address helps you manage your contacts jobs wether they are private, main/switchboard or contacts.</field> | ||
730 | 116 | </record> | 208 | </record> |
732 | 117 | 209 | ||
733 | 210 | <!-- Replace menuitem with new action | ||
734 | 211 | delete action window as menu deletion did not work --> | ||
735 | 212 | <delete model="ir.actions.act_window" id="base.action_partner_address_form" /> | ||
736 | 213 | |||
737 | 214 | <menuitem action="action_partner_address_form" id="menu_partner_address_form" | ||
738 | 215 | name="Addresses" | ||
739 | 216 | parent="base.menu_address_book" sequence="30"/> | ||
740 | 217 | |||
741 | 218 | |||
742 | 118 | <!-- | 219 | <!-- |
743 | 119 | Contacts for Suppliers | 220 | Contacts for Suppliers |
744 | 120 | --> | 221 | --> |
745 | @@ -126,8 +227,13 @@ | |||
746 | 126 | parent="base.menu_procurement_management_supplier" action="base.action_partner_supplier_form" sequence="1"/> | 227 | parent="base.menu_procurement_management_supplier" action="base.action_partner_supplier_form" sequence="1"/> |
747 | 127 | <menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form" | 228 | <menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form" |
748 | 128 | parent = "base.menu_procurement_management_supplier" sequence="2"/> | 229 | parent = "base.menu_procurement_management_supplier" sequence="2"/> |
749 | 230 | |||
750 | 231 | <menuitem action="action_partner_address_form" id="menu_purchase_partner_address_form" | ||
751 | 232 | name="Addresses" | ||
752 | 233 | parent="base.menu_procurement_management_supplier" sequence="30"/> | ||
753 | 234 | |||
754 | 129 | 235 | ||
756 | 130 | <!-- Views for Partners Form View --> | 236 | <!-- Views for Partner --> |
757 | 131 | 237 | ||
758 | 132 | <record model="ir.ui.view" id="view_partner_form_inherit"> | 238 | <record model="ir.ui.view" id="view_partner_form_inherit"> |
759 | 133 | <field name="name">Partner form inherited</field> | 239 | <field name="name">Partner form inherited</field> |
760 | @@ -135,17 +241,50 @@ | |||
761 | 135 | <field name="inherit_id" ref="base.view_partner_form"/> | 241 | <field name="inherit_id" ref="base.view_partner_form"/> |
762 | 136 | <field name="type">form</field> | 242 | <field name="type">form</field> |
763 | 137 | <field name="arch" type="xml"> | 243 | <field name="arch" type="xml"> |
771 | 138 | <separator string="Postal Address" position="after"> | 244 | <field name="address" position="replace" > |
772 | 139 | <field name="location_id" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', parent.id)]"/> | 245 | <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'}"> |
773 | 140 | </separator> | 246 | </field> |
774 | 141 | <xpath expr="//field[@string='Contact Name']" position="replace"> | 247 | </field> |
775 | 142 | <field name="contact_id"/> | 248 | |
769 | 143 | </xpath> | ||
770 | 144 | <field name="title" position="replace"/> | ||
776 | 145 | </field> | 249 | </field> |
777 | 146 | </record> | 250 | </record> |
780 | 147 | 251 | ||
781 | 148 | <!-- Views for Addresses --> | 252 | <record id="view_partner_tree" model="ir.ui.view"> |
782 | 253 | <field name="name">res.partner.tree</field> | ||
783 | 254 | <field name="model">res.partner</field> | ||
784 | 255 | <field name="inherit_id" ref="base.view_partner_tree"/> | ||
785 | 256 | <field name="type">tree</field> | ||
786 | 257 | <field name="arch" type="xml"> | ||
787 | 258 | |||
788 | 259 | <field name="phone" position="after" > | ||
789 | 260 | <field name="fax"/> | ||
790 | 261 | </field> | ||
791 | 262 | |||
792 | 263 | <field name="city" position="before" > | ||
793 | 264 | <field name="street"/> | ||
794 | 265 | </field> | ||
795 | 266 | |||
796 | 267 | </field> | ||
797 | 268 | </record> | ||
798 | 269 | |||
799 | 270 | <record id="view_res_partner_filter" model="ir.ui.view"> | ||
800 | 271 | <field name="name">res.partner.select</field> | ||
801 | 272 | <field name="model">res.partner</field> | ||
802 | 273 | <field name="inherit_id" ref="base.view_res_partner_filter"/> | ||
803 | 274 | <field name="type">search</field> | ||
804 | 275 | <field name="arch" type="xml"> | ||
805 | 276 | |||
806 | 277 | |||
807 | 278 | <field name="country" position="before"> | ||
808 | 279 | <field name="street" select="1"/> | ||
809 | 280 | <field name="city" select="1"/> | ||
810 | 281 | </field> | ||
811 | 282 | |||
812 | 283 | </field> | ||
813 | 284 | </record> | ||
814 | 285 | |||
815 | 286 | |||
816 | 287 | <!-- Views for Location --> | ||
817 | 149 | 288 | ||
818 | 150 | <record model="ir.ui.view" id="view_partner_location_form"> | 289 | <record model="ir.ui.view" id="view_partner_location_form"> |
819 | 151 | <field name="name">res.partner.location.form</field> | 290 | <field name="name">res.partner.location.form</field> |
820 | @@ -153,12 +292,24 @@ | |||
821 | 153 | <field name="type">form</field> | 292 | <field name="type">form</field> |
822 | 154 | <field name="arch" type="xml"> | 293 | <field name="arch" type="xml"> |
823 | 155 | <form string="Locations"> | 294 | <form string="Locations"> |
824 | 295 | <field name="partner_id" readonly="1" /> | ||
825 | 156 | <field name="street" colspan="4"/> | 296 | <field name="street" colspan="4"/> |
826 | 157 | <field name="street2" colspan="4"/> | 297 | <field name="street2" colspan="4"/> |
827 | 158 | <field name="zip"/> | 298 | <field name="zip"/> |
828 | 159 | <field name="city"/> | 299 | <field name="city"/> |
829 | 160 | <field name="country_id" /> | 300 | <field name="country_id" /> |
830 | 161 | <field name="state_id"/> | 301 | <field name="state_id"/> |
831 | 302 | <newline /> | ||
832 | 303 | <separator string="Addresses" colspan="4" /> | ||
833 | 304 | <field name="job_ids" nolabel="1" colspan="4" readonly="1" mode="tree"> | ||
834 | 305 | <tree string="Address"> | ||
835 | 306 | <field name = "contact_id" /> | ||
836 | 307 | <field name = "partner_id" /> | ||
837 | 308 | <field name = "function" /> | ||
838 | 309 | <field name = "type" /> | ||
839 | 310 | <field name = "state" /> | ||
840 | 311 | </tree> | ||
841 | 312 | </field> | ||
842 | 162 | </form> | 313 | </form> |
843 | 163 | </field> | 314 | </field> |
844 | 164 | </record> | 315 | </record> |
845 | @@ -170,6 +321,9 @@ | |||
846 | 170 | <field name="type">tree</field> | 321 | <field name="type">tree</field> |
847 | 171 | <field name="arch" type="xml"> | 322 | <field name="arch" type="xml"> |
848 | 172 | <tree string="Locations"> | 323 | <tree string="Locations"> |
849 | 324 | <field name="partner_id" string="Partner" /> | ||
850 | 325 | <field name="contact_id" /> | ||
851 | 326 | <field name="street" /> | ||
852 | 173 | <field name="city"/> | 327 | <field name="city"/> |
853 | 174 | <field name="country_id" /> | 328 | <field name="country_id" /> |
854 | 175 | <field name="state_id"/> | 329 | <field name="state_id"/> |
855 | @@ -177,19 +331,77 @@ | |||
856 | 177 | </field> | 331 | </field> |
857 | 178 | </record> | 332 | </record> |
858 | 179 | 333 | ||
859 | 334 | <record model="ir.ui.view" id="view_partner_location_search"> | ||
860 | 335 | <field name="name">res.partner.location.search</field> | ||
861 | 336 | <field name="model">res.partner.location</field> | ||
862 | 337 | <field name="type">search</field> | ||
863 | 338 | <field name="arch" type="xml"> | ||
864 | 339 | <search string="Partner Location"> | ||
865 | 340 | <field name="partner_id" string="Partner"/> | ||
866 | 341 | <field name="job_ids" /> | ||
867 | 342 | <field name="street" /> | ||
868 | 343 | <field name="city" /> | ||
869 | 344 | <field name="country_id" /> | ||
870 | 345 | </search> | ||
871 | 346 | </field> | ||
872 | 347 | </record> | ||
873 | 348 | |||
874 | 349 | |||
875 | 350 | <record model="ir.actions.act_window" id="action_partner_location_form"> | ||
876 | 351 | <field name="name">Locations</field> | ||
877 | 352 | <field name="res_model">res.partner.location</field> | ||
878 | 353 | <field name="view_type">form</field> | ||
879 | 354 | <field name="view_mode">tree,form</field> | ||
880 | 355 | <field name="view_id" ref="view_partner_location_tree"/> | ||
881 | 356 | <field name="search_view_id" ref="view_partner_location_search"/> | ||
882 | 357 | </record> | ||
883 | 358 | <!-- sequence=30 is because 11 is not enough for beeing below addresses to be checked further --> | ||
884 | 359 | <menuitem name="Locations" id="menu_partner_location_form" action="action_partner_location_form" | ||
885 | 360 | parent = "base.menu_address_book" groups="base.group_extended" sequence="40"/> | ||
886 | 361 | <menuitem name="Locations" id="menu_purchase_partner_location_form" action="action_partner_location_form" | ||
887 | 362 | parent = "base.menu_procurement_management_supplier" groups="base.group_extended" sequence="40"/> | ||
888 | 363 | |||
889 | 364 | |||
890 | 365 | <!-- Update default address view --> | ||
891 | 366 | |||
892 | 180 | <record model="ir.ui.view" id="view_partner_address_form_inherited0"> | 367 | <record model="ir.ui.view" id="view_partner_address_form_inherited0"> |
893 | 181 | <field name='name'>res.partner.address.form.inherited0</field> | 368 | <field name='name'>res.partner.address.form.inherited0</field> |
894 | 182 | <field name='model'>res.partner.address</field> | 369 | <field name='model'>res.partner.address</field> |
895 | 183 | <field name="inherit_id" ref="base.view_partner_address_form1"/> | 370 | <field name="inherit_id" ref="base.view_partner_address_form1"/> |
896 | 184 | <field name='type'>form</field> | 371 | <field name='type'>form</field> |
897 | 185 | <field name='arch' type='xml'> | 372 | <field name='arch' type='xml'> |
898 | 373 | |||
899 | 374 | <field name="partner_id" position="replace"> | ||
900 | 375 | <field name="partner_id" colspan="2" on_change="onchange_partner_id(partner_id)" attrs="{'required':[('contact_id','=', False)]}"/> | ||
901 | 376 | </field> | ||
902 | 377 | |||
903 | 186 | <field name="name" position="replace"> | 378 | <field name="name" position="replace"> |
906 | 187 | <field name="contact_id"/> | 379 | <field name="contact_id" on_change="onchange_contact_id(contact_id)" attrs="{'required':[('partner_id','=', False)]}"/> |
907 | 188 | </field> | 380 | <!-- <field name="name" string="use this field for initial name only" /> would require adaption of create--> |
908 | 381 | </field> | ||
909 | 382 | |||
910 | 383 | <field name="type" position="replace"> | ||
911 | 384 | <field name="type" required="1"/> | ||
912 | 385 | </field> | ||
913 | 386 | <field name="mobile" position="after"> | ||
914 | 387 | <field name="other" /> | ||
915 | 388 | |||
916 | 389 | </field> | ||
917 | 189 | <separator string="Postal Address" position="after"> | 390 | <separator string="Postal Address" position="after"> |
919 | 190 | <field name="location_id" on_change="onchange_location_id(location_id)"/> | 391 | <field name="location_id" required="1" |
920 | 392 | on_change="onchange_location_id(location_id)" | ||
921 | 393 | domain="[('partner_id', '=', partner_id)]" | ||
922 | 394 | context="{'default_partner_id': partner_id}"/> | ||
923 | 191 | </separator> | 395 | </separator> |
924 | 192 | <field name="title" position="replace"/> | 396 | <field name="title" position="replace"/> |
925 | 397 | <field name="function" position="after"> | ||
926 | 398 | <separator string="Status" colspan="6"/> | ||
927 | 399 | <field name="state" /> | ||
928 | 400 | <field name="date_start" /> | ||
929 | 401 | <field name="date_stop" /> | ||
930 | 402 | <separator string="Sequence" colspan="6" col="2"/> | ||
931 | 403 | <field name="sequence_contact" string="Contact Seq."/> | ||
932 | 404 | </field> | ||
933 | 193 | </field> | 405 | </field> |
934 | 194 | </record> | 406 | </record> |
935 | 195 | 407 | ||
936 | 196 | 408 | ||
937 | === modified file 'base_contact/security/ir.model.access.csv' | |||
938 | --- base_contact/security/ir.model.access.csv 2012-01-31 13:36:57 +0000 | |||
939 | +++ base_contact/security/ir.model.access.csv 2015-01-16 20:04:03 +0000 | |||
940 | @@ -1,7 +1,8 @@ | |||
941 | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
942 | 2 | "access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1 | 2 | "access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1 |
943 | 3 | "access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0 | 3 | "access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0 |
945 | 4 | "access_res_partner_location","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0 | 4 | "access_res_partner_location_manager","res.partner.location","model_res_partner_location","base.group_partner_manager",1,1,1,1 |
946 | 5 | "access_res_partner_location_all","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0 | ||
947 | 5 | "access_res_partner_location_sale_salesman","res.partner.location","model_res_partner_location","base.group_sale_salesman",1,1,1,0 | 6 | "access_res_partner_location_sale_salesman","res.partner.location","model_res_partner_location","base.group_sale_salesman",1,1,1,0 |
948 | 6 | "access_res_partner_address_sale_salesman","res.partner.address.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0 | 7 | "access_res_partner_address_sale_salesman","res.partner.address.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0 |
949 | 7 | "access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0 | 8 | "access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0 |
950 | 8 | 9 | ||
951 | === modified file 'base_report_designer/plugin/openerp_report_designer/bin/OOo_run.sh' (properties changed: +x to -x) | |||
952 | === modified file 'document/odt2txt.py' (properties changed: +x to -x) | |||
953 | === modified file 'document/test_cindex.py' (properties changed: +x to -x) | |||
954 | === modified file 'document_ftp/ftpserver/ftpserver.py' (properties changed: +x to -x) | |||
955 | === modified file 'document_webdav/test_davclient.py' (properties changed: +x to -x) | |||
956 | === modified file 'email_template/html2text.py' (properties changed: +x to -x) | |||
957 | === modified file 'l10n_ch/report/ocrbb.ttf' (properties changed: +x to -x) | |||
958 | === modified file 'l10n_ch/test/test.v11' (properties changed: +x to -x) | |||
959 | === modified file 'l10n_ch/test/test_part_1.v11' (properties changed: +x to -x) | |||
960 | === modified file 'l10n_ch/test/test_part_2.v11' (properties changed: +x to -x) | |||
961 | === modified file 'mail/static/scripts/openerp_mailgate.py' (properties changed: +x to -x) | |||
962 | === modified file 'plugin_thunderbird/static/thunderbird_plugin/install.sh' (properties changed: +x to -x) | |||
963 | === modified file 'purchase/purchase.py' (properties changed: +x to -x) | |||
964 | === modified file 'purchase/wizard/purchase_line_invoice.py' (properties changed: +x to -x) | |||
965 | === modified file 'purchase_double_validation/test/purchase_double_validation_test.yml' (properties changed: +x to -x) | |||
966 | === modified file 'purchase_requisition/test/purchase_requisition_demo.yml' (properties changed: +x to -x) | |||
967 | === modified file 'wiki/static/src/lib/wiky/Readme.md' (properties changed: +x to -x) | |||
968 | === modified file 'wiki/static/src/lib/wiky/autogit.sh' (properties changed: +x to -x) | |||
969 | === modified file 'wiki/static/src/lib/wiky/index.html' (properties changed: +x to -x) | |||
970 | === modified file 'wiki/static/src/lib/wiky/input_complete' (properties changed: +x to -x) | |||
971 | === modified file 'wiki/static/src/lib/wiky/jquery-1.4.2.min.js' (properties changed: +x to -x) | |||
972 | === modified file 'wiki/static/src/lib/wiky/wiky.css' (properties changed: +x to -x) | |||
973 | === modified file 'wiki/static/src/lib/wiky/wiky.js' (properties changed: +x to -x) |
Hi, Etienne, thank you for making again the MP properly. I will check it, but it's a huge diff for only a bugfix. I'm not sure if this is going to fit into OCB project and goals.
Let's see what others reviewers say.
Regards.