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 from __future__ import with_statement |
| 4 from string import Template |
| 5 import datetime |
3 import time | 6 import time |
4 from trytond.model import ModelView, ModelSQL, fields | 7 from trytond.model import ModelView, ModelSQL, fields |
5 from string import Template | |
6 import datetime | |
7 from trytond.tools import datetime_strftime | 8 from trytond.tools import datetime_strftime |
8 from trytond.pyson import In, Eval, Not | 9 from trytond.pyson import In, Eval, Not |
| 10 from trytond.transaction import Transaction |
9 | 11 |
10 | 12 |
11 class SequenceType(ModelSQL, ModelView): | 13 class SequenceType(ModelSQL, ModelView): |
12 "Sequence type" | 14 "Sequence type" |
13 _name = 'ir.sequence.type' | 15 _name = 'ir.sequence.type' |
14 _description = __doc__ | 16 _description = __doc__ |
15 name = fields.Char('Sequence Name', required=True, translate=True) | 17 name = fields.Char('Sequence Name', required=True, translate=True) |
16 code = fields.Char('Sequence Code', required=True) | 18 code = fields.Char('Sequence Code', required=True) |
17 | 19 |
18 SequenceType() | 20 SequenceType() |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 self._constraints += [ | 70 self._constraints += [ |
69 ('check_prefix_suffix', 'invalid_prefix_suffix'), | 71 ('check_prefix_suffix', 'invalid_prefix_suffix'), |
70 ('check_last_timestamp', 'future_last_timestamp'), | 72 ('check_last_timestamp', 'future_last_timestamp'), |
71 ] | 73 ] |
72 self._error_messages.update({ | 74 self._error_messages.update({ |
73 'missing': 'Missing sequence!', | 75 'missing': 'Missing sequence!', |
74 'invalid_prefix_suffix': 'Invalid prefix/suffix!', | 76 'invalid_prefix_suffix': 'Invalid prefix/suffix!', |
75 'future_last_timestamp': 'Last Timestamp could not be in future!', | 77 'future_last_timestamp': 'Last Timestamp could not be in future!', |
76 }) | 78 }) |
77 | 79 |
78 def default_active(self, cursor, user, context=None): | 80 def default_active(self): |
| 81 return True |
| 82 |
| 83 def default_type(self): |
| 84 return 'incremental' |
| 85 |
| 86 def default_number_increment(self): |
79 return 1 | 87 return 1 |
80 | 88 |
81 def default_type(self, cursor, user, context=None): | 89 def default_number_next(self): |
82 return 'incremental' | |
83 | |
84 def default_number_increment(self, cursor, user, context=None): | |
85 return 1 | 90 return 1 |
86 | 91 |
87 def default_number_next(self, cursor, user, context=None): | 92 def default_padding(self): |
88 return 1 | |
89 | |
90 def default_padding(self, cursor, user, context=None): | |
91 return 0 | 93 return 0 |
92 | 94 |
93 def default_timestamp_rounding(self, cursor, user, context=None): | 95 def default_timestamp_rounding(self): |
94 return 1.0 | 96 return 1.0 |
95 | 97 |
96 def default_timestamp_offset(self, cursor, user, context=None): | 98 def default_timestamp_offset(self): |
97 return 946681200.0 # Offset for 2000-01-01 | 99 return 946681200.0 # Offset for 2000-01-01 |
98 | 100 |
99 def default_last_timestamp(self, cursor, user, context=None): | 101 def default_last_timestamp(self): |
100 return 0.0 | 102 return 0.0 |
101 | 103 |
102 def default_code(self, cursor, user, context=None): | 104 def default_code(self): |
103 if context is None: | 105 return Transaction().context.get('code', False) |
104 context = {} | 106 |
105 return context.get('code', False) | 107 def code_get(self): |
106 | |
107 def code_get(self, cursor, user, context=None): | |
108 sequence_type_obj = self.pool.get('ir.sequence.type') | 108 sequence_type_obj = self.pool.get('ir.sequence.type') |
109 sequence_type_ids = sequence_type_obj.search(cursor, user, [], | 109 sequence_type_ids = sequence_type_obj.search([]) |
110 context=context) | 110 sequence_types = sequence_type_obj.browse(sequence_type_ids) |
111 sequence_types = sequence_type_obj.browse(cursor, user, | |
112 sequence_type_ids, context=context) | |
113 return [(x.code, x.name) for x in sequence_types] | 111 return [(x.code, x.name) for x in sequence_types] |
114 | 112 |
115 def check_prefix_suffix(self, cursor, user, ids): | 113 def check_prefix_suffix(self, ids): |
116 "Check prefix and suffix" | 114 "Check prefix and suffix" |
117 | 115 |
118 for sequence in self.browse(cursor, user, ids): | 116 for sequence in self.browse(ids): |
119 try: | 117 try: |
120 self._process(cursor, user, sequence.prefix) | 118 self._process(sequence.prefix) |
121 self._process(cursor, user, sequence.suffix) | 119 self._process(sequence.suffix) |
122 except Exception: | 120 except Exception: |
123 return False | 121 return False |
124 return True | 122 return True |
125 | 123 |
126 def check_last_timestamp(self, cursor, user, ids): | 124 def check_last_timestamp(self, ids): |
127 "Check last_timestamp" | 125 "Check last_timestamp" |
128 | 126 |
129 for sequence in self.browse(cursor, user, ids): | 127 for sequence in self.browse(ids): |
130 next_timestamp = self._timestamp(cursor, user, sequence) | 128 next_timestamp = self._timestamp(sequence) |
131 if sequence.last_timestamp > next_timestamp: | 129 if sequence.last_timestamp > next_timestamp: |
132 return False | 130 return False |
133 return True | 131 return True |
134 | 132 |
135 def _process(self, cursor, user, string, date=None, context=None): | 133 def _process(self, string, date=None): |
136 date_obj = self.pool.get('ir.date') | 134 date_obj = self.pool.get('ir.date') |
137 if not date: | 135 if not date: |
138 date = date_obj.today(cursor, user, context=context) | 136 date = date_obj.today() |
139 year = datetime_strftime(date, '%Y') | 137 year = datetime_strftime(date, '%Y') |
140 month = datetime_strftime(date, '%m') | 138 month = datetime_strftime(date, '%m') |
141 day = datetime_strftime(date, '%d') | 139 day = datetime_strftime(date, '%d') |
142 return Template(string or '').substitute( | 140 return Template(string or '').substitute( |
143 year=year, | 141 year=year, |
144 month=month, | 142 month=month, |
145 day=day, | 143 day=day, |
146 ) | 144 ) |
147 | 145 |
148 def _timestamp(self, cursor, user, sequence, context=None): | 146 def _timestamp(self, sequence): |
149 return int((time.time() - sequence.timestamp_offset) | 147 return int((time.time() - sequence.timestamp_offset) |
150 / sequence.timestamp_rounding) | 148 / sequence.timestamp_rounding) |
151 | 149 |
152 def _get_sequence(self, cursor, user, sequence, context=None): | 150 def _get_sequence(self, sequence): |
153 if sequence.type == 'incremental': | 151 if sequence.type == 'incremental': |
154 #Pre-fetch number_next | 152 #Pre-fetch number_next |
155 number_next = sequence.number_next or 0 | 153 number_next = sequence.number_next or 0 |
156 | 154 |
157 self.write(cursor, 0, sequence.id, { | 155 with Transaction().set_user(0): |
158 'number_next': number_next + sequence.number_increment, | 156 self.write(sequence.id, { |
159 }, context=context) | 157 'number_next': number_next + sequence.number_increment, |
| 158 }) |
160 return '%%0%sd' % sequence.padding % number_next | 159 return '%%0%sd' % sequence.padding % number_next |
161 elif sequence.type in ('decimal timestamp', 'hexadecimal timestamp'): | 160 elif sequence.type in ('decimal timestamp', 'hexadecimal timestamp'): |
162 timestamp = sequence.last_timestamp | 161 timestamp = sequence.last_timestamp |
163 while timestamp == sequence.last_timestamp: | 162 while timestamp == sequence.last_timestamp: |
164 timestamp = self._timestamp(cursor, user, sequence, | 163 timestamp = self._timestamp(sequence) |
165 context=context) | 164 with Transaction().set_user(0): |
166 self.write(cursor, 0, sequence.id, { | 165 self.write(sequence.id, { |
167 'last_timestamp': timestamp, | 166 'last_timestamp': timestamp, |
168 }, context=context) | 167 }) |
169 if sequence.type == 'decimal timestamp': | 168 if sequence.type == 'decimal timestamp': |
170 return '%d' % timestamp | 169 return '%d' % timestamp |
171 else: | 170 else: |
172 return hex(timestamp)[2:].upper() | 171 return hex(timestamp)[2:].upper() |
173 return '' | 172 return '' |
174 | 173 |
175 | 174 |
176 def get_id(self, cursor, user, domain, context=None): | 175 def get_id(self, domain): |
177 ''' | 176 ''' |
178 Return sequence value for the domain | 177 Return sequence value for the domain |
179 | 178 |
180 :param cursor: the database cursor | |
181 :param user: the user id | |
182 :param domain: a domain or a sequence id | 179 :param domain: a domain or a sequence id |
183 :param context: the context | |
184 :return: the sequence value | 180 :return: the sequence value |
185 ''' | 181 ''' |
186 if context is None: | |
187 context = {} | |
188 if isinstance(domain, (int, long)): | 182 if isinstance(domain, (int, long)): |
189 domain = [('id', '=', domain)] | 183 domain = [('id', '=', domain)] |
190 | 184 |
191 # bypass rules on sequences | 185 # bypass rules on sequences |
192 if 'user' in context: | 186 with Transaction().set_context(user=False): |
193 context = context.copy() | 187 with Transaction().set_user(0): |
194 del context['user'] | 188 sequence_ids = self.search(domain, limit=1) |
195 sequence_ids = self.search(cursor, 0, domain, limit=1, | 189 date = Transaction().context.get('date') |
196 context=context) | 190 if sequence_ids: |
197 date = context.get('date') | 191 with Transaction().set_user(0): |
198 if sequence_ids: | 192 sequence = self.browse(sequence_ids[0]) |
199 sequence = self.browse(cursor, 0, sequence_ids[0], | 193 return '%s%s%s' % ( |
200 context=context) | 194 self._process(sequence.prefix, date=date), |
201 return '%s%s%s' % ( | 195 self._get_sequence(sequence), |
202 self._process(cursor, user, sequence.prefix, date=date, | 196 self._process(sequence.suffix, date=date), |
203 context=context), | 197 ) |
204 self._get_sequence(cursor, user, sequence, | 198 self.raise_user_error('missing') |
205 context=context), | 199 |
206 self._process(cursor, user, sequence.suffix, date=date, | 200 def get(self, code): |
207 context=context)) | 201 return self.get_id([('code', '=', code)]) |
208 self.raise_user_error(cursor, 'missing', context=context) | |
209 | |
210 def get(self, cursor, user, code, context=None): | |
211 return self.get_id(cursor, user, [('code', '=', code)], context=context) | |
212 | 202 |
213 Sequence() | 203 Sequence() |
214 | 204 |
215 | 205 |
216 class SequenceStrict(Sequence): | 206 class SequenceStrict(Sequence): |
217 "Sequence Strict" | 207 "Sequence Strict" |
218 _name = 'ir.sequence.strict' | 208 _name = 'ir.sequence.strict' |
219 _description = __doc__ | 209 _description = __doc__ |
220 | 210 |
221 def get_id(self, cursor, user, clause, context=None): | 211 def get_id(self, clause): |
222 cursor.lock(self._table) | 212 Transaction().cursor.lock(self._table) |
223 return super(SequenceStrict, self).get_id(cursor, user, clause, | 213 return super(SequenceStrict, self).get_id(clause) |
224 context=context) | |
225 | 214 |
226 SequenceStrict() | 215 SequenceStrict() |
LEFT | RIGHT |