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