Merge lp:~openerp-dev/openobject-addons/trunk-kanban-column-rga into lp:openobject-addons
- trunk-kanban-column-rga
- Merge into trunk
Proposed by
Vidhin Mehta (OpenERP)
Status: | Work in progress |
---|---|
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-kanban-column-rga |
Merge into: | lp:openobject-addons |
Diff against target: |
673 lines (+309/-95) 10 files modified
crm/crm.py (+50/-0) crm/crm_case_section_view.xml (+1/-0) hr/hr_view.xml (+2/-0) hr_recruitment/hr_recruitment.py (+107/-37) hr_recruitment/hr_recruitment_demo.xml (+30/-1) hr_recruitment/hr_recruitment_menu.xml (+25/-20) hr_recruitment/hr_recruitment_view.xml (+33/-33) project/project.py (+57/-2) project/project_view.xml (+1/-0) project/security/ir.model.access.csv (+3/-2) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-kanban-column-rga |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenERP Core Team | Pending | ||
Review via email: mp+190307@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged revisions
- 8877. By Mahendra Barad(OpenERP)
-
[REV] revert the changes for global method
- 8876. By Mahendra Barad(OpenERP)
-
[Merge] merge with trunk
- 8875. By Mahendra Barad(OpenERP)
-
Merge with trunk
- 8874. By RGA(OpenERP)
-
[IMP] add context stage_m2m_field so we can link group with this field instead of add new group
- 8873. By RGA(OpenERP)
-
[IMP] hr_recruitment view add Application button on job position form view
- 8872. By RGA(OpenERP)
-
Merge with trunk
- 8871. By Mahendra Barad(OpenERP)
-
merge with trunk
- 8870. By Mahendra Barad(OpenERP)
-
[IMP]solve the deletion problem for stages
- 8869. By RGA(OpenERP)
-
Merge with lp:~openerp-dev/openobject-addons/trunk-kanban-column-exp-rga which add comman base stage
- 8868. By RGA(OpenERP)
-
Merge with trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'crm/crm.py' |
2 | --- crm/crm.py 2013-10-06 11:58:08 +0000 |
3 | +++ crm/crm.py 2013-10-10 08:36:19 +0000 |
4 | @@ -85,7 +85,57 @@ |
5 | 'type': 'both', |
6 | 'case_default': True, |
7 | } |
8 | + def create(self, cr, uid, value, context=None): |
9 | + if context is None: context = {} |
10 | + stage_id = self.search(cr, uid, [('name','=', value.get('name'))], context=context, limit=1) |
11 | + section_id = context.get('default_section_id', False) |
12 | + if section_id and stage_id: |
13 | + return self._stage_modify(cr, uid, stage_id[0], section_id, value, context=context) |
14 | + create_return = super(crm_case_stage, self).create(cr, uid, value, context=context) |
15 | + if section_id: |
16 | + self.pool.get('crm.case.section').write(cr ,uid, section_id, {'stage_ids': [(4, create_return)]}, context=context) |
17 | + return create_return |
18 | + |
19 | + def _stage_modify(self, cr, uid, stage_id, section_id, value, context=None): |
20 | + crm_lead = self.pool.get('crm.lead') |
21 | + section_browse = self.pool.get('crm.case.section').browse(cr, uid, section_id, context=context) |
22 | + crm_lead_ids = crm_lead.search(cr, uid, [('stage_id','=', stage_id),('section_id','=', section_id)], context=context) |
23 | + stage_ids = self.search(cr, uid, [('name','=', value.get('name'))], context=context, limit=1) |
24 | + if not stage_ids: |
25 | + value['state'] = self.browse(cr, uid, stage_id, context=context).name |
26 | + value['section_ids'] = [(6, 0, [section_id])] |
27 | + new_stage_id = self.copy(cr, uid, stage_id, default=value, context=context) |
28 | + else: |
29 | + new_stage_id = stage_ids[0] |
30 | + |
31 | + section_write = section_browse.write({'stage_ids': [(3, stage_id),(4, new_stage_id)]}, context=context) |
32 | + crm_write = crm_lead.write(cr, uid, crm_lead_ids, {'stage_id': new_stage_id} , context=context) |
33 | + if section_write and crm_write: |
34 | + return new_stage_id |
35 | + return False |
36 | |
37 | + def write(self, cr, uid, ids, value, context=None): |
38 | + if context is None: context = {} |
39 | + section_id = context.get('default_section_id', False) |
40 | + if value.get('name') and section_id: |
41 | + for stage_id in ids: |
42 | + return self._stage_modify(cr, uid, stage_id, section_id, value, context=context) |
43 | + return True |
44 | + return super(crm_case_stage, self).write(cr, uid, ids, value, context=context) |
45 | + |
46 | + def unlink(self, cr, uid, ids, context=None): |
47 | + if context is None: context = {} |
48 | + section_id = context.get('default_section_id', False) |
49 | + if section_id: |
50 | + crm_lead = self.pool.get('crm.lead') |
51 | + for stage_id in ids: |
52 | + crm_lead_ids = crm_lead.search(cr, uid, [('stage_id','=',stage_id),('section_id','=', section_id)]) |
53 | + crm_write = crm_lead.write(cr, uid, crm_lead_ids, {'stage_id': False} , context=context) |
54 | + section_write = self.pool.get('crm.case.section').write(cr, uid, section_id, {'stage_ids': [(3, stage_id)]}, context=context) |
55 | + if not crm_write or not section_write: |
56 | + return False |
57 | + return True |
58 | + return super(crm_case_stage,self).unlink(cr, uid, ids, context) |
59 | |
60 | class crm_case_section(osv.osv): |
61 | """ Model for sales teams. """ |
62 | |
63 | === modified file 'crm/crm_case_section_view.xml' |
64 | --- crm/crm_case_section_view.xml 2013-09-13 08:42:35 +0000 |
65 | +++ crm/crm_case_section_view.xml 2013-10-10 08:36:19 +0000 |
66 | @@ -48,6 +48,7 @@ |
67 | 'stage_type': 'opportunity', |
68 | 'default_type': 'opportunity', |
69 | 'default_user_id': uid, |
70 | + 'stage_m2m_field':'stage_ids', |
71 | } |
72 | </field> |
73 | <field name="help" type="html"> |
74 | |
75 | === modified file 'hr/hr_view.xml' |
76 | --- hr/hr_view.xml 2013-10-06 13:12:25 +0000 |
77 | +++ hr/hr_view.xml 2013-10-10 08:36:19 +0000 |
78 | @@ -336,6 +336,8 @@ |
79 | <field name="state" widget="statusbar" statusbar_visible="recruit,open"/> |
80 | </header> |
81 | <sheet> |
82 | + <div name="hr_applicant_button" class="oe_right oe_button_box"> |
83 | + </div> |
84 | <div class="oe_title"> |
85 | <label for="name" class="oe_edit_only"/> |
86 | <h1><field name="name" class="oe_inline"/></h1> |
87 | |
88 | === modified file 'hr_recruitment/hr_recruitment.py' |
89 | --- hr_recruitment/hr_recruitment.py 2013-09-19 14:23:38 +0000 |
90 | +++ hr_recruitment/hr_recruitment.py 2013-10-10 08:36:19 +0000 |
91 | @@ -51,14 +51,79 @@ |
92 | _columns = { |
93 | 'name': fields.char('Name', size=64, required=True, translate=True), |
94 | 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."), |
95 | - 'department_id':fields.many2one('hr.department', 'Specific to a Department', help="Stages of the recruitment process may be different per department. If this stage is common to all departments, keep this field empty."), |
96 | 'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."), |
97 | 'requirements': fields.text('Requirements'), |
98 | + 'case_default': fields.boolean('Default to New Job'), |
99 | + 'job_ids': fields.many2many('hr.job', 'job_stage_rel', 'stage_id','job_id', 'Stages') |
100 | } |
101 | + |
102 | + def _get_default_job_id(self, cr, uid, ctx={}): |
103 | + job = ctx.get('default_job_id', False) |
104 | + if type(job) is int: |
105 | + return [job] |
106 | + return job |
107 | + |
108 | _defaults = { |
109 | 'sequence': 1, |
110 | 'fold': False, |
111 | + 'job_ids': _get_default_job_id, |
112 | + 'case_default': True |
113 | } |
114 | + |
115 | + def _stage_modify(self, cr, uid, stage_id, job_id, vals, context=None): |
116 | + hr_applicant = self.pool.get('hr.applicant') |
117 | + hr_job = self.pool.get('hr.job').browse(cr, uid, job_id, context=context) |
118 | + hr_applicant_ids = hr_applicant.search(cr, uid, [('stage_id','=', stage_id),('job_id','=', job_id)], context=context) |
119 | + stage_ids = self.search(cr, uid, [('name','=', vals['name'])], context=context) |
120 | + if not stage_ids: |
121 | + vals['job_ids'] = [(6, 0, [job_id])] |
122 | + new_stage_id = self.copy(cr, uid, stage_id, default=vals, context=context) |
123 | + else: |
124 | + new_stage_id = stage_ids[0] |
125 | + |
126 | + hr_job_write = hr_job.write({'stage_ids': [(4, new_stage_id),(3, stage_id)]}, context=context) |
127 | + hr_applicant_write = hr_applicant.write(cr, uid, hr_applicant_ids, {'stage_id': new_stage_id} , context=context) |
128 | + if hr_job_write and hr_applicant_write: |
129 | + return new_stage_id |
130 | + return False |
131 | + |
132 | + def create(self, cr, uid, vals, context=None): |
133 | + if context is None: |
134 | + context = {} |
135 | + stage_ids = self.search(cr, uid, [('name','=', vals.get('name'))], context=context, limit=1) |
136 | + job_id = context.get('default_job_id') |
137 | + if job_id and stage_ids: |
138 | + return self._stage_modify(cr, uid, stage_ids[0], job_id, vals, context=context) |
139 | + create_return = super(hr_recruitment_stage, self).create(cr, uid, vals, context=context) |
140 | + if job_id: |
141 | + self.pool.get('hr.job').write(cr, uid, job_id, {'stage_ids': [(4, create_return)]}, context=context) |
142 | + return create_return |
143 | + |
144 | + def write(self, cr, uid, ids, vals, context=None): |
145 | + if context is None: |
146 | + context = {} |
147 | + job_id = context.get('default_job_id') |
148 | + if vals.get('name') and job_id: |
149 | + for stage_id in ids: |
150 | + return self._stage_modify(cr, uid, stage_id, job_id, vals, context=context) |
151 | + return True |
152 | + return super(hr_recruitment_stage, self).write(cr, uid, ids, vals, context=context) |
153 | + |
154 | + def unlink(self, cr, uid, ids, context=None): |
155 | + if context is None: |
156 | + context = {} |
157 | + job_id = context.get('default_job_id', False) |
158 | + if job_id: |
159 | + hr_application = self.pool.get('hr.applicant') |
160 | + for stage_id in ids: |
161 | + applicant_ids = hr_application.search(cr, uid, [('stage_id','=',stage_id),('job_id','=',job_id)]) |
162 | + hr_app_write = hr_application.write(cr, uid, applicant_ids, {'stage_id': False} , context=context) |
163 | + hr_job_write = self.pool.get('hr.job').write(cr, uid, job_id, {'stage_ids': [(3, stage_id)]}, context=context) |
164 | + if not hr_app_write or not hr_job_write: |
165 | + return False |
166 | + return True |
167 | + return super(hr_recruitment_stage,self).unlink(cr, uid, ids, context) |
168 | + |
169 | |
170 | class hr_recruitment_degree(osv.osv): |
171 | """ Degree of HR Recruitment """ |
172 | @@ -87,29 +152,29 @@ |
173 | }, |
174 | } |
175 | |
176 | - def _get_default_department_id(self, cr, uid, context=None): |
177 | + def _get_default_job_id(self, cr, uid, context=None): |
178 | """ Gives default department by checking if present in the context """ |
179 | - return (self._resolve_department_id_from_context(cr, uid, context=context) or False) |
180 | - |
181 | + return (self._resolve_job_id_from_context(cr, uid, context=context) or False) |
182 | + |
183 | def _get_default_stage_id(self, cr, uid, context=None): |
184 | """ Gives default stage_id """ |
185 | - department_id = self._get_default_department_id(cr, uid, context=context) |
186 | + department_id = self._get_default_job_id(cr, uid, context=context) |
187 | return self.stage_find(cr, uid, [], department_id, [('sequence', '=', '1')], context=context) |
188 | |
189 | - def _resolve_department_id_from_context(self, cr, uid, context=None): |
190 | - """ Returns ID of department based on the value of 'default_department_id' |
191 | - context key, or None if it cannot be resolved to a single |
192 | + def _resolve_job_id_from_context(self, cr, uid, context=None): |
193 | + """ Returns ID of job based on the value of 'default_job_id' |
194 | + context key, or None if it cannot be resolved to a single |
195 | department. |
196 | """ |
197 | if context is None: |
198 | context = {} |
199 | - if type(context.get('default_department_id')) in (int, long): |
200 | - return context.get('default_department_id') |
201 | - if isinstance(context.get('default_department_id'), basestring): |
202 | - department_name = context['default_department_id'] |
203 | - department_ids = self.pool.get('hr.department').name_search(cr, uid, name=department_name, context=context) |
204 | - if len(department_ids) == 1: |
205 | - return int(department_ids[0][0]) |
206 | + if type(context.get('default_job_id')) in (int, long): |
207 | + return context.get('default_job_id') |
208 | + if isinstance(context.get('default_job_id'), basestring): |
209 | + job_name = context['default_job_id'] |
210 | + job_ids = self.pool.get('hr.job').name_search(cr, uid, name=job_name, context=context) |
211 | + if len(job_ids) == 1: |
212 | + return int(job_ids[0][0]) |
213 | return None |
214 | |
215 | def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): |
216 | @@ -121,13 +186,14 @@ |
217 | order = "%s desc" % order |
218 | # retrieve section_id from the context and write the domain |
219 | # - ('id', 'in', 'ids'): add columns that should be present |
220 | - # - OR ('department_id', '=', False), ('fold', '=', False): add default columns that are not folded |
221 | - # - OR ('department_id', 'in', department_id), ('fold', '=', False) if department_id: add department columns that are not folded |
222 | - department_id = self._resolve_department_id_from_context(cr, uid, context=context) |
223 | + # - OR ('job_id', '=', False), ('fold', '=', False): add default columns that are not folded |
224 | + # - OR ('job_id', 'in', job_id), ('fold', '=', False) if job_id: add department columns that are not folded |
225 | + job_id = self._resolve_job_id_from_context(cr, uid, context=context) |
226 | search_domain = [] |
227 | - if department_id: |
228 | - search_domain += ['|', ('department_id', '=', department_id)] |
229 | - search_domain += ['|', ('id', 'in', ids), ('department_id', '=', False)] |
230 | + if job_id: |
231 | + search_domain += ['|', ('job_ids', '=', job_id)] |
232 | + search_domain += [('id', 'in', ids)] |
233 | + search_domain += ['|', '|', ('id', 'in', ids), ('job_ids', '=', False), ('case_default', '=', True)] |
234 | stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) |
235 | result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) |
236 | # restore order of the search |
237 | @@ -181,7 +247,7 @@ |
238 | 'create_date': fields.datetime('Creation Date', readonly=True, select=True), |
239 | 'write_date': fields.datetime('Update Date', readonly=True), |
240 | 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage', track_visibility='onchange', |
241 | - domain="['|', ('department_id', '=', department_id), ('department_id', '=', False)]"), |
242 | + domain="[('job_ids', '=', job_id)]"), |
243 | 'last_stage_id': fields.many2one('hr.recruitment.stage', 'Last Stage', |
244 | help='Stage of the applicant before being in the current stage. Used for lost cases analysis.'), |
245 | 'categ_ids': fields.many2many('hr.applicant_category', string='Tags'), |
246 | @@ -222,7 +288,7 @@ |
247 | 'active': lambda *a: 1, |
248 | 'user_id': lambda s, cr, uid, c: uid, |
249 | 'stage_id': lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c), |
250 | - 'department_id': lambda s, cr, uid, c: s._get_default_department_id(cr, uid, c), |
251 | + 'job_id': lambda s, cr, uid, c: s._get_default_job_id(cr, uid, c), |
252 | 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.applicant', context=c), |
253 | 'color': 0, |
254 | 'date_last_stage_update': fields.datetime.now, |
255 | @@ -239,11 +305,6 @@ |
256 | return {'value': {'department_id': job_record.department_id.id}} |
257 | return {} |
258 | |
259 | - def onchange_department_id(self, cr, uid, ids, department_id=False, stage_id=False, context=None): |
260 | - if not stage_id: |
261 | - stage_id = self.stage_find(cr, uid, [], department_id, [('sequence', '=', '1')], context=context) |
262 | - return {'value': {'stage_id': stage_id}} |
263 | - |
264 | def onchange_partner_id(self, cr, uid, ids, partner_id, context=None): |
265 | data = {'partner_phone': False, |
266 | 'partner_mobile': False, |
267 | @@ -264,17 +325,16 @@ |
268 | if isinstance(cases, (int, long)): |
269 | cases = self.browse(cr, uid, cases, context=context) |
270 | # collect all section_ids |
271 | - department_ids = [] |
272 | + job_ids = [] |
273 | if section_id: |
274 | - department_ids.append(section_id) |
275 | + job_ids.append(section_id) |
276 | for case in cases: |
277 | - if case.department_id: |
278 | - department_ids.append(case.department_id.id) |
279 | + if case.job_id: |
280 | + job_ids.append(case.job_id.id) |
281 | # OR all section_ids and OR with case_default |
282 | search_domain = [] |
283 | - if department_ids: |
284 | - search_domain += ['|', ('department_id', 'in', department_ids)] |
285 | - search_domain.append(('department_id', '=', False)) |
286 | + if job_ids: |
287 | + search_domain += ['|', ('job_ids', 'in', job_ids)] |
288 | # AND with the domain in parameter |
289 | search_domain += list(domain) |
290 | # perform search, return the first found |
291 | @@ -466,8 +526,18 @@ |
292 | 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, |
293 | help="Email alias for this job position. New emails will automatically " |
294 | "create new applicants for this job position."), |
295 | - } |
296 | - |
297 | + 'stage_ids':fields.many2many('hr.recruitment.stage', 'job_stage_rel','job_id', 'stage_id', 'Stages') |
298 | + } |
299 | + |
300 | + |
301 | + def _get_stage_common(self, cr, uid, context): |
302 | + ids = self.pool.get('hr.recruitment.stage').search(cr, uid, [('case_default','=',1)], context=context) |
303 | + return ids |
304 | + |
305 | + _defaults = { |
306 | + 'alias_domain': False, # always hide alias during creation |
307 | + 'stage_ids': _get_stage_common, |
308 | + } |
309 | def _auto_init(self, cr, context=None): |
310 | """Installation hook to create aliases for all jobs and avoid constraint errors.""" |
311 | return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(hr_job, self)._auto_init, |
312 | |
313 | === modified file 'hr_recruitment/hr_recruitment_demo.xml' |
314 | --- hr_recruitment/hr_recruitment_demo.xml 2013-03-13 09:37:09 +0000 |
315 | +++ hr_recruitment/hr_recruitment_demo.xml 2013-10-10 08:36:19 +0000 |
316 | @@ -124,6 +124,35 @@ |
317 | |
318 | <record id="hr.job_developer" model="hr.job"> |
319 | <field name="survey_id" ref="survey_job_0"/> |
320 | - </record> |
321 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
322 | + </record> |
323 | + <record id="hr.job_ceo" model="hr.job"> |
324 | + <field name="survey_id" ref="survey_job_0"/> |
325 | + <field name= "stage_ids" eval="[(4, stage_job3),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
326 | + </record> |
327 | + <record id="hr.job_cto" model="hr.job"> |
328 | + <field name="survey_id" ref="survey_job_0"/> |
329 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
330 | + </record> |
331 | + <record id="hr.job_hrm" model="hr.job"> |
332 | + <field name="survey_id" ref="survey_job_0"/> |
333 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
334 | + </record> |
335 | + <record id="hr.job_consultant" model="hr.job"> |
336 | + <field name="survey_id" ref="survey_job_0"/> |
337 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
338 | + </record> |
339 | + |
340 | + <record id="hr.job_marketing" model="hr.job"> |
341 | + <field name="survey_id" ref="survey_job_0"/> |
342 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
343 | + </record> |
344 | + |
345 | + <record id="hr.job_trainee" model="hr.job"> |
346 | + <field name="survey_id" ref="survey_job_0"/> |
347 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
348 | + </record> |
349 | + |
350 | + |
351 | </data> |
352 | </openerp> |
353 | \ No newline at end of file |
354 | |
355 | === modified file 'hr_recruitment/hr_recruitment_menu.xml' |
356 | --- hr_recruitment/hr_recruitment_menu.xml 2013-03-04 15:13:55 +0000 |
357 | +++ hr_recruitment/hr_recruitment_menu.xml 2013-10-10 08:36:19 +0000 |
358 | @@ -1,26 +1,6 @@ |
359 | <?xml version="1.0"?> |
360 | <openerp> |
361 | <data> |
362 | - |
363 | - ######################## JOB OPPORTUNITIES (menu) ########################### |
364 | - <record model="ir.actions.act_window" id="crm_case_categ0_act_job"> |
365 | - <field name="name">Applications</field> |
366 | - <field name="res_model">hr.applicant</field> |
367 | - <field name="view_mode">kanban,tree,form,graph,calendar</field> |
368 | - <field name="view_id" eval="False"/> |
369 | - <field name="search_view_id" ref="view_crm_case_jobs_filter"/> |
370 | - <field name="help" type="html"> |
371 | - <p> |
372 | - OpenERP helps you track applicants in the recruitment |
373 | - process and follow up all operations: meetings, interviews, etc. |
374 | - </p><p> |
375 | - Applicants and their attached CV are created automatically when an email is sent. |
376 | - If you install the document management modules, all resumes are indexed automatically, |
377 | - so that you can easily search through their content. |
378 | - </p> |
379 | - </field> |
380 | - </record> |
381 | - |
382 | <record model="ir.actions.act_window.view" id="action_hr_sec_kanban_view_act_job"> |
383 | <field name="sequence" eval="0"/> |
384 | <field name="view_mode">kanban</field> |
385 | @@ -64,6 +44,31 @@ |
386 | |
387 | <menuitem parent="hr.menu_hr_configuration" id="hr.menu_hr_job" action="hr.action_hr_job" sequence="2"/> |
388 | |
389 | + <menuitem name="Recruitment" |
390 | + id="menu_hr_recruitment_recruitment" |
391 | + parent="hr.menu_hr_configuration" |
392 | + sequence="40"/> |
393 | + |
394 | + <menuitem |
395 | + id="menu_hr_recruitment_stage" |
396 | + name="Stages" |
397 | + parent="menu_hr_recruitment_recruitment" |
398 | + action="hr_recruitment_stage_act" |
399 | + sequence="1" groups="base.group_no_one"/> |
400 | + |
401 | + <menuitem |
402 | + id="menu_hr_recruitment_degree" |
403 | + name="Degrees" |
404 | + parent="menu_hr_recruitment_recruitment" |
405 | + action="hr_recruitment_degree_action" |
406 | + sequence="5" groups="base.group_no_one"/> |
407 | + |
408 | + <menuitem |
409 | + id="menu_hr_recruitment_source" |
410 | + parent="menu_hr_recruitment_recruitment" |
411 | + action="hr_recruitment_source_action" |
412 | + groups="base.group_no_one" |
413 | + sequence="10"/> |
414 | |
415 | </data> |
416 | </openerp> |
417 | |
418 | === modified file 'hr_recruitment/hr_recruitment_view.xml' |
419 | --- hr_recruitment/hr_recruitment_view.xml 2013-09-04 14:11:22 +0000 |
420 | +++ hr_recruitment/hr_recruitment_view.xml 2013-10-10 08:36:19 +0000 |
421 | @@ -2,11 +2,6 @@ |
422 | <openerp> |
423 | <data> |
424 | |
425 | - <menuitem name="Recruitment" |
426 | - id="menu_hr_recruitment_recruitment" |
427 | - parent="hr.menu_hr_configuration" |
428 | - sequence="40"/> |
429 | - |
430 | <act_window |
431 | id="act_hr_applicant_to_meeting" |
432 | name="Meetings" |
433 | @@ -32,8 +27,7 @@ |
434 | </p> |
435 | </field> |
436 | </record> |
437 | - |
438 | - |
439 | + |
440 | <!-- Jobs --> |
441 | <record model="ir.ui.view" id="crm_case_tree_view_job"> |
442 | <field name="name">Applicants</field> |
443 | @@ -120,7 +114,7 @@ |
444 | <field name="survey" invisible="1"/> |
445 | <field name="response" invisible="1"/> |
446 | <field name="job_id" on_change="onchange_job(job_id)"/> |
447 | - <field name="department_id" on_change="onchange_department_id(department_id, stage_id)"/> |
448 | + <field name="department_id"/> |
449 | <label for="availability"/> |
450 | <div> |
451 | <field name="availability" class="oe_inline"/> <label string="Day(s)" class="oe_inline"/> |
452 | @@ -204,6 +198,25 @@ |
453 | </search> |
454 | </field> |
455 | </record> |
456 | + |
457 | + <!-- Applications Action--> |
458 | + <record model="ir.actions.act_window" id="crm_case_categ0_act_job"> |
459 | + <field name="name">Applications</field> |
460 | + <field name="res_model">hr.applicant</field> |
461 | + <field name="view_mode">kanban,tree,form,graph,calendar</field> |
462 | + <field name="view_id" eval="False"/> |
463 | + <field name="search_view_id" ref="view_crm_case_jobs_filter"/> |
464 | + <field name="help" type="html"> |
465 | + <p> |
466 | + OpenERP helps you track applicants in the recruitment |
467 | + process and follow up all operations: meetings, interviews, etc. |
468 | + </p><p> |
469 | + Applicants and their attached CV are created automatically when an email is sent. |
470 | + If you install the document management modules, all resumes are indexed automatically, |
471 | + so that you can easily search through their content. |
472 | + </p> |
473 | + </field> |
474 | + </record> |
475 | |
476 | <!-- CRM Lead Calendar View --> |
477 | <record model="ir.ui.view" id="hr_applicant_calendar_view"> |
478 | @@ -330,6 +343,14 @@ |
479 | <field name="alias_contact" class="oe_inline" string="Accept Emails From"/> |
480 | </group> |
481 | </xpath> |
482 | + <xpath expr="//div[@name='hr_applicant_button']" position="inside"> |
483 | + <button name="%(crm_case_categ0_act_job)d" string="Applications" type="action" |
484 | + context="{'search_default_job_id': active_id, 'default_job_id': active_id, 'stage_m2m_field':'stage_ids'}"/> |
485 | + </xpath> |
486 | + <xpath expr="//field[@name='requirements']" position="after"> |
487 | + <separator string="Recruitment Stages" /> |
488 | + <field name="stage_ids" nolabel="1"/> |
489 | + </xpath> |
490 | </field> |
491 | </record> |
492 | |
493 | @@ -341,7 +362,6 @@ |
494 | <tree string="Stages"> |
495 | <field name="sequence" invisible="1"/> |
496 | <field name="name"/> |
497 | - <field name="department_id"/> |
498 | </tree> |
499 | </field> |
500 | </record> |
501 | @@ -356,15 +376,16 @@ |
502 | <group string="Stage Definition"> |
503 | <group> |
504 | <field name="name"/> |
505 | - <field name="department_id"/> |
506 | + <field name="fold"/> |
507 | + <field name="case_default"/> |
508 | </group> |
509 | <group> |
510 | <field name="sequence"/> |
511 | - <field name="fold"/> |
512 | </group> |
513 | </group> |
514 | <separator string="Requirements"/> |
515 | <field name="requirements"/> |
516 | + <field name="job_ids" invisible="1"/> |
517 | </sheet> |
518 | </form> |
519 | </field> |
520 | @@ -385,14 +406,7 @@ |
521 | </p> |
522 | </field> |
523 | </record> |
524 | - |
525 | - <menuitem |
526 | - id="menu_hr_recruitment_stage" |
527 | - name="Stages" |
528 | - parent="menu_hr_recruitment_recruitment" |
529 | - action="hr_recruitment_stage_act" |
530 | - sequence="1" groups="base.group_no_one"/> |
531 | - |
532 | + |
533 | <!-- Degree Tree View --> |
534 | <record model="ir.ui.view" id="hr_recruitment_degree_tree"> |
535 | <field name="name">hr.recruitment.degree.tree</field> |
536 | @@ -429,13 +443,6 @@ |
537 | <field name="view_id" ref="hr_recruitment_degree_tree"/> |
538 | </record> |
539 | |
540 | - <menuitem |
541 | - id="menu_hr_recruitment_degree" |
542 | - name="Degrees" |
543 | - parent="menu_hr_recruitment_recruitment" |
544 | - action="hr_recruitment_degree_action" |
545 | - sequence="5" groups="base.group_no_one"/> |
546 | - |
547 | <!-- Source Tree View --> |
548 | <record model="ir.ui.view" id="hr_recruitment_source_tree"> |
549 | <field name="name">hr.recruitment.source.tree</field> |
550 | @@ -465,12 +472,5 @@ |
551 | <field name="view_type">form</field> |
552 | </record> |
553 | |
554 | - <menuitem |
555 | - id="menu_hr_recruitment_source" |
556 | - parent="menu_hr_recruitment_recruitment" |
557 | - action="hr_recruitment_source_action" |
558 | - groups="base.group_no_one" |
559 | - sequence="10"/> |
560 | - |
561 | </data> |
562 | </openerp> |
563 | |
564 | === modified file 'project/project.py' |
565 | --- project/project.py 2013-09-19 14:23:38 +0000 |
566 | +++ project/project.py 2013-10-10 08:36:19 +0000 |
567 | @@ -44,14 +44,69 @@ |
568 | 'fold': fields.boolean('Folded by Default', |
569 | help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."), |
570 | } |
571 | - |
572 | + |
573 | + def _get_default_project_id(self, cr, uid, context=None): |
574 | + project = self.pool['project.task']._get_default_project_id(cr, uid, context=context) |
575 | + if type(project) in (long, int,): |
576 | + return [project] |
577 | + return project |
578 | + |
579 | _defaults = { |
580 | 'sequence': 1, |
581 | 'fold': False, |
582 | 'case_default': False, |
583 | - 'project_ids': lambda self, cr, uid, ctx=None: self.pool['project.task']._get_default_project_id(cr, uid, context=ctx), |
584 | + 'project_ids':_get_default_project_id |
585 | } |
586 | _order = 'sequence' |
587 | + |
588 | + def write(self, cr, uid, ids, value, context=None): |
589 | + if context is None:context = {} |
590 | + project_id = context.get('default_project_id', False) |
591 | + if project_id and value.get('name'): |
592 | + for id in ids: |
593 | + return self._stage_modify(cr, uid, id, project_id, value, context=context) |
594 | + return True |
595 | + return super(project_task_type, self).write(cr, uid, ids, value, context=context) |
596 | + |
597 | + def _stage_modify(self, cr, uid, stage_id, project_id, vals, context=None): |
598 | + project = self.pool.get('project.project').browse(cr, uid, project_id, context=context) |
599 | + project_task = self.pool.get('project.task') |
600 | + stage_ids = self.search(cr, uid, [('name','=', vals.get('name'))], context=context, limit=1) |
601 | + task_ids = project_task.search(cr, uid, [('stage_id','=', stage_id),('project_id','=', project_id)], context=context) |
602 | + |
603 | + if not stage_ids: |
604 | + vals['project_ids'] = [(6, 0, [project_id])] |
605 | + new_stage_id = self.copy(cr, uid, stage_id, default=vals, context=context) |
606 | + else: |
607 | + new_stage_id = stage_ids[0] |
608 | + |
609 | + project_write = project.write({'type_ids': [(3, stage_id),(4, new_stage_id),]}, context=context) |
610 | + task_write = project_task.write(cr, uid, task_ids, {'stage_id': new_stage_id} , context=context) |
611 | + if project_write and task_write: |
612 | + return new_stage_id |
613 | + return False |
614 | + |
615 | + def create(self, cr, uid, value, context=None): |
616 | + if context is None:context = {} |
617 | + stage_id = self.search(cr, uid, [('name','=', value.get('name'))], context=context, limit=1) |
618 | + project_id = context.get('default_project_id', False) |
619 | + if project_id and stage_id: |
620 | + return self._stage_modify(cr, uid, stage_id[0], project_id, value, context=context) |
621 | + return super(project_task_type, self).create(cr, uid, value, context=context) |
622 | + |
623 | + def unlink(self, cr, uid, ids, context=None): |
624 | + if context is None: context = {} |
625 | + project_id = context.get('default_project_id') |
626 | + if project_id: |
627 | + project_task = self.pool.get('project.task') |
628 | + for stage_id in ids: |
629 | + task_ids = project_task.search(cr, uid, [('stage_id','=', stage_id),('project_id','=', project_id)]) |
630 | + task_write = project_task.write(cr, uid, task_ids, {'stage_id': False} , context=context) |
631 | + project_write = self.pool.get('project.project').write(cr, uid, project_id, {'type_ids': [(3, stage_id)]}, context=context) |
632 | + if not project_write or not task_write: |
633 | + return False |
634 | + return True |
635 | + return super(project_task_type,self).unlink(cr, uid, ids, context) |
636 | |
637 | |
638 | class project(osv.osv): |
639 | |
640 | === modified file 'project/project_view.xml' |
641 | --- project/project_view.xml 2013-10-08 13:56:50 +0000 |
642 | +++ project/project_view.xml 2013-10-10 08:36:19 +0000 |
643 | @@ -52,6 +52,7 @@ |
644 | 'search_default_project_id': [active_id], |
645 | 'default_project_id': active_id, |
646 | 'active_test': False, |
647 | + 'stage_m2m_field':'type_ids' |
648 | }</field> |
649 | <field name="search_view_id" ref="view_task_search_form"/> |
650 | <field name="help" type="html"> |
651 | |
652 | === modified file 'project/security/ir.model.access.csv' |
653 | --- project/security/ir.model.access.csv 2013-09-11 11:07:55 +0000 |
654 | +++ project/security/ir.model.access.csv 2013-10-10 08:36:19 +0000 |
655 | @@ -3,7 +3,8 @@ |
656 | access_project_project_manager,project.project,model_project_project,project.group_project_manager,1,1,1,1 |
657 | access_account_analytic_account_user,account.analytic.account,analytic.model_account_analytic_account,project.group_project_user,1,0,0,0 |
658 | access_account_analytic_account,account.analytic.account,analytic.model_account_analytic_account,project.group_project_manager,1,1,1,1 |
659 | -access_project_task_type_user,project.task.type user,model_project_task_type,project.group_project_user,1,1,1,1 |
660 | +access_project_task_type_manager,project.task.type manager,model_project_task_type,project.group_project_manager,1,1,1,1 |
661 | +access_project_task_type_user,project.task.type user,model_project_task_type,project.group_project_user,1,0,0,0 |
662 | access_project_task,project.task,model_project_task,project.group_project_user,1,1,1,1 |
663 | access_project_task_work,project.task.work,model_project_task_work,project.group_project_user,1,1,1,1 |
664 | access_report_project_task_user,report.project.task.user,model_report_project_task_user,project.group_project_manager,1,1,1,1 |
665 | @@ -11,7 +12,7 @@ |
666 | access_task_on_partner,project.task on partners,model_project_task,base.group_user,1,0,0,0 |
667 | access_project_on_partner,project.project on partners,model_project_project,base.group_user,1,0,0,0 |
668 | access_project_task_sale_user,project.task salesman,model_project_task,base.group_sale_salesman,1,1,1,1 |
669 | -access_project_task_type_sale_user,project.task.type salesman,project.model_project_task_type,base.group_sale_salesman,1,1,1,1 |
670 | +access_project_task_type_sale_user,project.task.type salesman,project.model_project_task_type,base.group_sale_salesman,1,0,0,0 |
671 | access_project_task_history_sale_user,project.task.history salesman,project.model_project_task_history,base.group_sale_salesman,1,1,1,1 |
672 | access_project_project_sale_user,project.project salesman,model_project_project,base.group_sale_salesman,1,0,0,0 |
673 | access_account_analytic_line_project,account.analytic.line project,analytic.model_account_analytic_line,project.group_project_manager,1,1,1,1 |