| LEFT | RIGHT |
|---|---|
| 1 #This file is part of Tryton. The COPYRIGHT file at the top level of | 1 #This file is part of Tryton. The COPYRIGHT file at the top level of |
| 2 #this repository contains the full copyright notices and license terms. | 2 #this repository contains the full copyright notices and license terms. |
| 3 | 3 |
| 4 from trytond.model import ModelView, ModelSQL, fields | 4 from trytond.model import ModelView, ModelSQL, fields |
| 5 from trytond.wizard import Wizard | 5 from trytond.wizard import Wizard |
| 6 from datetime import datetime, timedelta | 6 from datetime import datetime, timedelta |
| 7 from collections import deque, defaultdict | 7 from collections import deque, defaultdict |
| 8 from heapq import heappop, heappush | 8 from heapq import heappop, heappush |
| 9 import itertools | |
|
ced
2009/07/03 10:44:44
Not used
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> Not used
Don
| |
| 10 | 9 |
| 11 def intfloor(x): | 10 def intfloor(x): |
| 12 return int(round(x, 4)) | 11 return int(round(x, 4)) |
| 13 | 12 |
| 14 | 13 |
| 15 class Work(ModelSQL, ModelView): | 14 class Work(ModelSQL, ModelView): |
| 16 _name = 'project.work' | 15 _name = 'project.work' |
| 17 | 16 |
| 18 predecessors = fields.Many2Many('project.predecessor_successor', | 17 predecessors = fields.Many2Many('project.predecessor_successor', |
| 19 'successor', 'predecessor', 'Predecessors', | 18 'successor', 'predecessor', 'Predecessors', |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 :param context: the context | 91 :param context: the context |
| 93 :return: a dictionary with all field names as key and | 92 :return: a dictionary with all field names as key and |
| 94 a dictionary as value with id as key | 93 a dictionary as value with id as key |
| 95 ''' | 94 ''' |
| 96 req_ref_obj = self.pool.get('res.request.reference') | 95 req_ref_obj = self.pool.get('res.request.reference') |
| 97 | 96 |
| 98 res = {} | 97 res = {} |
| 99 | 98 |
| 100 if 'requests' in names: | 99 if 'requests' in names: |
| 101 requests = dict((i, []) for i in ids) | 100 requests = dict((i, []) for i in ids) |
| 102 req_ref_ids = req_ref_obj.search(cursor, user, [ | 101 |
| 103 ('reference', 'in', ['project.work,%s' % i for i in ids]), | 102 for i in range(0, len(ids), cursor.IN_MAX): |
| 104 ], context=context) | 103 sub_ids = ids[i:i + cursor.IN_MAX] |
| 105 req_refs = req_ref_obj.browse(cursor, user, req_ref_ids, | 104 |
| 106 context=context) | 105 req_ref_ids = req_ref_obj.search(cursor, user, [ |
| 107 for req_ref in req_refs: | 106 ('reference', 'in', [ |
| 108 _, work_id = req_ref.reference.split(',') | 107 'project.work,%s' % i for i in sub_ids |
|
ced
2009/07/03 10:44:44
work_id could be empty
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> work_id could
ced
2009/07/03 15:03:36
On 2009/07/03 14:51:47, Bertrand Chenal wrote:
> O
ced
2009/07/03 15:31:20
But the search clause will ensure that there is an
| |
| 109 requests[int(work_id)].append(req_ref.request.id) | 108 ] |
| 109 ), | |
| 110 ], context=context) | |
| 111 req_refs = req_ref_obj.browse(cursor, user, req_ref_ids, | |
| 112 context=context) | |
| 113 for req_ref in req_refs: | |
| 114 _, work_id = req_ref.reference.split(',') | |
| 115 requests[int(work_id)].append(req_ref.request.id) | |
| 110 | 116 |
| 111 res['requests'] = requests | 117 res['requests'] = requests |
| 112 | 118 |
| 113 if 'duration' in names: | 119 if 'duration' in names: |
| 114 all_ids = self.search(cursor, user, [ | 120 all_ids = self.search(cursor, user, [ |
| 115 ('parent', 'child_of', ids), | 121 ('parent', 'child_of', ids), |
| 116 ('active', '=', True)], context=context) + ids | 122 ('active', '=', True)], context=context) + ids |
| 117 all_ids = list(set(all_ids)) | 123 all_ids = list(set(all_ids)) |
| 118 | 124 |
| 119 works = self.browse(cursor, user, all_ids, context=context) | 125 works = self.browse(cursor, user, all_ids, context=context) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 | 175 |
| 170 return res | 176 return res |
| 171 | 177 |
| 172 def set_function_fields(self, cursor, user, id, name, value, arg, | 178 def set_function_fields(self, cursor, user, id, name, value, arg, |
| 173 context=None): | 179 context=None): |
| 174 request_obj = self.pool.get('res.request') | 180 request_obj = self.pool.get('res.request') |
| 175 req_ref_obj = self.pool.get('res.request.reference') | 181 req_ref_obj = self.pool.get('res.request.reference') |
| 176 | 182 |
| 177 if name == 'requests': | 183 if name == 'requests': |
| 178 work = self.browse(cursor, user, id, context=context) | 184 work = self.browse(cursor, user, id, context=context) |
| 179 current = dict((req.id, req) for req in work.requests) | 185 currents = dict((req.id, req) for req in work.requests) |
|
ced
2009/07/03 10:44:44
currents
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> currents
Don
| |
| 180 to_unlink = [] | |
| 181 to_link = [] | |
| 182 to_delete = [] | |
| 183 for v in value: | 186 for v in value: |
| 187 to_unlink = [] | |
| 188 to_link = [] | |
| 184 operator = v[0] | 189 operator = v[0] |
| 190 | |
| 185 ids = len(v) > 1 and v[1] or [] | 191 ids = len(v) > 1 and v[1] or [] |
| 186 if operator == 'set': | 192 if operator == 'set': |
|
ced
2009/07/03 10:44:44
I think it is better to make the operation directl
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> I think it is
| |
| 187 to_link.extend((i for i in ids if i not in current)) | 193 to_link.extend((i for i in ids if i not in currents)) |
| 188 to_unlink.extend((i for i in current if i not in ids)) | 194 to_unlink.extend((i for i in currents if i not in ids)) |
| 189 elif operator == 'add': | 195 elif operator == 'add': |
| 190 to_link.extend((i for i in ids if i not in current)) | 196 to_link.extend((i for i in ids if i not in currents)) |
| 191 elif operator == 'unlink': | 197 elif operator == 'unlink': |
| 192 to_unlink.extend((i for i in ids if i in current)) | 198 to_unlink.extend((i for i in ids if i in currents)) |
| 193 elif operator == 'unlink_all': | 199 elif operator == 'unlink_all': |
| 194 to_unlink.extend(current) | 200 to_unlink.extend(currents) |
| 195 elif operator == 'delete': | 201 elif operator == 'delete': |
| 196 to_delete.extend((i for i in ids if i in current)) | 202 request_obj.delete(cursor, user, to_delete, context=context) |
| 197 else: | 203 else: |
| 198 raise Exception('Operation not supported') | 204 raise Exception('Operation not supported') |
| 199 | 205 |
| 200 if to_delete: | |
| 201 request_obj.delete(cursor, user, to_delete, context=context) | |
| 202 print to_unlink | |
|
ced
2009/07/03 10:44:44
print statement
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> print stateme
| |
| 203 if to_unlink: | |
| 204 req_ref_ids = [] | 206 req_ref_ids = [] |
| 205 for i in to_unlink: | 207 for i in to_unlink: |
| 206 request = current[i] | 208 request = currents[i] |
| 207 for ref in request.references: | 209 for ref in request.references: |
| 208 if int(ref.reference.split(',')[1]) == id: | 210 if int(ref.reference.split(',')[1]) == id: |
| 209 req_ref_ids.append(ref.id) | 211 req_ref_ids.append(ref.id) |
| 210 print req_ref_ids | 212 req_ref_obj.delete(cursor, user, req_ref_ids, |
|
ced
2009/07/03 10:44:44
print statement
bch
2009/07/03 14:51:47
On 2009/07/03 10:44:44, ced wrote:
> print stateme
| |
| 211 req_ref_obj.delete(cursor, user, req_ref_ids, context=context) | 213 context=context) |
| 212 for i in to_link: | 214 |
| 213 req_ref_obj.create(cursor, user, { | 215 for i in to_link: |
| 214 'request': i, | 216 req_ref_obj.create(cursor, user, { |
| 215 'reference': 'project.work,%s' % id, | 217 'request': i, |
| 216 }, context=context) | 218 'reference': 'project.work,%s' % id, |
| 219 }, context=context) | |
| 217 return | 220 return |
| 218 | |
| 219 | 221 |
| 220 fun_fields = ('actual_start_date', 'actual_finish_date', | 222 fun_fields = ('actual_start_date', 'actual_finish_date', |
| 221 'constraint_start_date', 'constraint_finish_date') | 223 'constraint_start_date', 'constraint_finish_date') |
| 222 db_fields = ('actual_start_time', 'actual_finish_time', | 224 db_fields = ('actual_start_time', 'actual_finish_time', |
| 223 'constraint_start_time', 'constraint_finish_time') | 225 'constraint_start_time', 'constraint_finish_time') |
| 224 for fun_field, db_field in zip(fun_fields, db_fields): | 226 for fun_field, db_field in zip(fun_fields, db_fields): |
| 225 if fun_field == name: | 227 if fun_field == name: |
| 226 self.write(cursor, user, id, {db_field: value}, context=context) | 228 self.write(cursor, user, id, {db_field: value}, context=context) |
| 227 break | 229 break |
| 228 | 230 |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 res = super(Work, self).delete(cursor, user, ids, context=context) | 646 res = super(Work, self).delete(cursor, user, ids, context=context) |
| 645 | 647 |
| 646 for work_id in to_update: | 648 for work_id in to_update: |
| 647 self.reset_leveling(cursor, user, work_id, context=context) | 649 self.reset_leveling(cursor, user, work_id, context=context) |
| 648 self.compute_dates(cursor, user, work_id, context=context) | 650 self.compute_dates(cursor, user, work_id, context=context) |
| 649 | 651 |
| 650 return res | 652 return res |
| 651 Work() | 653 Work() |
| 652 | 654 |
| 653 | 655 |
| 656 | |
| 654 class PredecessorSuccessor(ModelSQL): | 657 class PredecessorSuccessor(ModelSQL): |
| 655 'Predecessor - Successor' | 658 'Predecessor - Successor' |
| 656 _name = 'project.predecessor_successor' | 659 _name = 'project.predecessor_successor' |
| 657 _description = __doc__ | 660 _description = __doc__ |
| 658 | 661 |
| 659 predecessor = fields.Many2One('project.work', 'Predecessor', | 662 predecessor = fields.Many2One('project.work', 'Predecessor', |
| 660 ondelete='CASCADE', required=True, select=1) | 663 ondelete='CASCADE', required=True, select=1) |
| 661 successor = fields.Many2One('project.work', 'Successor', | 664 successor = fields.Many2One('project.work', 'Successor', |
| 662 ondelete='CASCADE', required=True, select=1) | 665 ondelete='CASCADE', required=True, select=1) |
| 663 | 666 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 732 }, | 735 }, |
| 733 }, | 736 }, |
| 734 } | 737 } |
| 735 | 738 |
| 736 def _leveling(self, cursor, user, data, context=None): | 739 def _leveling(self, cursor, user, data, context=None): |
| 737 work_obj = self.pool.get('project.work') | 740 work_obj = self.pool.get('project.work') |
| 738 work_obj.create_leveling(cursor, user, data['id'], context=context) | 741 work_obj.create_leveling(cursor, user, data['id'], context=context) |
| 739 return {} | 742 return {} |
| 740 | 743 |
| 741 Leveling() | 744 Leveling() |
| LEFT | RIGHT |