Merge lp:~jfb-tempo-consulting/unifield-server/US-8366 into lp:unifield-server
- US-8366
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5975 |
Proposed branch: | lp:~jfb-tempo-consulting/unifield-server/US-8366 |
Merge into: | lp:unifield-server |
Diff against target: |
635 lines (+207/-34) (has conflicts) 14 files modified
bin/addons/msf_doc_import/purchase_order.py (+24/-8) bin/addons/msf_profile/data/patches.xml (+8/-0) bin/addons/msf_profile/msf_profile.py (+23/-0) bin/addons/msf_tools/automated_export.py (+22/-6) bin/addons/msf_tools/automated_export_data.xml (+1/-0) bin/addons/msf_tools/automated_export_function.py (+2/-0) bin/addons/msf_tools/automated_import.py (+75/-8) bin/addons/msf_tools/automated_import_data.xml (+5/-1) bin/addons/msf_tools/automated_import_function.py (+2/-0) bin/addons/msf_tools/automated_import_job.py (+10/-5) bin/addons/msf_tools/views/automated_export_view.xml (+16/-2) bin/addons/msf_tools/views/automated_import_view.xml (+15/-3) bin/osv/orm.py (+3/-1) bin/unifield-version.txt (+1/-0) Text conflict in bin/addons/msf_profile/data/patches.xml |
To merge this branch: | bzr merge lp:~jfb-tempo-consulting/unifield-server/US-8366 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+402432@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/msf_doc_import/purchase_order.py' |
2 | --- bin/addons/msf_doc_import/purchase_order.py 2020-12-14 16:49:10 +0000 |
3 | +++ bin/addons/msf_doc_import/purchase_order.py 2021-05-07 16:00:52 +0000 |
4 | @@ -65,12 +65,12 @@ |
5 | return result |
6 | |
7 | def export_po(self, cr, uid, ids, context=None): |
8 | - auto_job_ids = self.pool.get('automated.export').search(cr, uid, [('function_id.method_to_call', '=', 'auto_export_validated_purchase_order'), ('active', '=', True)], context=context) |
9 | + wiz = self.browse(cr, uid, ids[0], context) |
10 | + auto_job_ids = self.pool.get('automated.export').search(cr, uid, [('function_id.method_to_call', '=', 'auto_export_validated_purchase_order'), ('active', '=', True), ('partner_id', '=', wiz.purchase_id.partner_id.id)], context=context) |
11 | if not auto_job_ids: |
12 | raise osv.except_osv(_('Warning'), _('The job to export PO is not active.')) |
13 | |
14 | auto_job = self.pool.get('automated.export').browse(cr, uid, auto_job_ids[0], context=context) |
15 | - wiz = self.browse(cr, uid, ids[0], context) |
16 | |
17 | |
18 | processed, rejected, trash = self.pool.get('purchase.order').auto_export_validated_purchase_order(cr, uid, auto_job, [wiz.purchase_id.id], context=context) |
19 | @@ -126,11 +126,26 @@ |
20 | for id in ids: |
21 | ret[id] = False |
22 | |
23 | - if not self.pool.get('automated.export').search_exist(cr, uid, [('function_id.method_to_call', '=', 'auto_export_validated_purchase_order'), ('active', '=', True)], context=context): |
24 | - return ret |
25 | - |
26 | - for x in self.search(cr, uid, [('id', 'in', ids), ('partner_type', '=', 'esc'), ('state', 'in', ['validated', 'validated_p'])], context=context): |
27 | - ret[x] = True |
28 | + if not ids: |
29 | + return {} |
30 | + |
31 | + cr.execute(''' |
32 | + select o.id |
33 | + from |
34 | + purchase_order o, automated_export exp, automated_export_function fnct |
35 | + where |
36 | + o.id in %s and |
37 | + o.partner_type = 'esc' and |
38 | + o.state in ('validated', 'validated_p') and |
39 | + o.partner_id = exp.partner_id and |
40 | + exp.active = 't' and |
41 | + exp.function_id = fnct.id and |
42 | + fnct.method_to_call = 'auto_export_validated_purchase_order' |
43 | + ''', (tuple(ids), )) |
44 | + |
45 | + for x in cr.fetchall(): |
46 | + ret[x[0]] = True |
47 | + |
48 | return ret |
49 | |
50 | _columns = { |
51 | @@ -390,7 +405,8 @@ |
52 | ('partner_type', '=', 'esc'), |
53 | ('state', 'in', ['validated', 'validated_p']), |
54 | ('auto_exported_ok', '=', False), |
55 | - ], context= context) |
56 | + ('partner_id', '=', export_wiz.partner_id.id), |
57 | + ], context=context) |
58 | |
59 | if not po_ids: |
60 | msg = _('No PO to export !') |
61 | |
62 | === modified file 'bin/addons/msf_profile/data/patches.xml' |
63 | --- bin/addons/msf_profile/data/patches.xml 2021-02-25 15:48:01 +0000 |
64 | +++ bin/addons/msf_profile/data/patches.xml 2021-05-07 16:00:52 +0000 |
65 | @@ -647,9 +647,17 @@ |
66 | <field name="method">us_6796_hide_prod_status_inconsistencies</field> |
67 | </record> |
68 | |
69 | +<<<<<<< TREE |
70 | <record id="us_8166_hide_consolidated_sm_report" model="patch.scripts"> |
71 | <field name="method">us_8166_hide_consolidated_sm_report</field> |
72 | </record> |
73 | |
74 | +======= |
75 | + <!-- UF21.0 --> |
76 | + <record id="us_7941_auto_vi_set_partner" model="patch.scripts"> |
77 | + <field name="method">us_7941_auto_vi_set_partner</field> |
78 | + </record> |
79 | + |
80 | +>>>>>>> MERGE-SOURCE |
81 | </data> |
82 | </openerp> |
83 | |
84 | === modified file 'bin/addons/msf_profile/msf_profile.py' |
85 | --- bin/addons/msf_profile/msf_profile.py 2021-05-05 07:42:20 +0000 |
86 | +++ bin/addons/msf_profile/msf_profile.py 2021-05-07 16:00:52 +0000 |
87 | @@ -51,6 +51,29 @@ |
88 | _defaults = { |
89 | 'model': lambda *a: 'patch.scripts', |
90 | } |
91 | + # UF21.0 |
92 | + def us_7941_auto_vi_set_partner(self, cr, uid, *a, **b): |
93 | + cr.execute(''' |
94 | + update automated_import imp set partner_id = (select id from res_partner where ref='APU' and partner_type='esc' LIMIT 1) |
95 | + from automated_import_function function |
96 | + where |
97 | + function.id = imp.function_id and |
98 | + imp.partner_id is null and |
99 | + function.multiple='t' |
100 | + ''') |
101 | + self._logger.warn('APU set on %s VI import.' % (cr.rowcount,)) |
102 | + |
103 | + cr.execute(''' |
104 | + update automated_export exp set partner_id = (select id from res_partner where ref='APU' and partner_type='esc' LIMIT 1) |
105 | + from automated_export_function function |
106 | + where |
107 | + function.id = exp.function_id and |
108 | + exp.partner_id is null and |
109 | + function.multiple='t' |
110 | + ''') |
111 | + self._logger.warn('APU set on %s VI export.' % (cr.rowcount,)) |
112 | + |
113 | + return True |
114 | |
115 | # UF21.0 |
116 | def us_8166_hide_consolidated_sm_report(self, cr, uid, *a, **b): |
117 | |
118 | === modified file 'bin/addons/msf_tools/automated_export.py' |
119 | --- bin/addons/msf_tools/automated_export.py 2021-04-16 14:59:16 +0000 |
120 | +++ bin/addons/msf_tools/automated_export.py 2021-05-07 16:00:52 +0000 |
121 | @@ -33,6 +33,16 @@ |
122 | |
123 | class automated_export(osv.osv): |
124 | _name = 'automated.export' |
125 | + _order = 'name, id' |
126 | + |
127 | + def _auto_init(self, cr, context=None): |
128 | + res = super(automated_export, self)._auto_init(cr, context) |
129 | + # migration delete old constraint |
130 | + cr.drop_constraint_if_exists('automated_export', 'automated_export_export_function_id_uniq') |
131 | + cr.execute("SELECT indexname FROM pg_indexes WHERE indexname = 'automated_export_function_id_partner_id_uniq'") |
132 | + if not cr.fetchone(): |
133 | + cr.execute("CREATE UNIQUE INDEX automated_export_function_id_partner_id_uniq ON automated_export (function_id, coalesce(partner_id, 0))") |
134 | + return res |
135 | |
136 | _columns = { |
137 | 'name': fields.char( |
138 | @@ -77,6 +87,7 @@ |
139 | required=True, |
140 | ), |
141 | 'disable_cron': fields.related('function_id', 'disable_cron', string='Cron disabled', type='boolean', write_relate=False), |
142 | + 'multiple': fields.related('function_id', 'multiple', string='Multiple', type='boolean', write_relate=False), |
143 | 'export_format': fields.selection( |
144 | selection=[ |
145 | ('excel', 'Excel'), |
146 | @@ -109,6 +120,7 @@ |
147 | 'ftp_dest_ok': fields.boolean(string='on FTP server', help='Is given path is located on FTP server ?'), |
148 | 'ftp_dest_fail_ok': fields.boolean(string='on FTP server', help='Is given path is located on FTP server ?'), |
149 | 'ftp_report_ok': fields.boolean(string='on FTP server', help='Is given path is located on FTP server ?'), |
150 | + 'partner_id': fields.many2one('res.partner', 'Partner', domain=[('supplier', '=', True), ('partner_type', '=', 'esc')]), |
151 | 'pause': fields.integer('Pause between generation and transfer (in seconds)'), |
152 | |
153 | } |
154 | @@ -129,10 +141,11 @@ |
155 | _('Another Automated export with same name already exists (maybe inactive). Automated export name must be unique. Please select an other name.'), |
156 | ), |
157 | ( |
158 | - 'export_function_id_uniq', |
159 | - 'unique(function_id)', |
160 | - _('Another Automated export with same functionality already exists (maybe inactive). Only one automated export must be created for a '\ |
161 | - 'same functionality. Please select an other functionality.'), |
162 | + # declared in _auto_init |
163 | + 'function_id_partner_id_uniq', |
164 | + '', |
165 | + _('Another Automated export with same functionality and same partner already exists (maybe inactive). Only one automated export must be created for a '\ |
166 | + 'same functionality and partner.'), |
167 | ), |
168 | ( |
169 | 'export_positive_interval', |
170 | @@ -143,9 +156,12 @@ |
171 | |
172 | def change_function_id(self, cr, uid, ids, function_id, context=None): |
173 | disable_cron = False |
174 | + multiple = False |
175 | if function_id: |
176 | - disable_cron = self.pool.get('automated.export.function').browse(cr, uid, function_id, context=context).disable_cron |
177 | - return {'value': {'disable_cron': disable_cron}} |
178 | + fct_data = self.pool.get('automated.export.function').browse(cr, uid, function_id, context=context) |
179 | + disable_cron = fct_data.disable_cron |
180 | + multiple = fct_data.multiple |
181 | + return {'value': {'disable_cron': disable_cron, 'multiple': multiple}} |
182 | |
183 | def onchange_ftp_ok(self, cr, uid, ids, ftp_ok, context=None): |
184 | if context is None: |
185 | |
186 | === modified file 'bin/addons/msf_tools/automated_export_data.xml' |
187 | --- bin/addons/msf_tools/automated_export_data.xml 2020-09-18 10:39:31 +0000 |
188 | +++ bin/addons/msf_tools/automated_export_data.xml 2021-05-07 16:00:52 +0000 |
189 | @@ -5,6 +5,7 @@ |
190 | <field name="name">Export validated Purchase Order</field> |
191 | <field name="model_id" model="ir.model" search="[('model', '=', 'purchase.order')]" /> |
192 | <field name="method_to_call">auto_export_validated_purchase_order</field> |
193 | + <field name="multiple" eval="True" /> |
194 | </record> |
195 | <record id="auto_export_fnct_oca_finance_vi" model="automated.export.function"> |
196 | <field name="name">Export to HQ system (OCA) - Not yet exported</field> |
197 | |
198 | === modified file 'bin/addons/msf_tools/automated_export_function.py' |
199 | --- bin/addons/msf_tools/automated_export_function.py 2020-09-18 10:39:31 +0000 |
200 | +++ bin/addons/msf_tools/automated_export_function.py 2021-05-07 16:00:52 +0000 |
201 | @@ -45,11 +45,13 @@ |
202 | required=True, |
203 | ), |
204 | 'disable_cron': fields.boolean('No cron'), |
205 | + 'multiple': fields.boolean('Allow multiple jobs'), |
206 | } |
207 | |
208 | _defaults = { |
209 | 'method_to_call': lambda *a: 'export_data_from_csv', |
210 | 'disable_cron': False, |
211 | + 'multiple': False, |
212 | } |
213 | |
214 | _order = 'name' |
215 | |
216 | === modified file 'bin/addons/msf_tools/automated_import.py' |
217 | --- bin/addons/msf_tools/automated_import.py 2020-10-20 12:50:50 +0000 |
218 | +++ bin/addons/msf_tools/automated_import.py 2021-05-07 16:00:52 +0000 |
219 | @@ -33,6 +33,16 @@ |
220 | |
221 | class automated_import(osv.osv): |
222 | _name = 'automated.import' |
223 | + _order = 'name, id' |
224 | + |
225 | + def _auto_init(self, cr, context=None): |
226 | + res = super(automated_import, self)._auto_init(cr, context) |
227 | + # migration delete old constraint |
228 | + cr.drop_constraint_if_exists('automated_import', 'automated_import_import_function_id_uniq') |
229 | + cr.execute("SELECT indexname FROM pg_indexes WHERE indexname = 'automated_import_function_id_partner_id_uniq'") |
230 | + if not cr.fetchone(): |
231 | + cr.execute("CREATE UNIQUE INDEX automated_import_function_id_partner_id_uniq ON automated_import (function_id, coalesce(partner_id, 0))") |
232 | + return res |
233 | |
234 | def _check_paths(self, cr, uid, ids, context=None): |
235 | """ |
236 | @@ -73,6 +83,44 @@ |
237 | |
238 | return True |
239 | |
240 | + def _check_unicity(self, cr, uid, ids, context=None): |
241 | + ''' |
242 | + if the function_id allows multiple then the server / src_path must be unique |
243 | + if not multiple: then function_id must be unique |
244 | + ''' |
245 | + |
246 | + error = [] |
247 | + cr.execute(''' |
248 | + select function.name |
249 | + from automated_import import, automated_import_function function |
250 | + where |
251 | + function.id = import.function_id and |
252 | + coalesce(function.multiple, 'f') = 'f' |
253 | + group by function.name |
254 | + having(count(*) > 1) |
255 | + ''') |
256 | + for x in cr.fetchall(): |
257 | + error.append(_('Another Automated import with same functionality "%s" already exists (maybe inactive). Only one automated import must be created for a '\ |
258 | + 'same functionality. Please select an other functionality.') % x[0]) |
259 | + |
260 | + cr.execute(''' |
261 | + select function.name |
262 | + from automated_import import, automated_import_function function |
263 | + where |
264 | + function.id = import.function_id and |
265 | + coalesce(function.multiple, 'f') = 't' and |
266 | + coalesce(src_path, '') != '' |
267 | + group by function.name, src_path, ftp_url |
268 | + having(count(*) > 1) |
269 | + ''') |
270 | + for x in cr.fetchall(): |
271 | + error.append(_('Another Automated import with same functionality "%s", same server and same source already exists (maybe inactive).') % x[0]) |
272 | + |
273 | + if error: |
274 | + raise osv.except_osv(_('Warning'), "\n".join(error)) |
275 | + |
276 | + return True |
277 | + |
278 | def _get_isadmin(self, cr, uid, ids, *a, **b): |
279 | ret = {} |
280 | for _id in ids: |
281 | @@ -123,6 +171,7 @@ |
282 | string='Functionality', |
283 | required=True, |
284 | ), |
285 | + 'multiple': fields.related('function_id', 'multiple', string='Multiple', type='boolean', write_relate=False), |
286 | 'active': fields.boolean( |
287 | string='Active', |
288 | readonly=True, |
289 | @@ -149,6 +198,7 @@ |
290 | 'ftp_dest_fail_ok': fields.boolean(string='on FTP server', help='Is given path is located on FTP server ?'), |
291 | 'ftp_report_ok': fields.boolean(string='on FTP server', help='Is given path is located on FTP server ?'), |
292 | 'is_admin': fields.function(_get_isadmin, method=True, type='boolean', string='Is Admin'), |
293 | + 'partner_id': fields.many2one('res.partner', 'Partner', domain=[('partner_type', '=', 'esc')]), |
294 | } |
295 | |
296 | _defaults = { |
297 | @@ -167,10 +217,9 @@ |
298 | _('Another Automated import with same name already exists (maybe inactive). Automated import name must be unique. Please select an other name.'), |
299 | ), |
300 | ( |
301 | - 'import_function_id_uniq', |
302 | - 'unique(function_id)', |
303 | - _('Another Automated import with same functionality already exists (maybe inactive). Only one automated import must be created for a '\ |
304 | - 'same functionality. Please select an other functionality.'), |
305 | + 'function_id_partner_id_uniq', |
306 | + '', |
307 | + _('Another Automated import with same function / same partner already exists (maybe inactive).'), |
308 | ), |
309 | ( |
310 | 'import_positive_interval', |
311 | @@ -181,8 +230,20 @@ |
312 | |
313 | _constraints = [ |
314 | (_check_paths, _('There is a problem with paths'), ['active', 'src_path', 'dest_path', 'report_path', 'dest_path_failure']), |
315 | + (_check_unicity, _('There is a problem with paths'), []), |
316 | ] |
317 | |
318 | + def change_function_id(self, cr, uid, ids, function_id, context=None): |
319 | + multiple = False |
320 | + value = {} |
321 | + if function_id: |
322 | + fct_data = self.pool.get('automated.import.function').browse(cr, uid, function_id, context=context) |
323 | + multiple = fct_data.multiple |
324 | + if not multiple: |
325 | + value['partner_id'] = False |
326 | + value['multiple'] = multiple |
327 | + return {'value': value} |
328 | + |
329 | def onchange_ftp_ok(self, cr, uid, ids, ftp_ok, context=None): |
330 | if context is None: |
331 | context = {} |
332 | @@ -290,14 +351,20 @@ |
333 | |
334 | main_path = os.path.join(config.get('root_path'), 'vi_auto_import') |
335 | write_me = {'ftp_source_ok': False, 'ftp_dest_ok': False, 'ftp_dest_fail_ok': False, 'ftp_report_ok': False, 'ftp_ok': False, 'active': True, 'interval_unit': 'months', 'interval': 12} |
336 | + |
337 | + prefix = '' |
338 | + for job in self.browse(cr, uid, ids, fields_to_fetch=['name', 'function_id'], context=context): |
339 | + if job.function_id.multiple: |
340 | + num = self.search(cr, uid, [('function_id', '=', job.function_id.id), ('active', 'in', ['t', 'f'])], count=True, context=context) |
341 | + if num > 1: |
342 | + prefix = num |
343 | + self.log(cr, uid, job.id, 'Auto configuration done on job %s' % job.name) |
344 | + |
345 | for directory in ['src_path', 'dest_path', 'dest_path_failure', 'report_path']: |
346 | - target = os.path.join(main_path, directory) |
347 | + target = os.path.join(main_path, '%s%s' % (directory, prefix)) |
348 | write_me[directory] = target |
349 | if not os.path.exists(target): |
350 | os.makedirs(target) |
351 | - |
352 | - for job in self.read(cr, uid, ids, ['name'], context=context): |
353 | - self.log(cr, uid, job['id'], 'Auto configuration done on job %s' % job['name']) |
354 | self.write(cr, uid, ids, write_me, context=context) |
355 | return True |
356 | |
357 | |
358 | === modified file 'bin/addons/msf_tools/automated_import_data.xml' |
359 | --- bin/addons/msf_tools/automated_import_data.xml 2018-03-29 07:34:43 +0000 |
360 | +++ bin/addons/msf_tools/automated_import_data.xml 2021-05-07 16:00:52 +0000 |
361 | @@ -61,6 +61,7 @@ |
362 | <field name="model_id" model="ir.model" search="[('model', '=', 'supplier.catalogue')]" /> |
363 | <field name="method_to_call">auto_import</field> |
364 | <field name="startswith">SCL_</field> |
365 | + <field name="multiple" eval="True" /> |
366 | </record> |
367 | |
368 | <record id="auto_import_fnct_product_list" model="automated.import.function"> |
369 | @@ -75,6 +76,7 @@ |
370 | <field name="model_id" model="ir.model" search="[('model', '=', 'stock.picking')]" /> |
371 | <field name="method_to_call">auto_import_incoming_shipment</field> |
372 | <field name="startswith">SHPM_</field> |
373 | + <field name="multiple" eval="True" /> |
374 | </record> |
375 | |
376 | <record id="auto_import_fnct_purchase_order" model="automated.import.function"> |
377 | @@ -82,13 +84,15 @@ |
378 | <field name="model_id" model="ir.model" search="[('model', '=', 'purchase.order')]" /> |
379 | <field name="method_to_call">auto_import_purchase_order</field> |
380 | <field name="startswith">POV_</field> |
381 | + <field name="multiple" eval="True" /> |
382 | </record> |
383 | - |
384 | + |
385 | <record id="auto_import_fnct_confirmed_purchase_order" model="automated.import.function"> |
386 | <field name="name">Import Purchase Order and confirm</field> |
387 | <field name="model_id" model="ir.model" search="[('model', '=', 'purchase.order')]" /> |
388 | <field name="method_to_call">auto_import_confirmed_purchase_order</field> |
389 | <field name="startswith">POV_</field> |
390 | + <field name="multiple" eval="True" /> |
391 | </record> |
392 | |
393 | <record id="auto_import_fnct_product_categories" model="automated.import.function"> |
394 | |
395 | === modified file 'bin/addons/msf_tools/automated_import_function.py' |
396 | --- bin/addons/msf_tools/automated_import_function.py 2018-03-29 07:34:43 +0000 |
397 | +++ bin/addons/msf_tools/automated_import_function.py 2021-05-07 16:00:52 +0000 |
398 | @@ -45,10 +45,12 @@ |
399 | required=True, |
400 | ), |
401 | 'startswith': fields.char('Starts with', size=56), |
402 | + 'multiple': fields.boolean('Allow multiple jobs'), |
403 | } |
404 | |
405 | _defaults = { |
406 | 'method_to_call': lambda *a: 'import_data_from_csv', |
407 | + 'multiple': False, |
408 | } |
409 | |
410 | _order = 'name' |
411 | |
412 | === modified file 'bin/addons/msf_tools/automated_import_job.py' |
413 | --- bin/addons/msf_tools/automated_import_job.py 2020-10-20 15:14:32 +0000 |
414 | +++ bin/addons/msf_tools/automated_import_job.py 2021-05-07 16:00:52 +0000 |
415 | @@ -41,6 +41,7 @@ |
416 | from mission_stock.mission_stock import UnicodeWriter |
417 | |
418 | from threading import RLock |
419 | +import re |
420 | |
421 | def all_files_under(path, startswith=False, already=None): |
422 | """ |
423 | @@ -78,12 +79,17 @@ |
424 | ftp_connec.retrlines('RETR %s' % file, add_line) |
425 | return ch.getvalue() |
426 | elif sftp: |
427 | - tmp_file_path = os.path.join(tempfile.gettempdir(), os.path.basename(file)) |
428 | + tmp_file_path = os.path.join(tempfile.gettempdir(), remove_special_chars(os.path.basename(file))) |
429 | sftp.get(file, tmp_file_path) |
430 | with open(tmp_file_path, 'r') as fich: |
431 | return fich.read() |
432 | return False |
433 | |
434 | +def remove_special_chars(filename): |
435 | + if os.name == 'nt' and filename: |
436 | + return re.sub(r'[\\/:*?"<>|]', '_', filename) |
437 | + |
438 | + return filename |
439 | |
440 | def move_to_process_path(import_brw, ftp_connec, sftp, file, success): |
441 | """ |
442 | @@ -99,7 +105,7 @@ |
443 | if dest_on_ftp: |
444 | destname = posixpath.join(import_brw.dest_path if success else import_brw.dest_path_failure, '%s_%s' % (time.strftime('%Y%m%d_%H%M%S'), file)) |
445 | else: |
446 | - destname = os.path.join(import_brw.dest_path if success else import_brw.dest_path_failure, '%s_%s' % (time.strftime('%Y%m%d_%H%M%S'), file)) |
447 | + destname = os.path.join(import_brw.dest_path if success else import_brw.dest_path_failure, '%s_%s' % (time.strftime('%Y%m%d_%H%M%S'), remove_special_chars(file))) |
448 | |
449 | logging.getLogger('automated.import').info(_('Moving %s to %s') % (srcname, destname)) |
450 | |
451 | @@ -431,7 +437,6 @@ |
452 | import_obj.path_is_accessible(import_data[path[0]], path[1]) |
453 | except osv.except_osv as e: |
454 | error = tools.ustr(e) |
455 | - no_file = True |
456 | # In case of manual processing, raise the error |
457 | if job.file_to_import: |
458 | raise e |
459 | @@ -453,7 +458,6 @@ |
460 | except ValueError: |
461 | no_file = True |
462 | except Exception as e: |
463 | - no_file = True |
464 | error = tools.ustr(traceback.format_exc()) |
465 | |
466 | if not error: |
467 | @@ -484,6 +488,7 @@ |
468 | 'file_sum': md5, |
469 | 'state': 'done' if no_file else 'error', |
470 | }, context=context) |
471 | + no_file = True |
472 | continue |
473 | else: # file to import given |
474 | no_file = True |
475 | @@ -509,7 +514,7 @@ |
476 | temp_file.close() |
477 | oldest_file = temp_file.name |
478 | elif import_data.ftp_source_ok and import_data.ftp_protocol == 'sftp': |
479 | - tmp_dest_path = os.path.join(tempfile.gettempdir(), filename) |
480 | + tmp_dest_path = os.path.join(tempfile.gettempdir(), remove_special_chars(filename)) |
481 | sftp.get(oldest_file, tmp_dest_path) |
482 | oldest_file = tmp_dest_path |
483 | |
484 | |
485 | === modified file 'bin/addons/msf_tools/views/automated_export_view.xml' |
486 | --- bin/addons/msf_tools/views/automated_export_view.xml 2021-04-16 14:59:16 +0000 |
487 | +++ bin/addons/msf_tools/views/automated_export_view.xml 2021-05-07 16:00:52 +0000 |
488 | @@ -8,9 +8,16 @@ |
489 | <field name="type">search</field> |
490 | <field name="arch" type="xml"> |
491 | <search string="Automated exports"> |
492 | - <filter name="inactive" domain="[('active', '=', False)]" string="Inactive" icon="gtk-undo" /> |
493 | + <filter icon="terp-check" name="filteractive" string="Active" domain="[('active', '=', True)]" /> |
494 | + <filter icon="gtk-dialog-error" name="filterinactive" string="Inactive" domain="[('active', '=', False)]" /> |
495 | <field name="name" /> |
496 | <field name="function_id" /> |
497 | + <field name="partner_id" /> |
498 | + <newline /> |
499 | + <group expand="1" string="Group By..." colspan="4" col="4"> |
500 | + <filter string="Partner" name="groupby_partner_id" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/> |
501 | + <filter string="Function" name="groupby_function_id" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'function_id'}"/> |
502 | + </group> |
503 | </search> |
504 | </field> |
505 | </record> |
506 | @@ -20,12 +27,14 @@ |
507 | <field name="model">automated.export</field> |
508 | <field name="type">tree</field> |
509 | <field name="arch" type="xml"> |
510 | - <tree string="Automated exports"> |
511 | + <tree string="Automated exports" colors="red: not active"> |
512 | <field name="name" /> |
513 | <field name="function_id" /> |
514 | + <field name="partner_id" /> |
515 | <field name="start_time" /> |
516 | <field name="interval" /> |
517 | <field name="interval_unit" /> |
518 | + <field name="active" /> |
519 | </tree> |
520 | </field> |
521 | </record> |
522 | @@ -41,11 +50,15 @@ |
523 | <field name="function_id" widget="selection" on_change="change_function_id(function_id)"/> |
524 | <field name="active" /> |
525 | <field name="export_format" attrs="{'invisible': [('disable_cron', '=', True)]}"/> |
526 | + <label colspan="2" /> |
527 | + <field name="partner_id" attrs="{'invisible': [('multiple', '=', False)], 'required': [('multiple', '=', True)]}"/> |
528 | + <newline /> |
529 | <field name="pause" attrs="{'invisible': [('disable_cron', '=', False)]}"/> |
530 | <button name="run_job_manually" string="Run job manually" colspan="2" type="object" icon="gtk-execute" /> |
531 | <button name="sent_to_remote" string="Manually send to FTP" colspan="2" type="object" icon="cloud.png" attrs="{'invisible': ['|', ('disable_cron', '=', False), ('ftp_ok', '=', False)]}" /> |
532 | |
533 | <field name="disable_cron" invisible="1" /> |
534 | + <field name="multiple" invisible="1" /> |
535 | |
536 | <separator colspan="4" string="FTP server" /> |
537 | <group col="4" colspan="4"> |
538 | @@ -88,6 +101,7 @@ |
539 | <field name="res_model">automated.export</field> |
540 | <field name="view_type">form</field> |
541 | <field name="view_mode">tree,form</field> |
542 | + <field name="context">{'search_default_filteractive' : 1}</field> |
543 | </record> |
544 | <menuitem |
545 | id="automated_export_menu" |
546 | |
547 | === modified file 'bin/addons/msf_tools/views/automated_import_view.xml' |
548 | --- bin/addons/msf_tools/views/automated_import_view.xml 2020-10-20 15:14:32 +0000 |
549 | +++ bin/addons/msf_tools/views/automated_import_view.xml 2021-05-07 16:00:52 +0000 |
550 | @@ -8,9 +8,16 @@ |
551 | <field name="type">search</field> |
552 | <field name="arch" type="xml"> |
553 | <search string="Automated imports"> |
554 | - <filter name="inactive" domain="[('active', '=', False)]" string="Inactive" icon="gtk-undo" /> |
555 | + <filter icon="terp-check" name="filteractive" string="Active" domain="[('active', '=', True)]" /> |
556 | + <filter icon="gtk-dialog-error" name="filterinactive" string="Inactive" domain="[('active', '=', False)]" /> |
557 | <field name="name" /> |
558 | <field name="function_id" /> |
559 | + <field name="partner_id" /> |
560 | + <newline /> |
561 | + <group expand="1" string="Group By..." colspan="4" col="4"> |
562 | + <filter string="Partner" name="groupby_partner_id" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/> |
563 | + <filter string="Function" name="groupby_function_id" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'function_id'}"/> |
564 | + </group> |
565 | </search> |
566 | </field> |
567 | </record> |
568 | @@ -20,12 +27,14 @@ |
569 | <field name="model">automated.import</field> |
570 | <field name="type">tree</field> |
571 | <field name="arch" type="xml"> |
572 | - <tree string="Automated imports"> |
573 | + <tree string="Automated imports" colors="red: not active"> |
574 | <field name="name" /> |
575 | <field name="function_id" /> |
576 | + <field name="partner_id" /> |
577 | <field name="start_time" /> |
578 | <field name="interval" /> |
579 | <field name="interval_unit" /> |
580 | + <field name="active" /> |
581 | </tree> |
582 | </field> |
583 | </record> |
584 | @@ -58,9 +67,11 @@ |
585 | }); |
586 | </script> |
587 | </html> |
588 | + <field name="multiple" invisible="1" /> |
589 | <field name="name" /> |
590 | - <field name="function_id" widget="selection" /> |
591 | + <field name="function_id" widget="selection" on_change="change_function_id(function_id)" /> |
592 | <field name="active" /> |
593 | + <field name="partner_id" attrs="{'invisible': [('multiple', '=', False)], 'required': [('multiple', '=', True)]}"/> |
594 | <field name="is_admin" invisible="1"/> |
595 | <button name="run_job_manually" string="Run job manually" colspan="2" type="object" icon="gtk-execute" /> |
596 | <button name="local_autoconfig" string="Local Auto Configuration" colspan="2" type="object" icon="terp-dialog-close" confirm="This action should only be executed on a Sandbox, it will override the current configuration. Do you confirm ?" attrs="{'invisible': [('is_admin', '=', False)]}"/> |
597 | @@ -108,6 +119,7 @@ |
598 | <field name="res_model">automated.import</field> |
599 | <field name="view_type">form</field> |
600 | <field name="view_mode">tree,form</field> |
601 | + <field name="context">{'search_default_filteractive' : 1}</field> |
602 | </record> |
603 | <menuitem |
604 | id="automated_import_menu" |
605 | |
606 | === modified file 'bin/osv/orm.py' |
607 | --- bin/osv/orm.py 2021-02-02 10:20:51 +0000 |
608 | +++ bin/osv/orm.py 2021-05-07 16:00:52 +0000 |
609 | @@ -3425,6 +3425,8 @@ |
610 | cr.commit() # start a new transaction |
611 | |
612 | for (key, con, null) in self._sql_constraints: |
613 | + if not con: |
614 | + continue |
615 | conname = '%s_%s' % (self._table, key) |
616 | |
617 | cr.execute("SELECT conname, pg_catalog.pg_get_constraintdef(oid, true) as condef FROM pg_constraint where conname=%s", (conname,)) |
618 | @@ -4007,7 +4009,7 @@ |
619 | [('res_id','in',list(sub_ids)),('model','=',self._name)], |
620 | order='NO_ORDER', context=context) |
621 | |
622 | - if self._name in xmlid_no_delete.prevent_deletion: |
623 | + if referenced_ids and self._name in xmlid_no_delete.prevent_deletion: |
624 | cr.execute('''select module, name from ir_model_data |
625 | where |
626 | (module, name) in %s and |
627 | |
628 | === modified file 'bin/unifield-version.txt' |
629 | --- bin/unifield-version.txt 2021-04-30 12:22:42 +0000 |
630 | +++ bin/unifield-version.txt 2021-05-07 16:00:52 +0000 |
631 | @@ -85,3 +85,4 @@ |
632 | 5fe4c98efbdc3f75383ef8861f0809f6 2021-01-18 16:00:00 UF19.1 |
633 | 3b85912ea6e4cc65910b7be7ff5598d0 2021-03-15 11:00:00 UF20.0 |
634 | 965ee9cddbd999bd8d8201f4f6637ee5 2021-04-30 14:00:00 UF20.1 |
635 | +165ee9cddbd999bd8d8201f4f6637ee5 2021-04-30 14:00:00 UF20.1-t |