Merge lp:~mukunde/unifield-server/US-12645 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 6287
Proposed branch: lp:~mukunde/unifield-server/US-12645
Merge into: lp:unifield-server
Diff against target: 1115 lines (+706/-28) (has conflicts)
3 files modified
bin/addons/msf_profile/i18n/fr_MF.po (+213/-12)
bin/addons/product_asset/product_asset.py (+407/-9)
bin/addons/product_asset/product_asset_view.xml (+86/-7)
Text conflict in bin/addons/msf_profile/i18n/fr_MF.po
To merge this branch: bzr merge lp:~mukunde/unifield-server/US-12645
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+465661@code.launchpad.net
To post a comment you must log in.
lp:~mukunde/unifield-server/US-12645 updated
6250. By Gaël Mukunde

US-12440 [IMP] Add caches for frequently searched objects that may be the same across rows

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
2--- bin/addons/msf_profile/i18n/fr_MF.po 2024-05-02 13:19:58 +0000
3+++ bin/addons/msf_profile/i18n/fr_MF.po 2024-05-10 12:38:34 +0000
4@@ -5905,6 +5905,7 @@
5 #: field:wizard.temp.posting.line,name:0
6 #: field:product.template,name:0
7 #: field:product.asset.type,description:0
8+#: field:product.asset.import.entries.errors,name:0
9 #, python-format
10 msgid "Description"
11 msgstr "Description"
12@@ -8671,7 +8672,7 @@
13 msgid "The currency used to enter statement"
14 msgstr "Devise utilisée pour entrer les relevés"
15
16-#. modules: register_accounting, account_hq_entries, msf_homere_interface, msf_doc_import, account
17+#. modules: register_accounting, account_hq_entries, msf_homere_interface, msf_doc_import, account, product_asset
18 #: field:msf.doc.import.accounting,filename:0
19 #: field:hq.entries.import,filename:0
20 #: field:hr.expat.employee.import,filename:0
21@@ -8682,6 +8683,7 @@
22 #: field:account.invoice.import,filename:0
23 #: field:account.cv.import,filename:0
24 #: field:esc.line.import,filename:0
25+#: field:product.asset.import.entries,filename:0
26 msgid "Imported filename"
27 msgstr "Nom du fichier importé"
28
29@@ -10156,8 +10158,9 @@
30 msgid " e.g: 1 * (this unit) = ratio * (reference unit)"
31 msgstr " par exemple : 1 x (cette unité) = ratio x (unité de référence)"
32
33-#. module: msf_doc_import
34+#. module: msf_doc_import, product_asset
35 #: view:msf.doc.import.accounting:0
36+#: view:product.asset.import.entries:0
37 msgid "Import template"
38 msgstr "Import template"
39
40@@ -15467,6 +15470,7 @@
41 #: code:addons/consumption_calculation/history_consumption.py:719
42 #: field:msf_button_access_rights.button_access_rule,bar_type:0
43 #: report:addons/account/report/export_cv.mako:137
44+#: field:product.asset.import.entries.lines,type:0
45 msgid "Type"
46 msgstr "Type"
47
48@@ -19935,7 +19939,7 @@
49 msgid "Some entries are already reconciled !"
50 msgstr "Certaines écritures sont déjà lettrées !"
51
52-#. modules: msf_doc_import, register_accounting, consumption_calculation, account, account_hq_entries
53+#. modules: msf_doc_import, register_accounting, consumption_calculation, account, account_hq_entries, product_asset
54 #: field:weekly.forecast.report,progress:0
55 #: field:abstract.wizard.import,progression:0
56 #: field:msf.doc.import.accounting,progression:0
57@@ -19946,6 +19950,7 @@
58 #: field:hq.entries.import,progress:0
59 #: field:account.cv.import,progression:0
60 #: field:esc.line.import,progress:0
61+#: field:product.asset.import.entries,progression:0
62 msgid "Progression"
63 msgstr "Progression"
64
65@@ -20824,6 +20829,7 @@
66 #: selection:product.asset,state:0
67 #: selection:product.asset.event,asset_state:0
68 #: selection:signature.follow_up,doc_state:0
69+#: selection:product.asset.import.entries,state:0
70 msgid "Done"
71 msgstr "Clôturé"
72
73@@ -30182,7 +30188,7 @@
74 msgid "Operator '%s' not suported"
75 msgstr "Operator '%s' not suported"
76
77-#. modules: register_accounting, account_mcdb, msf_homere_interface, financing_contract, procurement_request, consumption_calculation, sync_client, msf_config_locations, stock_forecast, base, msf_currency_revaluation, specific_rules, msf_doc_import, stock, analytic_distribution, account, purchase, product
78+#. modules: register_accounting, account_mcdb, msf_homere_interface, financing_contract, procurement_request, consumption_calculation, sync_client, msf_config_locations, stock_forecast, base, msf_currency_revaluation, specific_rules, msf_doc_import, stock, analytic_distribution, account, purchase, product, product_asset
79 #: view:account.line.csv.export:0
80 #: field:account.line.csv.export,message:0
81 #: field:import.commitment.wizard,last_error:0
82@@ -30239,6 +30245,7 @@
83 #: field:product.mass.update,message:0
84 #: field:account.cv.import,message:0
85 #: field:message.action,message:0
86+#: field:product.asset.import.entries,message:0
87 msgid "Message"
88 msgstr "Message"
89
90@@ -37138,6 +37145,7 @@
91 #: view:product.asset.type:0
92 #: field:product.template,asset_type_id:0
93 #: field:product.asset.useful.life,asset_type_id:0
94+#: field:product.asset.import.entries.lines,asset_type_id:0
95 msgid "Asset Type"
96 msgstr "Type d'Immobilisation"
97
98@@ -38123,6 +38131,7 @@
99 #: view:account.move.line:0
100 #: field:wizard.account.invoice.line,move_lines:0
101 #: field:product.asset,move_line_id:0
102+#: field:product.asset.import.entries.lines,move_line_id:0
103 msgid "Journal Item"
104 msgstr "Ligne d'écriture comptable"
105
106@@ -39127,6 +39136,7 @@
107 #: field:sale.report,year:0
108 #: view:report.stock.move:0
109 #: field:report.stock.move,year:0
110+#: field:product.asset.import.entries.lines,year:0
111 msgid "Year"
112 msgstr "Année"
113
114@@ -39271,6 +39281,7 @@
115 #: field:sync.client.log_sale_purchase,model_id:0
116 #: view:account.model:0
117 #: field:signature,signature_res_model:0
118+#: field:product.asset.import.entries.lines,model:0
119 msgid "Model"
120 msgstr "Modèle"
121
122@@ -39703,6 +39714,7 @@
123 #: report:product.asset:0
124 #: field:product.asset,serial_nb:0
125 #: field:product.asset.event,serial_nb:0
126+#: field:product.asset.import.entries.lines,serial_nb:0
127 msgid "Serial Number"
128 msgstr "Numéro de Série"
129
130@@ -41160,6 +41172,7 @@
131 #: report:product.asset:0
132 #: field:product.asset,brand:0
133 #: field:product.asset.event,brand:0
134+#: field:product.asset.import.entries.lines,brand:0
135 msgid "Brand"
136 msgstr "Marque"
137
138@@ -41995,7 +42008,7 @@
139 msgid "Contract code/name:"
140 msgstr "Contrat - Code/Nom:"
141
142-#. modules: sales_followup, register_accounting, import_data, sync_client, base, purchase_followup, msf_doc_import, stock, product, account, account_hq_entries
143+#. modules: sales_followup, register_accounting, import_data, sync_client, base, purchase_followup, msf_doc_import, stock, product, account, account_hq_entries, product_asset
144 #: view:base.module.update:0
145 #: view:base.update.translations:0
146 #: selection:import_data,import_mode:0
147@@ -42026,6 +42039,7 @@
148 #: view:hq.entries.import:0
149 #: view:account.cv.import:0
150 #: view:esc.line.import:0
151+#: view:product.asset.import.entries:0
152 msgid "Update"
153 msgstr "Mettre à jour"
154
155@@ -43460,6 +43474,7 @@
156 #: field:unidata.project,msl_product_ids:0
157 #: field:replenishment.product.list,l_default_code:0
158 #: field:unifield.instance,msl_product_ids:0
159+#: field:product.asset.import.entries.lines,prod_int_code:0
160 #, python-format
161 msgid "Product Code"
162 msgstr "Code Produit"
163@@ -45042,7 +45057,7 @@
164 msgid "Output Out"
165 msgstr "Modèles de Taxe"
166
167-#. modules: stock_forecast, register_accounting, msf_outgoing, documents_done, unifield_setup, account_override, purchase_compare_rfq, base, stock, msf_profile, msf_doc_import, sale, account_hq_entries, res_currency_tables, account
168+#. modules: stock_forecast, register_accounting, msf_outgoing, documents_done, unifield_setup, account_override, purchase_compare_rfq, base, stock, msf_profile, msf_doc_import, sale, account_hq_entries, res_currency_tables, account, product_asset
169 #: field:wizard.split.invoice.lines,wizard_id:0
170 #: view:ir.actions.wizard:0
171 #: field:wizard.ir.model.menu.create.line,wizard_id:0
172@@ -45076,6 +45091,8 @@
173 #: field:wizard.hard.posting.line,wizard_id:0
174 #: field:wizard.ignore.posting.line,wizard_id:0
175 #: field:wizard.temp.posting.line,wizard_id:0
176+#: field:product.asset.import.entries.errors,wizard_id:0
177+#: field:product.asset.import.entries.lines,wizard_id:0
178 msgid "Wizard"
179 msgstr "Assistant"
180
181@@ -68707,7 +68724,7 @@
182 msgid "Kit Composition"
183 msgstr "Kit - Composition"
184
185-#. modules: register_accounting, msf_homere_interface, account_override, base, msf_doc_import, msf_profile, sync_client, msf_supply_doc_export, account
186+#. modules: register_accounting, msf_homere_interface, account_override, base, msf_doc_import, msf_profile, sync_client, msf_supply_doc_export, account, product_asset
187 #: view:ir.attachment:0
188 #: view:ir.attachment:0
189 #: selection:msf.doc.import.accounting,state:0
190@@ -68722,6 +68739,7 @@
191 #: code:addons/msf_supply_doc_export/msf_supply_doc_export.py:896
192 #: selection:account.invoice.import,state:0
193 #: selection:account.cv.import,state:0
194+#: selection:product.asset.import.entries,state:0
195 msgid "Created"
196 msgstr "Créé"
197
198@@ -72414,7 +72432,7 @@
199 msgid "Expected Pack Date"
200 msgstr "Date Prévue de Colisage"
201
202-#. modules: tender_flow, analytic_distribution_supply, product_nomenclature, financing_contract, msf_tools, account_hq_entries, export_import_lang, account_override, procurement_cycle, account_journal, register_accounting, mission_stock, return_claim, sync_client, account_mcdb, res_currency_tables, supplier_catalogue, stock_schedule, procurement_request, spreadsheet_xml, unifield_setup, purchase_compare_rfq, stock_batch_recall, purchase_followup, stock_override, msf_doc_import, analytic_distribution, msf_order_date, msf_cross_docking, reason_types_moves, purchase_allocation_report, finance, msf_homere_interface, msf_instance, account_reconciliation, service_purchasing, consumption_calculation, purchase_override, specific_rules, kit, base, account_subscription, res_currency_functional, msf_budget, account_corrections, account, msf_outgoing, stock_move_tracking, msf_partner, product_attributes, order_nomenclature, documents_done, sale, msf_config_locations, sales_followup, sourcing, msf_custom_settings, product_list, object_query, stock, msf_profile, product, msf_supply_doc_export, purchase
203+#. modules: tender_flow, analytic_distribution_supply, product_nomenclature, financing_contract, msf_tools, account_hq_entries, export_import_lang, account_override, procurement_cycle, account_journal, register_accounting, mission_stock, return_claim, sync_client, account_mcdb, res_currency_tables, supplier_catalogue, stock_schedule, procurement_request, spreadsheet_xml, unifield_setup, purchase_compare_rfq, stock_batch_recall, purchase_followup, stock_override, msf_doc_import, analytic_distribution, msf_order_date, msf_cross_docking, reason_types_moves, purchase_allocation_report, finance, msf_homere_interface, msf_instance, account_reconciliation, service_purchasing, consumption_calculation, purchase_override, specific_rules, kit, base, account_subscription, res_currency_functional, msf_budget, account_corrections, account, msf_outgoing, stock_move_tracking, msf_partner, product_attributes, order_nomenclature, documents_done, sale, msf_config_locations, sales_followup, sourcing, msf_custom_settings, product_list, object_query, stock, msf_profile, product, msf_supply_doc_export, purchase, product_asset
204 #: code:addons/account/account.py:294
205 #: code:addons/account/account.py:988
206 #: code:addons/account/account.py:992
207@@ -73589,6 +73607,7 @@
208 #: selection:unidata.sync,last_msl_execution_status:0
209 #: field:unidata.sync.log,error:0
210 #: selection:unidata.sync.log,state:0
211+#: selection:product.asset.import.entries,state:0
212 #, python-format, python-format
213 msgid "Error"
214 msgstr "Erreur"
215@@ -74026,7 +74045,7 @@
216 msgid "Do you want to update the Date of Stock Take of all/selected draft Order lines ?"
217 msgstr "Voulez-vous mettre à jour la Date de Prise de Stock sur toutes les lignes brouillon de la Commande ou les lignes brouillon sélectionnées ?"
218
219-#. modules: register_accounting, msf_homere_interface, documents_done, consumption_calculation, msf_button_access_rights, mission_stock, msf_doc_import, analytic_distribution, sourcing, sale, account, account_hq_entries
220+#. modules: register_accounting, msf_homere_interface, documents_done, consumption_calculation, msf_button_access_rights, mission_stock, msf_doc_import, analytic_distribution, sourcing, sale, account, account_hq_entries, product_asset
221 #: field:mass.reallocation.verification.wizard,error_ids:0
222 #: field:monthly.review.consumption.line,text_error:0
223 #: field:real.average.consumption.line,text_error:0
224@@ -74047,6 +74066,7 @@
225 #: field:hq.entries.import,nberrors:0
226 #: field:account.cv.import,error_ids:0
227 #: field:esc.line.import,nberrors:0
228+#: field:product.asset.import.entries,error_ids:0
229 #, python-format
230 msgid "Errors"
231 msgstr "Erreurs"
232@@ -81079,7 +81099,7 @@
233 msgid "Wizard lines for internal picking processor"
234 msgstr "Wizard lines for internal picking processor"
235
236-#. modules: vertical_integration, register_accounting, res_currency_tables, account_hq_entries, update_client, msf_tools, msf_doc_import, analytic_distribution, account, procurement_cycle
237+#. modules: vertical_integration, register_accounting, res_currency_tables, account_hq_entries, update_client, msf_tools, msf_doc_import, analytic_distribution, account, procurement_cycle, product_asset
238 #: view:hq.entries.import:0
239 #: view:import.commitment.wizard:0
240 #: view:msf.doc.import.accounting:0
241@@ -81099,6 +81119,7 @@
242 #: view:account.cv.import:0
243 #: view:esc.line.import:0
244 #: field:esc.line.import.rejected,wiz_id:0
245+#: view:product.asset.import.entries:0
246 msgid "Import"
247 msgstr "Importer"
248
249@@ -81809,6 +81830,7 @@
250 #: report:delivery.order:0
251 #: field:stock.move,ship_influenced_state:0
252 #: field:product.asset,state:0
253+#: field:product.asset.import.entries,state:0
254 #, python-format
255 msgid "State"
256 msgstr "Statut"
257@@ -82985,7 +83007,7 @@
258 msgid "Computation"
259 msgstr "Calcul"
260
261-#. modules: register_accounting, msf_homere_interface, import_data, account_hq_entries, export_import_lang, base, msf_doc_import, mission_stock, analytic_distribution, account
262+#. modules: register_accounting, msf_homere_interface, import_data, account_hq_entries, export_import_lang, base, msf_doc_import, mission_stock, analytic_distribution, account, product_asset
263 #: field:int.commitment.export.wizard,data:0
264 #: field:import_category,file:0
265 #: field:import_nomenclature,file:0
266@@ -83006,6 +83028,7 @@
267 #: field:account.invoice.import,file:0
268 #: field:account.cv.import,file:0
269 #: field:esc.line.import,file:0
270+#: field:product.asset.import.entries,file:0
271 msgid "File"
272 msgstr "Fichier"
273
274@@ -83663,7 +83686,7 @@
275 msgid "Sourced-n line"
276 msgstr "Ligne sourcée-n"
277
278-#. modules: analytic_distribution, sales_followup, register_accounting, reason_types_moves, msf_homere_interface, stock_override, consumption_calculation, sale, specific_rules, order_types, msf_tools, mission_stock, msf_doc_import, stock, product, acccount, msf_supply_doc_export, account
279+#. modules: analytic_distribution, sales_followup, register_accounting, reason_types_moves, msf_homere_interface, stock_override, consumption_calculation, sale, specific_rules, order_types, msf_tools, mission_stock, msf_doc_import, stock, product, acccount, msf_supply_doc_export, account, product_asset
280 #: field:import.commitment.wizard,in_progress:0
281 #: view:product.history.consumption:0
282 #: selection:product.history.consumption,fake_status:0
283@@ -83713,6 +83736,7 @@
284 #: selection:wizard.import.ad.line,state:0
285 #: selection:supplier.performance.wizard,state:0
286 #: selection:account.cv.import,state:0
287+#: selection:product.asset.import.entries,state:0
288 #, python-format
289 msgid "In Progress"
290 msgstr "En cours"
291@@ -96645,6 +96669,7 @@
292 #: selection:product.asset.event,asset_state:0
293 #: view:product.asset.generate.entries:0
294 #: view:journal.change.account:0
295+#: view:product.asset.import.entries:0
296 #, python-format
297 msgid "Cancel"
298 msgstr "Annuler"
299@@ -120983,6 +121008,7 @@
300 #: field:product.asset,asset_bs_depreciation_account_id:0
301 #: field:product.asset.line,asset_bs_depreciation_account_id:0
302 #: field:product.category,asset_bs_depreciation_account_id:0
303+#: field:product.asset.import.entries.lines,asset_bs_depreciation_account_id:0
304 msgid "Asset B/S Depreciation Account"
305 msgstr "Compte de bilan des amortissements"
306
307@@ -121028,6 +121054,7 @@
308 #. module: product_asset
309 #: field:product.asset,asset_pl_account_id:0
310 #: field:product.asset.line,asset_pl_account_id:0
311+#: field:product.asset.import.entries.lines,asset_pl_account_id:0
312 msgid "Asset P&L Depreciation Account"
313 msgstr "Compte de résultat des amortissements"
314
315@@ -121237,6 +121264,7 @@
316
317 #. module: product_asset
318 #: field:product.asset,useful_life_id:0
319+#: field:product.asset.import.entries.lines,useful_life_id:0
320 msgid "Useful Life"
321 msgstr "Durée Amortissement"
322
323@@ -121806,6 +121834,7 @@
324 #, python-format
325 msgid "This action can only be done on a Picking"
326 msgstr "Cette action peut uniquement être faite sur un Picking"
327+<<<<<<< TREE
328
329 #. modules: purchase, sale
330 #: code:addons/purchase/purchase_workflow.py:107
331@@ -122096,3 +122125,175 @@
332 msgid "No valid catalogue"
333 msgstr "Aucun catalogue valide"
334
335+=======
336+
337+#. module: product_asset
338+#: field:product.asset,external_asset_id:0
339+#: field:product.asset.import.entries.lines,external_asset_id:0
340+msgid "External Asset ID"
341+msgstr "Immobilisation - ID Externe"
342+
343+#. module: product_asset
344+#: model:ir.model,name:product_asset.model_product_asset_import_entries_errors
345+msgid "Asset Entries Import - Error List"
346+msgstr "Import d'immobilisations - Liste des erreurs"
347+
348+#. module: product_asset
349+#: code:addons/product_asset/product_asset.py:1462
350+#, python-format
351+msgid "Checking file..."
352+msgstr "Vérification du fichier..."
353+
354+#. module: product_asset
355+#: code:addons/product_asset/product_asset.py:1417
356+#, python-format
357+msgid "Cleaning up old imports..."
358+msgstr "Nettoyage des anciens imports..."
359+
360+#. module: product_asset
361+#: code:addons/product_asset/product_asset.py:1427
362+#, python-format
363+msgid "Copying file..."
364+msgstr "Copie du fichier..."
365+
366+#. module: product_asset
367+#: model:ir.actions.act_window,name:product_asset.action_product_asset_import_entries
368+#: model:ir.model,name:product_asset.model_product_asset_import_entries
369+#: model:ir.ui.menu,name:product_asset.menu_product_asset_import_entries
370+#: view:product.asset.import.entries:0
371+msgid "Import Asset Entries"
372+msgstr "Import d'immobilisations"
373+
374+#. module: product_asset
375+#: code:addons/product_asset/product_asset.py:1404
376+#, python-format
377+msgid "Initialization..."
378+msgstr "Initialisation..."
379+
380+#. module: product_asset
381+#: code:addons/product_asset/product_asset.py:1605
382+#, python-format
383+msgid "Line %s: A problem occurred for line registration. Please contact an Administrator."
384+msgstr "Ligne %s: Un problème est survenu lors de l'enregistrement de la ligne. Veuillez contacter un administrateur."
385+
386+#. module: product_asset
387+#: code:addons/product_asset/product_asset.py:1564
388+#, python-format
389+msgid "Line %s: Asset B/S Depreciation Account \"%s\" must have \"Regular\" as Internal Type and \"Asset\" as Account Type"
390+msgstr "Ligne %s: Le compte de bilan des amortissements \"%s\" doit avoir \"Normal\" comme type interne et \"Immobilisation\" comme type de compte"
391+
392+#. module: product_asset
393+#: code:addons/product_asset/product_asset.py:1560
394+#, python-format
395+msgid "Line %s: Asset B/S Depreciation Account \"%s\" not found!"
396+msgstr "Ligne %s: Le compte de bilan des amortissements \"%s\" n'a pas été trouvé!"
397+
398+#. module: product_asset
399+#: code:addons/product_asset/product_asset.py:1581
400+#, python-format
401+msgid "Line %s: Asset P&L Depreciation Account \"%s\" must have \"Expense\" or \"Income\" as Account Type"
402+msgstr "Ligne %s: Le compte de résultat des amortissements \"%s\" doit avoir \"Dépenses\" ou \"Recettes\" comme type de compte"
403+
404+#. module: product_asset
405+#: code:addons/product_asset/product_asset.py:1575
406+#, python-format
407+msgid "Line %s: Asset P&L Depreciation Account \"%s\" not found!"
408+msgstr "Ligne %s: Le compte de résultat des amortissements \"%s\" n'a pas été trouvé!"
409+
410+#. module: product_asset
411+#: code:addons/product_asset/product_asset.py:1507
412+#, python-format
413+msgid "Line %s: Asset Type \"%s\" not found!"
414+msgstr "Ligne %s: Le type d'immobilisation \"%s\" n'a pas été trouvé!"
415+
416+#. module: product_asset
417+#: code:addons/product_asset/product_asset.py:1535
418+#, python-format
419+msgid "Line %s: Journal Item \"%s\" not found!\n"
420+"Please check if that JI exists or has the product specified"
421+msgstr "Ligne %s: La ligne d'écriture comptable \"%s\" n'a pas été trouvé!\n"
422+"Veuillez vérifiez si cette ligne d'écriture existe ou si elle contient le produit spécifié"
423+
424+#. module: product_asset
425+#: code:addons/product_asset/product_asset.py:1501
426+#, python-format
427+msgid "Line %s: No Asset Type specified! (External Asset ID: %s, Serial Number: %s)"
428+msgstr "Ligne %s: Pas de type d'immobilisation spécifié! (Immobilisation - ID Externe: %s, Numéro de série: %s)"
429+
430+#. module: product_asset
431+#: code:addons/product_asset/product_asset.py:1488
432+#, python-format
433+msgid "Line %s: No Product Code specified! (External Asset ID: %s, Serial Number: %s)"
434+msgstr "Ligne %s: Pas de code produit spécifié! (Immobilisation - ID Externe: %s, Numéro de série: %s)"
435+
436+#. module: product_asset
437+#: code:addons/product_asset/product_asset.py:1515
438+#, python-format
439+msgid "Line %s: No Useful Life specified! (External Asset ID: %s, Serial Number: %s)"
440+msgstr "Ligne %s: Pas de durée d'amortissement spécifiée! (Immobilisation - ID Externe: %s, Numéro de série: %s)"
441+
442+#. module: product_asset
443+#: code:addons/product_asset/product_asset.py:1494
444+#, python-format
445+msgid "Line %s: Product Code \"%s\" not found!"
446+msgstr "Ligne %s: Le code produit \"%s\" n'a pas été trouvé!"
447+
448+#. module: product_asset
449+#: code:addons/product_asset/product_asset.py:1521
450+#, python-format
451+msgid "Line %s: The \"%s\" year(s) Useful Life of Asset Type \"%s\" not found!"
452+msgstr "Ligne %s: La durée d'amortissement \"%s\" an(s) du Type d'Immobilisation \"%s\" n'a pas été trouvé!"
453+
454+#. module: product_asset
455+#: code:addons/product_asset/product_asset.py:1547
456+#, python-format
457+msgid "Line %s: The Journal Entry \"%s\" has to be in \"posted\" state."
458+msgstr "Ligne %s: L'écriture comptable \"%s\" doit être à l'état \"comptabilisé\"."
459+
460+#. module: product_asset
461+#: code:addons/product_asset/product_asset.py:1550
462+#, python-format
463+msgid "Line %s: The account type of Journal Item \"%s\" has to be either Asset or Expense."
464+msgstr "Ligne %s: Le type du compte de la ligne d'écriture comptable \"%s\" doit être soit Immobilisations soit Dépenses."
465+
466+#. module: product_asset
467+#: code:addons/product_asset/product_asset.py:1544
468+#, python-format
469+msgid "Line %s: The debit of Journal Item \"%s\" has to be greater than 0."
470+msgstr "Ligne %s: Le débit de la ligne d'écriture comptable \"%s\" doit être supérieur à 0."
471+
472+#. module: product_asset
473+#: code:addons/product_asset/product_asset.py:1541
474+#, python-format
475+msgid "Line %s: The journal of Journal Item \"%s\" has to be of type Purchase, Correction HQ, HQ or Intermission!"
476+msgstr "Ligne %s: Le journal de la ligne d'écriture comptable \"%s\" doit être de type Achat, Correction HQ, HQ ou Intermission!"
477+
478+#. module: product_asset
479+#: code:addons/product_asset/product_asset.py:1435
480+#, python-format
481+msgid "Processing line..."
482+msgstr "Traitement de la ligne..."
483+
484+#. module: product_asset
485+#: code:addons/product_asset/product_asset.py:1439
486+#, python-format
487+msgid "Reading headers..."
488+msgstr "Lecture des entêtes..."
489+
490+#. module: product_asset
491+#: code:addons/product_asset/product_asset.py:1457
492+#, python-format
493+msgid "Reading lines..."
494+msgstr "Lecture des lignes..."
495+
496+#. module: product_asset
497+#: view:product.asset.import.entries:0
498+msgid "This will import Entries from an XML file."
499+msgstr "Ceci va importer les entrées d'immobilisations' depuis un fichier XML."
500+
501+#. module: product_asset
502+#: code:addons/product_asset/product_asset.py:1632
503+#, python-format
504+msgid "Writing changes..."
505+msgstr "Écriture des modifications..."
506+>>>>>>> MERGE-SOURCE
507
508=== modified file 'bin/addons/product_asset/product_asset.py'
509--- bin/addons/product_asset/product_asset.py 2023-11-16 13:03:16 +0000
510+++ bin/addons/product_asset/product_asset.py 2024-05-10 12:38:34 +0000
511@@ -6,6 +6,11 @@
512 from tools import misc
513 from datetime import datetime
514 from dateutil.relativedelta import relativedelta
515+import threading
516+import pooler
517+from tempfile import NamedTemporaryFile
518+from base64 import b64decode
519+from spreadsheet_xml.spreadsheet_xml import SpreadsheetXML
520
521
522 #----------------------------------------------------------
523@@ -187,7 +192,31 @@
524 'from_sync': False,
525 'event_ids': [],
526 'instance_id': False,
527- 'invoice_id': False
528+ 'invoice_id': False,
529+ 'move_line_id': False,
530+ 'quantity_divisor': False,
531+ 'invo_value': False,
532+ 'invo_currency': False,
533+ 'invo_date': False,
534+ 'invo_supplier_id': False,
535+ 'invo_donator_code': False,
536+ 'invo_certif_depreciation': False,
537+ 'serial_nb': False,
538+ 'brand': False,
539+ 'type': False,
540+ 'model': False,
541+ 'year': False,
542+ 'project_po': False,
543+ 'orig_mission_code': False,
544+ 'international_po': False,
545+ 'arrival_date': False,
546+ 'receipt_place': False,
547+ 'comment': False,
548+ 'line_ids': [],
549+ 'depreciation_amount': False,
550+ 'disposal_amount': False,
551+ 'start_date': False,
552+ 'depreciation_method': False,
553 })
554 return super(product_asset, self).copy_data(cr, uid, id, default, context=context)
555
556@@ -240,12 +269,12 @@
557 vals['state'] = 'open'
558
559 # fetch the product
560- if 'product_id' in vals:
561+ if 'product_id' in vals and not context.get('from_import'):
562 productId = vals['product_id']
563 # add readonly fields to vals
564 vals.update(self._getRelatedProductFields(cr, uid, productId, update_account=not from_sync))
565
566- if not from_sync and not vals.get('from_invoice') and 'move_line_id' in vals:
567+ if not from_sync and not vals.get('from_invoice') and not context.get('from_import') and 'move_line_id' in vals:
568 vals.update(self._getRelatedMoveLineFields(cr, uid, vals['move_line_id'], divisor=vals.get('quantity_divisor'), context=context))
569
570 # UF-1617: set the current instance into the new object if it has not been sent from the sync
571@@ -463,6 +492,7 @@
572 'asset_type_id': fields.many2one('product.asset.type', 'Asset Type'), # from product
573 'description': fields.char('Asset Description', size=128),
574 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade'),
575+ 'external_asset_id': fields.char('External Asset ID', size=32),
576 # msf codification
577 'prod_int_code': fields.char('Product Code', size=128, readonly=True), # from product
578 'prod_int_name': fields.char('Product Description', size=128, readonly=True), # from product
579@@ -484,13 +514,13 @@
580 'arrival_date': fields.date('Arrival Date'), # required=True),
581 'receipt_place': fields.char('Receipt Place', size=128), # required=True),
582 # Invoice
583- 'invo_date': fields.date('Invoice Date', required=True, readonly=1),
584- 'invo_value': fields.float('Value', required=True, readonly=1),
585+ 'invo_date': fields.date('Invoice Date', readonly=1),
586+ 'invo_value': fields.float('Value', readonly=1),
587 'invoice_id': fields.many2one('account.invoice', 'Invoice'),
588- 'move_line_id': fields.many2one('account.move.line', 'Journal Item', domain="['&', '&', '&', ('journal_id.type', 'in', ['purchase', 'correction_hq', 'hq', 'intermission']), ('debit', '>', 0), ('move_id.state', '=', 'posted'), ('account_id.user_type_code', 'in', ['asset', 'expense'])]", required=1),
589+ 'move_line_id': fields.many2one('account.move.line', 'Journal Item', domain="['&', '&', '&', ('journal_id.type', 'in', ['purchase', 'correction_hq', 'hq', 'intermission']), ('debit', '>', 0), ('move_id.state', '=', 'posted'), ('account_id.user_type_code', 'in', ['asset', 'expense'])]"),
590 'quantity_divisor': fields.integer_null('Divisor Quantity', help='This quantity will divide the total invoice value.'),
591 'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line'),
592- 'invo_currency': fields.many2one('res.currency', 'Currency', required=True, readonly=1),
593+ 'invo_currency': fields.many2one('res.currency', 'Currency', readonly=1),
594 'invo_supplier_id': fields.many2one('res.partner', 'Supplier', readonly=1),
595 'invo_donator_code': fields.char('Donator Code', size=128),
596 'invo_certif_depreciation': fields.char('Certificate of Depreciation', size=128),
597@@ -505,7 +535,7 @@
598 'asset_bs_depreciation_account_id': fields.many2one('account.account', 'Asset B/S Depreciation Account', domain=[('type', '=', 'other'), ('user_type_code', '=', 'asset')]),
599 'asset_pl_account_id': fields.many2one('account.account', 'Asset P&L Depreciation Account', domain=[('user_type_code', 'in', ['expense', 'income'])]),
600 'useful_life_id': fields.many2one('product.asset.useful.life', 'Useful Life', ondelete='restrict'),
601- 'start_date': fields.date('Start Date', required=1),
602+ 'start_date': fields.date('Start Date'),
603 'line_ids': fields.one2many('product.asset.line', 'asset_id', 'Depreciation Lines'),
604 'analytic_distribution_id': fields.many2one('analytic.distribution', 'Analytic Distribution'),
605 'depreciation_amount': fields.function(_get_book_value, string='Depreciation', type='float', method=True, help="Sum of all Asset journal item lines", multi='get_book', with_null=True),
606@@ -516,7 +546,7 @@
607 'can_be_disposed': fields.function(_get_can_be_disposed, string='Can be diposed', type='boolean', method=True),
608 'instance_level': fields.function(_get_instance_level, string='Instance Level', type='char', method=True),
609 'prorata': fields.boolean('Prorata Temporis'),
610- 'depreciation_method': fields.selection([('straight', 'Straight Line')], 'Depreciation Method', required=True),
611+ 'depreciation_method': fields.selection([('straight', 'Straight Line')], 'Depreciation Method'),
612 'period_id': fields.function(misc.get_fake, fnct_search=_search_period_id, method=True, type='many2one', relation='account.period', string='Start Period', domain=[('special', '=', False)]),
613 }
614
615@@ -1354,6 +1384,374 @@
616
617 product_asset_generate_entries()
618
619+
620+class product_asset_import_entries(osv.osv_memory):
621+ _name = 'product.asset.import.entries'
622+ _description = 'Import Asset Entries'
623+ _columns = {
624+ 'file': fields.binary(string="File", filters='*.xml, *.xls', required=True),
625+ 'filename': fields.char(string="Imported filename", size=256),
626+ 'progression': fields.float(string="Progression", readonly=True),
627+ 'message': fields.char(string="Message", size=256, readonly=True),
628+ 'state': fields.selection(
629+ [('draft', 'Created'), ('inprogress', 'In Progress'), ('error', 'Error'), ('done', 'Done')], string="State",
630+ readonly=True, required=True),
631+ 'error_ids': fields.one2many('product.asset.import.entries.errors', 'wizard_id', "Errors", readonly=True),
632+ }
633+ _defaults = {
634+ 'progression': lambda *a: 0.0,
635+ 'state': lambda *a: 'draft',
636+ 'message': lambda *a: _('Initialization...'),
637+ }
638+
639+ def _import(self, dbname, uid, ids, context=None):
640+ if context is None:
641+ context = {}
642+ cr = pooler.get_db(dbname).cursor()
643+ created = 0
644+ processed = 0
645+ errors = []
646+ current_line_num = None
647+ acc_cache = {}
648+ prod_cache = {}
649+ asset_type_cache = {}
650+ use_life_cache = {}
651+ try:
652+ # Update wizard
653+ self.write(cr, uid, ids, {'message': _('Cleaning up old imports...'), 'progression': 1.00})
654+ # Clean up old temporary imported lines
655+ old_lines_ids = self.pool.get('product.asset.import.entries.lines').search(cr, uid, [])
656+ self.pool.get('product.asset.import.entries.lines').unlink(cr, uid, old_lines_ids)
657+
658+ for wiz in self.browse(cr, uid, ids):
659+ # Check that a file was given
660+ if not wiz.file:
661+ raise osv.except_osv(_('Error'), _('Nothing to import.'))
662+ # Update wizard
663+ self.write(cr, uid, [wiz.id], {'message': _('Copying file...'), 'progression': 2.00})
664+ fileobj = NamedTemporaryFile('w+b', delete=False)
665+ fileobj.write(b64decode(wiz.file))
666+ fileobj.close()
667+ content = SpreadsheetXML(xmlfile=fileobj.name, context=context)
668+ if not content:
669+ raise osv.except_osv(_('Warning'), _('No content'))
670+ # Update wizard
671+ self.write(cr, uid, [wiz.id], {'message': _('Processing line...'), 'progression': 4.00})
672+ rows = content.getRows()
673+ nb_rows = len([x for x in content.getRows()])
674+ # Update wizard
675+ self.write(cr, uid, [wiz.id], {'message': _('Reading headers...'), 'progression': 5.00})
676+ # Use the first row to find which column to use
677+ cols = {}
678+ col_names = ['External Asset ID', 'Product Code', 'Asset Type', 'Useful Life', 'Serial Number', 'Brand',
679+ 'Type', 'Model', 'Year', 'Journal Item', 'Asset B/S Depreciation Account',
680+ 'Asset P&L Depreciation Account']
681+ for num, r in enumerate(rows):
682+ header = [x and x.data for x in r.iter_cells()]
683+ for el in col_names:
684+ if el in header:
685+ cols[el] = header.index(el)
686+ break
687+ # Number of line to bypass in line's count
688+ base_num = 2
689+ for el in col_names:
690+ if el not in cols:
691+ raise osv.except_osv(_('Error'), _("'%s' column not found in file.") % (el or '',))
692+ # Update wizard
693+ self.write(cr, uid, [wiz.id], {'message': _('Reading lines...'), 'progression': 6.00})
694+ # Check file's content
695+ for num, r in enumerate(rows):
696+ # Update wizard
697+ progression = ((float(num + 1) * 94) / float(nb_rows)) + 6
698+ self.write(cr, uid, [wiz.id], {'message': _('Checking file...'), 'progression': progression})
699+ # Prepare some values
700+ r_prod = False
701+ r_asset_type = False
702+ r_use_life = False
703+ r_ji = False
704+ r_bs_acc = False
705+ r_pl_acc = False
706+
707+ current_line_num = num + base_num
708+ # Fetch all XML row values
709+ line = self.pool.get('import.cell.data').get_line_values(cr, uid, ids, r, context=context)
710+
711+ # ignore empty lines
712+ if not self.pool.get('msf.doc.import.accounting')._check_has_data(line):
713+ continue
714+
715+ # Check line length and fill the cropped empty/missing cells at end of line with False
716+ if len(line) < len(col_names):
717+ line.extend([False] * (len(col_names) - len(line)))
718+
719+ line = self.pool.get('msf.doc.import.accounting')._format_special_char(line)
720+
721+ # Check Product Code
722+ if not line[cols['Product Code']]:
723+ errors.append(
724+ _('Line %s: No Product Code specified! (External Asset ID: %s, Serial Number: %s)') %
725+ (current_line_num, line[cols['External Asset ID']] or '_', line[cols['Serial Number']] or '_'))
726+ else:
727+ if not prod_cache.get(line[cols['Product Code']], False):
728+ product_ids = self.pool.get('product.product').search(cr, uid, [('default_code', '=', line[cols['Product Code']])])
729+ if product_ids:
730+ prod_cache[line[cols['Product Code']]] = product_ids[0]
731+ else:
732+ errors.append(_('Line %s: Product Code "%s" not found!') % (current_line_num, line[cols['Product Code']],))
733+ r_prod = prod_cache.get(line[cols['Product Code']], False)
734+
735+ # Check Asset Type
736+ if not line[cols['Asset Type']]:
737+ errors.append(
738+ _('Line %s: No Asset Type specified! (External Asset ID: %s, Serial Number: %s)') %
739+ (current_line_num, line[cols['External Asset ID']] or '_', line[cols['Serial Number']] or '_'))
740+ else:
741+ if not asset_type_cache.get(line[cols['Asset Type']], False):
742+ asset_type_ids = self.pool.get('product.asset.type').search(cr, uid, [('name', '=', line[cols['Asset Type']])])
743+ if asset_type_ids:
744+ asset_type_cache[line[cols['Asset Type']]] = asset_type_ids[0]
745+ else:
746+ errors.append(_('Line %s: Asset Type "%s" not found!') % (current_line_num, line[cols['Asset Type']],))
747+ r_asset_type = asset_type_cache.get(line[cols['Asset Type']], False)
748+
749+ # Check Useful Life
750+ if not line[cols['Useful Life']]:
751+ errors.append(
752+ _('Line %s: No Useful Life specified! (External Asset ID: %s, Serial Number: %s)') %
753+ (current_line_num, line[cols['External Asset ID']] or '_', line[cols['Serial Number']] or '_'))
754+ elif line[cols['Useful Life']] and r_asset_type:
755+ if not use_life_cache.get((line[cols['Useful Life']], r_asset_type), False):
756+ use_life_ids = self.pool.get('product.asset.useful.life').search(cr, uid, [('asset_type_id', '=', r_asset_type), ('year', '=', line[cols['Useful Life']])])
757+ if use_life_ids:
758+ use_life_cache[(line[cols['Useful Life']], r_asset_type)] = use_life_ids[0]
759+ else:
760+ errors.append(
761+ _('Line %s: The "%s" year(s) Useful Life of Asset Type "%s" not found!') %
762+ (current_line_num, line[cols['Useful Life']], line[cols['Asset Type']],))
763+ r_use_life = use_life_cache.get((line[cols['Useful Life']], r_asset_type), False)
764+
765+ # Check Journal Item
766+ move_ids = False
767+ aml_ids = False
768+ if line[cols['Journal Item']]:
769+ move_ids = self.pool.get('account.move').search(cr, uid, [('name', '=', line[cols['Journal Item']])])
770+ if move_ids and move_ids[0]:
771+ if r_prod:
772+ product = self.pool.get('product.product').browse(cr, uid, r_prod, context=context)
773+ aml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', move_ids[0]), ('product_id', '=', product.id)])
774+ if not move_ids or not aml_ids:
775+ errors.append(_('Line %s: Journal Item "%s" not found!\nPlease check if that JI exists or has the product specified') % (current_line_num, line[cols['Journal Item']],))
776+ elif aml_ids:
777+ ji_error = False
778+ # Apply the same restrictions as in the asset form view
779+ aml = self.pool.get('account.move.line').browse(cr, uid, aml_ids[0], context=context)
780+ if aml.journal_id.type not in ['purchase', 'correction_hq', 'hq', 'intermission']:
781+ errors.append(_('Line %s: The journal of Journal Item "%s" has to be of type Purchase, Correction HQ, HQ or Intermission!') % (current_line_num, line[cols['Journal Item']],))
782+ ji_error = True
783+ if not (aml.debit > 0):
784+ errors.append(_('Line %s: The debit of Journal Item "%s" has to be greater than 0.') % (current_line_num, line[cols['Journal Item']],))
785+ ji_error = True
786+ if aml.move_id.state != 'posted':
787+ errors.append(_('Line %s: The Journal Entry "%s" has to be in "posted" state.') % (current_line_num, line[cols['Journal Item']],))
788+ ji_error = True
789+ if aml.account_id.user_type_code not in ['asset', 'expense']:
790+ errors.append(_('Line %s: The account type of Journal Item "%s" has to be either Asset or Expense.') % (current_line_num, line[cols['Journal Item']],))
791+ ji_error = True
792+ if not ji_error:
793+ r_ji = aml_ids[0]
794+
795+ # Check Asset B/S Depreciation Account
796+ bs_ids = False
797+ if line[cols['Asset B/S Depreciation Account']]:
798+ if not acc_cache.get((line[cols['Asset B/S Depreciation Account']], 'bs'), False):
799+ bs_ids = self.pool.get('account.account').search(cr, uid, [('code', '=', line[cols['Asset B/S Depreciation Account']])])
800+ if not bs_ids:
801+ errors.append(_('Line %s: Asset B/S Depreciation Account "%s" not found!') % (current_line_num, line[cols['Asset B/S Depreciation Account']],))
802+ else:
803+ bs_account = self.pool.get('account.account').browse(cr, uid, bs_ids[0], context=context)
804+ if bs_account.type != 'other' or bs_account.user_type_code != 'asset':
805+ errors.append(_('Line %s: Asset B/S Depreciation Account "%s" must have "Regular" as Internal Type and "Asset" as Account Type') %
806+ (current_line_num, line[cols['Asset B/S Depreciation Account']],))
807+ else:
808+ acc_cache[(line[cols['Asset B/S Depreciation Account']], 'bs')] = bs_ids[0]
809+ else:
810+ r_bs_acc = acc_cache.get((line[cols['Asset B/S Depreciation Account']], 'bs'), False)
811+
812+ # Check Asset P&L Depreciation Account
813+ pl_ids = False
814+ if line[cols['Asset P&L Depreciation Account']]:
815+ if not acc_cache.get((line[cols['Asset P&L Depreciation Account']], 'pl'), False):
816+ pl_ids = self.pool.get('account.account').search(cr, uid, [('code', '=', line[cols['Asset P&L Depreciation Account']])])
817+ if not pl_ids:
818+ errors.append(_('Line %s: Asset P&L Depreciation Account "%s" not found!') %
819+ (current_line_num, line[cols['Asset P&L Depreciation Account']],))
820+ else:
821+ pl_account = self.pool.get('account.account').browse(cr, uid, pl_ids[0], context=context)
822+ if pl_account.user_type_code not in ['expense', 'income']:
823+ errors.append(
824+ _('Line %s: Asset P&L Depreciation Account "%s" must have "Expense" or "Income" as Account Type') %
825+ (current_line_num, line[cols['Asset P&L Depreciation Account']],))
826+ else:
827+ acc_cache[(line[cols['Asset P&L Depreciation Account']], 'pl')] = pl_ids[0]
828+ else:
829+ r_pl_acc = acc_cache.get((line[cols['Asset P&L Depreciation Account']], 'pl'), False)
830+
831+ vals = {
832+ 'external_asset_id': line[cols['External Asset ID']] or '',
833+ 'prod_int_code': line[cols['Product Code']],
834+ 'product_id': r_prod,
835+ 'asset_type_id': r_asset_type,
836+ 'useful_life_id': r_use_life,
837+ 'serial_nb': line[cols['Serial Number']] or '',
838+ 'brand': line[cols['Brand']],
839+ 'type': line[cols['Type']] or '',
840+ 'model': line[cols['Model']] or '',
841+ 'year': line[cols['Year']] or '',
842+ 'move_line_id': r_ji,
843+ 'asset_bs_depreciation_account_id': r_bs_acc,
844+ 'asset_pl_account_id': r_pl_acc,
845+ 'wizard_id': wiz.id,
846+ }
847+
848+ if not errors:
849+ line_res = self.pool.get('product.asset.import.entries.lines').create(cr, uid, vals, context=context)
850+ if not line_res:
851+ errors.append(_('Line %s: A problem occurred for line registration. Please contact an Administrator.') % (current_line_num,))
852+ continue
853+ created += 1
854+
855+ # Update wizard
856+ self.write(cr, uid, ids,
857+ {'message': _('Check complete. Reading potential errors or write needed changes.'),
858+ 'progression': 100.0})
859+
860+ wiz_state = 'done'
861+ # If errors, cancel probable modifications
862+ if errors:
863+ cr.rollback()
864+ created = 0
865+ message = _('Import FAILED.')
866+ # Delete old errors
867+ error_ids = self.pool.get('product.asset.import.entries.errors').search(cr, uid, [], context)
868+ if error_ids:
869+ self.pool.get('product.asset.import.entries.errors').unlink(cr, uid, error_ids, context)
870+ # create errors lines
871+ for e in errors:
872+ self.pool.get('product.asset.import.entries.errors').create(cr, uid,
873+ {'wizard_id': wiz.id, 'name': e},
874+ context)
875+ wiz_state = 'error'
876+ else:
877+ # Update wizard
878+ self.write(cr, uid, ids, {'message': _('Writing changes...'), 'progression': 0.0})
879+ # Create all asset entries
880+ import_lines_ids = self.pool.get('product.asset.import.entries.lines').search(cr, uid, [('wizard_id', '=', wiz.id)], context=context)
881+ import_lines = self.pool.get('product.asset.import.entries.lines').browse(cr, uid, import_lines_ids, context=context)
882+ context.update({'from_import': True})
883+ try:
884+ for asset in import_lines:
885+ asset_vals = {
886+ 'external_asset_id': asset.external_asset_id,
887+ 'prod_int_code': asset.prod_int_code,
888+ 'product_id': asset.product_id.id,
889+ 'asset_type_id': asset.asset_type_id.id,
890+ 'useful_life_id': asset.useful_life_id.id,
891+ 'serial_nb': asset.serial_nb,
892+ 'brand': asset.brand,
893+ 'type': asset.type,
894+ 'model': asset.model,
895+ 'year': asset.year,
896+ 'move_line_id': asset.move_line_id.id,
897+ 'asset_bs_depreciation_account_id': asset.asset_bs_depreciation_account_id.id,
898+ 'asset_pl_account_id': asset.asset_pl_account_id.id,
899+ }
900+ asset_id = self.pool.get('product.asset').create(cr, uid, asset_vals, context=context)
901+ message = _('Import successful.')
902+ except osv.except_osv as osv_error:
903+ cr.rollback()
904+ self.write(cr, uid, ids,
905+ {'message': _("An error occurred. %s: %s") % (osv_error.name, osv_error.value,),
906+ 'state': 'done', 'progression': 100.0})
907+ cr.close(True)
908+
909+ # Update wizard
910+ self.write(cr, uid, ids, {'message': message, 'state': wiz_state, 'progression': 100.0})
911+
912+ # Close cursor
913+ cr.commit()
914+ cr.close(True)
915+
916+ except osv.except_osv as osv_error:
917+ cr.rollback()
918+ self.write(cr, uid, ids, {'message': _("An error occurred. %s: %s") % (osv_error.name, osv_error.value,), 'state': 'done', 'progression': 100.0})
919+ cr.close(True)
920+ except Exception as e:
921+ cr.rollback()
922+ if current_line_num is not None:
923+ message = _("An error occurred on line %s: %s") % (current_line_num, e.args and e.args[0] or '')
924+ else:
925+ message = _("An error occurred: %s") % (e.args and e.args[0] or '',)
926+ self.write(cr, uid, ids, {'message': message, 'state': 'done', 'progression': 100.0})
927+ cr.close(True)
928+ return True
929+
930+ def button_validate(self, cr, uid, ids, context=None):
931+ """
932+ Launch process in a thread and return a wizard
933+ """
934+ if not context:
935+ context = {}
936+ thread = threading.Thread(target=self._import, args=(cr.dbname, uid, ids, context))
937+ thread.start()
938+ return self.write(cr, uid, ids, {'state': 'inprogress'}, context=context)
939+
940+ def button_update(self, cr, uid, ids, context=None):
941+ """
942+ Update view
943+ """
944+ return False
945+
946+
947+product_asset_import_entries()
948+
949+
950+class product_asset_import_entries_lines(osv.osv):
951+ _name = 'product.asset.import.entries.lines'
952+
953+ _columns = {
954+ 'external_asset_id': fields.char('External Asset ID', size=32, readonly=True),
955+ 'prod_int_code': fields.char('Product Code', size=128, readonly=True, required=True),
956+ 'product_id': fields.many2one('product.product', 'Product', required=True),
957+ 'asset_type_id': fields.many2one('product.asset.type', 'Asset Type', readonly=True, required=True),
958+ 'useful_life_id': fields.many2one('product.asset.useful.life', 'Useful Life', ondelete='restrict', readonly=True, required=True),
959+ 'serial_nb': fields.char('Serial Number', size=128, readonly=True),
960+ 'brand': fields.char('Brand', size=128, readonly=True),
961+ 'type': fields.char('Type', size=128, readonly=True),
962+ 'model': fields.char('Model', size=128, readonly=True),
963+ 'year': fields.char('Year', size=4, readonly=True),
964+ 'move_line_id': fields.many2one('account.move.line', 'Journal Item', readonly=True),
965+ 'asset_bs_depreciation_account_id': fields.many2one('account.account', 'Asset B/S Depreciation Account', readonly=True),
966+ 'asset_pl_account_id': fields.many2one('account.account', 'Asset P&L Depreciation Account', readonly=True),
967+ 'wizard_id': fields.integer("Wizard", required=True, readonly=True),
968+ }
969+
970+
971+product_asset_import_entries_lines()
972+
973+
974+class product_asset_import_entries_errors(osv.osv_memory):
975+ _name = 'product.asset.import.entries.errors'
976+ _description = 'Asset Entries Import - Error List'
977+
978+ _columns = {
979+ 'name': fields.text("Description", readonly=True, required=True),
980+ 'wizard_id': fields.many2one('product.asset.import.entries', "Wizard", required=True, readonly=True),
981+ }
982+
983+
984+product_asset_import_entries_errors()
985+
986+
987 #----------------------------------------------------------
988 # Products
989 #----------------------------------------------------------
990
991=== modified file 'bin/addons/product_asset/product_asset_view.xml'
992--- bin/addons/product_asset/product_asset_view.xml 2024-03-13 13:36:47 +0000
993+++ bin/addons/product_asset/product_asset_view.xml 2024-05-10 12:38:34 +0000
994@@ -68,7 +68,10 @@
995 <field name="arch" type="xml">
996 <form string="Asset">
997 <field name="name" />
998- <field name="instance_id" readonly='1'/>
999+ <group colspan="2" col="4">
1000+ <field name="external_asset_id" attrs="{'readonly': ['|', ('lock_open', '=', True), ('state', 'not in', ['draft', 'open'])]}"/>
1001+ <field name="instance_id" readonly='1'/>
1002+ </group>
1003 <field name="journal_id" />
1004 <group colspan="2" col="4">
1005 <field name="asset_type_id" on_change="change_asset_type_id(asset_type_id, useful_life_id)" required="1" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'open']), ('lock_open', '!=', False)]}" />
1006@@ -112,11 +115,11 @@
1007
1008 <group colspan="2" col="4">
1009 <separator string="Invoice" colspan="4" />
1010- <field name="move_line_id" colspan="4" attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('from_invoice', '=', True)]}" on_change="change_invo_date(move_line_id, product_id)" />
1011+ <field name="move_line_id" required="1" colspan="4" attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('from_invoice', '=', True)]}" on_change="change_invo_date(move_line_id, product_id)" />
1012 <field name="quantity_divisor" attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('from_invoice', '=', True)]}" on_change="change_quantity_divisor(quantity_divisor, move_line_id)"/>
1013- <field name="invo_value" />
1014- <field name="invo_currency" />
1015- <field name="invo_date" />
1016+ <field name="invo_value" required="1"/>
1017+ <field name="invo_currency" required="1"/>
1018+ <field name="invo_date" required="1"/>
1019 <field name="invo_supplier_id" colspan="4" />
1020 <field name="invo_donator_code" colspan="4" attrs="{'readonly': ['|', ('lock_open', '=', True), ('state', 'in', ['cancel', 'done'])]}"/>
1021 <field name="invo_certif_depreciation" colspan="4" attrs="{'readonly': ['|', ('lock_open', '=', True), ('state', 'in', ['cancel', 'done'])]}"/>
1022@@ -141,8 +144,8 @@
1023 </group>
1024 </page>
1025 <page string="Depreciation">
1026- <field name="start_date" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'open']), ('lock_open', '!=', False)]}" />
1027- <field name="depreciation_method" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'open']), ('lock_open', '!=', False)]}"/>
1028+ <field name="start_date" required="1" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'open']), ('lock_open', '!=', False)]}" />
1029+ <field name="depreciation_method" required="1" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'open']), ('lock_open', '!=', False)]}"/>
1030 <newline />
1031 <field name="depreciation_amount" />
1032 <field name="disposal_amount" />
1033@@ -585,6 +588,82 @@
1034
1035 <menuitem sequence="200" action="action_product_asset_generate_entries" id="menu_product_asset_generate_entries" parent="product_asset.menu_asset_sales" />
1036
1037+ <record id="view_product_asset_import_entries" model="ir.ui.view">
1038+ <field name="name">product.asset.import.entries.form</field>
1039+ <field name="model">product.asset.import.entries</field>
1040+ <field name="type">form</field>
1041+ <field name="arch" type="xml">
1042+ <form string="Import Asset Entries">
1043+ <separator string="This will import Entries from an XML file." colspan="4"/>
1044+ <field name="file" filename="filename" attrs="{'invisible': [('state', '!=', 'draft')]}"/>
1045+ <field name="filename" invisible="1"/>
1046+ <field name="progression" widget="progressbar" nolabel="1" attrs="{'invisible': [('state', '=', 'draft')]}" colspan="4" />
1047+ <field name="message" nolabel="1" attrs="{'invisible': [('state', '=', 'draft')]}"/>
1048+ <newline/>
1049+ <button name="button_update" type="object" string="Update" icon="gtk-refresh" attrs="{'invisible': [('state', '!=', 'inprogress')]}"/>
1050+ <newline />
1051+ <field name="error_ids" nolabel="1" attrs="{'invisible': [('state', '!=', 'error')]}"/>
1052+ <group col="4" colspan="4" attrs="{'invisible': [('state', '!=', 'draft')]}">
1053+ <separator string="Import template"/>
1054+ <newline />
1055+ <html>
1056+ <br />
1057+ <table style="margin: 0 auto;">
1058+ <thead>
1059+ <tr style='background-color: #ccc;font-size:1.2em;'>
1060+ <th class='external_asset_id' style='border: thin solid black; text-transform: none;'>External Asset ID</th>
1061+ <th class='prod_int_code' style='border: thin solid black; font-weigth:bold; border-left: none; text-transform: none;'>Product Code</th>
1062+ <th class='asset_type_id' style='border: thin solid black; font-weigth:bold; border-left: none; text-transform: none;'>Asset Type</th>
1063+ <th class='useful_life_id' style='border: thin solid black; font-weigth:bold; border-left: none; text-transform: none;'>Useful Life</th>
1064+ <th class='serial_nb' style="border: thin solid black; border-left: none; text-transform: none;">Serial Number</th>
1065+ <th class='brand' style='border: thin solid black; border-left: none; text-transform: none;'>Brand</th>
1066+ <th class='type' style='border: thin solid black; border-left: none; text-transform: none;'>Type</th>
1067+ <th class='model' style='border: thin solid black; border-left: none; text-transform: none;'>Model</th>
1068+ <th class='year' style='border: thin solid black; border-left: none; text-transform: none;'>Year</th>
1069+ <th class='move_line_id' style='border: thin solid black; border-left: none; text-transform: none;'>Journal Item</th>
1070+ <th class='asset_bs_depreciation_account_id' style='border: thin solid black; border-left: none; text-transform: none;'>Asset B/S Depreciation Account</th>
1071+ <th class='asset_pl_account_id' style='border: thin solid black; border-left: none; text-transform: none;'>Asset P&amp;L Depreciation Account</th>
1072+ </tr>
1073+ </thead>
1074+ <tbody>
1075+ <tr>
1076+ <th style="border: thin solid black; border-top: none;"></th>
1077+ <th style="border: thin solid black; color:red; font-weigth:bold; font-size:1.2em; border-left: none; border-top: none;">Mandatory</th>
1078+ <th style="border: thin solid black; color:red; font-weigth:bold; font-size:1.2em; border-left: none; border-top: none;">Mandatory</th>
1079+ <th style="border: thin solid black; color:red; font-weigth:bold; font-size:1.2em; border-left: none; border-top: none;">Mandatory</th>
1080+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1081+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1082+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1083+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1084+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1085+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1086+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1087+ <th style="border: thin solid black; border-left: none; border-top: none;"></th>
1088+ </tr>
1089+ </tbody>
1090+ </table>
1091+ <br />
1092+ </html>
1093+ </group>
1094+ <group colspan="4" col="2" attrs="{'invisible': [('state', '!=', 'draft')]}">
1095+ <button string="Cancel" special="cancel" icon="gtk-cancel"/>
1096+ <button name="button_validate" type="object" string="Import" icon="terp-camera_test"/>
1097+ </group>
1098+ <field name="state" invisible="1"/>
1099+ </form>
1100+ </field>
1101+ </record>
1102+
1103+ <record id="action_product_asset_import_entries" model="ir.actions.act_window">
1104+ <field name="name">Import Asset Entries</field>
1105+ <field name="res_model">product.asset.import.entries</field>
1106+ <field name="view_type">form</field>
1107+ <field name="view_mode">form</field>
1108+ <field name="target">new</field>
1109+ </record>
1110+
1111+ <menuitem sequence="300" action="action_product_asset_import_entries" id="menu_product_asset_import_entries" parent="product_asset.menu_asset_sales" />
1112+
1113
1114
1115 </data>

Subscribers

People subscribed via source and target branches