Merge lp:~openerp-dev/openobject-addons/trunk-kanban-column-vme-new into lp:openobject-addons
- trunk-kanban-column-vme-new
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-kanban-column-vme-new |
Merge into: | lp:openobject-addons |
Diff against target: |
1727 lines (+991/-114) 38 files modified
crm/__init__.py (+1/-1) crm/__openerp__.py (+2/-0) crm/crm.py (+21/-0) crm/crm_case_section_view.xml (+1/-1) crm/crm_lead.py (+7/-1) crm/crm_lead_view.xml (+2/-2) crm/security/ir.model.access.csv (+2/-0) crm/tests/__init__.py (+24/-0) crm/tests/test_crm_stages_case.py (+76/-0) crm/wizard/__init__.py (+1/-0) crm/wizard/crm_case_stage_management.py (+100/-0) crm/wizard/crm_case_stage_management_view.xml (+18/-0) hr/hr_view.xml (+3/-1) hr_recruitment/__init__.py (+1/-0) hr_recruitment/__openerp__.py (+1/-0) hr_recruitment/hr_recruitment.py (+77/-34) hr_recruitment/hr_recruitment_demo.xml (+7/-0) hr_recruitment/hr_recruitment_menu.xml (+30/-21) hr_recruitment/hr_recruitment_view.xml (+34/-34) hr_recruitment/security/ir.model.access.csv (+4/-1) hr_recruitment/tests/__init__.py (+24/-0) hr_recruitment/tests/test_hr_recruitment_stage.py (+77/-0) hr_recruitment/wizard/__init__.py (+1/-2) hr_recruitment/wizard/hr_recruitment_stage_management.py (+104/-0) hr_recruitment/wizard/hr_recruitment_stage_management_view.xml (+19/-0) project/__openerp__.py (+1/-0) project/project.py (+31/-5) project/project_view.xml (+1/-2) project/security/ir.model.access.csv (+5/-2) project/tests/__init__.py (+2/-1) project/tests/project_stage_management.py (+77/-0) project/wizard/__init__.py (+1/-0) project/wizard/project_stage_management.py (+104/-0) project/wizard/project_stage_management.xml (+18/-0) project_issue/project_issue.py (+8/-4) project_issue/project_issue_view.xml (+1/-2) project_issue/tests/__init__.py (+28/-0) project_issue/tests/project_stage_management.py (+77/-0) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-kanban-column-vme-new |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenERP Core Team | Pending | ||
Review via email: mp+196861@code.launchpad.net |
Commit message
Description of the change
- 8989. By Vidhin Mehta (OpenERP)
-
[CHANGE]comment
- 8990. By Vidhin Mehta (OpenERP)
-
[REM]limit
- 8991. By Vidhin Mehta (OpenERP)
-
[IMP]if default_XXX is not found in context than default behaviour of stage given.
- 8992. By Vidhin Mehta (OpenERP)
-
[IMP]forgot to add vals
- 8993. By Vidhin Mehta (OpenERP)
-
[ERM]jobid from tree view
- 8994. By Darshan Kalola(OpenERP)
-
[MERGE]sync with trunk and resolve conflicts.
- 8995. By Mahendra Barad(OpenERP)
-
[Merge]with trunk
- 8996. By Mahendra Barad(OpenERP)
-
[IMP]job_ids
- 8997. By Mahendra Barad(OpenERP)
-
[IMP]stage sequence changed in .sequence object if default projetc_id, section_id or job_id not in stage object
- 8998. By Mahendra Barad(OpenERP)
-
[IMP]stage load sequence if context in project_issue
- 8999. By Mahendra Barad(OpenERP)
-
[IMP]added access rule for new created sequence object
Unmerged revisions
- 8999. By Mahendra Barad(OpenERP)
-
[IMP]added access rule for new created sequence object
- 8998. By Mahendra Barad(OpenERP)
-
[IMP]stage load sequence if context in project_issue
- 8997. By Mahendra Barad(OpenERP)
-
[IMP]stage sequence changed in .sequence object if default projetc_id, section_id or job_id not in stage object
- 8996. By Mahendra Barad(OpenERP)
-
[IMP]job_ids
- 8995. By Mahendra Barad(OpenERP)
-
[Merge]with trunk
- 8994. By Darshan Kalola(OpenERP)
-
[MERGE]sync with trunk and resolve conflicts.
- 8993. By Vidhin Mehta (OpenERP)
-
[ERM]jobid from tree view
- 8992. By Vidhin Mehta (OpenERP)
-
[IMP]forgot to add vals
- 8991. By Vidhin Mehta (OpenERP)
-
[IMP]if default_XXX is not found in context than default behaviour of stage given.
- 8990. By Vidhin Mehta (OpenERP)
-
[REM]limit
Preview Diff
1 | === modified file 'crm/__init__.py' |
2 | --- crm/__init__.py 2014-01-15 09:38:05 +0000 |
3 | +++ crm/__init__.py 2014-02-27 12:12:58 +0000 |
4 | @@ -29,6 +29,6 @@ |
5 | import res_partner |
6 | import res_config |
7 | import base_partner_merge |
8 | - |
9 | +import tests |
10 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
11 | |
12 | |
13 | === modified file 'crm/__openerp__.py' |
14 | --- crm/__openerp__.py 2014-01-15 09:38:05 +0000 |
15 | +++ crm/__openerp__.py 2014-02-27 12:12:58 +0000 |
16 | @@ -75,6 +75,8 @@ |
17 | 'wizard/crm_opportunity_to_phonecall_view.xml', |
18 | |
19 | 'wizard/crm_merge_opportunities_view.xml', |
20 | + |
21 | + 'wizard/crm_case_stage_management_view.xml', |
22 | |
23 | 'crm_view.xml', |
24 | |
25 | |
26 | === modified file 'crm/crm.py' |
27 | --- crm/crm.py 2014-02-11 11:09:36 +0000 |
28 | +++ crm/crm.py 2014-02-27 12:12:58 +0000 |
29 | @@ -47,6 +47,17 @@ |
30 | 'active': lambda *a: 1, |
31 | } |
32 | |
33 | +class crm_case_stage_sequence(osv.osv): |
34 | + _name = 'crm.case.stage.sequence' |
35 | + _table = 'section_stage_rel' |
36 | + _description = 'Crm Case Stage Sequence' |
37 | + _order = 'sequence' |
38 | + _columns = { |
39 | + 'section_id': fields.many2one('crm.case.section', 'Sequence/Section'), |
40 | + 'stage_id': fields.many2one('crm.case.stage', 'Sequence/Stage'), |
41 | + 'sequence': fields.integer('Sequence') |
42 | + } |
43 | + |
44 | class crm_case_stage(osv.osv): |
45 | """ Model for case stages. This models the main stages of a document |
46 | management flow. Main CRM objects (leads, opportunities, project |
47 | @@ -87,6 +98,16 @@ |
48 | 'case_default': True, |
49 | } |
50 | |
51 | + def write(self, cr, uid, ids, vals, context=None): |
52 | + section_id = context.get('default_section_id') |
53 | + crm_case_stage_sequence = self.pool.get('crm.case.stage.sequence') |
54 | + |
55 | + if section_id: |
56 | + lead_ids = crm_case_stage_sequence.search(cr, uid, [('stage_id', '=', ids),('section_id', '=', section_id)], context=context) |
57 | + crm_case_stage_sequence.write(cr, uid, lead_ids, vals , context=context) |
58 | + else: |
59 | + return super(crm_case_stage, self).write(cr, uid, ids, vals, context=context) |
60 | + return True |
61 | |
62 | class crm_case_section(osv.osv): |
63 | """ Model for sales teams. """ |
64 | |
65 | === modified file 'crm/crm_case_section_view.xml' |
66 | --- crm/crm_case_section_view.xml 2014-02-20 16:38:15 +0000 |
67 | +++ crm/crm_case_section_view.xml 2014-02-27 12:12:58 +0000 |
68 | @@ -42,7 +42,7 @@ |
69 | <field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/> |
70 | <field name="context">{ |
71 | 'search_default_section_id': [active_id], |
72 | - 'default_section_id': active_id, |
73 | + 'search_default_assigned_to_me': 1, |
74 | 'stage_type': 'opportunity', |
75 | 'default_type': 'opportunity', |
76 | 'default_user_id': uid, |
77 | |
78 | === modified file 'crm/crm_lead.py' |
79 | --- crm/crm_lead.py 2014-02-20 16:38:15 +0000 |
80 | +++ crm/crm_lead.py 2014-02-27 12:12:58 +0000 |
81 | @@ -143,9 +143,15 @@ |
82 | search_domain += ['|', ('type', '=', type), ('type', '=', 'both')] |
83 | # perform search |
84 | stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) |
85 | + if section_id: |
86 | + sequence_ids = self.pool.get('crm.case.stage.sequence').search_read(cr, uid, [('section_id', '=', section_id), ('stage_id', 'in', stage_ids)], ['stage_id'], order=order, context=context) |
87 | + type_ids = map(lambda type_ids: type_ids['stage_id'][0], sequence_ids) |
88 | result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) |
89 | # restore order of the search |
90 | - result.sort(lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
91 | + if section_id: |
92 | + result.sort(lambda x,y: cmp(type_ids.index(x[0]), type_ids.index(y[0]))) |
93 | + else: |
94 | + result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
95 | |
96 | fold = {} |
97 | for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): |
98 | |
99 | === modified file 'crm/crm_lead_view.xml' |
100 | --- crm/crm_lead_view.xml 2014-02-12 18:08:45 +0000 |
101 | +++ crm/crm_lead_view.xml 2014-02-27 12:12:58 +0000 |
102 | @@ -259,7 +259,7 @@ |
103 | <field name="name">CRM - Leads Kanban</field> |
104 | <field name="model">crm.lead</field> |
105 | <field name="arch" type="xml"> |
106 | - <kanban default_group_by="stage_id"> |
107 | + <kanban default_group_by="stage_id" stage_management="crm.case.stage.management" stage_options = "{'group_by':'stage_id'}"> |
108 | <field name="stage_id"/> |
109 | <field name="color"/> |
110 | <field name="priority"/> |
111 | @@ -545,7 +545,7 @@ |
112 | <search string="Search Opportunities"> |
113 | <field name="name" string="Opportunity" filter_domain="['|','|','|',('partner_id','ilike',self),('partner_name','ilike',self),('email_from','ilike',self),('name', 'ilike', self)]"/> |
114 | <field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike', self)]"/> |
115 | - <field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/> |
116 | + <field name="section_id" groups="base.group_multi_salesteams"/> |
117 | <field name="user_id"/> |
118 | <field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/> |
119 | <field name="stage_id" domain="[]"/> |
120 | |
121 | === modified file 'crm/security/ir.model.access.csv' |
122 | --- crm/security/ir.model.access.csv 2013-11-27 15:32:57 +0000 |
123 | +++ crm/security/ir.model.access.csv 2014-02-27 12:12:58 +0000 |
124 | @@ -16,6 +16,8 @@ |
125 | access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1 |
126 | access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0 |
127 | access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1 |
128 | +access_crm_case_stage_sequence,crm.case.stage.sequence,model_crm_case_stage_sequence,,1,0,0,0 |
129 | +access_crm_case_stage_sequence_manager,crm.case.stage.sequence,model_crm_case_stage_sequence,base.group_sale_manager,1,1,1,1 |
130 | access_crm_case_resource_type_user,crm_case_resource_type user,model_crm_case_resource_type,base.group_sale_salesman,1,1,1,0 |
131 | access_crm_case_resource_type_manager,crm_case_resource_type manager,model_crm_case_resource_type,base.group_sale_manager,1,1,1,1 |
132 | access_crm_phonecall_report_user,crm.phonecall.report.user,model_crm_phonecall_report,base.group_sale_salesman,1,0,0,0 |
133 | |
134 | === added directory 'crm/tests' |
135 | === added file 'crm/tests/__init__.py' |
136 | --- crm/tests/__init__.py 1970-01-01 00:00:00 +0000 |
137 | +++ crm/tests/__init__.py 2014-02-27 12:12:58 +0000 |
138 | @@ -0,0 +1,24 @@ |
139 | +# -*- coding: utf-8 -*- |
140 | +############################################################################## |
141 | +# |
142 | +# OpenERP, Open Source Business Applications |
143 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
144 | +# |
145 | +# This program is free software: you can redistribute it and/or modify |
146 | +# it under the terms of the GNU Affero General Public License as |
147 | +# published by the Free Software Foundation, either version 3 of the |
148 | +# License, or (at your option) any later version. |
149 | +# |
150 | +# This program is distributed in the hope that it will be useful, |
151 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
152 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
153 | +# GNU Affero General Public License for more details. |
154 | +# |
155 | +# You should have received a copy of the GNU Affero General Public License |
156 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
157 | +# |
158 | +############################################################################## |
159 | +from . import test_crm_stages_case |
160 | +checks = [ |
161 | + test_crm_stages_case, |
162 | + ] |
163 | \ No newline at end of file |
164 | |
165 | === added file 'crm/tests/test_crm_stages_case.py' |
166 | --- crm/tests/test_crm_stages_case.py 1970-01-01 00:00:00 +0000 |
167 | +++ crm/tests/test_crm_stages_case.py 2014-02-27 12:12:58 +0000 |
168 | @@ -0,0 +1,76 @@ |
169 | +# -*- coding: utf-8 -*- |
170 | +############################################################################## |
171 | +# |
172 | +# OpenERP, Open Source Business Applications |
173 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
174 | +# |
175 | +# This program is free software: you can redistribute it and/or modify |
176 | +# it under the terms of the GNU Affero General Public License as |
177 | +# published by the Free Software Foundation, either version 3 of the |
178 | +# License, or (at your option) any later version. |
179 | +# |
180 | +# This program is distributed in the hope that it will be useful, |
181 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
182 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
183 | +# GNU Affero General Public License for more details. |
184 | +# |
185 | +# You should have received a copy of the GNU Affero General Public License |
186 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
187 | +# |
188 | +############################################################################## |
189 | +from openerp.osv.orm import except_orm |
190 | +from openerp.tests import common |
191 | + |
192 | + |
193 | +class TestCrmStagesCase(common.TransactionCase): |
194 | + def setUp(self): |
195 | + super(TestCrmStagesCase, self).setUp() |
196 | + |
197 | + def test_00_stage_management(self): |
198 | + cr, uid = self.cr, self.uid |
199 | + crm_stage_management = self.registry('crm.case.stage.management') |
200 | + crm_case_section = self.registry('crm.case.section') |
201 | + crm_case_stage= self.registry('crm.case.stage') |
202 | + crm_lead = self.registry('crm.lead'); |
203 | + crm_case_section_id = crm_case_section.create(cr, uid, {'name':'test_section'},context={}) |
204 | + context = {'default_section_id': crm_case_section_id, 'default_action':'create'} |
205 | + |
206 | + ''' For create when default_section_id pass in context |
207 | + If same name is present than returns its id otherwise create new. |
208 | + and link with given section. |
209 | + ''' |
210 | + |
211 | + stage_m2m_oldlist = crm_case_section.browse(cr, uid, crm_case_section_id, context=context).stage_ids |
212 | + crm_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
213 | + crm_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
214 | + check_len_id = crm_case_stage.search(cr, uid, [('name','=', 'First')], context=context) |
215 | + self.assertEqual(len(check_len_id), 1) |
216 | + opportunity_id = crm_lead.create(cr, uid, {'name':'Test1','stage_id': check_len_id[0],'section_id':crm_case_section_id}) |
217 | + test1 = check_len_id |
218 | + stage_m2m_newlist = crm_case_section.browse(cr, uid, crm_case_section_id, context=context).stage_ids |
219 | + self.assertEqual(len(stage_m2m_oldlist) + 1, len(stage_m2m_newlist)) |
220 | + |
221 | + ''' For edit when default_section_id pass in context |
222 | + If same name is present than returns its id otherwise create new. |
223 | + and link with given section and remove old link with section and crm_lead. |
224 | + ''' |
225 | + |
226 | + context.update({'active_id':test1[0], 'default_action':'write'}) |
227 | + crm_stage_management.modify_stage(cr, uid, {'name':'Second'},context=context) |
228 | + test2 = crm_case_stage.search(cr, uid, [('name','=', 'Second')], context=context) |
229 | + stage_m2m_newlist = crm_case_section.browse(cr, uid, crm_case_section_id, context=context).stage_ids |
230 | + |
231 | + check_crm_case_stage_id = crm_lead.browse(cr, uid, opportunity_id, context).stage_id.id |
232 | + self.assertEqual(check_crm_case_stage_id, test2[0]) |
233 | + self.assertIn(test2[0], [x.id for x in stage_m2m_newlist]) |
234 | + |
235 | + ''' For unlink when default_section_id pass in context |
236 | + It will unlink relation, not delete. |
237 | + ''' |
238 | + |
239 | + stage_m2m_oldlist = crm_case_section.browse(cr, uid, crm_case_section_id, context=context).stage_ids |
240 | + crm_stage_management.unlink(cr, uid, test2, context=context) |
241 | + stage_m2m_newlist = crm_case_section.browse(cr, uid, crm_case_section_id, context=context).stage_ids |
242 | + self.assertEqual(len(stage_m2m_oldlist) -1, len(stage_m2m_newlist)) |
243 | + unlink_id = crm_case_stage.search(cr, uid, [('name','=', 'Second')], context=context) |
244 | + self.assertEqual(unlink_id, test2) |
245 | |
246 | === modified file 'crm/wizard/__init__.py' |
247 | --- crm/wizard/__init__.py 2012-12-05 13:03:21 +0000 |
248 | +++ crm/wizard/__init__.py 2014-02-27 12:12:58 +0000 |
249 | @@ -24,5 +24,6 @@ |
250 | import crm_opportunity_to_phonecall |
251 | import crm_lead_to_opportunity |
252 | import crm_merge_opportunities |
253 | +import crm_case_stage_management |
254 | |
255 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
256 | |
257 | === added file 'crm/wizard/crm_case_stage_management.py' |
258 | --- crm/wizard/crm_case_stage_management.py 1970-01-01 00:00:00 +0000 |
259 | +++ crm/wizard/crm_case_stage_management.py 2014-02-27 12:12:58 +0000 |
260 | @@ -0,0 +1,100 @@ |
261 | +# -*- coding: utf-8 -*- |
262 | +############################################################################## |
263 | +# |
264 | +# OpenERP, Open Source Management Solution |
265 | +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). |
266 | +# |
267 | +# This program is free software: you can redistribute it and/or modify |
268 | +# it under the terms of the GNU Affero General Public License as |
269 | +# published by the Free Software Foundation, either version 3 of the |
270 | +# License, or (at your option) any later version. |
271 | +# |
272 | +# This program is distributed in the hope that it will be useful, |
273 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
274 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
275 | +# GNU Affero General Public License for more details. |
276 | +# |
277 | +# You should have received a copy of the GNU Affero General Public License |
278 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
279 | +# |
280 | +############################################################################## |
281 | +from openerp.osv import osv,fields |
282 | + |
283 | +class crm_case_stage_management(osv.TransientModel): |
284 | + |
285 | + _name = "crm.case.stage.management" |
286 | + _description = "Stage of opportunity" |
287 | + _columns = { |
288 | + 'name': fields.char('Stage Name', required= True, size=64), |
289 | + } |
290 | + def default_get(self, cr, uid, fields, context=None): |
291 | + if context is None:context = {} |
292 | + old_stage_id = context.get('active_id') |
293 | + res = super(crm_case_stage_management, self).default_get(cr, uid, fields, context) |
294 | + |
295 | + if(context.get('default_action') == "create"):return res |
296 | + crm_case_type = self.pool.get("crm.case.stage").browse(cr , uid, old_stage_id, context) |
297 | + res.update({'name': crm_case_type.name}) |
298 | + return res |
299 | + |
300 | + def create(self, cr, uid, vals, context): |
301 | + if context is None: context = {} |
302 | + action = context.get('default_action') |
303 | + if action == 'create': self.create_stage(cr, uid, vals.get('name'), context) |
304 | + if action == 'write': self.modify_stage(cr, uid, vals, context) |
305 | + return None |
306 | + |
307 | + def create_stage(self, cr, uid, name, context): |
308 | + if context is None:context = {} |
309 | + section_id = context.get('default_section_id') |
310 | + |
311 | + crm_case_section = self.pool.get('crm.case.section') |
312 | + crm_case_stage = self.pool.get("crm.case.stage") |
313 | + |
314 | + if section_id: |
315 | + new_id = crm_case_stage.search(cr, uid, [('name','=', name)], context=context, limit=1) |
316 | + if not new_id: |
317 | + new_id = [crm_case_stage.create(cr, uid, {'name': name}, context=context)] |
318 | + crm_case_section.write(cr, uid, [section_id], {'stage_ids': [(4, new_id[0])]}, context=context) |
319 | + else: |
320 | + new_id = [crm_case_stage.create(cr, uid, {'name': name}, context=context)] |
321 | + return new_id |
322 | + |
323 | + def unlink(self, cr, uid, ids, context): |
324 | + if context is None: context = {} |
325 | + section_id = context.get('default_section_id') |
326 | + |
327 | + crm_case_section = self.pool.get('crm.case.section') |
328 | + crm_lead = self.pool.get('crm.lead') |
329 | + crm_case_stage = self.pool.get("crm.case.stage") |
330 | + |
331 | + if section_id: |
332 | + for stage_id in ids: |
333 | + crm_lead_ids = crm_lead.search(cr, uid, [('stage_id','=',stage_id),('section_id','=', section_id)]) |
334 | + crm_lead.write(cr, uid, crm_lead_ids, {'stage_id': False} , context=context) |
335 | + crm_case_section.write(cr, uid, section_id, {'stage_ids': [(3, stage_id)]}, context=context) |
336 | + else: |
337 | + crm_case_stage.unlink(cr, uid, ids, context=context) |
338 | + return True |
339 | + |
340 | + def modify_stage(self,cr, uid, vals, context=None): |
341 | + old_stage_id = context.get('active_id') |
342 | + section_id = context.get('default_section_id') |
343 | + |
344 | + crm_case_section = self.pool.get('crm.case.section') |
345 | + crm_lead = self.pool.get('crm.lead') |
346 | + crm_case_stage = self.pool.get("crm.case.stage") |
347 | + if section_id: |
348 | + new_case_type_id = crm_case_stage.search(cr, uid, [('name','=', vals.get('name'))], context=context, limit=1) |
349 | + if not new_case_type_id: |
350 | + vals['section_ids'] = [(6, 0, [section_id])] |
351 | + new_case_type_id = [crm_case_stage.copy(cr, uid, old_stage_id, default=vals, context=context)] |
352 | + new_stage_id = new_case_type_id[0] |
353 | + |
354 | + opportunity_ids = crm_lead.search(cr, uid, [('stage_id','=', old_stage_id),('section_id','=', section_id)], context=context) |
355 | + crm_lead.write(cr, uid, opportunity_ids, {'stage_id': new_stage_id} , context=context) |
356 | + if section_id: |
357 | + crm_case_section.write(cr, uid, [section_id], {'stage_ids': [(3, old_stage_id),(4, new_stage_id),]}, context=context) |
358 | + else: |
359 | + crm_case_stage.write(cr, uid, old_stage_id, vals, context=context) |
360 | + return True |
361 | |
362 | === added file 'crm/wizard/crm_case_stage_management_view.xml' |
363 | --- crm/wizard/crm_case_stage_management_view.xml 1970-01-01 00:00:00 +0000 |
364 | +++ crm/wizard/crm_case_stage_management_view.xml 2014-02-27 12:12:58 +0000 |
365 | @@ -0,0 +1,18 @@ |
366 | +<?xml version="1.0" encoding="utf-8"?> |
367 | +<openerp> |
368 | + <data> |
369 | + <record model="ir.ui.view" id="crm_stage_form_wizard"> |
370 | + <field name="name">crm.case.stage.management.form</field> |
371 | + <field name="model">crm.case.stage.management</field> |
372 | + <field name="arch" type="xml"> |
373 | + <form string="Stage" version="7.0"> |
374 | + <group> |
375 | + <group> |
376 | + <field name="name"/> |
377 | + </group> |
378 | + </group> |
379 | + </form> |
380 | + </field> |
381 | + </record> |
382 | + </data> |
383 | +</openerp> |
384 | \ No newline at end of file |
385 | |
386 | === modified file 'hr/hr_view.xml' |
387 | --- hr/hr_view.xml 2014-02-11 12:04:33 +0000 |
388 | +++ hr/hr_view.xml 2014-02-27 12:12:58 +0000 |
389 | @@ -338,6 +338,8 @@ |
390 | <field name="state" widget="statusbar" statusbar_visible="recruit,open"/> |
391 | </header> |
392 | <sheet> |
393 | + <div name="hr_applicant_button" class="oe_right oe_button_box"> |
394 | + </div> |
395 | <div class="oe_title"> |
396 | <label for="name" class="oe_edit_only"/> |
397 | <h1><field name="name" class="oe_inline"/></h1> |
398 | @@ -484,4 +486,4 @@ |
399 | <menuitem action="open_module_tree_department" id="menu_hr_department_tree" parent="hr.menu_hr_configuration" sequence="5"/> |
400 | |
401 | </data> |
402 | -</openerp> |
403 | +</openerp> |
404 | \ No newline at end of file |
405 | |
406 | === modified file 'hr_recruitment/__init__.py' |
407 | --- hr_recruitment/__init__.py 2012-04-02 05:44:18 +0000 |
408 | +++ hr_recruitment/__init__.py 2014-02-27 12:12:58 +0000 |
409 | @@ -23,5 +23,6 @@ |
410 | import report |
411 | import wizard |
412 | import res_config |
413 | +import tests |
414 | |
415 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
416 | |
417 | === modified file 'hr_recruitment/__openerp__.py' |
418 | --- hr_recruitment/__openerp__.py 2014-02-10 07:21:00 +0000 |
419 | +++ hr_recruitment/__openerp__.py 2014-02-27 12:12:58 +0000 |
420 | @@ -48,6 +48,7 @@ |
421 | ], |
422 | 'data': [ |
423 | 'wizard/hr_recruitment_create_partner_job_view.xml', |
424 | + 'wizard/hr_recruitment_stage_management_view.xml', |
425 | 'hr_recruitment_view.xml', |
426 | 'hr_recruitment_menu.xml', |
427 | 'security/hr_recruitment_security.xml', |
428 | |
429 | === modified file 'hr_recruitment/hr_recruitment.py' |
430 | --- hr_recruitment/hr_recruitment.py 2014-02-12 10:43:40 +0000 |
431 | +++ hr_recruitment/hr_recruitment.py 2014-02-27 12:12:58 +0000 |
432 | @@ -41,6 +41,17 @@ |
433 | 'name': fields.char('Source Name', size=64, required=True, translate=True), |
434 | } |
435 | |
436 | +class hr_recruitment_stage_sequence(osv.osv): |
437 | + _name = 'hr.recruitment.stage.sequence' |
438 | + _table = 'job_stage_rel' |
439 | + _description = 'Hr Recruitment Stage Sequence' |
440 | + _order = 'sequence' |
441 | + _columns = { |
442 | + 'job_id': fields.many2one('hr.job', 'Sequence/Job'), |
443 | + 'stage_id': fields.many2one('hr.recruitment.stage', 'Sequence/Stage'), |
444 | + 'sequence': fields.integer('Sequence') |
445 | + } |
446 | + |
447 | class hr_recruitment_stage(osv.osv): |
448 | """ Stage of HR Recruitment """ |
449 | _name = "hr.recruitment.stage" |
450 | @@ -49,17 +60,38 @@ |
451 | _columns = { |
452 | 'name': fields.char('Name', size=64, required=True, translate=True), |
453 | 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."), |
454 | - '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."), |
455 | + 'job_ids': fields.many2many('hr.job', 'job_stage_rel', 'stage_id','job_id', 'Stages'), |
456 | 'requirements': fields.text('Requirements'), |
457 | + 'case_default': fields.boolean('Default for New Job'), |
458 | 'template_id': fields.many2one('email.template', 'Use template', help="If set, a message is posted on the applicant using the template when the applicant is set to the stage."), |
459 | 'fold': fields.boolean('Folded in Kanban View', |
460 | help='This stage is folded in the kanban view when' |
461 | 'there are no records in that stage to display.'), |
462 | } |
463 | + |
464 | + def _get_default_job_id(self, cr, uid, ctx={}): |
465 | + job = ctx.get('default_job_id', False) |
466 | + if type(job) in (int, long): |
467 | + return [job] |
468 | + return job |
469 | + |
470 | _defaults = { |
471 | 'sequence': 1, |
472 | + 'job_ids': _get_default_job_id, |
473 | + 'case_default': True, |
474 | } |
475 | |
476 | + def write(self, cr, uid, ids, vals, context=None): |
477 | + job_id = context.get('default_job_id') |
478 | + hr_recruitment_stage_sequence = self.pool.get('hr.recruitment.stage.sequence') |
479 | + |
480 | + if job_id: |
481 | + recruitment_ids = hr_recruitment_stage_sequence.search(cr, uid, [('stage_id', '=', ids),('job_id', '=', job_id)], context=context) |
482 | + hr_recruitment_stage_sequence.write(cr, uid, recruitment_ids, vals , context=context) |
483 | + else: |
484 | + return super(hr_recruitment_stage, self).write(cr, uid, ids, vals, context=context) |
485 | + return True |
486 | + |
487 | class hr_recruitment_degree(osv.osv): |
488 | """ Degree of HR Recruitment """ |
489 | _name = "hr.recruitment.degree" |
490 | @@ -88,29 +120,29 @@ |
491 | }, |
492 | } |
493 | |
494 | - def _get_default_department_id(self, cr, uid, context=None): |
495 | + def _get_default_job_id(self, cr, uid, context=None): |
496 | """ Gives default department by checking if present in the context """ |
497 | - return (self._resolve_department_id_from_context(cr, uid, context=context) or False) |
498 | - |
499 | + return (self._resolve_job_id_from_context(cr, uid, context=context) or False) |
500 | + |
501 | def _get_default_stage_id(self, cr, uid, context=None): |
502 | """ Gives default stage_id """ |
503 | - department_id = self._get_default_department_id(cr, uid, context=context) |
504 | - return self.stage_find(cr, uid, [], department_id, [('fold', '=', False)], context=context) |
505 | + job_id = self._get_default_job_id(cr, uid, context=context) |
506 | + return self.stage_find(cr, uid, [], job_id, [('sequence', '=', '1')], context=context) |
507 | |
508 | - def _resolve_department_id_from_context(self, cr, uid, context=None): |
509 | - """ Returns ID of department based on the value of 'default_department_id' |
510 | - context key, or None if it cannot be resolved to a single |
511 | + def _resolve_job_id_from_context(self, cr, uid, context=None): |
512 | + """ Returns ID of job based on the value of 'default_job_id' |
513 | + context key, or None if it cannot be resolved to a single |
514 | department. |
515 | """ |
516 | if context is None: |
517 | context = {} |
518 | - if type(context.get('default_department_id')) in (int, long): |
519 | - return context.get('default_department_id') |
520 | - if isinstance(context.get('default_department_id'), basestring): |
521 | - department_name = context['default_department_id'] |
522 | - department_ids = self.pool.get('hr.department').name_search(cr, uid, name=department_name, context=context) |
523 | - if len(department_ids) == 1: |
524 | - return int(department_ids[0][0]) |
525 | + if type(context.get('default_job_id')) in (int, long): |
526 | + return context.get('default_job_id') |
527 | + if isinstance(context.get('default_job_id'), basestring): |
528 | + job_name = context['default_job_id'] |
529 | + job_ids = self.pool.get('hr.job').name_search(cr, uid, name=job_name, context=context) |
530 | + if len(job_ids) == 1: |
531 | + return int(job_ids[0][0]) |
532 | return None |
533 | |
534 | def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): |
535 | @@ -122,18 +154,23 @@ |
536 | order = "%s desc" % order |
537 | # retrieve section_id from the context and write the domain |
538 | # - ('id', 'in', 'ids'): add columns that should be present |
539 | - # - OR ('department_id', '=', False), ('fold', '=', False): add default columns that are not folded |
540 | - # - OR ('department_id', 'in', department_id), ('fold', '=', False) if department_id: add department columns that are not folded |
541 | - department_id = self._resolve_department_id_from_context(cr, uid, context=context) |
542 | + # - OR ('job_id', '=', False), ('fold', '=', False): add default columns that are not folded |
543 | + # - OR ('job_id', 'in', job_id), ('fold', '=', False) if job_id: add department columns that are not folded |
544 | + job_id = self._resolve_job_id_from_context(cr, uid, context=context) |
545 | search_domain = [] |
546 | - if department_id: |
547 | - search_domain += ['|', ('department_id', '=', department_id)] |
548 | - search_domain += ['|', ('id', 'in', ids), ('department_id', '=', False)] |
549 | + if job_id: |
550 | + search_domain += [('job_ids', '=', job_id)] |
551 | + search_domain += ['|', '|', ('id', 'in', ids), ('job_ids', '=', False), ('case_default', '=', True)] |
552 | stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) |
553 | + if job_id: |
554 | + sequence_ids = self.pool.get('hr.recruitment.stage.sequence').search_read(cr, uid, [('job_id', '=', job_id), ('stage_id', 'in', stage_ids)], ['stage_id'], order=order, context=context) |
555 | + type_ids = map(lambda type_ids: type_ids['stage_id'][0], sequence_ids) |
556 | result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) |
557 | # restore order of the search |
558 | - result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
559 | - |
560 | + if job_id: |
561 | + result.sort(lambda x,y: cmp(type_ids.index(x[0]), type_ids.index(y[0]))) |
562 | + else: |
563 | + result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
564 | fold = {} |
565 | for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): |
566 | fold[stage.id] = stage.fold or False |
567 | @@ -188,7 +225,7 @@ |
568 | 'create_date': fields.datetime('Creation Date', readonly=True, select=True), |
569 | 'write_date': fields.datetime('Update Date', readonly=True), |
570 | 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage', track_visibility='onchange', |
571 | - domain="['|', ('department_id', '=', department_id), ('department_id', '=', False)]"), |
572 | + domain="['|', ('job_ids', '=', job_id), ('job_ids', '=', False)]"), |
573 | 'last_stage_id': fields.many2one('hr.recruitment.stage', 'Last Stage', |
574 | help='Stage of the applicant before being in the current stage. Used for lost cases analysis.'), |
575 | 'categ_ids': fields.many2many('hr.applicant_category', string='Tags'), |
576 | @@ -229,7 +266,7 @@ |
577 | 'active': lambda *a: 1, |
578 | 'user_id': lambda s, cr, uid, c: uid, |
579 | 'stage_id': lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c), |
580 | - 'department_id': lambda s, cr, uid, c: s._get_default_department_id(cr, uid, c), |
581 | + 'job_id': lambda s, cr, uid, c: s._get_default_job_id(cr, uid, c), |
582 | 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.applicant', context=c), |
583 | 'color': 0, |
584 | 'date_last_stage_update': fields.datetime.now, |
585 | @@ -272,17 +309,16 @@ |
586 | if isinstance(cases, (int, long)): |
587 | cases = self.browse(cr, uid, cases, context=context) |
588 | # collect all section_ids |
589 | - department_ids = [] |
590 | + job_ids = [] |
591 | if section_id: |
592 | - department_ids.append(section_id) |
593 | + job_ids.append(section_id) |
594 | for case in cases: |
595 | - if case.department_id: |
596 | - department_ids.append(case.department_id.id) |
597 | + if case.job_id: |
598 | + job_ids.append(case.job_id.id) |
599 | # OR all section_ids and OR with case_default |
600 | search_domain = [] |
601 | - if department_ids: |
602 | - search_domain += ['|', ('department_id', 'in', department_ids)] |
603 | - search_domain.append(('department_id', '=', False)) |
604 | + if job_ids: |
605 | + search_domain += ['|', ('job_ids', 'in', job_ids)] |
606 | # AND with the domain in parameter |
607 | search_domain += list(domain) |
608 | # perform search, return the first found |
609 | @@ -395,6 +431,7 @@ |
610 | if vals.get('user_id'): |
611 | vals['date_start'] = fields.datetime.now() |
612 | # stage_id: track last stage before update |
613 | + res = True |
614 | if 'stage_id' in vals: |
615 | vals['date_last_stage_update'] = fields.datetime.now() |
616 | for applicant in self.browse(cr, uid, ids, context=None): |
617 | @@ -522,6 +559,7 @@ |
618 | 'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True, |
619 | help="Email alias for this job position. New emails will automatically " |
620 | "create new applicants for this job position."), |
621 | + 'stage_ids':fields.many2many('hr.recruitment.stage', 'job_stage_rel','job_id', 'stage_id', 'Stages'), |
622 | 'address_id': fields.many2one('res.partner', 'Job Location', help="Address where employees are working"), |
623 | 'application_ids': fields.one2many('hr.applicant', 'job_id', 'Applications'), |
624 | 'manager_id': fields.related('department_id', 'manager_id', type='many2one', string='Department Manager', relation='hr.employee', readonly=True, store=True), |
625 | @@ -534,7 +572,12 @@ |
626 | user = self.pool.get('res.users').browse(cr, uid, uid, context=context) |
627 | return user.company_id.partner_id.id |
628 | |
629 | + def _get_stage_common(self, cr, uid, context): |
630 | + return self.pool.get('hr.recruitment.stage').search(cr, uid, [('case_default','=',1)], context=context) |
631 | + |
632 | _defaults = { |
633 | + 'alias_domain': False, # always hide alias during creation |
634 | + 'stage_ids': _get_stage_common, |
635 | 'address_id': _address_get |
636 | } |
637 | |
638 | @@ -596,4 +639,4 @@ |
639 | 'name': fields.char('Name', size=64, required=True, translate=True), |
640 | } |
641 | |
642 | -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
643 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
644 | \ No newline at end of file |
645 | |
646 | === modified file 'hr_recruitment/hr_recruitment_demo.xml' |
647 | --- hr_recruitment/hr_recruitment_demo.xml 2013-12-24 05:37:04 +0000 |
648 | +++ hr_recruitment/hr_recruitment_demo.xml 2014-02-27 12:12:58 +0000 |
649 | @@ -127,32 +127,39 @@ |
650 | <field name="state">recruit</field> |
651 | <field name="no_of_recruitment">4</field> |
652 | <field name="survey_id" ref="survey_job_0"/> |
653 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
654 | </record> |
655 | <record id="hr.job_ceo" model="hr.job"> |
656 | <field name="survey_id" ref="survey_job_0"/> |
657 | + <field name= "stage_ids" eval="[(4, stage_job3),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
658 | </record> |
659 | <record id="hr.job_cto" model="hr.job"> |
660 | <field name="survey_id" ref="survey_job_0"/> |
661 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job4),(4, stage_job5),(4, stage_job6)]" /> |
662 | </record> |
663 | <record id="hr.job_consultant" model="hr.job"> |
664 | <field name="state">recruit</field> |
665 | <field name="no_of_recruitment">1</field> |
666 | <field name="survey_id" ref="survey_job_0"/> |
667 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
668 | </record> |
669 | <record id="hr.job_hrm" model="hr.job"> |
670 | <field name="no_of_recruitment">1</field> |
671 | <field name="state">recruit</field> |
672 | <field name="survey_id" ref="survey_job_0"/> |
673 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
674 | </record> |
675 | <record id="hr.job_marketing" model="hr.job"> |
676 | <field name="state">recruit</field> |
677 | <field name="no_of_recruitment">3</field> |
678 | <field name="survey_id" ref="survey_job_0"/> |
679 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
680 | </record> |
681 | <record id="hr.job_trainee" model="hr.job"> |
682 | <field name="state">recruit</field> |
683 | <field name="no_of_recruitment">6</field> |
684 | <field name="survey_id" ref="survey_job_0"/> |
685 | + <field name= "stage_ids" eval="[(4, stage_job1),(4, stage_job2),(4, stage_job3),(4, stage_job4)]" /> |
686 | </record> |
687 | |
688 | <record id="message_application_demo" model="mail.message"> |
689 | |
690 | === modified file 'hr_recruitment/hr_recruitment_menu.xml' |
691 | --- hr_recruitment/hr_recruitment_menu.xml 2014-02-11 11:41:21 +0000 |
692 | +++ hr_recruitment/hr_recruitment_menu.xml 2014-02-27 12:12:58 +0000 |
693 | @@ -1,26 +1,6 @@ |
694 | <?xml version="1.0"?> |
695 | <openerp> |
696 | <data> |
697 | - ######################## JOB OPPORTUNITIES (menu) ########################### |
698 | - <record model="ir.actions.act_window" id="crm_case_categ0_act_job"> |
699 | - <field name="name">Applications</field> |
700 | - <field name="res_model">hr.applicant</field> |
701 | - <field name="view_mode">kanban,tree,form,graph,calendar</field> |
702 | - <field name="view_id" eval="False"/> |
703 | - <field name="search_view_id" ref="view_crm_case_jobs_filter"/> |
704 | - <field name="context">{'empty_list_help_model': 'hr.job'}</field> |
705 | - <field name="help" type="html"> |
706 | - <p> |
707 | - OpenERP helps you track applicants in the recruitment |
708 | - process and follow up all operations: meetings, interviews, etc. |
709 | - </p><p> |
710 | - Applicants and their attached CV are created automatically when an email is sent. |
711 | - If you install the document management modules, all resumes are indexed automatically, |
712 | - so that you can easily search through their content. |
713 | - </p> |
714 | - </field> |
715 | - </record> |
716 | - |
717 | <record model="ir.actions.act_window.view" id="action_hr_sec_kanban_view_act_job"> |
718 | <field name="sequence" eval="0"/> |
719 | <field name="view_mode">kanban</field> |
720 | @@ -61,5 +41,34 @@ |
721 | name="Applications" |
722 | parent="base.menu_crm_case_job_req_main" |
723 | id="menu_crm_case_categ0_act_job" action="crm_case_categ0_act_job" sequence="2"/> |
724 | + |
725 | + <menuitem parent="hr.menu_hr_configuration" id="hr.menu_hr_job" action="hr.action_hr_job" sequence="2"/> |
726 | + |
727 | + <menuitem name="Recruitment" |
728 | + id="menu_hr_recruitment_recruitment" |
729 | + parent="hr.menu_hr_configuration" |
730 | + sequence="40"/> |
731 | + |
732 | + <menuitem |
733 | + id="menu_hr_recruitment_stage" |
734 | + name="Stages" |
735 | + parent="menu_hr_recruitment_recruitment" |
736 | + action="hr_recruitment_stage_act" |
737 | + sequence="1" groups="base.group_no_one"/> |
738 | + |
739 | + <menuitem |
740 | + id="menu_hr_recruitment_degree" |
741 | + name="Degrees" |
742 | + parent="menu_hr_recruitment_recruitment" |
743 | + action="hr_recruitment_degree_action" |
744 | + sequence="5" groups="base.group_no_one"/> |
745 | + |
746 | + <menuitem |
747 | + id="menu_hr_recruitment_source" |
748 | + parent="menu_hr_recruitment_recruitment" |
749 | + action="hr_recruitment_source_action" |
750 | + groups="base.group_no_one" |
751 | + sequence="10"/> |
752 | + |
753 | </data> |
754 | -</openerp> |
755 | +</openerp> |
756 | \ No newline at end of file |
757 | |
758 | === modified file 'hr_recruitment/hr_recruitment_view.xml' |
759 | --- hr_recruitment/hr_recruitment_view.xml 2014-02-11 12:23:08 +0000 |
760 | +++ hr_recruitment/hr_recruitment_view.xml 2014-02-27 12:12:58 +0000 |
761 | @@ -2,11 +2,6 @@ |
762 | <openerp> |
763 | <data> |
764 | |
765 | - <menuitem name="Recruitment" |
766 | - id="menu_hr_recruitment_recruitment" |
767 | - parent="hr.menu_hr_configuration" |
768 | - sequence="40"/> |
769 | - |
770 | <act_window |
771 | id="act_hr_applicant_to_meeting" |
772 | name="Meetings" |
773 | @@ -33,7 +28,6 @@ |
774 | </field> |
775 | </record> |
776 | |
777 | - |
778 | <!-- Applicants --> |
779 | <record model="ir.ui.view" id="crm_case_tree_view_job"> |
780 | <field name="name">Applicants</field> |
781 | @@ -121,7 +115,7 @@ |
782 | <field name="survey" invisible="1"/> |
783 | <field name="response" invisible="1"/> |
784 | <field name="job_id" on_change="onchange_job(job_id)"/> |
785 | - <field name="department_id" on_change="onchange_department_id(department_id, stage_id)"/> |
786 | + <field name="department_id"/> |
787 | <field name="company_id" /> |
788 | <label for="availability"/> |
789 | <div> |
790 | @@ -207,6 +201,25 @@ |
791 | </search> |
792 | </field> |
793 | </record> |
794 | + |
795 | + <!-- Applications Action--> |
796 | + <record model="ir.actions.act_window" id="crm_case_categ0_act_job"> |
797 | + <field name="name">Applications</field> |
798 | + <field name="res_model">hr.applicant</field> |
799 | + <field name="view_mode">kanban,tree,form,graph,calendar</field> |
800 | + <field name="view_id" eval="False"/> |
801 | + <field name="search_view_id" ref="view_crm_case_jobs_filter"/> |
802 | + <field name="help" type="html"> |
803 | + <p> |
804 | + OpenERP helps you track applicants in the recruitment |
805 | + process and follow up all operations: meetings, interviews, etc. |
806 | + </p><p> |
807 | + Applicants and their attached CV are created automatically when an email is sent. |
808 | + If you install the document management modules, all resumes are indexed automatically, |
809 | + so that you can easily search through their content. |
810 | + </p> |
811 | + </field> |
812 | + </record> |
813 | |
814 | <!-- CRM Lead Calendar View --> |
815 | <record model="ir.ui.view" id="hr_applicant_calendar_view"> |
816 | @@ -228,7 +241,7 @@ |
817 | <field name="name">Hr Applicants kanban</field> |
818 | <field name="model">hr.applicant</field> |
819 | <field name="arch" type="xml"> |
820 | - <kanban default_group_by="stage_id"> |
821 | + <kanban default_group_by="stage_id" stage_management="hr.recruitment.stage.management" stage_options = "{'group_by':'stage_id'}"> |
822 | <field name="stage_id"/> |
823 | <field name="color"/> |
824 | <field name="priority"/> |
825 | @@ -364,6 +377,14 @@ |
826 | </div> |
827 | </div> |
828 | </xpath> |
829 | + <xpath expr="//div[@name='hr_applicant_button']" position="inside"> |
830 | + <button name="%(crm_case_categ0_act_job)d" string="Applications" type="action" |
831 | + context="{'search_default_job_id': active_id, 'stage_m2m_field':'stage_ids'}"/> |
832 | + </xpath> |
833 | + <xpath expr="//field[@name='requirements']" position="after"> |
834 | + <separator string="Recruitment Stages" /> |
835 | + <field name="stage_ids" nolabel="1"/> |
836 | + </xpath> |
837 | <xpath expr="//field[@name='department_id']" position="after"> |
838 | <field name="user_id" class="oe_inline"/> |
839 | </xpath> |
840 | @@ -499,7 +520,6 @@ |
841 | <tree string="Stages"> |
842 | <field name="sequence" invisible="1"/> |
843 | <field name="name"/> |
844 | - <field name="department_id"/> |
845 | <field name="fold"/> |
846 | </tree> |
847 | </field> |
848 | @@ -515,16 +535,17 @@ |
849 | <group string="Stage Definition"> |
850 | <group> |
851 | <field name="name"/> |
852 | - <field name="department_id"/> |
853 | + <field name="fold"/> |
854 | + <field name="case_default"/> |
855 | </group> |
856 | <group> |
857 | <field name="sequence"/> |
858 | - <field name="fold"/> |
859 | <field name="template_id" domain= "[('model_id.model', '=', 'hr.applicant')]"/> |
860 | </group> |
861 | </group> |
862 | <separator string="Requirements"/> |
863 | <field name="requirements"/> |
864 | + <field name="job_ids" invisible="1"/> |
865 | </sheet> |
866 | </form> |
867 | </field> |
868 | @@ -545,14 +566,7 @@ |
869 | </p> |
870 | </field> |
871 | </record> |
872 | - |
873 | - <menuitem |
874 | - id="menu_hr_recruitment_stage" |
875 | - name="Stages" |
876 | - parent="menu_hr_recruitment_recruitment" |
877 | - action="hr_recruitment_stage_act" |
878 | - sequence="1" groups="base.group_no_one"/> |
879 | - |
880 | + |
881 | <!-- Degree Tree View --> |
882 | <record model="ir.ui.view" id="hr_recruitment_degree_tree"> |
883 | <field name="name">hr.recruitment.degree.tree</field> |
884 | @@ -589,13 +603,6 @@ |
885 | <field name="view_id" ref="hr_recruitment_degree_tree"/> |
886 | </record> |
887 | |
888 | - <menuitem |
889 | - id="menu_hr_recruitment_degree" |
890 | - name="Degrees" |
891 | - parent="menu_hr_recruitment_recruitment" |
892 | - action="hr_recruitment_degree_action" |
893 | - sequence="5" groups="base.group_no_one"/> |
894 | - |
895 | <!-- Source Tree View --> |
896 | <record model="ir.ui.view" id="hr_recruitment_source_tree"> |
897 | <field name="name">hr.recruitment.source.tree</field> |
898 | @@ -625,12 +632,5 @@ |
899 | <field name="view_type">form</field> |
900 | </record> |
901 | |
902 | - <menuitem |
903 | - id="menu_hr_recruitment_source" |
904 | - parent="menu_hr_recruitment_recruitment" |
905 | - action="hr_recruitment_source_action" |
906 | - groups="base.group_no_one" |
907 | - sequence="10"/> |
908 | - |
909 | </data> |
910 | -</openerp> |
911 | +</openerp> |
912 | \ No newline at end of file |
913 | |
914 | === modified file 'hr_recruitment/security/ir.model.access.csv' |
915 | --- hr_recruitment/security/ir.model.access.csv 2014-01-15 09:38:05 +0000 |
916 | +++ hr_recruitment/security/ir.model.access.csv 2014-02-27 12:12:58 +0000 |
917 | @@ -1,7 +1,10 @@ |
918 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
919 | access_hr_applicant_user,hr.applicant.user,model_hr_applicant,base.group_hr_user,1,1,1,1 |
920 | access_hr_recruitment_report,hr.recruitment.report,model_hr_recruitment_report,base.group_hr_manager,1,1,1,1 |
921 | -access_hr_recruitment_stage_user,hr.recruitment.stage.user,model_hr_recruitment_stage,base.group_hr_user,1,1,1,1 |
922 | +access_hr_recruitment_stage_user,hr.recruitment.stage.user,model_hr_recruitment_stage,base.group_hr_user,1,0,0,0 |
923 | +access_hr_recruitment_stage_manager,hr.recruitment.stage.manager,model_hr_recruitment_stage,base.group_hr_manager,1,1,1,1 |
924 | +access_hr_recruitment_stage_sequence_user,hr.recruitment.stage.sequence.user,model_hr_recruitment_stage_sequence,base.group_hr_user,1,0,0,0 |
925 | +access_hr_recruitment_stage_sequence_manager,hr.recruitment.stage.sequence.manager,model_hr_recruitment_stage_sequence,base.group_hr_manager,1,1,1,1 |
926 | access_hr_recruitment_degree,hr.recruitment.degree,model_hr_recruitment_degree,base.group_hr_user,1,1,1,1 |
927 | access_res_partner_hr_user,res.partner.user,base.model_res_partner,base.group_hr_user,1,1,1,1 |
928 | access_survey_hr_user,survey.hr.user,survey.model_survey,base.group_hr_user,1,1,1,0 |
929 | |
930 | === added directory 'hr_recruitment/tests' |
931 | === added file 'hr_recruitment/tests/__init__.py' |
932 | --- hr_recruitment/tests/__init__.py 1970-01-01 00:00:00 +0000 |
933 | +++ hr_recruitment/tests/__init__.py 2014-02-27 12:12:58 +0000 |
934 | @@ -0,0 +1,24 @@ |
935 | +# -*- coding: utf-8 -*- |
936 | +############################################################################## |
937 | +# |
938 | +# OpenERP, Open Source Business Applications |
939 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
940 | +# |
941 | +# This program is free software: you can redistribute it and/or modify |
942 | +# it under the terms of the GNU Affero General Public License as |
943 | +# published by the Free Software Foundation, either version 3 of the |
944 | +# License, or (at your option) any later version. |
945 | +# |
946 | +# This program is distributed in the hope that it will be useful, |
947 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
948 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
949 | +# GNU Affero General Public License for more details. |
950 | +# |
951 | +# You should have received a copy of the GNU Affero General Public License |
952 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
953 | +# |
954 | +############################################################################## |
955 | +from . import test_hr_recruitment_stage |
956 | +checks = [ |
957 | + test_hr_recruitment_stage, |
958 | + ] |
959 | \ No newline at end of file |
960 | |
961 | === added file 'hr_recruitment/tests/test_hr_recruitment_stage.py' |
962 | --- hr_recruitment/tests/test_hr_recruitment_stage.py 1970-01-01 00:00:00 +0000 |
963 | +++ hr_recruitment/tests/test_hr_recruitment_stage.py 2014-02-27 12:12:58 +0000 |
964 | @@ -0,0 +1,77 @@ |
965 | +# -*- coding: utf-8 -*- |
966 | +############################################################################## |
967 | +# |
968 | +# OpenERP, Open Source Business Applications |
969 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
970 | +# |
971 | +# This program is free software: you can redistribute it and/or modify |
972 | +# it under the terms of the GNU Affero General Public License as |
973 | +# published by the Free Software Foundation, either version 3 of the |
974 | +# License, or (at your option) any later version. |
975 | +# |
976 | +# This program is distributed in the hope that it will be useful, |
977 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
978 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
979 | +# GNU Affero General Public License for more details. |
980 | +# |
981 | +# You should have received a copy of the GNU Affero General Public License |
982 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
983 | +# |
984 | +############################################################################## |
985 | +from openerp.osv.orm import except_orm |
986 | +from openerp.tests import common |
987 | + |
988 | + |
989 | +class TestHrRecruitmentStage(common.TransactionCase): |
990 | + def setUp(self): |
991 | + super(TestHrRecruitmentStage, self).setUp() |
992 | + |
993 | + def test_00_stage_management(self): |
994 | + cr, uid = self.cr, self.uid |
995 | + recruitment_stage_management = self.registry('hr.recruitment.stage.management') |
996 | + hr_job = self.registry('hr.job') |
997 | + hr_recruitment_stage= self.registry('hr.recruitment.stage') |
998 | + hr_applicant = self.registry('hr.applicant'); |
999 | + hr_job_id = hr_job.create(cr, uid, {'name':'test_section'},context={}) |
1000 | + context = {'default_job_id': hr_job_id, 'default_action':'create'} |
1001 | + |
1002 | + ''' For create when default_job_id pass in context |
1003 | + If same name is present than returns its id otherwise create new. |
1004 | + and link with given job. |
1005 | + ''' |
1006 | + |
1007 | + stage_m2m_oldlist = hr_job.browse(cr, uid, hr_job_id, context=context).stage_ids |
1008 | + recruitment_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1009 | + recruitment_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1010 | + check_len_id = hr_recruitment_stage.search(cr, uid, [('name','=', 'First')], context=context) |
1011 | + self.assertEqual(len(check_len_id), 1) |
1012 | + hr_applicant_id = hr_applicant.create(cr, uid, {'name':'Test1','stage_id': check_len_id[0],'job_id':hr_job_id}) |
1013 | + test1 = check_len_id |
1014 | + stage_m2m_newlist = hr_job.browse(cr, uid, hr_job_id, context=context).stage_ids |
1015 | + self.assertEqual(len(stage_m2m_oldlist) + 1, len(stage_m2m_newlist)) |
1016 | + |
1017 | + ''' For edit when default_job_id pass in context |
1018 | + If same name is present than returns its id otherwise create new. |
1019 | + and link with given job and remove old link with job and project_task. |
1020 | + ''' |
1021 | + |
1022 | + context.update({'active_id':test1[0], 'default_action':'create'}) |
1023 | + recruitment_stage_management.modify_stage(cr, uid, {'name':'Second'}, context=context) |
1024 | + test2 = hr_recruitment_stage.search(cr, uid, [('name','=', 'Second')], context=context) |
1025 | + stage_m2m_newlist = hr_job.browse(cr, uid, hr_job_id, context=context).stage_ids |
1026 | + |
1027 | + check_hr_recruitment_stage_id = hr_applicant.browse(cr, uid, hr_applicant_id, context).stage_id.id |
1028 | + self.assertEqual(check_hr_recruitment_stage_id, test2[0]) |
1029 | + self.assertIn(test2[0], [x.id for x in stage_m2m_newlist]) |
1030 | + |
1031 | + ''' For unlink when default_job_id pass in context |
1032 | + It will unlink relation, not delete. |
1033 | + ''' |
1034 | + |
1035 | + stage_m2m_oldlist = hr_job.browse(cr, uid, hr_job_id, context=context).stage_ids |
1036 | + recruitment_stage_management.unlink(cr, uid, test2, context=context) |
1037 | + stage_m2m_newlist = hr_job.browse(cr, uid, hr_job_id, context=context).stage_ids |
1038 | + self.assertEqual(len(stage_m2m_oldlist) -1, len(stage_m2m_newlist)) |
1039 | + unlink_id = hr_recruitment_stage.search(cr, uid, [('name','=', 'Second')], context=context) |
1040 | + self.assertEqual(unlink_id, test2) |
1041 | + |
1042 | |
1043 | === modified file 'hr_recruitment/wizard/__init__.py' |
1044 | --- hr_recruitment/wizard/__init__.py 2013-10-27 12:31:04 +0000 |
1045 | +++ hr_recruitment/wizard/__init__.py 2014-02-27 12:12:58 +0000 |
1046 | @@ -20,6 +20,5 @@ |
1047 | ############################################################################## |
1048 | |
1049 | import hr_recruitment_create_partner_job |
1050 | - |
1051 | +import hr_recruitment_stage_management |
1052 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1053 | - |
1054 | |
1055 | === added file 'hr_recruitment/wizard/hr_recruitment_stage_management.py' |
1056 | --- hr_recruitment/wizard/hr_recruitment_stage_management.py 1970-01-01 00:00:00 +0000 |
1057 | +++ hr_recruitment/wizard/hr_recruitment_stage_management.py 2014-02-27 12:12:58 +0000 |
1058 | @@ -0,0 +1,104 @@ |
1059 | +# -*- coding: utf-8 -*- |
1060 | +############################################################################## |
1061 | +# |
1062 | +# OpenERP, Open Source Management Solution |
1063 | +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved |
1064 | +# $Id$ |
1065 | +# |
1066 | +# This program is free software: you can redistribute it and/or modify |
1067 | +# it under the terms of the GNU Affero General Public License as published by |
1068 | +# the Free Software Foundation, either version 3 of the License, or |
1069 | +# (at your option) any later version. |
1070 | +# |
1071 | +# This program is distributed in the hope that it will be useful, |
1072 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1073 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1074 | +# GNU Affero General Public License for more details. |
1075 | +# |
1076 | +# You should have received a copy of the GNU Affero General Public License |
1077 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1078 | +# |
1079 | +############################################################################## |
1080 | +from openerp.osv import fields, osv |
1081 | +from openerp.tools.translate import _ |
1082 | + |
1083 | +class hr_recruitment_stage_management(osv.TransientModel): |
1084 | + |
1085 | + _name = "hr.recruitment.stage.management" |
1086 | + _description = "Stages of application" |
1087 | + |
1088 | + _columns = { |
1089 | + 'name': fields.char('Stage Name', required= True, size=64), |
1090 | + } |
1091 | + def default_get(self, cr, uid, fields, context=None): |
1092 | + if context is None:context = {} |
1093 | + old_stage_id = context.get('active_id') |
1094 | + res = super(hr_recruitment_stage_management, self).default_get(cr, uid, fields, context) |
1095 | + |
1096 | + if(context.get('default_action') == "create"):return res |
1097 | + hr_rec_stage = self.pool.get("hr.recruitment.stage").browse(cr , uid, old_stage_id, context) |
1098 | + res.update({'name': hr_rec_stage.name}) |
1099 | + return res |
1100 | + |
1101 | + |
1102 | + def create(self, cr, uid, vals, context): |
1103 | + if context is None: context = {} |
1104 | + action = context.get('default_action') |
1105 | + if action == 'create': self.create_stage(cr, uid, vals.get('name'), context) |
1106 | + if action == 'write': self.modify_stage(cr, uid, vals, context) |
1107 | + return None |
1108 | + |
1109 | + def create_stage(self, cr, uid, name, context): |
1110 | + if context is None:context = {} |
1111 | + job_id = context.get('default_job_id') |
1112 | + |
1113 | + hr_job = self.pool.get('hr.job') |
1114 | + hr_rec_stage = self.pool.get("hr.recruitment.stage") |
1115 | + |
1116 | + if job_id: |
1117 | + new_id = hr_rec_stage.search(cr, uid, [('name','=', name)], context=context, limit=1) |
1118 | + if not new_id: |
1119 | + new_id = [hr_rec_stage.create(cr, uid, {'name': name}, context = context)] |
1120 | + hr_job.write(cr, uid, [job_id], {'stage_ids': [(4, new_id[0])]}, context=context) |
1121 | + else: |
1122 | + new_id = [hr_rec_stage.create(cr, uid, {'name': name}, context = context)] |
1123 | + return new_id |
1124 | + |
1125 | + def unlink(self, cr, uid, ids, context=None): |
1126 | + if context is None: context = {} |
1127 | + job_id = context.get('default_job_id') |
1128 | + |
1129 | + hr_applicant = self.pool.get('hr.applicant') |
1130 | + hr_job = self.pool.get('hr.job') |
1131 | + hr_rec_stage = self.pool.get("hr.recruitment.stage") |
1132 | + |
1133 | + if job_id: |
1134 | + for stage_id in ids: |
1135 | + hr_applicant_ids = hr_applicant.search(cr, uid, [('stage_id','=',stage_id),('job_id','=', job_id)]) |
1136 | + hr_applicant.write(cr, uid, hr_applicant_ids, {'stage_id': False} , context=context) |
1137 | + hr_job.write(cr, uid, job_id, {'stage_ids': [(3, stage_id)]}, context=context) |
1138 | + else: |
1139 | + hr_rec_stage.unlink(cr, uid, ids, context=context) |
1140 | + return True |
1141 | + |
1142 | + def modify_stage(self,cr, uid, vals, context=None): |
1143 | + old_stage_id = context.get('active_id') |
1144 | + job_id = context.get('default_job_id') |
1145 | + |
1146 | + hr_job = self.pool.get('hr.job') |
1147 | + hr_applicant = self.pool.get('hr.applicant') |
1148 | + hr_rec_stage = self.pool.get("hr.recruitment.stage") |
1149 | + |
1150 | + if job_id: |
1151 | + hr_rec_stage_id = hr_rec_stage.search(cr, uid, [('name','=', vals.get('name'))], context=context, limit=1) |
1152 | + if not hr_rec_stage_id: |
1153 | + vals['job_ids'] = [(6, 0, [job_id])] |
1154 | + hr_rec_stage_id = [hr_rec_stage.copy(cr, uid, old_stage_id, default=vals, context=context)] |
1155 | + new_stage_id = hr_rec_stage_id[0] |
1156 | + |
1157 | + applicant_ids = hr_applicant.search(cr, uid, [('stage_id','=', old_stage_id),('job_id','=', job_id)], context=context) |
1158 | + hr_applicant.write(cr, uid, applicant_ids, {'stage_id': new_stage_id} , context=context) |
1159 | + hr_job.write(cr, uid, [job_id], {'stage_ids': [(3, old_stage_id),(4, new_stage_id),]}, context=context) |
1160 | + else: |
1161 | + hr_rec_stage.write(cr, uid, old_stage_id, vals, context=context) |
1162 | + return True |
1163 | \ No newline at end of file |
1164 | |
1165 | === added file 'hr_recruitment/wizard/hr_recruitment_stage_management_view.xml' |
1166 | --- hr_recruitment/wizard/hr_recruitment_stage_management_view.xml 1970-01-01 00:00:00 +0000 |
1167 | +++ hr_recruitment/wizard/hr_recruitment_stage_management_view.xml 2014-02-27 12:12:58 +0000 |
1168 | @@ -0,0 +1,19 @@ |
1169 | +<?xml version="1.0"?> |
1170 | +<openerp> |
1171 | + <data> |
1172 | + <record model="ir.ui.view" id="crm_case_stage_form_wizard"> |
1173 | + <field name="name">hr.recruitment.stage.management.form</field> |
1174 | + <field name="model">hr.recruitment.stage.management</field> |
1175 | + <field name="arch" type="xml"> |
1176 | + <form string="Stage" version="7.0"> |
1177 | + <group> |
1178 | + <group> |
1179 | + <field name="name"/> |
1180 | + </group> |
1181 | + </group> |
1182 | + </form> |
1183 | + </field> |
1184 | + </record> |
1185 | + |
1186 | + </data> |
1187 | +</openerp> |
1188 | \ No newline at end of file |
1189 | |
1190 | === modified file 'project/__openerp__.py' |
1191 | --- project/__openerp__.py 2013-10-27 12:31:04 +0000 |
1192 | +++ project/__openerp__.py 2014-02-27 12:12:58 +0000 |
1193 | @@ -65,6 +65,7 @@ |
1194 | 'data': [ |
1195 | 'security/project_security.xml', |
1196 | 'wizard/project_task_delegate_view.xml', |
1197 | + 'wizard/project_stage_management.xml', |
1198 | 'security/ir.model.access.csv', |
1199 | 'project_data.xml', |
1200 | 'project_view.xml', |
1201 | |
1202 | === modified file 'project/project.py' |
1203 | --- project/project.py 2014-02-12 17:51:41 +0000 |
1204 | +++ project/project.py 2014-02-27 12:12:58 +0000 |
1205 | @@ -29,6 +29,16 @@ |
1206 | from openerp.osv import fields, osv |
1207 | from openerp.tools.translate import _ |
1208 | |
1209 | +class project_task_type_sequence(osv.osv): |
1210 | + _name = 'project.task.type.sequence' |
1211 | + _table = 'project_task_type_rel' |
1212 | + _description = 'Task Stage Sequence' |
1213 | + _order = 'sequence' |
1214 | + _columns = { |
1215 | + 'project_id': fields.many2one('project.project', 'Sequence/Project'), |
1216 | + 'type_id': fields.many2one('project.task.type', 'Sequence/Stage'), |
1217 | + 'sequence': fields.integer('Sequence') |
1218 | + } |
1219 | |
1220 | class project_task_type(osv.osv): |
1221 | _name = 'project.task.type' |
1222 | @@ -56,8 +66,19 @@ |
1223 | 'sequence': 1, |
1224 | 'project_ids': _get_default_project_ids, |
1225 | } |
1226 | + |
1227 | _order = 'sequence' |
1228 | |
1229 | + def write(self, cr, uid, ids, vals, context=None): |
1230 | + project_id = context.get('default_project_id') |
1231 | + project_task_type_sequence = self.pool.get('project.task.type.sequence') |
1232 | + |
1233 | + if project_id: |
1234 | + task_ids = project_task_type_sequence.search(cr, uid, [('type_id', '=', ids),('project_id', '=', project_id)], context=context) |
1235 | + project_task_type_sequence.write(cr, uid, task_ids, vals , context=context) |
1236 | + else: |
1237 | + return super(project_task_type, self).write(cr, uid, ids, vals, context=context) |
1238 | + return True |
1239 | |
1240 | class project(osv.osv): |
1241 | _name = "project.project" |
1242 | @@ -197,7 +218,8 @@ |
1243 | ctx['active_test'] = False |
1244 | task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)], context=ctx) |
1245 | for task in self.pool.get('project.task').browse(cr, uid, task_ids, context): |
1246 | - res[task.project_id.id] += 1 |
1247 | + if task.stage_id.fold == False: |
1248 | + res[task.project_id.id] += 1 |
1249 | return res |
1250 | |
1251 | def _get_alias_models(self, cr, uid, context=None): |
1252 | @@ -618,13 +640,17 @@ |
1253 | search_domain = [] |
1254 | project_id = self._resolve_project_id_from_context(cr, uid, context=context) |
1255 | if project_id: |
1256 | - search_domain += ['|', ('project_ids', '=', project_id)] |
1257 | - search_domain += [('id', 'in', ids)] |
1258 | + search_domain += [('project_ids', '=', project_id)] |
1259 | stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) |
1260 | + if project_id: |
1261 | + sequence_ids = self.pool.get('project.task.type.sequence').search_read(cr, uid, [('project_id', '=', project_id), ('type_id', 'in', stage_ids)], ['type_id'], order=order, context=context) |
1262 | + type_ids = map(lambda type_ids: type_ids['type_id'][0], sequence_ids) |
1263 | result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) |
1264 | # restore order of the search |
1265 | - result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
1266 | - |
1267 | + if project_id: |
1268 | + result.sort(lambda x,y: cmp(type_ids.index(x[0]), type_ids.index(y[0]))) |
1269 | + else: |
1270 | + result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
1271 | fold = {} |
1272 | for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): |
1273 | fold[stage.id] = stage.fold or False |
1274 | |
1275 | === modified file 'project/project_view.xml' |
1276 | --- project/project_view.xml 2013-12-24 10:29:22 +0000 |
1277 | +++ project/project_view.xml 2014-02-27 12:12:58 +0000 |
1278 | @@ -50,7 +50,6 @@ |
1279 | <field name="view_mode">kanban,tree,form,calendar,gantt,graph</field> |
1280 | <field name="context">{ |
1281 | 'search_default_project_id': [active_id], |
1282 | - 'default_project_id': active_id, |
1283 | 'active_test': False, |
1284 | }</field> |
1285 | <field name="search_view_id" ref="view_task_search_form"/> |
1286 | @@ -469,7 +468,7 @@ |
1287 | <field name="name">project.task.kanban</field> |
1288 | <field name="model">project.task</field> |
1289 | <field name="arch" type="xml"> |
1290 | - <kanban default_group_by="stage_id" > |
1291 | + <kanban default_group_by="stage_id" stage_management="project.stage.management" stage_options = "{'group_by':'stage_id'}"> |
1292 | <field name="color"/> |
1293 | <field name="priority"/> |
1294 | <field name="stage_id"/> |
1295 | |
1296 | === modified file 'project/security/ir.model.access.csv' |
1297 | --- project/security/ir.model.access.csv 2013-10-27 12:31:04 +0000 |
1298 | +++ project/security/ir.model.access.csv 2014-02-27 12:12:58 +0000 |
1299 | @@ -3,7 +3,10 @@ |
1300 | access_project_project_manager,project.project,model_project_project,project.group_project_manager,1,1,1,1 |
1301 | access_account_analytic_account_user,account.analytic.account,analytic.model_account_analytic_account,project.group_project_user,1,0,0,0 |
1302 | access_account_analytic_account,account.analytic.account,analytic.model_account_analytic_account,project.group_project_manager,1,1,1,1 |
1303 | -access_project_task_type_user,project.task.type user,model_project_task_type,project.group_project_user,1,1,1,1 |
1304 | +access_project_task_type_user,project.task.type user,model_project_task_type,project.group_project_user,1,0,0,0 |
1305 | +access_project_task_type_manager,project.task.type manager,model_project_task_type,project.group_project_manager,1,1,1,1 |
1306 | +access_project_task_type_sequence_user,project.task.type.sequence user,model_project_task_type_sequence,project.group_project_user,1,0,0,0 |
1307 | +access_project_task_type_sequence_manager,project.task.type.sequence manager,model_project_task_type_sequence,project.group_project_manager,1,1,1,1 |
1308 | access_project_task,project.task,model_project_task,project.group_project_user,1,1,1,1 |
1309 | access_project_task_work,project.task.work,model_project_task_work,project.group_project_user,1,1,1,1 |
1310 | access_report_project_task_user,report.project.task.user,model_report_project_task_user,project.group_project_manager,1,1,1,1 |
1311 | @@ -11,7 +14,7 @@ |
1312 | access_task_on_partner,project.task on partners,model_project_task,base.group_user,1,0,0,0 |
1313 | access_project_on_partner,project.project on partners,model_project_project,base.group_user,1,0,0,0 |
1314 | access_project_task_sale_user,project.task salesman,model_project_task,base.group_sale_salesman,1,1,1,1 |
1315 | -access_project_task_type_sale_user,project.task.type salesman,project.model_project_task_type,base.group_sale_salesman,1,1,1,1 |
1316 | +access_project_task_type_sale_user,project.task.type salesman,project.model_project_task_type,base.group_sale_salesman,1,0,0,0 |
1317 | access_project_task_history_sale_user,project.task.history salesman,project.model_project_task_history,base.group_sale_salesman,1,1,1,1 |
1318 | access_project_project_sale_user,project.project salesman,model_project_project,base.group_sale_salesman,1,0,0,0 |
1319 | access_account_analytic_line_project,account.analytic.line project,analytic.model_account_analytic_line,project.group_project_manager,1,1,1,1 |
1320 | |
1321 | === modified file 'project/tests/__init__.py' |
1322 | --- project/tests/__init__.py 2013-07-10 10:15:08 +0000 |
1323 | +++ project/tests/__init__.py 2014-02-27 12:12:58 +0000 |
1324 | @@ -19,10 +19,11 @@ |
1325 | # |
1326 | ############################################################################## |
1327 | |
1328 | -from . import test_project_flow |
1329 | +from . import test_project_flow,project_stage_management |
1330 | |
1331 | checks = [ |
1332 | test_project_flow, |
1333 | + project_stage_management, |
1334 | ] |
1335 | |
1336 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1337 | |
1338 | === added file 'project/tests/project_stage_management.py' |
1339 | --- project/tests/project_stage_management.py 1970-01-01 00:00:00 +0000 |
1340 | +++ project/tests/project_stage_management.py 2014-02-27 12:12:58 +0000 |
1341 | @@ -0,0 +1,77 @@ |
1342 | +# -*- coding: utf-8 -*- |
1343 | +############################################################################## |
1344 | +# |
1345 | +# OpenERP, Open Source Business Applications |
1346 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
1347 | +# |
1348 | +# This program is free software: you can redistribute it and/or modify |
1349 | +# it under the terms of the GNU Affero General Public License as |
1350 | +# published by the Free Software Foundation, either version 3 of the |
1351 | +# License, or (at your option) any later version. |
1352 | +# |
1353 | +# This program is distributed in the hope that it will be useful, |
1354 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1355 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1356 | +# GNU Affero General Public License for more details. |
1357 | +# |
1358 | +# You should have received a copy of the GNU Affero General Public License |
1359 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1360 | +# |
1361 | +############################################################################## |
1362 | +from openerp.osv.orm import except_orm |
1363 | +from openerp.tests import common |
1364 | + |
1365 | + |
1366 | +class TestCrmStagesCase(common.TransactionCase): |
1367 | + def setUp(self): |
1368 | + super(TestCrmStagesCase, self).setUp() |
1369 | + |
1370 | + def test_00_stage_management(self): |
1371 | + cr, uid = self.cr, self.uid |
1372 | + project_stage_management = self.registry('project.stage.management') |
1373 | + project_project = self.registry('project.project') |
1374 | + project_task_type= self.registry('project.task.type') |
1375 | + project_task = self.registry('project.task'); |
1376 | + project_project_id = project_project.create(cr, uid, {'name':'test_section'},context={}) |
1377 | + context = {'default_project_id': project_project_id, 'default_action':'create'} |
1378 | + |
1379 | + ''' For create when default_project_id pass in context |
1380 | + If same name is present than returns its id otherwise create new. |
1381 | + and link with given project |
1382 | + ''' |
1383 | + |
1384 | + stage_m2m_oldlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1385 | + project_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1386 | + project_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1387 | + check_len_id = project_task_type.search(cr, uid, [('name','=', 'First')], context=context) |
1388 | + self.assertEqual(len(check_len_id), 1) |
1389 | + task_id = project_task.create(cr, uid, {'name':'Test1','stage_id': check_len_id[0],'project_id':project_project_id}) |
1390 | + test1 = check_len_id |
1391 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1392 | + |
1393 | + self.assertEqual(len(stage_m2m_oldlist) + 1, len(stage_m2m_newlist)) |
1394 | + |
1395 | + ''' For edit when default_project_id pass in context |
1396 | + If same name is present than returns its id otherwise create new. |
1397 | + and link with given project and remove old link with project and project_task. |
1398 | + ''' |
1399 | + context.update({'active_id':test1[0], 'current_model':'project.task','default_action':'write'}) |
1400 | + project_stage_management.modify_stage(cr, uid, {'name':'Second'}, context=context) |
1401 | + test2 = project_task_type.search(cr, uid, [('name','=', 'Second')], context=context) |
1402 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1403 | + |
1404 | + self.assertIn(test2[0], [x.id for x in stage_m2m_newlist]) |
1405 | + check_project_task_stage_id = project_task.browse(cr, uid, task_id, context).stage_id.id |
1406 | + self.assertEqual(check_project_task_stage_id, test2[0]) |
1407 | + |
1408 | + ''' For unlink when default_project_id pass in context |
1409 | + It will unlink relation, not delete. |
1410 | + ''' |
1411 | + |
1412 | + stage_m2m_oldlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1413 | + project_stage_management.unlink(cr, uid, test2, context=context) |
1414 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1415 | + self.assertEqual(len(stage_m2m_oldlist) -1, len(stage_m2m_newlist)) |
1416 | + unlink_id = project_task_type.search(cr, uid, [('name','=', 'Second')], context=context) |
1417 | + self.assertEqual(unlink_id, test2) |
1418 | + |
1419 | \ No newline at end of file |
1420 | |
1421 | === modified file 'project/wizard/__init__.py' |
1422 | --- project/wizard/__init__.py 2013-10-27 12:31:04 +0000 |
1423 | +++ project/wizard/__init__.py 2014-02-27 12:12:58 +0000 |
1424 | @@ -20,5 +20,6 @@ |
1425 | ############################################################################## |
1426 | |
1427 | import project_task_delegate |
1428 | +import project_stage_management |
1429 | |
1430 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1431 | |
1432 | === added file 'project/wizard/project_stage_management.py' |
1433 | --- project/wizard/project_stage_management.py 1970-01-01 00:00:00 +0000 |
1434 | +++ project/wizard/project_stage_management.py 2014-02-27 12:12:58 +0000 |
1435 | @@ -0,0 +1,104 @@ |
1436 | +# -*- coding: utf-8 -*- |
1437 | +############################################################################## |
1438 | +# |
1439 | +# OpenERP, Open Source Management Solution |
1440 | +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). |
1441 | +# |
1442 | +# This program is free software: you can redistribute it and/or modify |
1443 | +# it under the terms of the GNU Affero General Public License as |
1444 | +# published by the Free Software Foundation, either version 3 of the |
1445 | +# License, or (at your option) any later version. |
1446 | +# |
1447 | +# This program is distributed in the hope that it will be useful, |
1448 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1449 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1450 | +# GNU Affero General Public License for more details. |
1451 | +# |
1452 | +# You should have received a copy of the GNU Affero General Public License |
1453 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1454 | +# |
1455 | +############################################################################## |
1456 | +from openerp.osv import osv,fields |
1457 | + |
1458 | +class project_stage_management(osv.TransientModel): |
1459 | + |
1460 | + _name = "project.stage.management" |
1461 | + _description = "Management of stages for project" |
1462 | + _columns = { |
1463 | + 'name': fields.char('Stage Name', required= True, size=64), |
1464 | + } |
1465 | + def default_get(self, cr, uid, fields, context=None): |
1466 | + if context is None:context = {} |
1467 | + old_stage_id = context.get('active_id') |
1468 | + res = super(project_stage_management, self).default_get(cr, uid, fields, context) |
1469 | + |
1470 | + if(context.get('default_action') == "create"):return res |
1471 | + project_task_type = self.pool.get('project.task.type').browse(cr , uid, old_stage_id, context) |
1472 | + res.update({'name': project_task_type.name}) |
1473 | + return res |
1474 | + |
1475 | + def create(self, cr, uid, vals, context): |
1476 | + if context is None:context = {} |
1477 | + action = context.get('default_action') |
1478 | + if action == 'create':self.create_stage(cr, uid, vals.get('name'), context) |
1479 | + if action == 'write':self.modify_stage(cr, uid, vals, context) |
1480 | + return None |
1481 | + |
1482 | + def create_stage(self, cr, uid, name, context): |
1483 | + if context is None:context = {} |
1484 | + project_id = context.get('default_project_id') |
1485 | + |
1486 | + project = self.pool.get('project.project') |
1487 | + project_task_type = self.pool.get('project.task.type') |
1488 | + |
1489 | + if project_id: |
1490 | + task_type_id = project_task_type.search(cr, uid, [('name','=', name)], context=context, limit=1) |
1491 | + if not task_type_id: |
1492 | + task_type_id = [project_task_type.create(cr, uid, {'name': name}, context=context)] |
1493 | + project.write(cr, uid, [project_id], {'type_ids': [(4, task_type_id[0]),]}, context=context) |
1494 | + else: |
1495 | + task_type_id = [project_task_type.create(cr, uid, {'name': name}, context=context)] |
1496 | + return task_type_id |
1497 | + |
1498 | + def unlink(self, cr, uid, ids, context=None): |
1499 | + if context is None:context = {} |
1500 | + project_id = context.get('default_project_id') |
1501 | + model = context.get('current_model') |
1502 | + if not model: return False |
1503 | + |
1504 | + project_task_or_issue = self.pool.get(model) |
1505 | + project_project = self.pool.get('project.project') |
1506 | + project_task_type = self.pool.get('project.task.type') |
1507 | + |
1508 | + if project_id: |
1509 | + for stage_id in ids: |
1510 | + task_ids = project_task_or_issue.search(cr, uid, [('stage_id','=', stage_id),('project_id','=', project_id)]) |
1511 | + project_task_or_issue.write(cr, uid, task_ids, {'stage_id': False} , context=context) |
1512 | + project_project.write(cr, uid, project_id, {'type_ids': [(3, stage_id)]}, context=context) |
1513 | + else: |
1514 | + project_task_type.unlink(cr, uid, ids, context=context) |
1515 | + return True |
1516 | + |
1517 | + def modify_stage(self,cr, uid, vals, context=None): |
1518 | + old_stage_id = context.get('active_id') |
1519 | + project_id = context.get('default_project_id') |
1520 | + model = context.get('current_model') |
1521 | + if not model: return False |
1522 | + |
1523 | + project_task_type = self.pool.get('project.task.type') |
1524 | + project_project = self.pool.get('project.project') |
1525 | + project_task_or_issue = self.pool.get(model) |
1526 | + |
1527 | + if project_id: |
1528 | + new_task_type_id = project_task_type.search(cr, uid, [('name','=', vals.get('name'))], context=context, limit=1) |
1529 | + if not new_task_type_id: |
1530 | + vals['project_ids'] = [(6, 0, [project_id])] |
1531 | + new_task_type_id = [project_task_type.copy(cr, uid, old_stage_id, default=vals, context=context)] |
1532 | + new_stage_id = new_task_type_id[0] |
1533 | + |
1534 | + task_ids = project_task_or_issue.search(cr, uid, [('stage_id','=', old_stage_id),('project_id','=', project_id)], context=context) |
1535 | + project_task_or_issue.write(cr, uid, task_ids, {'stage_id': new_stage_id} , context=context) |
1536 | + project_project.write(cr, uid, [project_id], {'type_ids': [(3, old_stage_id),(4, new_stage_id),]}, context=context) |
1537 | + else: |
1538 | + project_task_type.write(cr, uid, old_stage_id, vals, context=context) |
1539 | + return True |
1540 | \ No newline at end of file |
1541 | |
1542 | === added file 'project/wizard/project_stage_management.xml' |
1543 | --- project/wizard/project_stage_management.xml 1970-01-01 00:00:00 +0000 |
1544 | +++ project/wizard/project_stage_management.xml 2014-02-27 12:12:58 +0000 |
1545 | @@ -0,0 +1,18 @@ |
1546 | +<?xml version="1.0" encoding="utf-8"?> |
1547 | +<openerp> |
1548 | + <data> |
1549 | + <record model="ir.ui.view" id="project_stage_form_wizard"> |
1550 | + <field name="name">project.stage.management.form</field> |
1551 | + <field name="model">project.stage.management</field> |
1552 | + <field name="arch" type="xml"> |
1553 | + <form string="Stage" version="7.0"> |
1554 | + <group> |
1555 | + <group> |
1556 | + <field name="name"/> |
1557 | + </group> |
1558 | + </group> |
1559 | + </form> |
1560 | + </field> |
1561 | + </record> |
1562 | + </data> |
1563 | +</openerp> |
1564 | |
1565 | === modified file 'project_issue/project_issue.py' |
1566 | --- project_issue/project_issue.py 2013-12-02 15:09:25 +0000 |
1567 | +++ project_issue/project_issue.py 2014-02-27 12:12:58 +0000 |
1568 | @@ -106,14 +106,18 @@ |
1569 | search_domain = [] |
1570 | project_id = self._resolve_project_id_from_context(cr, uid, context=context) |
1571 | if project_id: |
1572 | - search_domain += ['|', ('project_ids', '=', project_id)] |
1573 | - search_domain += [('id', 'in', ids)] |
1574 | + search_domain += [('project_ids', '=', project_id)] |
1575 | # perform search |
1576 | stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) |
1577 | + if project_id: |
1578 | + sequence_ids = self.pool.get('project.task.type.sequence').search_read(cr, uid, [('project_id', '=', project_id), ('type_id', 'in', stage_ids)], ['type_id'], order=order, context=context) |
1579 | + type_ids = map(lambda type_ids: type_ids['type_id'][0], sequence_ids) |
1580 | result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) |
1581 | # restore order of the search |
1582 | - result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
1583 | - |
1584 | + if project_id: |
1585 | + result.sort(lambda x,y: cmp(type_ids.index(x[0]), type_ids.index(y[0]))) |
1586 | + else: |
1587 | + result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) |
1588 | fold = {} |
1589 | for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): |
1590 | fold[stage.id] = stage.fold or False |
1591 | |
1592 | === modified file 'project_issue/project_issue_view.xml' |
1593 | --- project_issue/project_issue_view.xml 2013-11-29 09:46:10 +0000 |
1594 | +++ project_issue/project_issue_view.xml 2014-02-27 12:12:58 +0000 |
1595 | @@ -184,7 +184,7 @@ |
1596 | <field name="name">Project Issue Kanban</field> |
1597 | <field name="model">project.issue</field> |
1598 | <field name="arch" type="xml"> |
1599 | - <kanban default_group_by="stage_id"> |
1600 | + <kanban default_group_by="stage_id" stage_management="project.stage.management" stage_options = "{'group_by':'stage_id','default_context_key':'default_project_id'}"> |
1601 | <field name="stage_id"/> |
1602 | <field name="color"/> |
1603 | <field name="priority"/> |
1604 | @@ -281,7 +281,6 @@ |
1605 | <field name="view_mode">kanban,tree,form,calendar,graph</field> |
1606 | <field name="context">{ |
1607 | 'search_default_project_id': [active_id], |
1608 | - 'default_project_id': active_id, |
1609 | } |
1610 | </field> |
1611 | <field name="help" type="html"> |
1612 | |
1613 | === added directory 'project_issue/tests' |
1614 | === added file 'project_issue/tests/__init__.py' |
1615 | --- project_issue/tests/__init__.py 1970-01-01 00:00:00 +0000 |
1616 | +++ project_issue/tests/__init__.py 2014-02-27 12:12:58 +0000 |
1617 | @@ -0,0 +1,28 @@ |
1618 | +# -*- coding: utf-8 -*- |
1619 | +############################################################################## |
1620 | +# |
1621 | +# OpenERP, Open Source Business Applications |
1622 | +# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com> |
1623 | +# |
1624 | +# This program is free software: you can redistribute it and/or modify |
1625 | +# it under the terms of the GNU Affero General Public License as |
1626 | +# published by the Free Software Foundation, either version 3 of the |
1627 | +# License, or (at your option) any later version. |
1628 | +# |
1629 | +# This program is distributed in the hope that it will be useful, |
1630 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1631 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1632 | +# GNU Affero General Public License for more details. |
1633 | +# |
1634 | +# You should have received a copy of the GNU Affero General Public License |
1635 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1636 | +# |
1637 | +############################################################################## |
1638 | + |
1639 | +from . import project_stage_management |
1640 | + |
1641 | +checks = [ |
1642 | + project_stage_management, |
1643 | +] |
1644 | + |
1645 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1646 | |
1647 | === added file 'project_issue/tests/project_stage_management.py' |
1648 | --- project_issue/tests/project_stage_management.py 1970-01-01 00:00:00 +0000 |
1649 | +++ project_issue/tests/project_stage_management.py 2014-02-27 12:12:58 +0000 |
1650 | @@ -0,0 +1,77 @@ |
1651 | +# -*- coding: utf-8 -*- |
1652 | +############################################################################## |
1653 | +# |
1654 | +# OpenERP, Open Source Business Applications |
1655 | +# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com> |
1656 | +# |
1657 | +# This program is free software: you can redistribute it and/or modify |
1658 | +# it under the terms of the GNU Affero General Public License as |
1659 | +# published by the Free Software Foundation, either version 3 of the |
1660 | +# License, or (at your option) any later version. |
1661 | +# |
1662 | +# This program is distributed in the hope that it will be useful, |
1663 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1664 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1665 | +# GNU Affero General Public License for more details. |
1666 | +# |
1667 | +# You should have received a copy of the GNU Affero General Public License |
1668 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1669 | +# |
1670 | +############################################################################## |
1671 | +from openerp.osv.orm import except_orm |
1672 | +from openerp.tests import common |
1673 | + |
1674 | + |
1675 | +class TestProjectStagesCase(common.TransactionCase): |
1676 | + def setUp(self): |
1677 | + super(TestProjectStagesCase, self).setUp() |
1678 | + |
1679 | + def test_00_stage_management(self): |
1680 | + cr, uid = self.cr, self.uid |
1681 | + project_issue_stage_management = self.registry('project.stage.management') |
1682 | + project_project = self.registry('project.project') |
1683 | + project_issue_type= self.registry('project.task.type') |
1684 | + project_issue = self.registry('project.issue') |
1685 | + project_project_id = project_project.create(cr, uid, {'name':'test_section'},context={}) |
1686 | + context = {'default_project_id': project_project_id, 'default_action':'create'} |
1687 | + |
1688 | + ''' For create when default_project_id pass in context |
1689 | + If same name is present than returns its id otherwise create new. |
1690 | + and link with given project. |
1691 | + ''' |
1692 | + |
1693 | + stage_m2m_oldlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1694 | + project_issue_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1695 | + project_issue_stage_management.create(cr, uid, {'name':'First','action':'create'},context) |
1696 | + check_len_id = project_issue_type.search(cr, uid, [('name','=', 'First')], context=context) |
1697 | + self.assertEqual(len(check_len_id), 1) |
1698 | + issue_id = project_issue.create(cr, uid, {'name':'Test1','stage_id': check_len_id[0],'project_id':project_project_id}) |
1699 | + test1 = check_len_id |
1700 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1701 | + |
1702 | + self.assertEqual(len(stage_m2m_oldlist) + 1, len(stage_m2m_newlist)) |
1703 | + |
1704 | + ''' For edit when default_project_id pass in context |
1705 | + If same name is present than returns its id otherwise create new. |
1706 | + and link with given project and remove old link with project and project_issue. |
1707 | + ''' |
1708 | + |
1709 | + context.update({'active_id':test1[0],'current_model':'project.issue', 'default_action':'write'}) |
1710 | + project_issue_stage_management.modify_stage(cr, uid, {'name':'Second'}, context=context) |
1711 | + test2 = project_issue_type.search(cr, uid, [('name','=', 'Second')], context=context) |
1712 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1713 | + |
1714 | + self.assertIn(test2[0], [x.id for x in stage_m2m_newlist]) |
1715 | + check_project_task_stage_id = project_issue.browse(cr, uid, issue_id, context).stage_id.id |
1716 | + self.assertEqual(check_project_task_stage_id, test2[0]) |
1717 | + |
1718 | + ''' For unlink when default_project_id pass in context |
1719 | + It will unlink relation, not delete. |
1720 | + ''' |
1721 | + |
1722 | + stage_m2m_oldlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1723 | + project_issue_stage_management.unlink(cr, uid, test2, context=context) |
1724 | + stage_m2m_newlist = project_project.browse(cr, uid, project_project_id, context=context).type_ids |
1725 | + self.assertEqual(len(stage_m2m_oldlist) -1, len(stage_m2m_newlist)) |
1726 | + unlink_id = project_issue_type.search(cr, uid, [('name','=', 'Second')], context=context) |
1727 | + self.assertEqual(unlink_id, test2) |