Merge lp:~openerp-dev/openobject-addons/trunk-common-action-controller-jas into lp:openobject-addons
- trunk-common-action-controller-jas
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-common-action-controller-jas |
Merge into: | lp:openobject-addons |
Diff against target: |
443 lines (+224/-4) 13 files modified
account/account_invoice.py (+15/-0) analytic/analytic.py (+21/-0) crm/crm_lead.py (+18/-0) event/event.py (+14/-0) fleet/fleet.py (+15/-0) fleet/fleet_view.xml (+4/-0) hr_holidays/hr_holidays.py (+14/-0) hr_recruitment/hr_recruitment.py (+24/-0) mail/controllers/main.py (+15/-0) mail/mail_thread.py (+50/-4) mail/views/mail_actions_button.html (+6/-0) project/project.py (+10/-0) project_issue/project_issue.py (+18/-0) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-common-action-controller-jas |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenERP Core Team | Pending | ||
Review via email: mp+219454@code.launchpad.net |
Commit message
Description of the change
- 9452. By Jamin Shah(OpenERP)
-
[IMP]: Optimization
- 9453. By Jamin Shah(OpenERP)
-
[IMP]: change in _mail_action condition and optimization
- 9454. By Jamin Shah(OpenERP)
-
[IMP]: add action_xml_id in _mail_object
- 9455. By Jamin Shah(OpenERP)
-
[MERGE]: with Trunk
- 9456. By Jamin Shah(OpenERP)
-
[IMP]: changes in write() for sending template
- 9457. By Jamin Shah(OpenERP)
-
[IMP]: add _mail_actions in hr_applicant and safe coding in mail write method for calling message_post
- 9458. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9459. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9460. By Jamin Shah(OpenERP)
-
[MERGE]: with trunk
- 9461. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9462. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
Unmerged revisions
- 9462. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9461. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9460. By Jamin Shah(OpenERP)
-
[MERGE]: with trunk
- 9459. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9458. By Jamin Shah(OpenERP)
-
[IMP]: Code Optimization
- 9457. By Jamin Shah(OpenERP)
-
[IMP]: add _mail_actions in hr_applicant and safe coding in mail write method for calling message_post
- 9456. By Jamin Shah(OpenERP)
-
[IMP]: changes in write() for sending template
- 9455. By Jamin Shah(OpenERP)
-
[MERGE]: with Trunk
- 9454. By Jamin Shah(OpenERP)
-
[IMP]: add action_xml_id in _mail_object
- 9453. By Jamin Shah(OpenERP)
-
[IMP]: change in _mail_action condition and optimization
Preview Diff
1 | === modified file 'account/account_invoice.py' | |||
2 | --- account/account_invoice.py 2014-05-07 17:01:12 +0000 | |||
3 | +++ account/account_invoice.py 2014-05-20 08:59:26 +0000 | |||
4 | @@ -225,6 +225,21 @@ | |||
5 | 225 | 'account.mt_invoice_validated': lambda self, cr, uid, obj, ctx=None: obj.state == 'open' and obj.type in ('out_invoice', 'out_refund'), | 225 | 'account.mt_invoice_validated': lambda self, cr, uid, obj, ctx=None: obj.state == 'open' and obj.type in ('out_invoice', 'out_refund'), |
6 | 226 | }, | 226 | }, |
7 | 227 | } | 227 | } |
8 | 228 | _mail_actions = [{ | ||
9 | 229 | 'name': 'invoice_validate', | ||
10 | 230 | 'type': 'object', | ||
11 | 231 | 'string': 'Validate', | ||
12 | 232 | 'condition': lambda self, obj, context=None: obj.state == 'draft', | ||
13 | 233 | 'button_type': 'success' | ||
14 | 234 | }, | ||
15 | 235 | { | ||
16 | 236 | 'name': 'action_cancel', | ||
17 | 237 | 'type': 'object', | ||
18 | 238 | 'string': 'Cancel', | ||
19 | 239 | 'condition': lambda self, obj, context=None: obj.state == 'draft', | ||
20 | 240 | 'button_type': 'warning' | ||
21 | 241 | }] | ||
22 | 242 | |||
23 | 228 | _columns = { | 243 | _columns = { |
24 | 229 | 'name': fields.char('Reference/Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}), | 244 | 'name': fields.char('Reference/Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}), |
25 | 230 | 'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}), | 245 | 'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}), |
26 | 231 | 246 | ||
27 | === modified file 'analytic/analytic.py' | |||
28 | --- analytic/analytic.py 2014-04-01 12:36:57 +0000 | |||
29 | +++ analytic/analytic.py 2014-05-20 08:59:26 +0000 | |||
30 | @@ -38,6 +38,27 @@ | |||
31 | 38 | 'analytic.mt_account_opened': lambda self, cr, uid, obj, ctx=None: obj.state == 'open', | 38 | 'analytic.mt_account_opened': lambda self, cr, uid, obj, ctx=None: obj.state == 'open', |
32 | 39 | }, | 39 | }, |
33 | 40 | } | 40 | } |
34 | 41 | _mail_actions = [{ | ||
35 | 42 | 'name': 'set_pending', | ||
36 | 43 | 'type': 'object', | ||
37 | 44 | 'string': 'Renew', | ||
38 | 45 | 'condition': lambda self, obj, context=None: obj.state == 'open', | ||
39 | 46 | 'button_type': 'success' | ||
40 | 47 | }, | ||
41 | 48 | { | ||
42 | 49 | 'name': 'set_close', | ||
43 | 50 | 'type': 'object', | ||
44 | 51 | 'string': 'Close', | ||
45 | 52 | 'condition': lambda self, obj, context=None: obj.state == 'open' or obj.state == 'pending', | ||
46 | 53 | 'button_type': 'warning' | ||
47 | 54 | }, | ||
48 | 55 | { | ||
49 | 56 | 'name': 'set_cancel', | ||
50 | 57 | 'type': 'object', | ||
51 | 58 | 'string': 'Cancel', | ||
52 | 59 | 'condition': lambda self, obj, context=None: obj.state == 'open' or obj.state == 'pending', | ||
53 | 60 | 'button_type': 'warning' | ||
54 | 61 | }] | ||
55 | 41 | 62 | ||
56 | 42 | def _compute_level_tree(self, cr, uid, ids, child_ids, res, field_names, context=None): | 63 | def _compute_level_tree(self, cr, uid, ids, child_ids, res, field_names, context=None): |
57 | 43 | currency_obj = self.pool.get('res.currency') | 64 | currency_obj = self.pool.get('res.currency') |
58 | 44 | 65 | ||
59 | === modified file 'crm/crm_lead.py' | |||
60 | --- crm/crm_lead.py 2014-05-12 11:41:49 +0000 | |||
61 | +++ crm/crm_lead.py 2014-05-20 08:59:26 +0000 | |||
62 | @@ -79,6 +79,21 @@ | |||
63 | 79 | 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.fold and obj.stage_id.sequence > 1, | 79 | 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.fold and obj.stage_id.sequence > 1, |
64 | 80 | }, | 80 | }, |
65 | 81 | } | 81 | } |
66 | 82 | _mail_actions = [{ | ||
67 | 83 | 'name': 'set_user', | ||
68 | 84 | 'type': 'object', | ||
69 | 85 | 'string': 'I will manage it', | ||
70 | 86 | 'condition': lambda self, obj, context=None: not obj.user_id, | ||
71 | 87 | 'button_type': 'success' | ||
72 | 88 | }, | ||
73 | 89 | { | ||
74 | 90 | 'type': 'action', | ||
75 | 91 | 'string': 'Not interested', | ||
76 | 92 | 'condition': lambda self, obj, context=None: not obj.user_id, | ||
77 | 93 | 'button_type': 'warning', | ||
78 | 94 | 'action_xml_id': 'crm_case_category_act_oppor11', | ||
79 | 95 | 'module': 'crm' | ||
80 | 96 | }] | ||
81 | 82 | _mail_mass_mailing = _('Leads / Opportunities') | 97 | _mail_mass_mailing = _('Leads / Opportunities') |
82 | 83 | 98 | ||
83 | 84 | def get_empty_list_help(self, cr, uid, help, context=None): | 99 | def get_empty_list_help(self, cr, uid, help, context=None): |
84 | @@ -317,6 +332,9 @@ | |||
85 | 317 | ('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!') | 332 | ('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!') |
86 | 318 | ] | 333 | ] |
87 | 319 | 334 | ||
88 | 335 | def set_user(self, cr, uid, ids, context=None): | ||
89 | 336 | self.pool['crm.lead'].write(cr, uid, ids, {'user_id':uid}) | ||
90 | 337 | |||
91 | 320 | def onchange_stage_id(self, cr, uid, ids, stage_id, context=None): | 338 | def onchange_stage_id(self, cr, uid, ids, stage_id, context=None): |
92 | 321 | if not stage_id: | 339 | if not stage_id: |
93 | 322 | return {'value': {}} | 340 | return {'value': {}} |
94 | 323 | 341 | ||
95 | === modified file 'event/event.py' | |||
96 | --- event/event.py 2014-05-12 07:23:31 +0000 | |||
97 | +++ event/event.py 2014-05-20 08:59:26 +0000 | |||
98 | @@ -327,6 +327,20 @@ | |||
99 | 327 | } | 327 | } |
100 | 328 | _order = 'name, create_date desc' | 328 | _order = 'name, create_date desc' |
101 | 329 | 329 | ||
102 | 330 | _mail_actions = [{ | ||
103 | 331 | 'name': 'registration_open', | ||
104 | 332 | 'type': 'object', | ||
105 | 333 | 'string': 'Confirm', | ||
106 | 334 | 'condition': lambda self, obj, context=None: obj.state == 'draft', | ||
107 | 335 | 'button_type': 'success' | ||
108 | 336 | }, | ||
109 | 337 | { | ||
110 | 338 | 'name': 'button_reg_cancel', | ||
111 | 339 | 'type': 'object', | ||
112 | 340 | 'string': 'Cancel', | ||
113 | 341 | 'condition': lambda self, obj, context=None: obj.state == 'draft' or obj.state == 'open', | ||
114 | 342 | 'button_type': 'warning' | ||
115 | 343 | }] | ||
116 | 330 | 344 | ||
117 | 331 | def _check_seats_limit(self, cr, uid, ids, context=None): | 345 | def _check_seats_limit(self, cr, uid, ids, context=None): |
118 | 332 | for registration in self.browse(cr, uid, ids, context=context): | 346 | for registration in self.browse(cr, uid, ids, context=context): |
119 | 333 | 347 | ||
120 | === modified file 'fleet/fleet.py' | |||
121 | --- fleet/fleet.py 2014-05-07 07:56:45 +0000 | |||
122 | +++ fleet/fleet.py 2014-05-20 08:59:26 +0000 | |||
123 | @@ -792,10 +792,25 @@ | |||
124 | 792 | res[contract.id] = totalsum | 792 | res[contract.id] = totalsum |
125 | 793 | return res | 793 | return res |
126 | 794 | 794 | ||
127 | 795 | _inherit = ['mail.thread'] | ||
128 | 795 | _inherits = {'fleet.vehicle.cost': 'cost_id'} | 796 | _inherits = {'fleet.vehicle.cost': 'cost_id'} |
129 | 796 | _name = 'fleet.vehicle.log.contract' | 797 | _name = 'fleet.vehicle.log.contract' |
130 | 797 | _description = 'Contract information on a vehicle' | 798 | _description = 'Contract information on a vehicle' |
131 | 798 | _order='state desc,expiration_date' | 799 | _order='state desc,expiration_date' |
132 | 800 | _mail_actions = [{ | ||
133 | 801 | 'name': 'act_renew_contract', | ||
134 | 802 | 'type': 'object', | ||
135 | 803 | 'string': 'Renew', | ||
136 | 804 | 'condition': lambda self, obj, context=None: obj.state == 'open' or obj.state == 'closed', | ||
137 | 805 | 'button_type': 'success' | ||
138 | 806 | }, | ||
139 | 807 | { | ||
140 | 808 | 'name': 'contract_close', | ||
141 | 809 | 'type': 'object', | ||
142 | 810 | 'string': 'Terminate', | ||
143 | 811 | 'condition': lambda self, obj, context=None: obj.state == 'open', | ||
144 | 812 | 'button_type': 'warning' | ||
145 | 813 | }] | ||
146 | 799 | _columns = { | 814 | _columns = { |
147 | 800 | 'name': fields.function(_vehicle_contract_name_get_fnc, type="text", string='Name', store=True), | 815 | 'name': fields.function(_vehicle_contract_name_get_fnc, type="text", string='Name', store=True), |
148 | 801 | 'start_date': fields.date('Contract Start Date', help='Date when the coverage of the contract begins'), | 816 | 'start_date': fields.date('Contract Start Date', help='Date when the coverage of the contract begins'), |
149 | 802 | 817 | ||
150 | === modified file 'fleet/fleet_view.xml' | |||
151 | --- fleet/fleet_view.xml 2014-03-28 13:30:51 +0000 | |||
152 | +++ fleet/fleet_view.xml 2014-05-20 08:59:26 +0000 | |||
153 | @@ -502,6 +502,10 @@ | |||
154 | 502 | <field name="notes" nolabel="1" placeholder="Write here all other information relative to this contract" /> | 502 | <field name="notes" nolabel="1" placeholder="Write here all other information relative to this contract" /> |
155 | 503 | </group> | 503 | </group> |
156 | 504 | </sheet> | 504 | </sheet> |
157 | 505 | <div class="oe_chatter"> | ||
158 | 506 | <field name="message_follower_ids" widget="mail_followers"/> | ||
159 | 507 | <field name="message_ids" widget="mail_thread"/> | ||
160 | 508 | </div> | ||
161 | 505 | </form> | 509 | </form> |
162 | 506 | </field> | 510 | </field> |
163 | 507 | </record> | 511 | </record> |
164 | 508 | 512 | ||
165 | === modified file 'hr_holidays/hr_holidays.py' | |||
166 | --- hr_holidays/hr_holidays.py 2014-05-07 08:35:56 +0000 | |||
167 | +++ hr_holidays/hr_holidays.py 2014-05-20 08:59:26 +0000 | |||
168 | @@ -111,6 +111,20 @@ | |||
169 | 111 | 'hr_holidays.mt_holidays_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state == 'confirm', | 111 | 'hr_holidays.mt_holidays_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state == 'confirm', |
170 | 112 | }, | 112 | }, |
171 | 113 | } | 113 | } |
172 | 114 | _mail_actions = [{ | ||
173 | 115 | 'name': 'holidays_validate', | ||
174 | 116 | 'type': 'object', | ||
175 | 117 | 'string': 'Approve', | ||
176 | 118 | 'condition': lambda self, obj, context=None: obj.state == 'confirm', | ||
177 | 119 | 'button_type': 'success' | ||
178 | 120 | }, | ||
179 | 121 | { | ||
180 | 122 | 'name': 'holidays_refuse', | ||
181 | 123 | 'type': 'object', | ||
182 | 124 | 'string': 'Refuse', | ||
183 | 125 | 'condition': lambda self, obj, context=None: obj.state == 'confirm' or obj.state == 'validate', | ||
184 | 126 | 'button_type': 'warning' | ||
185 | 127 | }] | ||
186 | 114 | 128 | ||
187 | 115 | def _employee_get(self, cr, uid, context=None): | 129 | def _employee_get(self, cr, uid, context=None): |
188 | 116 | emp_id = context.get('default_employee_id', False) | 130 | emp_id = context.get('default_employee_id', False) |
189 | 117 | 131 | ||
190 | === modified file 'hr_recruitment/hr_recruitment.py' | |||
191 | --- hr_recruitment/hr_recruitment.py 2014-05-08 12:35:29 +0000 | |||
192 | +++ hr_recruitment/hr_recruitment.py 2014-05-20 08:59:26 +0000 | |||
193 | @@ -87,6 +87,20 @@ | |||
194 | 87 | 'hr_recruitment.mt_applicant_stage_changed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence > 1, | 87 | 'hr_recruitment.mt_applicant_stage_changed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence > 1, |
195 | 88 | }, | 88 | }, |
196 | 89 | } | 89 | } |
197 | 90 | _mail_actions = [{ | ||
198 | 91 | 'name': 'applicant_first_interview', | ||
199 | 92 | 'type': 'object', | ||
200 | 93 | 'string': 'Approve', | ||
201 | 94 | 'condition': lambda self, obj, context=None: obj.stage_id.name == 'Initial Qualification', | ||
202 | 95 | 'button_type': 'success' | ||
203 | 96 | }, | ||
204 | 97 | { | ||
205 | 98 | 'name': 'applicant_refused', | ||
206 | 99 | 'type': 'object', | ||
207 | 100 | 'string': 'Refuse', | ||
208 | 101 | 'condition': lambda self, obj, context=None: obj.stage_id.name == 'Initial Qualification', | ||
209 | 102 | 'button_type': 'warning' | ||
210 | 103 | }] | ||
211 | 90 | _mail_mass_mailing = _('Applicants') | 104 | _mail_mass_mailing = _('Applicants') |
212 | 91 | 105 | ||
213 | 92 | def _get_default_department_id(self, cr, uid, context=None): | 106 | def _get_default_department_id(self, cr, uid, context=None): |
214 | @@ -240,6 +254,16 @@ | |||
215 | 240 | 'stage_id': _read_group_stage_ids | 254 | 'stage_id': _read_group_stage_ids |
216 | 241 | } | 255 | } |
217 | 242 | 256 | ||
218 | 257 | def applicant_first_interview(self, cr, uid, ids, context=None): | ||
219 | 258 | stage_id = self.pool['hr.recruitment.stage'].search(cr, uid, [('name','=','First Interview')], context=context) | ||
220 | 259 | if stage_id: | ||
221 | 260 | self.pool['hr.applicant'].write(cr, uid, ids, {'stage_id':stage_id[0]}, context=context) | ||
222 | 261 | |||
223 | 262 | def applicant_refused(self, cr, uid, ids, context=None): | ||
224 | 263 | stage_id = self.pool['hr.recruitment.stage'].search(cr, uid, [('name','=','Refused')], context=context) | ||
225 | 264 | if stage_id: | ||
226 | 265 | self.pool['hr.applicant'].write(cr, uid, ids, {'stage_id':stage_id[0]}, context=context) | ||
227 | 266 | |||
228 | 243 | def onchange_job(self, cr, uid, ids, job_id=False, context=None): | 267 | def onchange_job(self, cr, uid, ids, job_id=False, context=None): |
229 | 244 | department_id = False | 268 | department_id = False |
230 | 245 | if job_id: | 269 | if job_id: |
231 | 246 | 270 | ||
232 | === modified file 'mail/controllers/main.py' | |||
233 | --- mail/controllers/main.py 2014-04-30 11:00:48 +0000 | |||
234 | +++ mail/controllers/main.py 2014-05-20 08:59:26 +0000 | |||
235 | @@ -1,5 +1,6 @@ | |||
236 | 1 | import base64 | 1 | import base64 |
237 | 2 | import psycopg2 | 2 | import psycopg2 |
238 | 3 | import werkzeug | ||
239 | 3 | 4 | ||
240 | 4 | import openerp | 5 | import openerp |
241 | 5 | from openerp import SUPERUSER_ID | 6 | from openerp import SUPERUSER_ID |
242 | @@ -42,3 +43,17 @@ | |||
243 | 42 | except psycopg2.Error: | 43 | except psycopg2.Error: |
244 | 43 | pass | 44 | pass |
245 | 44 | return True | 45 | return True |
246 | 46 | |||
247 | 47 | @http.route('/mail_action/<model>/<int:id>', type='http', auth='user') | ||
248 | 48 | def mail_action(self, model, id, action_name=None, action_type=None, action_id=None): | ||
249 | 49 | if not request.session.uid: | ||
250 | 50 | return login_redirect() | ||
251 | 51 | redirect_url = "/web?db=%s#id=%s&model=%s" %(request.db, id, model) | ||
252 | 52 | object_pool = request.registry.get(model) | ||
253 | 53 | if action_type in ['workflow','object']: | ||
254 | 54 | action = getattr(object_pool,action_name) | ||
255 | 55 | action(request.cr, request.uid, [id], context=request.context) | ||
256 | 56 | redirect_url += "&view_type=form" | ||
257 | 57 | if action_type == 'action': | ||
258 | 58 | redirect_url += "&action=%s" % action_id | ||
259 | 59 | return werkzeug.utils.redirect(redirect_url) | ||
260 | 45 | 60 | ||
261 | === modified file 'mail/mail_thread.py' | |||
262 | --- mail/mail_thread.py 2014-05-12 10:04:00 +0000 | |||
263 | +++ mail/mail_thread.py 2014-05-20 08:59:26 +0000 | |||
264 | @@ -24,6 +24,8 @@ | |||
265 | 24 | import datetime | 24 | import datetime |
266 | 25 | import dateutil | 25 | import dateutil |
267 | 26 | import email | 26 | import email |
268 | 27 | import jinja2 | ||
269 | 28 | import sys | ||
270 | 27 | try: | 29 | try: |
271 | 28 | import simplejson as json | 30 | import simplejson as json |
272 | 29 | except ImportError: | 31 | except ImportError: |
273 | @@ -46,6 +48,14 @@ | |||
274 | 46 | 48 | ||
275 | 47 | _logger = logging.getLogger(__name__) | 49 | _logger = logging.getLogger(__name__) |
276 | 48 | 50 | ||
277 | 51 | if hasattr(sys, 'frozen'): | ||
278 | 52 | # When running on compiled windows binary, we don't have access to package loader. | ||
279 | 53 | path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views')) | ||
280 | 54 | loader = jinja2.FileSystemLoader(path) | ||
281 | 55 | else: | ||
282 | 56 | loader = jinja2.PackageLoader('openerp.addons.mail', "views") | ||
283 | 57 | |||
284 | 58 | env = jinja2.Environment(loader=loader, autoescape=True) | ||
285 | 49 | 59 | ||
286 | 50 | def decode_header(message, header, separator=' '): | 60 | def decode_header(message, header, separator=' '): |
287 | 51 | return separator.join(map(decode, filter(None, message.get_all(header, [])))) | 61 | return separator.join(map(decode, filter(None, message.get_all(header, [])))) |
288 | @@ -96,6 +106,14 @@ | |||
289 | 96 | # :param obj: is a browse_record | 106 | # :param obj: is a browse_record |
290 | 97 | # :param function lambda: returns whether the tracking should record using this subtype | 107 | # :param function lambda: returns whether the tracking should record using this subtype |
291 | 98 | _track = {} | 108 | _track = {} |
292 | 109 | _default_mail_actions = [{ | ||
293 | 110 | 'name': 'message_unsubscribe_users', | ||
294 | 111 | 'type': 'object', | ||
295 | 112 | 'string': 'Mute', | ||
296 | 113 | 'condition': lambda self, obj, context=None: True, | ||
297 | 114 | 'button_type': 'info' | ||
298 | 115 | }] | ||
299 | 116 | _mail_actions = [] | ||
300 | 99 | 117 | ||
301 | 100 | # Mass mailing feature | 118 | # Mass mailing feature |
302 | 101 | _mail_mass_mailing = False | 119 | _mail_mass_mailing = False |
303 | @@ -346,6 +364,23 @@ | |||
304 | 346 | res['arch'] = etree.tostring(doc) | 364 | res['arch'] = etree.tostring(doc) |
305 | 347 | return res | 365 | return res |
306 | 348 | 366 | ||
307 | 367 | def _prepare_body_mail_action(self, cr, uid, obj, context=None): | ||
308 | 368 | mail_actions = [] | ||
309 | 369 | data_pool = self.pool['ir.model.data'] | ||
310 | 370 | for mail_action in self._mail_actions + self._default_mail_actions: | ||
311 | 371 | condition_fn = mail_action['condition'] | ||
312 | 372 | if mail_action.get('action_xml_id'): | ||
313 | 373 | dummy, act_id = data_pool.get_object_reference(cr, uid, mail_action['module'], mail_action['action_xml_id']) | ||
314 | 374 | mail_action['xml_id'] = act_id | ||
315 | 375 | if condition_fn(self, obj, context=context): | ||
316 | 376 | mail_actions.append(mail_action) | ||
317 | 377 | mail_actions_body = env.get_template("mail_actions_button.html").render({ | ||
318 | 378 | 'mail_actions': mail_actions, | ||
319 | 379 | 'model': self._name, | ||
320 | 380 | 'res_id': obj.id | ||
321 | 381 | }) | ||
322 | 382 | return mail_actions_body | ||
323 | 383 | |||
324 | 349 | #------------------------------------------------------ | 384 | #------------------------------------------------------ |
325 | 350 | # CRUD overrides for automatic subscription and logging | 385 | # CRUD overrides for automatic subscription and logging |
326 | 351 | #------------------------------------------------------ | 386 | #------------------------------------------------------ |
327 | @@ -358,7 +393,6 @@ | |||
328 | 358 | """ | 393 | """ |
329 | 359 | if context is None: | 394 | if context is None: |
330 | 360 | context = {} | 395 | context = {} |
331 | 361 | |||
332 | 362 | if context.get('tracking_disable'): | 396 | if context.get('tracking_disable'): |
333 | 363 | return super(mail_thread, self).create( | 397 | return super(mail_thread, self).create( |
334 | 364 | cr, uid, values, context=context) | 398 | cr, uid, values, context=context) |
335 | @@ -370,11 +404,17 @@ | |||
336 | 370 | message_follower_ids.append([4, pid]) | 404 | message_follower_ids.append([4, pid]) |
337 | 371 | values['message_follower_ids'] = message_follower_ids | 405 | values['message_follower_ids'] = message_follower_ids |
338 | 372 | thread_id = super(mail_thread, self).create(cr, uid, values, context=context) | 406 | thread_id = super(mail_thread, self).create(cr, uid, values, context=context) |
340 | 373 | 407 | message_body = '' | |
341 | 408 | mail_actions_body = '' | ||
342 | 409 | if thread_id: | ||
343 | 410 | obj = self.browse(cr, uid, thread_id, context=context) | ||
344 | 411 | mail_actions_body = self._prepare_body_mail_action(cr, uid, obj) | ||
345 | 374 | # automatic logging unless asked not to (mainly for various testing purpose) | 412 | # automatic logging unless asked not to (mainly for various testing purpose) |
346 | 375 | if not context.get('mail_create_nolog'): | 413 | if not context.get('mail_create_nolog'): |
349 | 376 | self.message_post(cr, uid, thread_id, body=_('%s created') % (self._description), context=context) | 414 | message_body +=_('%s created %s') % (self._description, mail_actions_body) |
350 | 377 | 415 | else: | |
351 | 416 | message_body += mail_actions_body | ||
352 | 417 | self.message_post(cr, uid, thread_id, body=message_body, context=context) | ||
353 | 378 | # auto_subscribe: take values and defaults into account | 418 | # auto_subscribe: take values and defaults into account |
354 | 379 | create_values = dict(values) | 419 | create_values = dict(values) |
355 | 380 | for key, val in context.iteritems(): | 420 | for key, val in context.iteritems(): |
356 | @@ -415,6 +455,12 @@ | |||
357 | 415 | initial_values = dict((record.id, dict((key, getattr(record, key)) for key in tracked_fields)) | 455 | initial_values = dict((record.id, dict((key, getattr(record, key)) for key in tracked_fields)) |
358 | 416 | for record in records) | 456 | for record in records) |
359 | 417 | 457 | ||
360 | 458 | if ids: | ||
361 | 459 | obj = self.browse(cr, uid, ids[0], context=context) | ||
362 | 460 | mail_actions_body = self._prepare_body_mail_action(cr, uid, obj) | ||
363 | 461 | message_body = mail_actions_body | ||
364 | 462 | self.message_post(cr, uid, ids[0], body=message_body, context=context) | ||
365 | 463 | |||
366 | 418 | # Perform write, update followers | 464 | # Perform write, update followers |
367 | 419 | result = super(mail_thread, self).write(cr, uid, ids, values, context=context) | 465 | result = super(mail_thread, self).write(cr, uid, ids, values, context=context) |
368 | 420 | self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values) | 466 | self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values) |
369 | 421 | 467 | ||
370 | === added file 'mail/views/mail_actions_button.html' | |||
371 | --- mail/views/mail_actions_button.html 1970-01-01 00:00:00 +0000 | |||
372 | +++ mail/views/mail_actions_button.html 2014-05-20 08:59:26 +0000 | |||
373 | @@ -0,0 +1,6 @@ | |||
374 | 1 | <div name="mail_actions_group"> | ||
375 | 2 | {% set button_style = {'info': 'background: gray', 'warning': 'background: red', 'success': 'background:green'} %} | ||
376 | 3 | {% for button in mail_actions %} | ||
377 | 4 | <a class="btn btn-default" name="mail_action" style="color:BLACK;{{ button_style[button.button_type] }}" href="/mail_action/{{ model }}/{{ res_id }}?action_name={{ button.name }}&action_type={{ button.type }}&action_id={{ button.xml_id }}"> {{ button.string }} </a> | ||
378 | 5 | {% endfor %} | ||
379 | 6 | </div> | ||
380 | 0 | 7 | ||
381 | === modified file 'project/project.py' | |||
382 | --- project/project.py 2014-05-13 11:18:37 +0000 | |||
383 | +++ project/project.py 2014-05-20 08:59:26 +0000 | |||
384 | @@ -568,6 +568,13 @@ | |||
385 | 568 | 'project.mt_task_ready': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'done', | 568 | 'project.mt_task_ready': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'done', |
386 | 569 | }, | 569 | }, |
387 | 570 | } | 570 | } |
388 | 571 | _mail_actions = [{ | ||
389 | 572 | 'name': 'set_user', | ||
390 | 573 | 'type': 'object', | ||
391 | 574 | 'string': 'I will do it', | ||
392 | 575 | 'condition': lambda self, obj, context=None: not obj.user_id, | ||
393 | 576 | 'button_type': 'success' | ||
394 | 577 | }] | ||
395 | 571 | 578 | ||
396 | 572 | def _get_default_partner(self, cr, uid, context=None): | 579 | def _get_default_partner(self, cr, uid, context=None): |
397 | 573 | project_id = self._get_default_project_id(cr, uid, context) | 580 | project_id = self._get_default_project_id(cr, uid, context) |
398 | @@ -666,6 +673,9 @@ | |||
399 | 666 | res[task.id]['progress'] = 100.0 | 673 | res[task.id]['progress'] = 100.0 |
400 | 667 | return res | 674 | return res |
401 | 668 | 675 | ||
402 | 676 | def set_user(self, cr, uid, ids, context=None): | ||
403 | 677 | self.pool['project.task'].write(cr, uid, ids, {'user_id':uid}) | ||
404 | 678 | |||
405 | 669 | def onchange_remaining(self, cr, uid, ids, remaining=0.0, planned=0.0): | 679 | def onchange_remaining(self, cr, uid, ids, remaining=0.0, planned=0.0): |
406 | 670 | if remaining and not planned: | 680 | if remaining and not planned: |
407 | 671 | return {'value': {'planned_hours': remaining}} | 681 | return {'value': {'planned_hours': remaining}} |
408 | 672 | 682 | ||
409 | === modified file 'project_issue/project_issue.py' | |||
410 | --- project_issue/project_issue.py 2014-05-08 15:25:36 +0000 | |||
411 | +++ project_issue/project_issue.py 2014-05-20 08:59:26 +0000 | |||
412 | @@ -60,6 +60,21 @@ | |||
413 | 60 | 'project_issue.mt_issue_ready': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'done', | 60 | 'project_issue.mt_issue_ready': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'done', |
414 | 61 | }, | 61 | }, |
415 | 62 | } | 62 | } |
416 | 63 | _mail_actions = [{ | ||
417 | 64 | 'name': 'set_user', | ||
418 | 65 | 'type': 'object', | ||
419 | 66 | 'string': 'I will do it', | ||
420 | 67 | 'condition': lambda self, obj, context=None: not obj.user_id, | ||
421 | 68 | 'button_type': 'success' | ||
422 | 69 | }, | ||
423 | 70 | { | ||
424 | 71 | 'type': 'action', | ||
425 | 72 | 'string': 'Not interested', | ||
426 | 73 | 'condition': lambda self, obj, context=None: not obj.user_id, | ||
427 | 74 | 'button_type': 'warning', | ||
428 | 75 | 'action_xml_id': 'action_view_issues', | ||
429 | 76 | 'module': 'project_issue' | ||
430 | 77 | }] | ||
431 | 63 | 78 | ||
432 | 64 | def _get_default_partner(self, cr, uid, context=None): | 79 | def _get_default_partner(self, cr, uid, context=None): |
433 | 65 | project_id = self._get_default_project_id(cr, uid, context) | 80 | project_id = self._get_default_project_id(cr, uid, context) |
434 | @@ -306,6 +321,9 @@ | |||
435 | 306 | 'stage_id': _read_group_stage_ids | 321 | 'stage_id': _read_group_stage_ids |
436 | 307 | } | 322 | } |
437 | 308 | 323 | ||
438 | 324 | def set_user(self, cr, uid, ids, context=None): | ||
439 | 325 | self.pool['project.issue'].write(cr, uid, ids, {'user_id':uid}) | ||
440 | 326 | |||
441 | 309 | def copy(self, cr, uid, id, default=None, context=None): | 327 | def copy(self, cr, uid, id, default=None, context=None): |
442 | 310 | issue = self.read(cr, uid, id, ['name'], context=context) | 328 | issue = self.read(cr, uid, id, ['name'], context=context) |
443 | 311 | if not default: | 329 | if not default: |