Merge lp:~julie-w/unifield-server/US-5216 into lp:unifield-server
- US-5216
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5777 |
Proposed branch: | lp:~julie-w/unifield-server/US-5216 |
Merge into: | lp:unifield-server |
Diff against target: |
1436 lines (+578/-168) (has conflicts) 14 files modified
bin/addons/account/account.py (+144/-39) bin/addons/account/account_view.xml (+25/-19) bin/addons/account/wizard/account_subscription_generate.py (+4/-3) bin/addons/account/wizard/account_subscription_generate_view.xml (+2/-2) bin/addons/account/wizard/account_validate_account_move.py (+10/-0) bin/addons/account_period_closing_level/account_period.py (+1/-14) bin/addons/account_subscription/__init__.py (+0/-1) bin/addons/account_subscription/account_model.py (+125/-7) bin/addons/account_subscription/account_model_view.xml (+72/-19) bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py (+5/-0) bin/addons/msf_profile/data/patches.xml (+7/-0) bin/addons/msf_profile/i18n/fr_MF.po (+122/-63) bin/addons/msf_profile/msf_profile.py (+60/-0) bin/addons/msf_profile/usability.xml (+1/-1) Text conflict in bin/addons/msf_profile/data/patches.xml Text conflict in bin/addons/msf_profile/i18n/fr_MF.po |
To merge this branch: | bzr merge lp:~julie-w/unifield-server/US-5216 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+388868@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/account/account.py' |
2 | --- bin/addons/account/account.py 2020-03-11 13:40:27 +0000 |
3 | +++ bin/addons/account/account.py 2020-08-07 12:54:52 +0000 |
4 | @@ -2354,6 +2354,29 @@ |
5 | break |
6 | return res |
7 | |
8 | + def _is_frozen_model(self, cr, uid, ids, name, arg, context=None): |
9 | + """ |
10 | + Returns True for the Recurring Plans for which the model field should be frozen, i.e. readonly: |
11 | + - if journal entries have been generated, posted or not |
12 | + - if the model already selected is in Done state (note that Done models aren't selectable, so the model would |
13 | + have been selected BEFORE it becomes Done). |
14 | + """ |
15 | + if context is None: |
16 | + context = {} |
17 | + if isinstance(ids, (int, long)): |
18 | + ids = [ids] |
19 | + res = {} |
20 | + for plan in self.browse(cr, uid, ids, fields_to_fetch=['model_id', 'lines_id'], context=context): |
21 | + res[plan.id] = False |
22 | + if plan.model_id.state == 'done': |
23 | + res[plan.id] = True |
24 | + else: |
25 | + for line in plan.lines_id: |
26 | + if line.move_id: |
27 | + res[plan.id] = True |
28 | + break |
29 | + return res |
30 | + |
31 | _columns = { |
32 | 'name': fields.char('Name', size=64, required=True), |
33 | 'ref': fields.char('Reference', size=16), |
34 | @@ -2361,45 +2384,142 @@ |
35 | |
36 | 'date_start': fields.date('Start Date', required=True), |
37 | 'period_total': fields.integer('Number of Periods', required=True), |
38 | - 'period_nbr': fields.integer('Period', required=True), |
39 | + 'period_nbr': fields.integer('Repeat', required=True, |
40 | + help="This field will determine how often entries will be generated: if the period type is 'month' and the repeat '2' then entries will be generated every 2 months"), |
41 | 'period_type': fields.selection([('day','days'),('month','month'),('year','year')], 'Period Type', required=True), |
42 | 'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'State', required=True, readonly=True), |
43 | |
44 | 'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines'), |
45 | 'has_unposted_entries': fields.function(_get_has_unposted_entries, method=True, type='boolean', |
46 | store=False, string='Has unposted entries'), |
47 | + 'frozen_model': fields.function(_is_frozen_model, method=True, type='boolean', store=False, string='Frozen model'), |
48 | } |
49 | _defaults = { |
50 | 'date_start': lambda *a: time.strftime('%Y-%m-%d'), |
51 | 'period_type': 'month', |
52 | - 'period_total': 12, |
53 | + 'period_total': 0, |
54 | 'period_nbr': 1, |
55 | 'state': 'draft', |
56 | } |
57 | |
58 | - def check(self, cr, uid, ids, context=None): |
59 | - todone = [] |
60 | - for sub in self.browse(cr, uid, ids, context=context): |
61 | - ok = True |
62 | - for line in sub.lines_id: |
63 | - if not line.move_id.id: |
64 | - ok = False |
65 | + _order = 'date_start desc, id desc' |
66 | + |
67 | + def _check_repeat_value(self, cr, uid, ids, context=None): |
68 | + """ |
69 | + Prevents negative frequency |
70 | + """ |
71 | + for plan in self.read(cr, uid, ids, ['period_nbr']): |
72 | + if plan['period_nbr'] < 1: |
73 | + return False |
74 | + return True |
75 | + |
76 | + def _check_plan_name_unicity(self, cr, uid, ids, context=None): |
77 | + """ |
78 | + Prevents having 2 rec. plans using the same name |
79 | + """ |
80 | + for plan in self.read(cr, uid, ids, ['name']): |
81 | + if self.search_exist(cr, uid, [('name', '=', plan['name']), ('id', '!=', plan['id'])]): |
82 | + raise osv.except_osv(_('Error'), |
83 | + _('It is not possible to have several Recurring Plans with the same name: %s.') % plan['name']) |
84 | + return True |
85 | + |
86 | + _constraints = [ |
87 | + (_check_repeat_value, 'The value in the field "Repeat" must be greater than 0!', ['period_nbr']), |
88 | + (_check_plan_name_unicity, 'It is not possible to have several Recurring Plans with the same name.', ['name']), |
89 | + ] |
90 | + |
91 | + def copy(self, cr, uid, acc_sub_id, default=None, context=None): |
92 | + """ |
93 | + Account Subscription duplication: |
94 | + - block the process if the model has been set to Done as it shouldn't be used in any plans created afterwards |
95 | + - don't copy the link with subscription lines |
96 | + - add " (copy)" after the name |
97 | + """ |
98 | + if context is None: |
99 | + context = {} |
100 | + sub_copied = self.browse(cr, uid, acc_sub_id, fields_to_fetch=['name', 'model_id'], context=context) |
101 | + if sub_copied.model_id.state == 'done': |
102 | + raise osv.except_osv(_('Warning'), _('You cannot duplicate a Recurring Plan with a Done model.')) |
103 | + suffix = ' (copy)' |
104 | + name = '%s%s' % (sub_copied.name[:64 - len(suffix)], suffix) |
105 | + if default is None: |
106 | + default = {} |
107 | + default.update({ |
108 | + 'lines_id': [], |
109 | + 'name': name, |
110 | + }) |
111 | + return super(account_subscription, self).copy(cr, uid, acc_sub_id, default, context=context) |
112 | + |
113 | + def write(self, cr, uid, ids, vals, context=None): |
114 | + """ |
115 | + Edition of the Recurring Plans. If the model has been changed, triggers the recomputation of the state of the previous model used. |
116 | + |
117 | + UC: use the model X in one plan. Compute Rec. entries => the plans and models are Running. |
118 | + Select another model in the plan => model X must be set back to Draft. |
119 | + """ |
120 | + if not ids: |
121 | + return True |
122 | + if isinstance(ids, (int, long)): |
123 | + ids = [ids] |
124 | + if context is None: |
125 | + context = {} |
126 | + rec_model_obj = self.pool.get('account.model') |
127 | + models_to_check = set() |
128 | + for rec_plan in self.browse(cr, uid, ids, fields_to_fetch=['model_id'], context=context): |
129 | + previous_model_id = rec_plan.model_id.id |
130 | + if 'model_id' in vals and vals['model_id'] != previous_model_id: |
131 | + models_to_check.add(previous_model_id) |
132 | + res = super(account_subscription, self).write(cr, uid, ids, vals, context=context) |
133 | + if models_to_check: |
134 | + # check model states after the plan states have been updated |
135 | + rec_model_obj._store_set_values(cr, uid, list(models_to_check), ['state'], context) |
136 | + return res |
137 | + |
138 | + def unlink(self, cr, uid, ids, context=None): |
139 | + """ |
140 | + Prevents deletion in case the subscription lines have already been computed |
141 | + """ |
142 | + if context is None: |
143 | + context = {} |
144 | + if isinstance(ids, (int, long)): |
145 | + ids = [ids] |
146 | + sub_lines_obj = self.pool.get('account.subscription.line') |
147 | + if sub_lines_obj.search_exist(cr, uid, [('subscription_id', 'in', ids)], context=context): |
148 | + raise osv.except_osv(_('Warning'), _('You cannot delete a Recurring Plan if Subscription lines have already been computed.')) |
149 | + return super(account_subscription, self).unlink(cr, uid, ids, context=context) |
150 | + |
151 | + def update_plan_state(self, cr, uid, subscription_id, context=None): |
152 | + """ |
153 | + Updates the Recurring Plan state with the following rules: |
154 | + - no lines computed = Draft |
155 | + - lines computed but not all lines posted = Running |
156 | + - all lines posted = Done |
157 | + """ |
158 | + if context is None: |
159 | + context = {} |
160 | + sub = self.browse(cr, uid, subscription_id, fields_to_fetch=['lines_id'], context=context) |
161 | + if not sub.lines_id: |
162 | + state = 'draft' |
163 | + else: |
164 | + running = False |
165 | + for sub_line in sub.lines_id: |
166 | + if not sub_line.move_id or sub_line.move_id.state != 'posted': |
167 | + running = True |
168 | break |
169 | - if ok: |
170 | - todone.append(sub.id) |
171 | - if todone: |
172 | - self.write(cr, uid, todone, {'state':'done'}) |
173 | - return False |
174 | + if running: |
175 | + state = 'running' |
176 | + else: |
177 | + state = 'done' |
178 | + self.write(cr, uid, subscription_id, {'state': state}, context=context) |
179 | |
180 | def remove_line(self, cr, uid, ids, context=None): |
181 | toremove = [] |
182 | for sub in self.browse(cr, uid, ids, context=context): |
183 | for line in sub.lines_id: |
184 | - if not line.move_id.id: |
185 | + if not line.move_id: |
186 | toremove.append(line.id) |
187 | if toremove: |
188 | self.pool.get('account.subscription.line').unlink(cr, uid, toremove) |
189 | - self.write(cr, uid, ids, {'state':'draft'}) |
190 | return False |
191 | |
192 | def delete_unposted(self, cr, uid, ids, context=None): |
193 | @@ -2407,29 +2527,17 @@ |
194 | This method: |
195 | - searches for the unposted Journal Entries linked to the account subscription(s) |
196 | - deletes the unposted JEs, and the related JIs and AJIs |
197 | - - deletes all the Subscription Lines not linked to a Posted JE |
198 | - - triggers the "Compute" method on the subscription(s) to get the correct lines and state |
199 | """ |
200 | if context is None: |
201 | context = {} |
202 | - subline_obj = self.pool.get('account.subscription.line') |
203 | je_obj = self.pool.get('account.move') |
204 | - subline_to_delete_ids = [] |
205 | je_to_delete_ids = [] |
206 | for sub in self.browse(cr, uid, ids, fields_to_fetch=['lines_id'], context=context): |
207 | for subline in sub.lines_id: |
208 | - if not subline.move_id: |
209 | - # also deletes the sub. lines without JE (covers the case where frequency has been modified |
210 | - # => avoids having inconsistent lines at the end of the process) |
211 | - subline_to_delete_ids.append(subline.id) |
212 | - elif subline.move_id.state == 'draft': # draft = Unposted state |
213 | - subline_to_delete_ids.append(subline.id) |
214 | + if subline.move_id and subline.move_id.state == 'draft': # draft = Unposted state |
215 | je_to_delete_ids.append(subline.move_id.id) |
216 | - subline_obj.unlink(cr, uid, subline_to_delete_ids, context=context) |
217 | - je_obj.unlink(cr, uid, je_to_delete_ids, context=context) # also deletes JIs / AJIs |
218 | - # retrigger the creation of the subscription lines "to be generated" |
219 | - # and recompute the state of the subscription accordingly (= "Running" if lines have been generated) |
220 | - self.compute(cr, uid, ids, context=context) |
221 | + if je_to_delete_ids: |
222 | + je_obj.unlink(cr, uid, je_to_delete_ids, context=context) # also deletes JIs / AJIs |
223 | return True |
224 | |
225 | def get_dates_to_create(self, cr, uid, subscription_id, context=None): |
226 | @@ -2460,6 +2568,9 @@ |
227 | if context is None: |
228 | context = {} |
229 | for sub in self.browse(cr, uid, ids, context=context): |
230 | + if sub.state == 'running': |
231 | + # first remove existing lines without JE |
232 | + self.remove_line(cr, uid, ids, context=context) |
233 | if sub.model_id and sub.model_id.has_any_bad_ad_line_exp_in: |
234 | # UFTP-103: block compute if recurring model has line with |
235 | # expense/income accounts with invalid AD |
236 | @@ -2474,10 +2585,7 @@ |
237 | 'date': date_sub, |
238 | 'subscription_id': sub.id, |
239 | }) |
240 | - if dates_to_create: |
241 | - self.write(cr, uid, sub.id, {'state': 'running'}, context=context) |
242 | - else: # all the subscription lines were already created => the account subscription can be marked as "Done" |
243 | - self.write(cr, uid, sub.id, {'state': 'done'}, context=context) |
244 | + self.update_plan_state(cr, uid, sub.id, context=context) |
245 | return True |
246 | account_subscription() |
247 | |
248 | @@ -2492,19 +2600,16 @@ |
249 | _order = 'date, id' |
250 | |
251 | def move_create(self, cr, uid, ids, context=None): |
252 | - tocheck = {} |
253 | all_moves = [] |
254 | obj_model = self.pool.get('account.model') |
255 | for line in self.browse(cr, uid, ids, context=context): |
256 | datas = { |
257 | 'date': line.date, |
258 | + 'ref': line.subscription_id.ref or '', |
259 | } |
260 | move_ids = obj_model.generate(cr, uid, [line.subscription_id.model_id.id], datas, context) |
261 | - tocheck[line.subscription_id.id] = True |
262 | self.write(cr, uid, [line.id], {'move_id':move_ids[0]}) |
263 | all_moves.extend(move_ids) |
264 | - if tocheck: |
265 | - self.pool.get('account.subscription').check(cr, uid, tocheck.keys(), context) |
266 | return all_moves |
267 | |
268 | _rec_name = 'date' |
269 | |
270 | === modified file 'bin/addons/account/account_view.xml' |
271 | --- bin/addons/account/account_view.xml 2019-11-04 09:40:45 +0000 |
272 | +++ bin/addons/account/account_view.xml 2020-08-07 12:54:52 +0000 |
273 | @@ -1711,10 +1711,12 @@ |
274 | <field name="model">account.model</field> |
275 | <field name="type">tree</field> |
276 | <field name="arch" type="xml"> |
277 | - <tree string="Journal Entry Model"> |
278 | + <tree string="Journal Entry Model" colors="grey:state=='done';blue:state=='draft';black:state=='running'"> |
279 | <field name="name"/> |
280 | <field name="journal_id"/> |
281 | <field name="company_id" groups="base.group_multi_company"/> |
282 | + <field name="create_date"/> |
283 | + <field name="state"/> |
284 | </tree> |
285 | </field> |
286 | </record> |
287 | @@ -1729,9 +1731,11 @@ |
288 | <filter string="Sale" icon="terp-camera_test" domain="[('journal_id.type', '=', 'sale')]"/> |
289 | <filter string="Purchase" icon="terp-purchase" domain="[('journal_id.type', '=', 'purchase')]"/> |
290 | <separator orientation="vertical"/> |
291 | + <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state', '=', 'draft')]"/> |
292 | + <filter icon="terp-camera_test" string="Running" name="running" domain="[('state', '=', 'running')]"/> |
293 | + <filter icon="terp-dialog-close" string="Done" name="done" domain="[('state', '=', 'done')]" /> |
294 | <field name="name"/> |
295 | - <field name="journal_id" widget="selection"/> |
296 | - <field name="company_id" widget="selection" groups="base.group_multi_company"/> |
297 | + <field name="journal_id" domain="[('type', '=', 'purchase'), ('is_current_instance', '=', True)]"/> |
298 | </group> |
299 | <newline/> |
300 | <group expand="0" string="Group By..."> |
301 | @@ -1746,6 +1750,7 @@ |
302 | <field name="res_model">account.model</field> |
303 | <field name="view_type">form</field> |
304 | <field name="view_mode">tree,form</field> |
305 | + <field name="context">{'search_default_draft': 1, 'search_default_running': 1}</field> |
306 | <field name="search_view_id" ref="view_model_search"/> |
307 | </record> |
308 | <menuitem |
309 | @@ -1885,7 +1890,7 @@ |
310 | <field name="model">account.subscription</field> |
311 | <field name="type">tree</field> |
312 | <field name="arch" type="xml"> |
313 | - <tree colors="blue:state in ('draft');gray:state in ('done');black:state in ('running')" string="Entry Subscription"> |
314 | + <tree colors="blue:state=='draft';grey:state=='done';black:state=='running'" string="Recurring Plan"> |
315 | <field name="name"/> |
316 | <field name="model_id"/> |
317 | <field name="ref"/> |
318 | @@ -1900,10 +1905,10 @@ |
319 | <field name="model">account.subscription</field> |
320 | <field name="type">search</field> |
321 | <field name="arch" type="xml"> |
322 | - <search string="Entry Subscription"> |
323 | + <search string="Recurring Plan"> |
324 | <group col="8" colspan="4"> |
325 | - <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]" help="Draft Subscription"/> |
326 | - <filter icon="terp-camera_test" string="Running" name="running" domain="[('state','=','running')]" help="Running Subscription"/> |
327 | + <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state', '=', 'draft')]"/> |
328 | + <filter icon="terp-camera_test" string="Running" name="running" domain="[('state', '=', 'running')]"/> |
329 | <filter icon="terp-dialog-close" string="Done" name="done" domain="[('state','=','done')]" /> |
330 | <separator orientation="vertical"/> |
331 | <field name="name"/> |
332 | @@ -1924,19 +1929,20 @@ |
333 | <field name="model">account.subscription</field> |
334 | <field name="type">form</field> |
335 | <field name="arch" type="xml"> |
336 | - <form string="Recurring"> |
337 | - <group col="6" colspan="4"> |
338 | + <form string="Recurring Plan"> |
339 | + <group col="6" colspan="4" attrs="{'readonly': [('state', '=', 'done')]}"> |
340 | <field name="name" select="1"/> |
341 | - <field name="model_id"/> |
342 | + <field name="frozen_model" invisible="1"/> |
343 | + <field name="model_id" domain="[('state', '!=', 'done')]" attrs="{'readonly': [('frozen_model', '=', True)]}"/> |
344 | <field name="ref" select="1"/> |
345 | </group> |
346 | - <group col="2" colspan="2"> |
347 | + <group col="2" colspan="2" attrs="{'readonly': [('state', '=', 'done')]}"> |
348 | <separator colspan="4" string="Starts on"/> |
349 | <field name="date_start" select="1"/> |
350 | <field name="period_total"/> |
351 | </group> |
352 | |
353 | - <group col="2" colspan="2"> |
354 | + <group col="2" colspan="2" attrs="{'readonly': [('state', '=', 'done')]}"> |
355 | <separator colspan="4" string="Valid Up to"/> |
356 | <field name="period_nbr"/> |
357 | <field name="period_type"/> |
358 | @@ -1945,7 +1951,8 @@ |
359 | <group col="2" colspan="2"> |
360 | </group> |
361 | <separator colspan="4" string="Subscription Lines"/> |
362 | - <field colspan="4" name="lines_id" widget="one2many_list" nolabel="1"/> |
363 | + <field colspan="4" name="lines_id" widget="one2many_list" nolabel="1" |
364 | + attrs="{'readonly': [('state', '=', 'done')]}"/> |
365 | |
366 | <group col="6" colspan="4"> |
367 | <field name="state"/> |
368 | @@ -1953,23 +1960,22 @@ |
369 | <button name="delete_unposted" type="object" icon="terp-gtk-stop" |
370 | string="Delete Unposted Entries" |
371 | attrs="{'readonly': [('has_unposted_entries', '=', False)]}"/> |
372 | - <button name="compute" states="draft" string="Compute" type="object" icon="terp-stock_format-scientific"/> |
373 | - <button name="remove_line" states="running" string="Remove Lines" type="object" icon="gtk-remove"/> |
374 | + <button name="compute" states="draft,running" string="Compute" type="object" icon="terp-stock_format-scientific"/> |
375 | </group> |
376 | </form> |
377 | </field> |
378 | </record> |
379 | <record id="action_subscription_form" model="ir.actions.act_window"> |
380 | - <field name="name">Recurring Lines</field> |
381 | + <field name="name">Recurring Plan</field> |
382 | <field name="res_model">account.subscription</field> |
383 | <field name="view_type">form</field> |
384 | <field name="view_mode">tree,form</field> |
385 | <field name="search_view_id" ref="view_subscription_search"/> |
386 | - <field name="context">{'search_default_draft': 1, 'search_default_running': 1}</field> |
387 | - <field name="help">A recurring entry is a miscellaneous entry that occurs on a recurrent basis from a specific date, i.e. corresponding to the signature of a contract or an agreement with a customer or a supplier. With Define Recurring Entries, you can create such entries to automate the postings in the system.</field> |
388 | + <field name="context">{'search_default_running': 1, 'search_default_draft': 1}</field> |
389 | + <field name="help">A recurring entry is a miscellaneous entry that occurs on a recurrent basis from a specific date, i.e. corresponding to the signature of a contract or an agreement with a customer or a supplier. With Recurring Plan, you can create such entries to automate the postings in the system.</field> |
390 | </record> |
391 | <menuitem |
392 | - name="Define Recurring Entries" action="action_subscription_form" |
393 | + name="Recurring Plan" action="action_subscription_form" |
394 | groups="base.group_extended" |
395 | id="menu_action_subscription_form" sequence="1" |
396 | parent="account.menu_finance_recurrent_entries"/> |
397 | |
398 | === modified file 'bin/addons/account/wizard/account_subscription_generate.py' |
399 | --- bin/addons/account/wizard/account_subscription_generate.py 2018-10-17 09:25:17 +0000 |
400 | +++ bin/addons/account/wizard/account_subscription_generate.py 2020-08-07 12:54:52 +0000 |
401 | @@ -41,7 +41,7 @@ |
402 | account_obj = self.pool.get('account.account') |
403 | moves_created=[] |
404 | for data in self.read(cr, uid, ids, context=context): |
405 | - cr.execute('select id from account_subscription_line where date<%s and move_id is null', (data['date'],)) |
406 | + cr.execute('select id from account_subscription_line where date<=%s and move_id is null;', (data['date'],)) |
407 | line_ids = map(lambda x: x[0], cr.fetchall()) |
408 | # check that the entry is valid before creating it |
409 | for sub_line in sub_line_obj.browse(cr, uid, line_ids, context=context): |
410 | @@ -66,10 +66,11 @@ |
411 | raise osv.except_osv(_('Warning'), _('The entry is not balanced for the Recurring Model %s!') % (acc_model.name)) |
412 | moves = self.pool.get('account.subscription.line').move_create(cr, uid, line_ids, context=context) |
413 | moves_created.extend(moves) |
414 | - result = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_line_form') |
415 | + result = mod_obj.get_object_reference(cr, uid, 'account_subscription', 'act_account_subscription_to_account_move_line_open') |
416 | id = result and result[1] or False |
417 | result = act_obj.read(cr, uid, [id], context=context)[0] |
418 | - result['domain'] = str([('id','in',moves_created)]) |
419 | + # restrict display to Draft lines so that they automatically disappear from the list once the user posts them |
420 | + result['domain'] = str([('move_id', 'in', moves_created), ('move_state', '=', 'draft')]) |
421 | return result |
422 | |
423 | account_subscription_generate() |
424 | |
425 | === modified file 'bin/addons/account/wizard/account_subscription_generate_view.xml' |
426 | --- bin/addons/account/wizard/account_subscription_generate_view.xml 2011-01-14 00:11:01 +0000 |
427 | +++ bin/addons/account/wizard/account_subscription_generate_view.xml 2020-08-07 12:54:52 +0000 |
428 | @@ -8,8 +8,8 @@ |
429 | <field name="type">form</field> |
430 | <field name="arch" type="xml"> |
431 | <form string="Subscription Compute"> |
432 | - <separator string="Generate Entries before:" colspan="4"/> |
433 | - <label string ="Automatically generate entries based on what has been entered in the system before a specific date." colspan="4" nolabel="1"/> |
434 | + <separator string="Generate Entries until:" colspan="4"/> |
435 | + <label string = "Automatically generate entries based on what has been entered in the system until a specific date." colspan="4" nolabel="1"/> |
436 | <newline/> |
437 | <field name="date"/> |
438 | <separator colspan="4" /> |
439 | |
440 | === modified file 'bin/addons/account/wizard/account_validate_account_move.py' |
441 | --- bin/addons/account/wizard/account_validate_account_move.py 2011-01-14 00:11:01 +0000 |
442 | +++ bin/addons/account/wizard/account_validate_account_move.py 2020-08-07 12:54:52 +0000 |
443 | @@ -49,6 +49,8 @@ |
444 | def validate_move_lines(self, cr, uid, ids, context=None): |
445 | obj_move_line = self.pool.get('account.move.line') |
446 | obj_move = self.pool.get('account.move') |
447 | + obj_subscription_line = self.pool.get('account.subscription.line') |
448 | + obj_recurring_plan = self.pool.get('account.subscription') |
449 | move_ids = [] |
450 | if context is None: |
451 | context = {} |
452 | @@ -60,6 +62,14 @@ |
453 | if not move_ids: |
454 | raise osv.except_osv(_('Warning'), _('Selected Entry Lines does not have any account move enties in draft state')) |
455 | obj_move.button_validate(cr, uid, move_ids, context) |
456 | + # update the state of the related Recurring Plans if any |
457 | + sub_line_ids = obj_subscription_line.search(cr, uid, [('move_id', 'in', move_ids)], context=context) |
458 | + if sub_line_ids: |
459 | + recurring_plans = set() |
460 | + for sub_line in obj_subscription_line.browse(cr, uid, sub_line_ids, fields_to_fetch=['subscription_id'], context=context): |
461 | + recurring_plans.add(sub_line.subscription_id.id) |
462 | + for recurring_plan_id in recurring_plans: |
463 | + obj_recurring_plan.update_plan_state(cr, uid, recurring_plan_id, context=context) |
464 | return {'type': 'ir.actions.act_window_close'} |
465 | validate_account_move_lines() |
466 | |
467 | |
468 | === modified file 'bin/addons/account_period_closing_level/account_period.py' |
469 | --- bin/addons/account_period_closing_level/account_period.py 2020-03-20 14:08:02 +0000 |
470 | +++ bin/addons/account_period_closing_level/account_period.py 2020-08-07 12:54:52 +0000 |
471 | @@ -25,7 +25,6 @@ |
472 | from tools.safe_eval import safe_eval |
473 | from account_period_closing_level import ACCOUNT_PERIOD_STATE_SELECTION |
474 | from register_accounting import register_tools |
475 | -from datetime import datetime |
476 | |
477 | |
478 | class account_period(osv.osv): |
479 | @@ -69,7 +68,6 @@ |
480 | |
481 | # Prepare some elements |
482 | reg_obj = self.pool.get('account.bank.statement') |
483 | - sub_obj = self.pool.get('account.subscription') |
484 | sub_line_obj = self.pool.get('account.subscription.line') |
485 | curr_obj = self.pool.get('res.currency') |
486 | curr_rate_obj = self.pool.get('res.currency.rate') |
487 | @@ -233,21 +231,10 @@ |
488 | "to close and have a balance which isn't equal to 0:\n" |
489 | "%s") % ", ".join([r.name for r in reg_ko])) |
490 | |
491 | - # check if subscriptions lines haven't been generated yet for this period |
492 | - draft_sub_ids = sub_obj.search(cr, uid, [('state', '=', 'draft')], order='NO_ORDER', context=context) |
493 | - for draft_sub_id in draft_sub_ids: |
494 | - dates_to_create = sub_obj.get_dates_to_create(cr, uid, draft_sub_id, context=context) |
495 | - date_stop_dt = datetime.strptime(period.date_stop, "%Y-%m-%d") |
496 | - for date_to_create in dates_to_create: |
497 | - date_to_create_dt = datetime.strptime(date_to_create, "%Y-%m-%d") |
498 | - if date_to_create_dt <= date_stop_dt: |
499 | - raise osv.except_osv(_('Warning'), _("Subscription Lines included in the Period \"%s\" or before haven't been generated. " |
500 | - "Please generate them and create the related recurring entries " |
501 | - "before closing the period.") % (period.name,)) |
502 | # for subscription lines generated check if some related recurring entries haven't been created yet |
503 | if sub_line_obj.search_exist(cr, uid, [('date', '<=', period.date_stop), ('move_id', '=', False)], context=context): |
504 | raise osv.except_osv(_('Warning'), _("Recurring entries included in the Period \"%s\" or before haven't been created. " |
505 | - "Please create them before closing the period.") % (period.name,)) |
506 | + "Please generate them before closing the period.") % (period.name,)) |
507 | # then verify that all currencies have a fx rate in this period |
508 | # retrieve currencies for this period (in account_move_lines) |
509 | sql = """SELECT DISTINCT currency_id |
510 | |
511 | === modified file 'bin/addons/account_subscription/__init__.py' |
512 | --- bin/addons/account_subscription/__init__.py 2012-08-09 11:20:48 +0000 |
513 | +++ bin/addons/account_subscription/__init__.py 2020-08-07 12:54:52 +0000 |
514 | @@ -22,6 +22,5 @@ |
515 | import account_move_line |
516 | import account_model |
517 | import account_use_model |
518 | -import account_subscription |
519 | |
520 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
521 | |
522 | === modified file 'bin/addons/account_subscription/account_model.py' |
523 | --- bin/addons/account_subscription/account_model.py 2020-01-22 10:35:39 +0000 |
524 | +++ bin/addons/account_subscription/account_model.py 2020-08-07 12:54:52 +0000 |
525 | @@ -133,6 +133,7 @@ |
526 | selection=[('no_exp_in', 'Not expense/income'), ('no_header', 'No header'), |
527 | ('valid', 'Valid'), ('invalid', 'Invalid'), ('invalid_small_amount', 'Invalid')], |
528 | string='Expense/income line status'), # UFTP-103 |
529 | + 'is_balanced': fields.related('model_id', 'is_balanced', type='boolean', string='Is balanced', readonly=True, store=False), |
530 | } |
531 | |
532 | _defaults = { |
533 | @@ -253,6 +254,75 @@ |
534 | break |
535 | return res |
536 | |
537 | + def _get_model_state(self, cr, uid, ids, name, args, context=None): |
538 | + """ |
539 | + A model is: |
540 | + - in Done state if it is used in a least one Done Recurring Plan, |
541 | + - in Running state if it is used in a least one Running Recurring Plan, |
542 | + - in Draft state otherwise. |
543 | + """ |
544 | + if context is None: |
545 | + context = {} |
546 | + if isinstance(ids, (int, long)): |
547 | + ids = [ids] |
548 | + res = {} |
549 | + recurring_plan_obj = self.pool.get('account.subscription') |
550 | + for model_id in ids: |
551 | + if recurring_plan_obj.search_exist(cr, uid, [('model_id', '=', model_id), ('state', '=', 'done')], context=context): |
552 | + state = 'done' |
553 | + elif recurring_plan_obj.search_exist(cr, uid, [('model_id', '=', model_id), ('state', '=', 'running')], context=context): |
554 | + state = 'running' |
555 | + else: |
556 | + state = 'draft' |
557 | + res[model_id] = state |
558 | + return res |
559 | + |
560 | + def _get_models_to_check(self, cr, uid, recurring_plan_ids, context=None): |
561 | + """ |
562 | + Returns the list of Recurring Models for which the state should be checked and updated if necessary |
563 | + """ |
564 | + if context is None: |
565 | + context = {} |
566 | + res = set() |
567 | + recurring_plan_obj = self.pool.get('account.subscription') |
568 | + for rec_plan in recurring_plan_obj.browse(cr, uid, recurring_plan_ids, fields_to_fetch=['model_id'], context=context): |
569 | + res.add(rec_plan.model_id.id) |
570 | + return list(res) |
571 | + |
572 | + def unlink(self, cr, uid, ids, context=None): |
573 | + """ |
574 | + Prevents deletion in case the model has been selected into a Recurring Plan |
575 | + """ |
576 | + if context is None: |
577 | + context = {} |
578 | + if isinstance(ids, (int, long)): |
579 | + ids = [ids] |
580 | + recurring_plan_obj = self.pool.get('account.subscription') |
581 | + recurring_plan_ids = recurring_plan_obj.search(cr, uid, [('model_id', 'in', ids)], context=context) |
582 | + if recurring_plan_ids: |
583 | + plan_names = [p.name for p in recurring_plan_obj.browse(cr, uid, recurring_plan_ids, fields_to_fetch=['name'], context=context)] |
584 | + raise osv.except_osv(_('Warning'), _('You cannot delete a model which is used in the following plan(s): %s') % |
585 | + (', '.join(plan_names),)) |
586 | + return super(account_model, self).unlink(cr, uid, ids, context=context) |
587 | + |
588 | + def _get_is_balanced(self, cr, uid, ids, name, arg, context=None): |
589 | + """ |
590 | + Returns True for the models for which the total of the lines is zero |
591 | + """ |
592 | + if context is None: |
593 | + context = {} |
594 | + if isinstance(ids, (int, long)): |
595 | + ids = [ids] |
596 | + res = {} |
597 | + for model in self.browse(cr, uid, ids, fields_to_fetch=['lines_id'], context=context): |
598 | + debit = sum([l.debit or 0.0 for l in model.lines_id]) or 0.0 |
599 | + credit = sum([l.credit or 0.0 for l in model.lines_id]) or 0.0 |
600 | + if abs(debit - credit) <= 10**-3: |
601 | + res[model.id] = True |
602 | + else: |
603 | + res[model.id] = False |
604 | + return res |
605 | + |
606 | _columns = { |
607 | 'currency_id': fields.many2one('res.currency', 'Currency', required=True), |
608 | 'analytic_distribution_id': fields.many2one('analytic.distribution', 'Analytic Distribution'), |
609 | @@ -260,13 +330,38 @@ |
610 | method=True, type='boolean', |
611 | string='Has bad analytic distribution on expense/income lines', |
612 | help='There is lines with expense or income accounts with invalid analytic distribution or using header AD that is not defined or not compatible.'), # UFTP-103 |
613 | + 'state': fields.function(_get_model_state, method=True, type='selection', string="State", |
614 | + selection=[('draft', 'Draft'), ('running', 'Running'), ('done', 'Done')], |
615 | + store={ |
616 | + 'account.subscription': (_get_models_to_check, ['model_id', 'state'], 10), |
617 | + }), |
618 | + 'is_balanced': fields.function(_get_is_balanced, method=True, type='boolean', string="Is balanced", readonly=True, store=False), |
619 | + 'create_date': fields.date('Creation date', readonly=True), # overwrites the standard create_date so it can be displayed in the views |
620 | + 'recurring_plan_ids': fields.one2many('account.subscription', 'model_id', string='Recurring Plans', readonly=True), |
621 | } |
622 | |
623 | _defaults = { |
624 | 'currency_id': lambda self, cr, uid, context: self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id, |
625 | 'has_any_bad_ad_line_exp_in': False, |
626 | + 'state': lambda *a: 'draft', |
627 | } |
628 | |
629 | + _order = 'create_date DESC, id DESC' |
630 | + |
631 | + def _check_model_name_unicity(self, cr, uid, ids, context=None): |
632 | + """ |
633 | + Prevents having 2 models using the same name |
634 | + """ |
635 | + for model in self.read(cr, uid, ids, ['name']): |
636 | + if self.search_exist(cr, uid, [('name', '=', model['name']), ('id', '!=', model['id'])]): |
637 | + raise osv.except_osv(_('Error'), |
638 | + _('It is not possible to have several Recurring Models with the same name: %s.') % model['name']) |
639 | + return True |
640 | + |
641 | + _constraints = [ |
642 | + (_check_model_name_unicity, 'It is not possible to have several Recurring Models with the same name.', ['name']), |
643 | + ] |
644 | + |
645 | # @@@override@account.account_model.generate() |
646 | def generate(self, cr, uid, ids, datas={}, context=None): |
647 | move_ids = [] |
648 | @@ -275,6 +370,7 @@ |
649 | account_move_line_obj = self.pool.get('account.move.line') |
650 | pt_obj = self.pool.get('account.payment.term') |
651 | ana_obj = self.pool.get('analytic.distribution') |
652 | + period_obj = self.pool.get('account.period') |
653 | |
654 | if context is None: |
655 | context = {} |
656 | @@ -282,13 +378,15 @@ |
657 | if datas.get('date', False): |
658 | context.update({'date': datas['date']}) |
659 | |
660 | - period_id = self.pool.get('account.period').find(cr, uid, dt=context.get('date', False)) |
661 | - if not period_id: |
662 | + period_domain = [('date_start', '<=', context.get('date')), ('date_stop', '>=', context.get('date')), ('special', '=', False)] |
663 | + period_ids = period_obj.search(cr, uid, period_domain, context=context) |
664 | + |
665 | + if not period_ids: |
666 | raise osv.except_osv(_('No period found !'), _('Unable to find a valid period !')) |
667 | - period_id = period_id[0] |
668 | + period_id = period_ids[0] |
669 | # UFTP-105: Check that period is open. Otherwise raise an error |
670 | - period = self.pool.get('account.period').browse(cr, uid, period_id, context=context) |
671 | - if not period or period.state != 'draft': |
672 | + period = period_obj.browse(cr, uid, period_id, fields_to_fetch=['state', 'name'], context=context) |
673 | + if period.state != 'draft': |
674 | raise osv.except_osv(_('Warning'), _('This period should be in open state: %s') % (period.name)) |
675 | |
676 | for model in self.browse(cr, uid, ids, context=context): |
677 | @@ -315,8 +413,9 @@ |
678 | except Exception: |
679 | raise osv.except_osv(_('Error'), _('The name of the Recurring Model used is incorrect: %s\n' |
680 | 'You can find a list of the formatted strings usable on the Recurring Model form.') % model.name) |
681 | + ref = datas.get('ref', '') or entry['name'] |
682 | move_id = account_move_obj.create(cr, uid, { |
683 | - 'ref': entry['name'], |
684 | + 'ref': ref, |
685 | 'period_id': period_id, |
686 | 'journal_id': model.journal_id.id, |
687 | 'date': context.get('date',time.strftime('%Y-%m-%d')) |
688 | @@ -327,10 +426,11 @@ |
689 | 'move_id': move_id, |
690 | 'journal_id': model.journal_id.id, |
691 | 'period_id': period_id, |
692 | + 'reference': ref, |
693 | } |
694 | if line.account_id.is_analytic_addicted: |
695 | if line.analytic_distribution_state == 'invalid': |
696 | - raise osv.except_osv(_('Invalid Analytic Distribution !'),_("Please define a valid analytic distribution for the recurring model '%s'!") % (line.name)) |
697 | + raise osv.except_osv(_('Invalid Analytic Distribution !'),_("Please define a valid analytic distribution for the recurring model '%s'!") % (line.model_id.name)) |
698 | if not model.journal_id.analytic_journal_id: |
699 | raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (model.journal_id.name,)) |
700 | if line.analytic_distribution_id: |
701 | @@ -438,5 +538,23 @@ |
702 | recurring_obj.write(cr, uid, to_reset, {'analytic_distribution_id': False}) |
703 | return True |
704 | |
705 | + def copy(self, cr, uid, model_id, default=None, context=None): |
706 | + """ |
707 | + Recurring Model duplication: don't copy the link with the rec. plans, and add " (copy)" after the name |
708 | + """ |
709 | + if context is None: |
710 | + context = {} |
711 | + suffix = ' (copy)' |
712 | + model_copied = self.read(cr, uid, model_id, ['name'], context=context) |
713 | + name = '%s%s' % (model_copied['name'][:64 - len(suffix)], suffix) |
714 | + if default is None: |
715 | + default = {} |
716 | + default.update({ |
717 | + 'name': name, |
718 | + 'recurring_plan_ids': [], |
719 | + }) |
720 | + return super(account_model, self).copy(cr, uid, model_id, default, context=context) |
721 | + |
722 | + |
723 | account_model() |
724 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
725 | |
726 | === modified file 'bin/addons/account_subscription/account_model_view.xml' |
727 | --- bin/addons/account_subscription/account_model_view.xml 2020-01-22 10:35:39 +0000 |
728 | +++ bin/addons/account_subscription/account_model_view.xml 2020-08-07 12:54:52 +0000 |
729 | @@ -9,7 +9,7 @@ |
730 | <field name="inherit_id" ref="account.view_model_form"/> |
731 | <field name="arch" type="xml"> |
732 | <form string="Journal Entry Model" position="replace"> |
733 | - <form string="Journal Entry Model"> |
734 | + <form string="Recurring Models"> |
735 | <group><html> |
736 | <p id="para_has_any_bad_ad_line_exp_in" |
737 | style="display:none; text-align:center; color: red; font-weight: bold; font-size: 1.2em;"> |
738 | @@ -24,19 +24,38 @@ |
739 | </script> |
740 | </html></group> |
741 | <group col="6" colspan="4"> |
742 | - <field name="name"/> |
743 | - <field name="journal_id" domain="[('type','=','purchase'),('is_current_instance','=',True)]"/> |
744 | - <field name="currency_id"/> |
745 | + <group attrs="{'readonly': [('state', '=', 'done')]}" colspan="6" col="6"> |
746 | + <field name="name"/> |
747 | + <field name="journal_id" domain="[('type', '=', 'purchase'), ('is_current_instance', '=', True)]"/> |
748 | + <field name="currency_id"/> |
749 | + </group> |
750 | <group colspan="6" col="6" attrs="{'invisible': [('analytic_distribution_id', '=', False)]}"> |
751 | <button name="button_analytic_distribution" string="Analytical Distribution" type="object" icon="terp-check" context="context" colspan="3" attrs="{'invisible': [('analytic_distribution_id', '=', False)]}"/> |
752 | - <button name="button_reset_distribution" string="Reset AD at line level" type="object" icon="gtk-undelete" colspan="3"/> |
753 | + <button name="button_reset_distribution" string="Reset AD at line level" type="object" |
754 | + icon="gtk-undelete" colspan="3" attrs="{'invisible': [('state', '=', 'done')]}"/> |
755 | </group> |
756 | <group colspan="6" col="6" attrs="{'invisible': [('analytic_distribution_id', '!=', False)]}"> |
757 | <button name="button_analytic_distribution" string="Analytical Distribution" type="object" icon="terp-emblem-important" context="context" colspan="3" attrs="{'invisible': [('analytic_distribution_id', '!=', False)]}"/> |
758 | - <button name="button_reset_distribution" string="Reset AD at line level" type="object" icon="gtk-undelete" colspan="3"/> |
759 | + <button name="button_reset_distribution" string="Reset AD at line level" type="object" |
760 | + icon="gtk-undelete" colspan="3" attrs="{'invisible': [('state', '=', 'done')]}"/> |
761 | </group> |
762 | <field name="analytic_distribution_id" invisible="1"/> |
763 | - <field colspan="6" nolabel="1" name="lines_id" widget="one2many_list"/> |
764 | + <notebook colspan="4"> |
765 | + <page string="Model"> |
766 | + <field nolabel="1" name="lines_id" widget="one2many_list" colspan="4" |
767 | + attrs="{'readonly': [('state', '=', 'done')]}"/> |
768 | + </page> |
769 | + <page string="Related plans"> |
770 | + <field nolabel="1" name="recurring_plan_ids" colspan="4"> |
771 | + <tree> |
772 | + <field name="name" string="Plan names"/> |
773 | + <field name="state" string="Plan status"/> |
774 | + </tree> |
775 | + </field> |
776 | + </page> |
777 | + </notebook> |
778 | + <label string="" colspan="4"/> |
779 | + <field name="state" readonly="1"/> |
780 | <separator colspan="6" string="Legend (for the Model Name)"/> |
781 | <group col="8" colspan="6"> |
782 | <group> |
783 | @@ -91,7 +110,8 @@ |
784 | <field name="type">tree</field> |
785 | <field name="arch" type="xml"> |
786 | <tree string="Journal Entry Model Line" editable="bottom" |
787 | - colors="red: exp_in_ad_state in ('no_header', 'bad_header', 'invalid', 'invalid_small_amount')"> |
788 | + colors="red: exp_in_ad_state in ('no_header', 'bad_header', 'invalid', 'invalid_small_amount');blue:not is_balanced and exp_in_ad_state not in ('no_header', 'bad_header', 'invalid', 'invalid_small_amount')"> |
789 | + <field name="is_balanced" invisible="1"/> |
790 | <field name="sequence" readonly="1"/> |
791 | <field name="name"/> |
792 | <field name="account_id" domain="[('restricted_area', '=', 'recurring_lines')]"/> |
793 | @@ -101,8 +121,8 @@ |
794 | <field name="analytic_distribution_state" invisible="1"/> |
795 | <field name="is_allocatable" invisible="1"/> |
796 | <field name="partner_id"/> |
797 | - <field name="debit"/> |
798 | - <field name="credit"/> |
799 | + <field name="debit" sum="Total Debit"/> |
800 | + <field name="credit" sum="Total Credit"/> |
801 | <field name="exp_in_ad_state" invisible="1"/> |
802 | </tree> |
803 | </field> |
804 | @@ -162,7 +182,7 @@ |
805 | <field name="type">tree</field> |
806 | <field name="priority" eval="14"/> |
807 | <field name="arch" type="xml"> |
808 | - <tree string="Recurring Entries To Validate" min_rows="100" |
809 | + <tree string="Recurring Entries To Post" min_rows="100" |
810 | hide_new_button="1" hide_delete_button="1" hide_edit_button="1" |
811 | colors="red:analytic_distribution_state not in ('valid')"> |
812 | <field name="instance_id"/> |
813 | @@ -209,14 +229,47 @@ |
814 | </field> |
815 | </record> |
816 | |
817 | - <act_window |
818 | - id="act_account_subscription_to_account_move_line_open" |
819 | - name="Recurring Entries To Validate" |
820 | - domain="[('move_id.state','=','draft'), ('is_recurring', '=', True)]" |
821 | - context="{'from_recurring_entries': True}" |
822 | - res_model="account.move.line" |
823 | - src_model="account.subscription" |
824 | - view_id="account_move_line_recurring_entries_to_validate"/> |
825 | + <!-- Recurring Entries To Post Search View --> |
826 | + <record id="view_recurring_entries_to_post_search" model="ir.ui.view"> |
827 | + <field name="name">recurring.entries.to.post.search</field> |
828 | + <field name="model">account.move.line</field> |
829 | + <field name="type">search</field> |
830 | + <field name="priority" eval="25"/> |
831 | + <field name="arch" type="xml"> |
832 | + <search> |
833 | + <group colspan="6" col="14"> |
834 | + <field name="move_id"/> |
835 | + <field name="name"/> |
836 | + <field name="ref"/> |
837 | + <field name="document_date"/> |
838 | + <field name="date"/> |
839 | + <field name="period_id" domain="[('special', '=', False), ('state', '=', 'draft')]"/> |
840 | + <field name="account_id" domain="[('restricted_area', '=', 'recurring_lines')]"/> |
841 | + <newline/> |
842 | + <!-- title matching with the tree view but only Partners are possible --> |
843 | + <field name="partner_id" string="Third Parties"/> |
844 | + <field name="debit_currency"/> |
845 | + <field name="credit_currency"/> |
846 | + <field name="currency_id"/> |
847 | + <field name="debit"/> |
848 | + <field name="credit"/> |
849 | + </group> |
850 | + </search> |
851 | + </field> |
852 | + </record> |
853 | + |
854 | + <!-- Recurring Entries To Post Entry Menu --> |
855 | + <record id="act_account_subscription_to_account_move_line_open" model="ir.actions.act_window"> |
856 | + <field name="name">Recurring Entries To Post</field> |
857 | + <field name="res_model">account.move.line</field> |
858 | + <field name="src_model">account.subscription</field> |
859 | + <field name="view_type">form</field> |
860 | + <field name="view_mode">tree,form</field> |
861 | + <field name="view_id" ref="account_move_line_recurring_entries_to_validate"/> |
862 | + <field name="context">{'from_recurring_entries': True}</field> |
863 | + <field name="domain">[('move_id.state', '=', 'draft'), ('is_recurring', '=', True)]</field> |
864 | + <field name="search_view_id" ref="view_recurring_entries_to_post_search"/> |
865 | + </record> |
866 | |
867 | </data> |
868 | </openerp> |
869 | |
870 | === removed file 'bin/addons/account_subscription/account_subscription.py' |
871 | === modified file 'bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py' |
872 | --- bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py 2020-02-21 15:15:49 +0000 |
873 | +++ bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py 2020-08-07 12:54:52 +0000 |
874 | @@ -549,6 +549,11 @@ |
875 | if not context.get('from_correction', False) and \ |
876 | el.move_id.state and el.move_id.state not in ['draft']: |
877 | res[el.id] = False |
878 | + # check Recurring Model state |
879 | + if el.model_id and el.model_id.state == 'done': |
880 | + res[el.id] = False |
881 | + if el.model_line_id and el.model_line_id.model_id.state == 'done': |
882 | + res[el.id] = False |
883 | return res |
884 | |
885 | def _have_header(self, cr, uid, ids, name, args, context=None): |
886 | |
887 | === modified file 'bin/addons/msf_profile/data/patches.xml' |
888 | --- bin/addons/msf_profile/data/patches.xml 2020-08-04 08:00:56 +0000 |
889 | +++ bin/addons/msf_profile/data/patches.xml 2020-08-07 12:54:52 +0000 |
890 | @@ -577,9 +577,16 @@ |
891 | <field name="method">us_7412_set_fy_closure_settings</field> |
892 | </record> |
893 | |
894 | +<<<<<<< TREE |
895 | <record id="us_6453_set_ref_on_in" model="patch.scripts"> |
896 | <field name="method">us_6453_set_ref_on_in</field> |
897 | </record> |
898 | |
899 | +======= |
900 | + <record id="us_5216_update_recurring_object_state" model="patch.scripts"> |
901 | + <field name="method">us_5216_update_recurring_object_state</field> |
902 | + </record> |
903 | + |
904 | +>>>>>>> MERGE-SOURCE |
905 | </data> |
906 | </openerp> |
907 | |
908 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
909 | --- bin/addons/msf_profile/i18n/fr_MF.po 2020-08-04 08:46:20 +0000 |
910 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2020-08-07 12:54:52 +0000 |
911 | @@ -8436,7 +8436,7 @@ |
912 | msgid "Either there are no moves linked to the picking or Accounting Journals are misconfigured!" |
913 | msgstr "Soit les Journaux Comptables sont mal configurés, soit il n'y a pas de mouvement connexe à ce prélèvement !" |
914 | |
915 | -#. modules: tender_flow, financing_contract, msf_tools, account_override, purchase_allocation_report, register_accounting, mission_stock, msf_accrual, finance, sync_client, return_claim, account_mcdb, res_currency_tables, supplier_catalogue, procurement_request, stock_forecast, analytic, stock_override, msf_doc_import, analytic_distribution, msf_order_date, msf_homere_interface, consumption_calculation, msf_instance, purchase_override, specific_rules, kit, out_step, base, msf_supply_doc_export, msf_budget, account_corrections, account, msf_outgoing, documents_done, sale, sales_followup, procurement, sourcing, purchase, msf_audittrail, stock, product, procurement_cycle |
916 | +#. modules: tender_flow, financing_contract, msf_tools, account_override, purchase_allocation_report, register_accounting, mission_stock, msf_accrual, finance, sync_client, return_claim, account_mcdb, res_currency_tables, supplier_catalogue, procurement_request, stock_forecast, analytic, stock_override, msf_doc_import, analytic_distribution, msf_order_date, msf_homere_interface, consumption_calculation, msf_instance, purchase_override, specific_rules, kit, out_step, base, msf_supply_doc_export, msf_budget, account_corrections, account, msf_outgoing, documents_done, sale, sales_followup, procurement, sourcing, purchase, msf_audittrail, stock, product, procurement_cycle, account_subscription |
917 | #: code:addons/msf_supply_doc_export/wizard/po_follow_up.py:106 |
918 | #: selection:msf.instance.cloud,state:0 |
919 | #: field:ppl.processor,draft_step2:0 |
920 | @@ -8609,6 +8609,8 @@ |
921 | #: selection:replenishment.segment,state:0 |
922 | #: view:product.stock_out:0 |
923 | #: selection:product.stock_out,state:0 |
924 | +#: selection:account.model,state:0 |
925 | +#: view:account.model:0 |
926 | #, python-format |
927 | msgid "Draft" |
928 | msgstr "Brouillon" |
929 | @@ -10058,11 +10060,6 @@ |
930 | msgid "Funding pools:" |
931 | msgstr "Funding pools:" |
932 | |
933 | -#. module: account |
934 | -#: view:account.subscription:0 |
935 | -msgid "Entry Subscription" |
936 | -msgstr "Ecriture de souscription" |
937 | - |
938 | #. modules: account, account_period_closing_level |
939 | #: model:ir.actions.act_window,help:account.action_account_period_tree |
940 | #: model:ir.actions.act_window,help:account_period_closing_level.action_account_period_closing_level_tree |
941 | @@ -13614,9 +13611,10 @@ |
942 | msgid "Invoice Control" |
943 | msgstr "Contrôle Facture" |
944 | |
945 | -#. module: account |
946 | +#. modules: account, account_subscription |
947 | #: model:ir.actions.act_window,name:account.action_model_form |
948 | #: model:ir.ui.menu,name:account.menu_action_model_form |
949 | +#: view:account.model:0 |
950 | msgid "Recurring Models" |
951 | msgstr "Modèles périodiques" |
952 | |
953 | @@ -20777,12 +20775,11 @@ |
954 | msgid "Etc/GMT-11" |
955 | msgstr "Etc/GMT-11" |
956 | |
957 | -#. modules: sales_followup, msf_tools, account |
958 | +#. modules: sales_followup, msf_tools |
959 | #: selection:ir.followup.location.wizard,state:0 |
960 | #: selection:job.in_progress,state:0 |
961 | -#: view:account.subscription:0 |
962 | msgid "Done" |
963 | -msgstr "Cloturé" |
964 | +msgstr "Clôturé" |
965 | |
966 | #. module: delivery_mechanism |
967 | #: code:addons/delivery_mechanism/delivery_mechanism.py:360 |
968 | @@ -23927,7 +23924,7 @@ |
969 | #. module: account |
970 | #: field:account.subscription,period_nbr:0 |
971 | msgid "Repeat" |
972 | -msgstr "Repeat" |
973 | +msgstr "Périodicité" |
974 | |
975 | #. module: sourcing |
976 | #: code:addons/sourcing/sale_order_line.py:905 |
977 | @@ -30362,8 +30359,8 @@ |
978 | |
979 | #. module: account |
980 | #: view:account.subscription.generate:0 |
981 | -msgid "Automatically generate entries based on what has been entered in the system before a specific date." |
982 | -msgstr "Génère automatiquement des écritures en se basant sur ce qui a été enregistré dans le système avant une date spécifique" |
983 | +msgid "Automatically generate entries based on what has been entered in the system until a specific date." |
984 | +msgstr "Génère automatiquement des écritures en se basant sur ce qui a été enregistré dans le système jusqu'à une date spécifique." |
985 | |
986 | #. module: base |
987 | #: model:res.currency,currency_name:base.DZD |
988 | @@ -33535,11 +33532,6 @@ |
989 | msgid "used in statement reconciliation domain, but shouldn't be used elswhere." |
990 | msgstr "utilisé dans le domaine du lettrage de relevés, mais ne devrait pas être utilisé ailleurs" |
991 | |
992 | -#. module: account |
993 | -#: view:account.subscription:0 |
994 | -msgid "Draft Subscription" |
995 | -msgstr "Draft Subscription" |
996 | - |
997 | #. module: base |
998 | #: view:partner.wizard.ean.check:0 |
999 | msgid "Correct EAN13" |
1000 | @@ -38135,11 +38127,6 @@ |
1001 | msgid "Reservation Destination" |
1002 | msgstr "Destination de la Réservation" |
1003 | |
1004 | -#. module: account |
1005 | -#: view:account.subscription:0 |
1006 | -msgid "Remove Lines" |
1007 | -msgstr "Supprimer des lignes" |
1008 | - |
1009 | #. module: base |
1010 | #: help:ir.cron,function:0 |
1011 | msgid "Name of the method to be called on the object when this scheduler is executed." |
1012 | @@ -38308,7 +38295,7 @@ |
1013 | #: code:addons/account/wizard/account_subscription_generate.py:52 |
1014 | #, python-format |
1015 | msgid "The Recurring Model %s must have at least two lines." |
1016 | -msgstr "Le Modèle Récurrent %s doit au moins avoir deux lignes." |
1017 | +msgstr "Le Modèle Périodique %s doit avoir au moins deux lignes." |
1018 | |
1019 | #. module: msf_doc_import |
1020 | #: code:addons/msf_doc_import/msf_import_export.py:103 |
1021 | @@ -38581,7 +38568,7 @@ |
1022 | msgid "Is inactive for destination given in context" |
1023 | msgstr "Is inactive for destination given in context" |
1024 | |
1025 | -#. modules: sales_followup, account, documents_done, consumption_calculation, sale, specific_rules, transport_mgmt, account_override, purchase_allocation_report, product_list, tender_flow, msf_doc_import, stock, product_attributes, purchase_override, purchase |
1026 | +#. modules: sales_followup, account, documents_done, consumption_calculation, sale, specific_rules, transport_mgmt, account_override, purchase_allocation_report, product_list, tender_flow, msf_doc_import, stock, product_attributes, purchase_override, purchase, account_subscription |
1027 | #: field:account.move.line,date_created:0 |
1028 | #: field:account.move.reconcile,create_date:0 |
1029 | #: report:allocation.invoices.report:0 |
1030 | @@ -38608,6 +38595,7 @@ |
1031 | #: field:internal.request.import,in_creation_date:0 |
1032 | #: field:purchase.order.line,create_date:0 |
1033 | #: field:internal.request.import,in_creation_date:0 |
1034 | +#: field:account.model,create_date:0 |
1035 | #, python-format |
1036 | msgid "Creation date" |
1037 | msgstr "Date de création" |
1038 | @@ -39212,7 +39200,7 @@ |
1039 | msgid "RfQs" |
1040 | msgstr "DdD" |
1041 | |
1042 | -#. modules: account, sync_client, product_asset, base, msf_audittrail, board, object_query, msf_profile, msf_field_access_rights, msf_button_access_rights,msf_tools |
1043 | +#. modules: account, sync_client, product_asset, base, msf_audittrail, board, object_query, msf_profile, msf_field_access_rights, msf_button_access_rights, msf_tools, account_subscription |
1044 | #: field:account.model.line,model_id:0 |
1045 | #: view:account.subscription:0 |
1046 | #: field:account.subscription,model_id:0 |
1047 | @@ -39241,6 +39229,7 @@ |
1048 | #: field:automated.import.function,model_id:0 |
1049 | #: field:sync.client.log_sale_purchase,model:0 |
1050 | #: field:sync.client.log_sale_purchase,model_id:0 |
1051 | +#: view:account.model:0 |
1052 | msgid "Model" |
1053 | msgstr "Modèle" |
1054 | |
1055 | @@ -43211,6 +43200,7 @@ |
1056 | #. modules: account, finance |
1057 | #: view:account.move:0 |
1058 | #: view:cash.request:0 |
1059 | +#: view:account.model.line:0 |
1060 | msgid "Total Debit" |
1061 | msgstr "Total Débit" |
1062 | |
1063 | @@ -44394,8 +44384,8 @@ |
1064 | |
1065 | #. module: account |
1066 | #: model:ir.actions.act_window,help:account.action_subscription_form |
1067 | -msgid "A recurring entry is a miscellaneous entry that occurs on a recurrent basis from a specific date, i.e. corresponding to the signature of a contract or an agreement with a customer or a supplier. With Define Recurring Entries, you can create such entries to automate the postings in the system." |
1068 | -msgstr "Une écriture périodique est une écriture qui est configurée par le biais de la fonctionnalité Définir Ecritures Périodiques. Ceci vous permet d'enregistrer une écriture à partir d'une date spécifique. Cette écriture sera reproduite automatiquement dans votre comptabilité et à une fréquence définie. Vous pouvez utiliser cette fonctionnalité par exemple pour étaler la charge d'un loyer sur plusieurs mensualités. " |
1069 | +msgid "A recurring entry is a miscellaneous entry that occurs on a recurrent basis from a specific date, i.e. corresponding to the signature of a contract or an agreement with a customer or a supplier. With Recurring Plan, you can create such entries to automate the postings in the system." |
1070 | +msgstr "Une écriture périodique est une écriture qui est configurée par le biais de la fonctionnalité Plan d'Ecritures Périodiques. Ceci vous permet d'enregistrer une écriture à partir d'une date spécifique. Cette écriture sera reproduite automatiquement dans votre comptabilité et à une fréquence définie. Vous pouvez utiliser cette fonctionnalité par exemple pour étaler la charge d'un loyer sur plusieurs mensualités." |
1071 | |
1072 | #. modules: account, finance |
1073 | #: view:account.bank.statement:0 |
1074 | @@ -50461,11 +50451,6 @@ |
1075 | msgid "Logs Sequence" |
1076 | msgstr "Journaux de bord - Sequence" |
1077 | |
1078 | -#. module: account |
1079 | -#: view:account.subscription:0 |
1080 | -msgid "Running Subscription" |
1081 | -msgstr "Running Subscription" |
1082 | - |
1083 | #. modules: base, msf_currency_revaluation |
1084 | #: code:addons/msf_currency_revaluation/res_currency.py:40 |
1085 | #: code:addons/base/res/res_currency.py:108 |
1086 | @@ -62609,8 +62594,8 @@ |
1087 | #. module: account_subscription |
1088 | #: model:ir.actions.act_window,name:account_subscription.act_account_subscription_to_account_move_line_open |
1089 | #: view:account.move.line:0 |
1090 | -msgid "Recurring Entries To Validate" |
1091 | -msgstr "Entrées récurrentes à valider" |
1092 | +msgid "Recurring Entries To Post" |
1093 | +msgstr "Lignes Périodiques à Poster" |
1094 | |
1095 | #. module: product |
1096 | #: view:product.product:0 |
1097 | @@ -62763,8 +62748,8 @@ |
1098 | |
1099 | #. module: account |
1100 | #: view:account.subscription.generate:0 |
1101 | -msgid "Generate Entries before:" |
1102 | -msgstr "Générer les Ecritures avant :" |
1103 | +msgid "Generate Entries until:" |
1104 | +msgstr "Générer les Ecritures jusqu'au :" |
1105 | |
1106 | #. modules: account, msf_instance |
1107 | #: field:account.invoice.refund,journal_id:0 |
1108 | @@ -65459,10 +65444,9 @@ |
1109 | msgid "Supplier catalogue" |
1110 | msgstr "Catalogue du fournisseur" |
1111 | |
1112 | -#. module: account_subscription |
1113 | -#: code:addons/account_subscription/account_subscription.py:41 |
1114 | -#: code:addons/account_subscription/account_subscription.py:50 |
1115 | -#, python-format |
1116 | +#. modules: account, account_subscription |
1117 | +#: constraint:account.subscription:0 |
1118 | +#: constraint:account.subscription:0 |
1119 | msgid "The value in the field \"Repeat\" must be greater than 0!" |
1120 | msgstr "La valeur dans le champ \"Périodicité\" doit être supérieure à 0 !" |
1121 | |
1122 | @@ -66574,6 +66558,7 @@ |
1123 | #. modules: account, finance |
1124 | #: view:account.move:0 |
1125 | #: view:cash.request:0 |
1126 | +#: view:account.model.line:0 |
1127 | msgid "Total Credit" |
1128 | msgstr "Total Crédit" |
1129 | |
1130 | @@ -74124,14 +74109,8 @@ |
1131 | #. module: account_period_closing_level |
1132 | #: code:addons/account_period_closing_level/account_period.py:236 |
1133 | #, python-format |
1134 | -msgid "Recurring entries included in the Period \"%s\" or before haven't been created. Please create them before closing the period." |
1135 | -msgstr "Des Ecritures périodiques incluses dans la Période \"%s\" ou avant n'ont pas été créées. Veuillez les créer avant de clôturer la période." |
1136 | - |
1137 | -#. module: account_period_closing_level |
1138 | -#: code:addons/account_period_closing_level/account_period.py:231 |
1139 | -#, python-format |
1140 | -msgid "Subscription Lines included in the Period \"%s\" or before haven't been generated. Please generate them and create the related recurring entries before closing the period." |
1141 | -msgstr "Des Lignes d'Abonnement incluses dans la Période \"%s\" ou avant n'ont pas été générées. Veuillez les générer et créer les écritures périodiques associées avant de clôturer la période." |
1142 | +msgid "Recurring entries included in the Period \"%s\" or before haven't been created. Please generate them before closing the period." |
1143 | +msgstr "Des Ecritures périodiques incluses dans la Période \"%s\" ou avant n'ont pas été créées. Veuillez les générer avant de clôturer la période." |
1144 | |
1145 | #. module: msf_field_access_rights |
1146 | #: view:msf_field_access_rights.field_access_rule:0 |
1147 | @@ -74940,9 +74919,11 @@ |
1148 | msgstr "Line %s in your Excel file: %s: %s\n" |
1149 | "" |
1150 | |
1151 | -#. module: account |
1152 | +#. modules: account, account_subscription |
1153 | #: view:account.subscription:0 |
1154 | #: selection:account.subscription,state:0 |
1155 | +#: selection:account.model,state:0 |
1156 | +#: view:account.model:0 |
1157 | msgid "Running" |
1158 | msgstr "En cours" |
1159 | |
1160 | @@ -76426,7 +76407,7 @@ |
1161 | #. module: account |
1162 | #: help:account.subscription,period_nbr:0 |
1163 | msgid "This field will determine how often entries will be generated: if the period type is 'month' and the repeat '2' then entries will be generated every 2 months" |
1164 | -msgstr "This field will determine how often entries will be generated: if the period type is 'month' and the repeat '2' then entries will be generated every 2 months" |
1165 | +msgstr "Ce champ déterminera la fréquence à laquelle les écritures seront générées : si le type de période est 'mois' et la périodicité est '2', alors les écritures seront générées tous les 2 mois." |
1166 | |
1167 | #. module: sync_client |
1168 | #: selection:sync.client.log_sale_purchase,action_type:0 |
1169 | @@ -81523,7 +81504,7 @@ |
1170 | msgid "Confirm the selected invoices" |
1171 | msgstr "Confirmer les factures sélectionnées" |
1172 | |
1173 | -#. modules: purchase, res_currency_tables,tender_flow, sync_client, account_mcdb, sales_followup, supplier_catalogue, sale, account, stock_forecast, export_import_lang, purchase_followup, msf_supply_doc_export, specific_rules, analytic_distribution, useability_dashboard_and_menu, procurement_request, out_step, consumption_calculation, stock_override, process, account_reconciliation, msf_instance, purchase_override, account_hq_entries, purchase_allocation_report, msf_tools, vertical_integration, msf_outgoing, register_accounting, documents_done, transport_mgmt, analytic, msf_audittrail, msf_doc_import, stock, msf_budget, msf_homere_interface, kit, hr, finance, financing_contract, update_client, account_override, base, return_claim, procurement, procurement_cycle |
1174 | +#. modules: purchase, res_currency_tables,tender_flow, sync_client, account_mcdb, sales_followup, supplier_catalogue, sale, account, stock_forecast, export_import_lang, purchase_followup, msf_supply_doc_export, specific_rules, analytic_distribution, useability_dashboard_and_menu, procurement_request, out_step, consumption_calculation, stock_override, process, account_reconciliation, msf_instance, purchase_override, account_hq_entries, purchase_allocation_report, msf_tools, vertical_integration, msf_outgoing, register_accounting, documents_done, transport_mgmt, analytic, msf_audittrail, msf_doc_import, stock, msf_budget, msf_homere_interface, kit, hr, finance, financing_contract, update_client, account_override, base, return_claim, procurement, procurement_cycle, account_subscription |
1175 | #: view:account.bank.statement:0 |
1176 | #: field:account.bank.statement,state:0 |
1177 | #: field:account.entries.report,move_state:0 |
1178 | @@ -81735,6 +81716,7 @@ |
1179 | #: field:account.invoice.import,state:0 |
1180 | #: report:addons/procurement_cycle/report/product_stock_out.mako:436 |
1181 | #: field:product.stock_out,state:0 |
1182 | +#: field:account.model,state:0 |
1183 | #, python-format |
1184 | msgid "State" |
1185 | msgstr "Statut" |
1186 | @@ -82770,10 +82752,9 @@ |
1187 | msgid "Select a supplier" |
1188 | msgstr "Sélectionner un fournisseur" |
1189 | |
1190 | -#. modules: delivery_mechanism, msf_budget, account, msf_outgoing, msf_homere_interface, sync_client, register_accounting, specific_rules, sale, sales_followup, base, stock, tender_flow, msf_tools, return_claim, msf_doc_import, analytic_distribution, finance, product |
1191 | +#. modules: delivery_mechanism, msf_budget, account, msf_outgoing, msf_homere_interface, sync_client, register_accounting, specific_rules, sale, sales_followup, base, stock, tender_flow, msf_tools, return_claim, msf_doc_import, analytic_distribution, finance, product, account_subscription |
1192 | #: selection:account.invoice.report,state:0 |
1193 | #: selection:account.journal.period,state:0 |
1194 | -#: selection:account.subscription,state:0 |
1195 | #: selection:report.invoice.created,state:0 |
1196 | #: view:account.commitment:0 |
1197 | #: selection:account.commitment,state:0 |
1198 | @@ -82838,6 +82819,10 @@ |
1199 | #: selection:wizard.import.product.line,state:0 |
1200 | #: selection:product.mass.update,state:0 |
1201 | #: selection:account.invoice.import,state:0 |
1202 | +#: view:account.subscription:0 |
1203 | +#: view:account.model:0 |
1204 | +#: selection:account.model,state:0 |
1205 | +#: selection:account.subscription,state:0 |
1206 | #, python-format |
1207 | msgid "Done" |
1208 | msgstr "Terminé" |
1209 | @@ -85076,7 +85061,7 @@ |
1210 | #: code:addons/account_subscription/account_model.py:306 |
1211 | #, python-format |
1212 | msgid "Please define a valid analytic distribution for the recurring model '%s'!" |
1213 | -msgstr "Please define a valid analytic distribution for the recurring model '%s'!" |
1214 | +msgstr "Veuillez définir une distribution analytique valide pour le modèle périodique '%s' !" |
1215 | |
1216 | #. module: sale |
1217 | #: model:ir.actions.act_window,name:sale.action_sale_donation_stock_moves |
1218 | @@ -85148,11 +85133,6 @@ |
1219 | msgid "Qty Balance" |
1220 | msgstr "Bilan des Qtés" |
1221 | |
1222 | -#. module: account |
1223 | -#: model:ir.actions.act_window,name:account.action_subscription_form |
1224 | -msgid "Recurring Lines" |
1225 | -msgstr "Lignes périodiques" |
1226 | - |
1227 | #. module: msf_doc_import |
1228 | #: code:addons/msf_doc_import/account.py:54 |
1229 | #, python-format |
1230 | @@ -93378,7 +93358,7 @@ |
1231 | msgid "Additional Information" |
1232 | msgstr "Information Complémentaire" |
1233 | |
1234 | -#. modules: account, register_accounting, account_mcdb, msf_homere_interface, msf_audittrail, account_corrections |
1235 | +#. modules: account, register_accounting, account_mcdb, msf_homere_interface, msf_audittrail, account_corrections, account_subscription |
1236 | #: report:combined.journals.report.pdf:0 |
1237 | #: report:addons/account_mcdb/report/combined_journals_report.mako:226 |
1238 | #: field:hr.payroll.msf,partner_type:0 |
1239 | @@ -93396,6 +93376,7 @@ |
1240 | #: selection:account.journal.column,field:0 |
1241 | #: field:account.bank.statement.line,partner_type2:0 |
1242 | #: report:addons/register_accounting/report/fully_report_xls.mako:563 |
1243 | +#: view:account.move.line:0 |
1244 | msgid "Third Parties" |
1245 | msgstr "Tiers" |
1246 | |
1247 | @@ -94298,8 +94279,15 @@ |
1248 | |
1249 | #. module: account |
1250 | #: model:ir.ui.menu,name:account.menu_action_subscription_form |
1251 | -msgid "Define Recurring Entries" |
1252 | -msgstr "Définir des Ecritures Périodiques" |
1253 | +#: model:ir.actions.act_window,name:account.action_subscription_form |
1254 | +#: view:account.subscription:0 |
1255 | +msgid "Recurring Plan" |
1256 | +msgstr "Plan d'Ecritures Périodiques" |
1257 | + |
1258 | +#. module: account_subscription |
1259 | +#: field:account.model,recurring_plan_ids:0 |
1260 | +msgid "Recurring Plans" |
1261 | +msgstr "Plans d'Ecritures Périodiques" |
1262 | |
1263 | #. module: msf_doc_import |
1264 | #: code:addons/msf_doc_import/wizard/wizard_po_simulation_screen.py:628 |
1265 | @@ -110353,6 +110341,68 @@ |
1266 | msgid "IN-line %s Wrong BN/ED attributes" |
1267 | msgstr "Ligne du IN %s: Mauvais attributs NL/DE" |
1268 | |
1269 | +#. module: account |
1270 | +#: code:addons/account/account.py:2475 |
1271 | +#, python-format |
1272 | +msgid "You cannot delete a Recurring Plan if Subscription lines have already been computed." |
1273 | +msgstr "Vous ne pouvez pas supprimer un Plan d'Ecritures Périodiques si les lignes d'Abonnement ont déjà été calculées." |
1274 | + |
1275 | +#. module: account |
1276 | +#: field:account.subscription,frozen_model:0 |
1277 | +msgid "Frozen model" |
1278 | +msgstr "Modèle figé" |
1279 | + |
1280 | +#. module: account_subscription |
1281 | +#: code:addons/account_subscription/account_model.py:303 |
1282 | +#, python-format |
1283 | +msgid "You cannot delete a model which is used in the following plan(s): %s" |
1284 | +msgstr "Vous ne pouvez pas supprimer un modèle qui est utilisé dans le(s) plan(s) suivant(s) : %s" |
1285 | + |
1286 | +#. modules: account, account_subscription |
1287 | +#: constraint:account.model:0 |
1288 | +#: constraint:account.model:0 |
1289 | +msgid "It is not possible to have several Recurring Models with the same name." |
1290 | +msgstr "Il n'est pas possible d'avoir plusieurs Modèles périodiques portant le même nom." |
1291 | + |
1292 | +#. module: account_subscription |
1293 | +#: code:addons/account_subscription/account_model.py:358 |
1294 | +#, python-format |
1295 | +msgid "It is not possible to have several Recurring Models with the same name: %s." |
1296 | +msgstr "Il n'est pas possible d'avoir plusieurs Modèles périodiques portant le même nom : %s." |
1297 | + |
1298 | +#. modules: account, account_subscription |
1299 | +#: constraint:account.subscription:0 |
1300 | +#: constraint:account.subscription:0 |
1301 | +msgid "It is not possible to have several Recurring Plans with the same name." |
1302 | +msgstr "Il n'est pas possible d'avoir plusieurs Plans d'Ecritures Périodiques portant le même nom." |
1303 | + |
1304 | +#. module: account |
1305 | +#: code:addons/account/account.py:2423 |
1306 | +#, python-format |
1307 | +msgid "It is not possible to have several Recurring Plans with the same name: %s." |
1308 | +msgstr "Il n'est pas possible d'avoir plusieurs Plans d'Ecritures Périodiques portant le même nom : %s." |
1309 | + |
1310 | +#. module: account_subscription |
1311 | +#: field:account.model,is_balanced:0 |
1312 | +#: field:account.model.line,is_balanced:0 |
1313 | +msgid "Is balanced" |
1314 | +msgstr "Est équilibré" |
1315 | + |
1316 | +#. module: account_subscription |
1317 | +#: view:account.model:0 |
1318 | +msgid "Plan names" |
1319 | +msgstr "Nom des plans" |
1320 | + |
1321 | +#. module: account_subscription |
1322 | +#: view:account.model:0 |
1323 | +msgid "Plan status" |
1324 | +msgstr "Statut des plans" |
1325 | + |
1326 | +#. module: account_subscription |
1327 | +#: view:account.model:0 |
1328 | +msgid "Related plans" |
1329 | +msgstr "Plans associés" |
1330 | + |
1331 | #. module: product |
1332 | #: view:product.product:0 |
1333 | msgid "Merge product" |
1334 | @@ -110363,9 +110413,18 @@ |
1335 | #, python-format |
1336 | msgid "is dispatched." |
1337 | msgstr "est expédié." |
1338 | +<<<<<<< TREE |
1339 | |
1340 | #. module: sale |
1341 | #: code:addons/sale/sale_workflow.py:584 |
1342 | #, python-format |
1343 | msgid "You can not validate a line of a Regular FO with an Inter-section Customer if it was not created by sync." |
1344 | msgstr "Vous ne pouvez pas valider une ligne de CdT Normale qui a un Client Inter-section si elle n'a pas été créée par synchro." |
1345 | +======= |
1346 | + |
1347 | +#. module: account |
1348 | +#: code:addons/account/account.py:2441 |
1349 | +#, python-format |
1350 | +msgid "You cannot duplicate a Recurring Plan with a Done model." |
1351 | +msgstr "Vous ne pouvez pas dupliquer un Plan d'Ecritures Périodiques utilisant un modèle Terminé." |
1352 | +>>>>>>> MERGE-SOURCE |
1353 | |
1354 | === modified file 'bin/addons/msf_profile/msf_profile.py' |
1355 | --- bin/addons/msf_profile/msf_profile.py 2020-08-04 08:00:56 +0000 |
1356 | +++ bin/addons/msf_profile/msf_profile.py 2020-08-07 12:54:52 +0000 |
1357 | @@ -53,6 +53,66 @@ |
1358 | } |
1359 | |
1360 | # UF18.0 |
1361 | + def us_5216_update_recurring_object_state(self, cr, uid, *a, **b): |
1362 | + """ |
1363 | + Updates the state of the Recurring Plans and Recurring Models with the new rules set in US-5216. |
1364 | + """ |
1365 | + if not self.pool.get('sync.server.update'): |
1366 | + rec_plan_obj = self.pool.get('account.subscription') |
1367 | + rec_model_obj = self.pool.get('account.model') |
1368 | + # Recurring Plans |
1369 | + rec_plans = { |
1370 | + 'draft': [], |
1371 | + 'running': [], |
1372 | + 'done': [], |
1373 | + } |
1374 | + rec_plan_ids = rec_plan_obj.search(cr, uid, [], order='NO_ORDER') |
1375 | + for rec_plan in rec_plan_obj.browse(cr, uid, rec_plan_ids, fields_to_fetch=['lines_id']): |
1376 | + if not rec_plan.lines_id: |
1377 | + rec_plans['draft'].append(rec_plan.id) |
1378 | + else: |
1379 | + running = False |
1380 | + for sub_line in rec_plan.lines_id: |
1381 | + if not sub_line.move_id or sub_line.move_id.state != 'posted': |
1382 | + running = True |
1383 | + break |
1384 | + if running: |
1385 | + rec_plans['running'].append(rec_plan.id) |
1386 | + else: |
1387 | + rec_plans['done'].append(rec_plan.id) |
1388 | + for plan_state in rec_plans: |
1389 | + if rec_plans[plan_state]: |
1390 | + update_rec_plans = """ |
1391 | + UPDATE account_subscription |
1392 | + SET state = %s |
1393 | + WHERE id IN %s; |
1394 | + """ |
1395 | + cr.execute(update_rec_plans, (plan_state, tuple(rec_plans[plan_state]))) |
1396 | + # Recurring Models |
1397 | + rec_models = { |
1398 | + 'draft': [], |
1399 | + 'running': [], |
1400 | + 'done': [], |
1401 | + } |
1402 | + rec_model_ids = rec_model_obj.search(cr, uid, [], order='NO_ORDER') |
1403 | + for model_id in rec_model_ids: |
1404 | + if rec_plan_obj.search_exist(cr, uid, [('model_id', '=', model_id), ('state', '=', 'done')]): |
1405 | + state = 'done' |
1406 | + elif rec_plan_obj.search_exist(cr, uid, [('model_id', '=', model_id), ('state', '=', 'running')]): |
1407 | + state = 'running' |
1408 | + else: |
1409 | + state = 'draft' |
1410 | + rec_models[state].append(model_id) |
1411 | + for model_state in rec_models: |
1412 | + if rec_models[model_state]: |
1413 | + update_rec_models = """ |
1414 | + UPDATE account_model |
1415 | + SET state = %s |
1416 | + WHERE id IN %s; |
1417 | + """ |
1418 | + cr.execute(update_rec_models, (model_state, tuple(rec_models[model_state]))) |
1419 | + return True |
1420 | + |
1421 | def us_7412_set_fy_closure_settings(self, cr, uid, *a, **b): |
1422 | """ |
1423 | Sets the Fiscal Year Closure options depending on the OC. |
1424 | |
1425 | === modified file 'bin/addons/msf_profile/usability.xml' |
1426 | --- bin/addons/msf_profile/usability.xml 2012-11-06 14:18:56 +0000 |
1427 | +++ bin/addons/msf_profile/usability.xml 2020-08-07 12:54:52 +0000 |
1428 | @@ -7,7 +7,7 @@ |
1429 | <!-- reorder existing ones --> |
1430 | <menuitem id="account.menu_finance_periodical_processing" name="Periodical Processing" parent="account.menu_finance" sequence="7" /> |
1431 | <menuitem id="account.menu_finance_charts" name="Charts" parent="account.menu_finance" sequence="8"/> |
1432 | - <menuitem name="Define Recurring Entries" action="account.action_subscription_form" id="account.menu_action_subscription_form" sequence="2" parent="account.menu_finance_recurrent_entries"/> |
1433 | + <menuitem name="Recurring Plan" action="account.action_subscription_form" id="account.menu_action_subscription_form" sequence="2" parent="account.menu_finance_recurrent_entries"/> |
1434 | <menuitem id="account.menu_finance_entries" name="Journal Entries" parent="account.menu_finance" sequence="10" /> |
1435 | <menuitem id="account.menu_action_model_form" action="account.action_model_form" sequence="1" parent="account.menu_finance_recurrent_entries" /> |
1436 | <menuitem id="account.menu_finance_accounting" name="Financial Accounting" parent="account.menu_finance_configuration" sequence="1"/> |