Merge lp:~julie-w/unifield-server/US-6766 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 5682
Proposed branch: lp:~julie-w/unifield-server/US-6766
Merge into: lp:unifield-server
Diff against target: 1339 lines (+833/-25)
12 files modified
bin/addons/account/__openerp__.py (+1/-0)
bin/addons/account/account_report.xml (+12/-0)
bin/addons/account/report/__init__.py (+1/-0)
bin/addons/account/report/export_invoice.mako (+171/-0)
bin/addons/account/report/export_invoice.py (+58/-0)
bin/addons/account/wizard/__init__.py (+1/-0)
bin/addons/account/wizard/account_invoice_import.py (+300/-0)
bin/addons/account/wizard/account_invoice_import.xml (+48/-0)
bin/addons/account_override/account_invoice_view.xml (+14/-4)
bin/addons/account_override/invoice.py (+27/-0)
bin/addons/msf_profile/i18n/fr_MF.po (+191/-19)
bin/addons/register_accounting/account_invoice_view.xml (+9/-2)
To merge this branch: bzr merge lp:~julie-w/unifield-server/US-6766
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+382986@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/account/__openerp__.py'
2--- bin/addons/account/__openerp__.py 2019-10-10 15:06:49 +0000
3+++ bin/addons/account/__openerp__.py 2020-04-27 09:12:30 +0000
4@@ -85,6 +85,7 @@
5 'wizard/account_reconcile_view.xml',
6 'wizard/account_reconcile_partner_process_view.xml',
7 'wizard/account_automatic_reconcile_view.xml',
8+ 'wizard/account_invoice_import.xml',
9 'project/wizard/project_account_analytic_line_view.xml',
10 'account_end_fy.xml',
11 'account_invoice_view.xml',
12
13=== modified file 'bin/addons/account/account_report.xml'
14--- bin/addons/account/account_report.xml 2020-04-06 16:32:38 +0000
15+++ bin/addons/account/account_report.xml 2020-04-27 09:12:30 +0000
16@@ -165,5 +165,17 @@
17 ('name', '=', 'Invoice Excel Export')]]" />
18 <value eval="{'sequence': 97}" />
19 </function>
20+
21+ <!-- Export Invoice report -->
22+ <report id="export_invoice"
23+ string="Export - Invoice"
24+ target_filename="Export - Invoice"
25+ model="account.invoice"
26+ name="account.export_invoice"
27+ file="account/report/export_invoice.mako"
28+ report_type="webkit"
29+ header="False"
30+ auto="False"
31+ menu="False"/>
32 </data>
33 </openerp>
34
35=== modified file 'bin/addons/account/report/__init__.py'
36--- bin/addons/account/report/__init__.py 2020-04-03 14:03:55 +0000
37+++ bin/addons/account/report/__init__.py 2020-04-27 09:12:30 +0000
38@@ -43,6 +43,7 @@
39 import account_liquidity_balance
40 import free_allocation_report
41 import invoice_excel_export
42+import export_invoice
43
44 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
45
46
47=== added file 'bin/addons/account/report/export_invoice.mako'
48--- bin/addons/account/report/export_invoice.mako 1970-01-01 00:00:00 +0000
49+++ bin/addons/account/report/export_invoice.mako 2020-04-27 09:12:30 +0000
50@@ -0,0 +1,171 @@
51+<?xml version="1.0"?>
52+<?mso-application progid="Excel.Sheet"?>
53+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
54+ xmlns:o="urn:schemas-microsoft-com:office:office"
55+ xmlns:x="urn:schemas-microsoft-com:office:excel"
56+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
57+ xmlns:html="http://www.w3.org/TR/REC-html40">
58+ <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
59+ <Title>${_('Export - Invoice')}</Title>
60+ </DocumentProperties>
61+ <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
62+ <WindowHeight>13170</WindowHeight>
63+ <WindowWidth>19020</WindowWidth>
64+ <WindowTopX>120</WindowTopX>
65+ <WindowTopY>60</WindowTopY>
66+ <ProtectStructure>False</ProtectStructure>
67+ <ProtectWindows>False</ProtectWindows>
68+ </ExcelWorkbook>
69+<Styles>
70+ <Style ss:ID="editable">
71+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
72+ <Borders>
73+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
74+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
75+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
76+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
77+ </Borders>
78+ <Protection ss:Protected="0"/>
79+ </Style>
80+ <Style ss:ID="editable_number">
81+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
82+ <Borders>
83+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
84+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
85+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
86+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
87+ </Borders>
88+ <NumberFormat ss:Format="Standard"/>
89+ <Protection ss:Protected="0"/>
90+ </Style>
91+ <Style ss:ID="non_editable">
92+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
93+ <Interior ss:Color="#ffcc99" ss:Pattern="Solid"/>
94+ <Borders>
95+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
96+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
97+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
98+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
99+ </Borders>
100+ <Protection/>
101+ </Style>
102+ <Style ss:ID="non_editable_number">
103+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
104+ <Interior ss:Color="#ffcc99" ss:Pattern="Solid"/>
105+ <Borders>
106+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
107+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
108+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
109+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
110+ </Borders>
111+ <NumberFormat ss:Format="Standard"/>
112+ <Protection/>
113+ </Style>
114+ <Style ss:ID="non_editable_date">
115+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
116+ <Interior ss:Color="#ffcc99" ss:Pattern="Solid"/>
117+ <Borders>
118+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
119+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
120+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
121+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
122+ </Borders>
123+ <NumberFormat ss:Format="Short Date"/>
124+ <Protection/>
125+ </Style>
126+</Styles>
127+% for o in objects:
128+<!-- Sheet must be protected otherwise the protection on the cells has no effect -->
129+<!-- Default Sheet name is "Sheet1" (we can export only one inv. at a time) -->
130+<ss:Worksheet ss:Name="${o.number or "%s%s" % (_('Sheet'), 1)|x}" ss:Protected="1">
131+<Table x:FullColumns="1" x:FullRows="1">
132+ <Column ss:AutoFitWidth="1" ss:Width="100"/>
133+ <Column ss:AutoFitWidth="1" ss:Width="250"/>
134+ <Column ss:AutoFitWidth="1" ss:Width="100"/>
135+ <Column ss:AutoFitWidth="1" ss:Width="150" ss:Span="1"/>
136+
137+ <Row>
138+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Number')}</Data></Cell>
139+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${o.number or ''|x}</Data></Cell>
140+ </Row>
141+ <Row>
142+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Journal')}</Data></Cell>
143+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${o.journal_id.code|x}</Data></Cell>
144+ </Row>
145+ <Row>
146+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Currency')}</Data></Cell>
147+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${o.currency_id.name|x}</Data></Cell>
148+ </Row>
149+ <Row>
150+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Partner')}</Data></Cell>
151+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${o.partner_id.name|x}</Data></Cell>
152+ </Row>
153+ <Row>
154+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Document Date')}</Data></Cell>
155+ <Cell ss:StyleID="non_editable_date"><Data ss:Type="DateTime">${o.document_date or False|n}T00:00:00.000</Data></Cell>
156+ </Row>
157+ <Row>
158+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Posting Date')}</Data></Cell>
159+ <Cell ss:StyleID="non_editable_date"><Data ss:Type="DateTime">${o.date_invoice or False|n}T00:00:00.000</Data></Cell>
160+ </Row>
161+ <Row>
162+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Account')}</Data></Cell>
163+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${o.account_id.code|x}</Data></Cell>
164+ </Row>
165+
166+ <Row><Cell ss:StyleID="editable"><Data ss:Type="String"></Data></Cell></Row>
167+
168+ <Row>
169+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Line number')}</Data></Cell>
170+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Product')}</Data></Cell>
171+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Account')}</Data></Cell>
172+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Quantity')}</Data></Cell>
173+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${_('Unit Price')}</Data></Cell>
174+ </Row>
175+
176+ <% is_ro = is_readonly(o) %>
177+ % for inv_line in o.invoice_line:
178+ <Row>
179+ <Cell ss:StyleID="non_editable"><Data ss:Type="String">${inv_line.line_number or ''|x}</Data></Cell>
180+ % if is_ro:
181+ <Cell ss:StyleID="non_editable">
182+ % else:
183+ <Cell ss:StyleID="editable">
184+ % endif
185+ <Data ss:Type="String">${inv_line.product_id and inv_line.product_id.default_code or ''|x}</Data></Cell>
186+
187+ <Cell ss:StyleID="editable"><Data ss:Type="String">${inv_line.account_id.code|x}</Data></Cell>
188+
189+ % if is_ro:
190+ <Cell ss:StyleID="non_editable_number">
191+ % else:
192+ <Cell ss:StyleID="editable_number">
193+ % endif
194+ <Data ss:Type="Number">${inv_line.quantity|x}</Data></Cell>
195+
196+ <Cell ss:StyleID="editable_number"><Data ss:Type="Number">${inv_line.price_unit|x}</Data></Cell>
197+ </Row>
198+ % endfor
199+
200+</Table>
201+<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
202+ <FitToPage/>
203+ <PageSetup>
204+ <Layout x:Orientation="Portrait"/>
205+ <Header x:Margin="0.4921259845"/>
206+ <Footer x:Margin="0.4921259845"/>
207+ <PageMargins x:Bottom="0.984251969" x:Left="0.78740157499999996" x:Right="0.78740157499999996" x:Top="0.984251969"/>
208+ </PageSetup>
209+ <Print>
210+ <ValidPrinterInfo/>
211+ <PaperSizeIndex>9</PaperSizeIndex>
212+ <HorizontalResolution>600</HorizontalResolution>
213+ <VerticalResolution>600</VerticalResolution>
214+ </Print>
215+ <Selected/>
216+ <ProtectObjects>False</ProtectObjects>
217+ <ProtectScenarios>False</ProtectScenarios>
218+</WorksheetOptions>
219+</ss:Worksheet>
220+% endfor
221+</Workbook>
222
223=== added file 'bin/addons/account/report/export_invoice.py'
224--- bin/addons/account/report/export_invoice.py 1970-01-01 00:00:00 +0000
225+++ bin/addons/account/report/export_invoice.py 2020-04-27 09:12:30 +0000
226@@ -0,0 +1,58 @@
227+# -*- coding: utf-8 -*-
228+##############################################################################
229+#
230+# OpenERP, Open Source Management Solution
231+# Copyright (C) 2020 TeMPO Consulting, MSF. All Rights Reserved
232+#
233+# This program is free software: you can redistribute it and/or modify
234+# it under the terms of the GNU Affero General Public License as
235+# published by the Free Software Foundation, either version 3 of the
236+# License, or (at your option) any later version.
237+#
238+# This program is distributed in the hope that it will be useful,
239+# but WITHOUT ANY WARRANTY; without even the implied warranty of
240+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
241+# GNU Affero General Public License for more details.
242+#
243+# You should have received a copy of the GNU Affero General Public License
244+# along with this program. If not, see <http://www.gnu.org/licenses/>.
245+#
246+##############################################################################
247+
248+from report import report_sxw
249+from spreadsheet_xml.spreadsheet_xml_write import SpreadsheetReport
250+
251+
252+def is_readonly(self, inv):
253+ """
254+ Returns True if the fields Product and Quantity of the invoice must be readonly = not editable
255+ """
256+ if inv.type == 'in_invoice' and not inv.is_direct_invoice and not inv.is_inkind_donation: # IVI or SI
257+ is_readonly = inv.from_supply or inv.synced
258+ elif inv.type == 'out_invoice' and inv.is_intermission: # IVO
259+ is_readonly = inv.from_supply
260+ elif inv.type == 'out_invoice' and not inv.is_intermission and not inv.is_debit_note: # STV
261+ is_readonly = inv.from_supply and inv.partner_type == 'section'
262+ else: # other inv. types are not supposed to be handled in this report
263+ is_readonly = True
264+ return is_readonly
265+
266+
267+class export_invoice(report_sxw.rml_parse):
268+
269+ def __init__(self, cr, uid, name, context=None):
270+ super(export_invoice, self).__init__(cr, uid, name, context=context)
271+ self.localcontext.update({
272+ 'is_readonly': self.is_readonly,
273+ })
274+
275+ def is_readonly(self, inv):
276+ """
277+ Returns True if the fields Product and Quantity of the invoice must be readonly = not editable
278+ """
279+ return is_readonly(self, inv)
280+
281+
282+SpreadsheetReport('report.account.export_invoice', 'account.invoice',
283+ 'addons/account/report/export_invoice.mako', parser=export_invoice)
284+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
285
286=== modified file 'bin/addons/account/wizard/__init__.py'
287--- bin/addons/account/wizard/__init__.py 2019-07-24 14:20:02 +0000
288+++ bin/addons/account/wizard/__init__.py 2020-04-27 09:12:30 +0000
289@@ -66,6 +66,7 @@
290 import account_report_liquidity_balance
291
292 import free_allocation_wizard
293+import account_invoice_import
294 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
295
296
297
298=== added file 'bin/addons/account/wizard/account_invoice_import.py'
299--- bin/addons/account/wizard/account_invoice_import.py 1970-01-01 00:00:00 +0000
300+++ bin/addons/account/wizard/account_invoice_import.py 2020-04-27 09:12:30 +0000
301@@ -0,0 +1,300 @@
302+#!/usr/bin/env python
303+#-*- encoding:utf-8 -*-
304+##############################################################################
305+#
306+# OpenERP, Open Source Management Solution
307+# Copyright (C) TeMPO Consulting (<http://www.tempo-consulting.fr/>), MSF.
308+# All Rights Reserved
309+#
310+# This program is free software: you can redistribute it and/or modify
311+# it under the terms of the GNU Affero General Public License as
312+# published by the Free Software Foundation, either version 3 of the
313+# License, or (at your option) any later version.
314+#
315+# This program is distributed in the hope that it will be useful,
316+# but WITHOUT ANY WARRANTY; without even the implied warranty of
317+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
318+# GNU Affero General Public License for more details.
319+#
320+# You should have received a copy of the GNU Affero General Public License
321+# along with this program. If not, see <http://www.gnu.org/licenses/>.
322+#
323+##############################################################################
324+
325+from osv import osv
326+from osv import fields
327+from tools.translate import _
328+from tempfile import NamedTemporaryFile
329+from base64 import decodestring
330+from spreadsheet_xml.spreadsheet_xml import SpreadsheetXML
331+from account.report import export_invoice
332+from datetime import datetime
333+import threading
334+import pooler
335+import logging
336+import tools
337+
338+
339+class account_invoice_import(osv.osv_memory):
340+ _name = 'account.invoice.import'
341+
342+ _columns = {
343+ 'file': fields.binary(string="File", filters='*.xml, *.xls', required=True),
344+ 'filename': fields.char(string="Imported filename", size=256),
345+ 'progression': fields.float(string="Progression", readonly=True),
346+ 'message': fields.char(string="Message", size=256, readonly=True),
347+ 'state': fields.selection([('draft', 'Created'), ('inprogress', 'In Progress'), ('error', 'Error'), ('done', 'Done')],
348+ string="State", readonly=True, required=True),
349+ 'error_ids': fields.one2many('account.invoice.import.errors', 'wizard_id', "Errors", readonly=True),
350+ 'invoice_id': fields.many2one('account.invoice', 'Invoice', required=True, readonly=True),
351+ }
352+
353+ _defaults = {
354+ 'progression': lambda *a: 0.0,
355+ 'state': lambda *a: 'draft',
356+ }
357+
358+ def _import(self, dbname, uid, ids, context=None):
359+ """
360+ Checks file data, and either updates the lines or displays the errors found
361+ """
362+ if context is None:
363+ context = {}
364+ cr = pooler.get_db(dbname).cursor()
365+ errors = []
366+ invoice_obj = self.pool.get('account.invoice')
367+ invoice_line_obj = self.pool.get('account.invoice.line')
368+ currency_obj = self.pool.get('res.currency')
369+ partner_obj = self.pool.get('res.partner')
370+ account_obj = self.pool.get('account.account')
371+ product_obj = self.pool.get('product.product')
372+ import_cell_data_obj = self.pool.get('import.cell.data')
373+ errors_obj = self.pool.get('account.invoice.import.errors')
374+
375+ try:
376+ for wiz in self.browse(cr, uid, ids, context):
377+ self.write(cr, uid, [wiz.id], {'message': _('Checking file…'), 'progression': 1.00}, context)
378+ if not wiz.file:
379+ raise osv.except_osv(_('Error'), _('Nothing to import.'))
380+ fileobj = NamedTemporaryFile('w+b', delete=False)
381+ fileobj.write(decodestring(wiz.file))
382+ fileobj.close()
383+ content = SpreadsheetXML(xmlfile=fileobj.name, context=context)
384+ if not content:
385+ raise osv.except_osv(_('Warning'), _('No content.'))
386+ invoice = wiz.invoice_id
387+ if invoice.state != 'draft':
388+ raise osv.except_osv(_('Warning'), _('The import is allowed only in Draft state.'))
389+ rows = content.getRows()
390+ nb_rows = len([x for x in content.getRows()])
391+ self.write(cr, uid, [wiz.id], {'message': _('Checking header…'), 'progression': 5.00}, context)
392+ # indexes of the file columns:
393+ cols = {
394+ 'line_number': 0,
395+ 'product': 1,
396+ 'account': 2,
397+ 'quantity': 3,
398+ 'unit_price': 4,
399+ }
400+ # number of the first line in the file containing data (not header)
401+ base_num = 10
402+ rows.next() # number is ignored
403+ rows.next() # journal is ignored
404+ currency_line = import_cell_data_obj.get_line_values(cr, uid, ids, rows.next())
405+ try:
406+ currency_name = currency_line[1]
407+ except IndexError, e:
408+ raise osv.except_osv(_('Warning'), _('No currency found.'))
409+ currency_ids = currency_obj.search(cr, uid,
410+ [('name', '=', currency_name), ('currency_table_id', '=', False),
411+ ('active', '=', True)], limit=1, context=context)
412+ if not currency_ids:
413+ raise osv.except_osv(_('Error'), _("Currency %s not found or inactive.") % (currency_name or '',))
414+ partner_line = import_cell_data_obj.get_line_values(cr, uid, ids, rows.next())
415+ try:
416+ partner_name = partner_line[1]
417+ except IndexError, e:
418+ raise osv.except_osv(_('Warning'), _('No partner found.'))
419+ partner_ids = partner_obj.search(cr, uid, [('name', '=', partner_name), ('active', '=', True)], context=context)
420+ if not partner_ids:
421+ raise osv.except_osv(_('Error'), _("Partner %s not found or inactive.") % (partner_name or '',))
422+ rows.next() # document date is ignored
423+ posting_date_line = import_cell_data_obj.get_line_values(cr, uid, ids, rows.next())
424+ try:
425+ posting_date = posting_date_line[1] or False
426+ except IndexError, e:
427+ posting_date = False
428+ if posting_date:
429+ try:
430+ posting_date = posting_date.strftime('%Y-%m-%d')
431+ except AttributeError, e:
432+ raise osv.except_osv(_('Warning'), _("The posting date has a wrong format."))
433+ invoice_dom = [('id', '=', invoice.id),
434+ ('currency_id', '=', currency_ids[0]),
435+ ('partner_id', '=', partner_ids[0]),
436+ ('date_invoice', '=', posting_date)]
437+ if not invoice_obj.search_exist(cr, uid, invoice_dom, context=context):
438+ raise osv.except_osv(_('Warning'),
439+ _("The combination \"Currency, Partner and Posting Date\" of the imported file "
440+ "doesn't match with the current invoice."))
441+ # ignore: header account, empty line, line with titles
442+ for i in range(3):
443+ rows.next()
444+ header_percent = 10 # percentage of the process reached AFTER having checked the header
445+ self.write(cr, uid, [wiz.id], {'message': _('Checking lines…'), 'progression': header_percent}, context)
446+ lines_percent = 99 # % of the process to be reached AFTER having checked and updated the lines
447+ # use the method from export_invoice to determine whether the product and quantity columns are editable
448+ all_fields_editable = not export_invoice.is_readonly(self, invoice)
449+ # check the lines
450+ for num, r in enumerate(rows):
451+ current_line_num = num + base_num
452+ vals = {}
453+ line = import_cell_data_obj.get_line_values(cr, uid, ids, r)
454+ line.extend([False for i in range(len(cols) - len(line))])
455+ # get the data
456+ line_number = line[cols['line_number']] and tools.ustr(line[cols['line_number']])
457+ product_code = line[cols['product']] and tools.ustr(line[cols['product']])
458+ account_code = line[cols['account']] and tools.ustr(line[cols['account']])
459+ quantity = line[cols['quantity']] or 0.0
460+ unit_price = line[cols['unit_price']] or 0.0
461+ if not line_number:
462+ errors.append(_('Line %s: the line number is missing.') % (current_line_num,))
463+ continue
464+ invoice_line_dom = [('invoice_id', '=', invoice.id), ('line_number', '=', line_number)]
465+ invoice_line_ids = invoice_line_obj.search(cr, uid, invoice_line_dom, limit=1, context=context)
466+ if not invoice_line_ids:
467+ errors.append(_("Line %s: the line number %s doesn't exist in the invoice.") % (current_line_num, line_number))
468+ continue
469+ if not account_code:
470+ errors.append(_("Line %s: the account (mandatory) is missing.") % (current_line_num,))
471+ continue
472+ account_ids = account_obj.search(cr, uid, [('code', '=', account_code)], limit=1, context=context)
473+ if not account_ids:
474+ errors.append(_("Line %s: the account %s doesn't exist.") % (current_line_num, account_code))
475+ continue
476+ account = account_obj.browse(cr, uid, account_ids[0], fields_to_fetch=['activation_date', 'inactivation_date'],
477+ context=context)
478+ checking_date = posting_date or datetime.now().strftime('%Y-%m-%d')
479+ if checking_date < account.activation_date or (account.inactivation_date and checking_date >= account.inactivation_date):
480+ errors.append(_("Line %s: the account %s is inactive.") % (current_line_num, account_code))
481+ continue
482+ # restricted_area = accounts allowed. Note: the context is different for each type and used in the related fnct_search
483+ if invoice.is_intermission:
484+ restricted_area = 'intermission_lines' # for IVI / IVO
485+ else:
486+ restricted_area = 'invoice_lines' # for SI / STV
487+ if not account_obj.search_exist(cr, uid, [('id', '=', account.id), ('restricted_area', '=', restricted_area)],
488+ context=context):
489+ errors.append(_("Line %s: the account %s is not allowed.") % (current_line_num, account_code))
490+ continue
491+ vals['account_id'] = account.id
492+ try:
493+ unit_price = float(unit_price)
494+ except ValueError, e:
495+ errors.append(_("Line %s: the unit price format is incorrect.") % (current_line_num,))
496+ continue
497+ vals['price_unit'] = unit_price
498+ # edit the Product and Quantity only if it is allowed
499+ if all_fields_editable:
500+ if not product_code:
501+ vals['product_id'] = False # delete the existing value
502+ else:
503+ product_ids = product_obj.search(cr, uid, [('default_code', '=', product_code), ('active', '=', True)],
504+ limit=1, context=context)
505+ if not product_ids:
506+ errors.append(_("Line %s: the product %s doesn't exist or is inactive.") % (current_line_num, product_code))
507+ continue
508+ vals['product_id'] = product_ids[0]
509+ try:
510+ quantity = float(quantity)
511+ except ValueError, e:
512+ errors.append(_("Line %s: the quantity format is incorrect.") % (current_line_num,))
513+ continue
514+ vals['quantity'] = quantity
515+ # update the line
516+ invoice_line_obj.write(cr, uid, invoice_line_ids[0], vals, context=context)
517+ # update the percent
518+ if current_line_num == nb_rows:
519+ self.write(cr, uid, [wiz.id], {'progression': lines_percent}, context)
520+ elif current_line_num % 5 == 0: # refresh every 5 lines
521+ self.write(cr, uid, [wiz.id],
522+ {'progression': header_percent + (current_line_num / float(nb_rows) * (lines_percent - header_percent))},
523+ context)
524+ wiz_state = 'done'
525+ # cancel the process in case of errors
526+ if errors:
527+ cr.rollback()
528+ message = _('Import FAILED.')
529+ # delete old errors and create new ones
530+ error_ids = errors_obj.search(cr, uid, [], context)
531+ if error_ids:
532+ errors_obj.unlink(cr, uid, error_ids, context)
533+ for e in errors:
534+ errors_obj.create(cr, uid, {'wizard_id': wiz.id, 'name': e}, context)
535+ wiz_state = 'error'
536+ else:
537+ message = _('Import successful.')
538+ # 100% progression
539+ self.write(cr, uid, ids, {'message': message, 'state': wiz_state, 'progression': 100.0}, context)
540+ cr.commit()
541+ cr.close(True)
542+ except osv.except_osv as osv_error:
543+ logging.getLogger('account.invoice.import').warn('OSV Exception', exc_info=True)
544+ cr.rollback()
545+ self.write(cr, uid, ids, {'message': _("An error occurred: %s: %s") %
546+ (osv_error.name, osv_error.value), 'state': 'done', 'progression': 100.0})
547+ cr.close(True)
548+ except Exception as e:
549+ logging.getLogger('account.invoice.import').warn('Exception', exc_info=True)
550+ cr.rollback()
551+ self.write(cr, uid, ids, {'message': _("An error occurred: %s") %
552+ (e and e.args and e.args[0] or ''), 'state': 'done', 'progression': 100.0})
553+ cr.close(True)
554+ return True
555+
556+ def button_validate(self, cr, uid, ids, context=None):
557+ """
558+ Starts thread and returns the wizard with the state "inprogress"
559+ """
560+ if context is None:
561+ context = {}
562+ thread = threading.Thread(target=self._import, args=(cr.dbname, uid, ids, context))
563+ thread.start()
564+ self.write(cr, uid, ids, {'state': 'inprogress'}, context)
565+ return {
566+ 'type': 'ir.actions.act_window',
567+ 'res_model': 'account.invoice.import',
568+ 'view_type': 'form',
569+ 'view_mode': 'form',
570+ 'res_id': ids[0],
571+ 'context': context,
572+ 'target': 'new',
573+ }
574+
575+ def button_update(self, cr, uid, ids, context=None):
576+ """
577+ Updates the view to follow the progression
578+ """
579+ return False
580+
581+ def button_refresh_invoice(self, cr, uid, ids, context=None):
582+ """
583+ Closes the wizard and refreshes the invoice view
584+ """
585+ return {'type': 'ir.actions.act_window_close'}
586+
587+
588+account_invoice_import()
589+
590+
591+class account_invoice_import_errors(osv.osv_memory):
592+ _name = 'account.invoice.import.errors'
593+
594+ _columns = {
595+ 'name': fields.text("Description", readonly=True, required=True),
596+ 'wizard_id': fields.many2one('account.invoice.import', "Wizard", required=True, readonly=True),
597+ }
598+
599+
600+account_invoice_import_errors()
601+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
602
603=== added file 'bin/addons/account/wizard/account_invoice_import.xml'
604--- bin/addons/account/wizard/account_invoice_import.xml 1970-01-01 00:00:00 +0000
605+++ bin/addons/account/wizard/account_invoice_import.xml 2020-04-27 09:12:30 +0000
606@@ -0,0 +1,48 @@
607+<?xml version="1.0"?>
608+<openerp>
609+ <data>
610+
611+ <record id="wizard_account_invoice_import_errors_tree" model="ir.ui.view">
612+ <field name="name">wizard.account.invoice.import.errors.tree</field>
613+ <field name="model">account.invoice.import.errors</field>
614+ <field name="type">tree</field>
615+ <field name="arch" type="xml">
616+ <tree string="Information">
617+ <field name="name" />
618+ </tree>
619+ </field>
620+ </record>
621+
622+ <!-- Import invoice wizard -->
623+ <record model="ir.ui.view" id="wizard_account_invoice_import_form">
624+ <field name='name'>wizard.account.invoice.import.form</field>
625+ <field name='model'>account.invoice.import</field>
626+ <field name='type'>form</field>
627+ <field name='arch' type='xml'>
628+ <form string="Import Invoice">
629+ <label string="Select file to import" colspan="4" align="0.0"/>
630+ <newline/>
631+ <group col="4" colspan="4">
632+ <field name="file" filename="filename" colspan="4" attrs="{'invisible': [('state', '!=', 'draft')]}"/>
633+ <field name="filename" invisible="1"/>
634+ </group>
635+ <newline />
636+ <field name="progression" widget="progressbar" nolabel="1" attrs="{'invisible': [('state', '=', 'draft')]}" colspan="4" />
637+ <field name="message" nolabel="1" attrs="{'invisible': [('state', '=', 'draft')]}" widget="text"/>
638+ <newline/>
639+ <button name="button_update" type="object" string="Update" icon="gtk-refresh" attrs="{'invisible': [('state', '!=', 'inprogress')]}"/>
640+ <newline />
641+ <field name="error_ids" nolabel="1" attrs="{'invisible': [('state', '!=', 'error')]}"/>
642+ <group colspan="4" col="2" attrs="{'invisible': [('state', '!=', 'draft')]}">
643+ <button string="Cancel" special="cancel" icon="gtk-cancel"/>
644+ <button name="button_validate" type="object" string="Import" icon="terp-camera_test"/>
645+ </group>
646+ <button name="button_refresh_invoice" type="object" icon="terp-camera_test" string="Ok"
647+ attrs="{'invisible': [('state', '!=', 'done')]}"/>
648+ <field name="state" invisible="1"/>
649+ </form>
650+ </field>
651+ </record>
652+
653+ </data>
654+</openerp>
655
656=== modified file 'bin/addons/account_override/account_invoice_view.xml'
657--- bin/addons/account_override/account_invoice_view.xml 2020-04-02 16:24:30 +0000
658+++ bin/addons/account_override/account_invoice_view.xml 2020-04-27 09:12:30 +0000
659@@ -528,8 +528,11 @@
660 <field name="name" string="Reference"
661 attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('from_supply', '=', True)]}"/>
662 <newline/>
663- <group name="import" string=" Import Lines " colspan="4" col="4" attrs="{'invisible':[('state', '!=', 'draft')]}">
664- <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" type="object"
665+ <group name="import" string=" Import Lines " colspan="4" col="4">
666+ <button name="import_invoice" string="Import Invoice" icon="gtk-execute" colspan="2" type="object"
667+ attrs="{'readonly': [('state', '!=', 'draft')]}"/>
668+ <button name="export_invoice" string="Export Invoice" icon="gtk-execute" colspan="2" type="object"/>
669+ <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" colspan="4" type="object"
670 attrs="{'invisible': [('state', '!=', 'draft')],
671 'readonly': ['|',
672 ('from_supply', '=', True),
673@@ -737,8 +740,15 @@
674 <button name="button_reset_taxes" position="replace"/>
675 <button name="invoice_proforma2" position="replace"/>
676 <xpath expr="/form/notebook/page[@string='Invoice']/field[@name='invoice_line']" position="before" >
677- <group name="import" string=" Import Lines " colspan="4" col="4" attrs="{'invisible':[('state', '!=', 'draft')]}">
678- <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" type="object"
679+ <group name="import" string=" Import Lines " colspan="4" col="4"
680+ attrs="{'invisible': [('state', '!=', 'draft'), ('type', '!=', 'out_invoice')]}">
681+ <button name="import_invoice" string="Import Invoice" icon="gtk-execute" colspan="2" type="object"
682+ attrs="{'readonly': [('state', '!=', 'draft')],
683+ 'invisible': [('type', '!=', 'out_invoice')]}"/>
684+ <button name="export_invoice" string="Export Invoice" icon="gtk-execute" colspan="2" type="object"
685+ attrs="{'invisible': [('type', '!=', 'out_invoice')]}"/>
686+ <newline/>
687+ <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" colspan="4" type="object"
688 attrs="{'invisible': [('state', '!=', 'draft')],
689 'readonly': [('type', '=', 'out_invoice'),
690 ('from_supply', '=', True),
691
692=== modified file 'bin/addons/account_override/invoice.py'
693--- bin/addons/account_override/invoice.py 2020-04-20 08:28:46 +0000
694+++ bin/addons/account_override/invoice.py 2020-04-27 09:12:30 +0000
695@@ -1631,6 +1631,33 @@
696 return True
697 return False
698
699+ def export_invoice(self, cr, uid, ids, data, context=None):
700+ """
701+ Opens the Export Invoice report
702+ """
703+ return {
704+ 'type': 'ir.actions.report.xml',
705+ 'report_name': 'account.export_invoice',
706+ 'datas': data,
707+ }
708+
709+ def import_invoice(self, cr, uid, ids, data, context=None):
710+ """
711+ Opens the Import Invoice wizard
712+ """
713+ if isinstance(ids, (int, long)):
714+ ids = [ids]
715+ wiz_id = self.pool.get('account.invoice.import').create(cr, uid, {'invoice_id': ids[0]}, context=context)
716+ return {
717+ 'name': _('Import Invoice'),
718+ 'type': 'ir.actions.act_window',
719+ 'res_model': 'account.invoice.import',
720+ 'target': 'new',
721+ 'view_mode': 'form,tree',
722+ 'view_type': 'form',
723+ 'res_id': [wiz_id],
724+ }
725+
726
727 account_invoice()
728
729
730=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
731--- bin/addons/msf_profile/i18n/fr_MF.po 2020-04-20 08:36:07 +0000
732+++ bin/addons/msf_profile/i18n/fr_MF.po 2020-04-27 09:12:30 +0000
733@@ -5924,6 +5924,7 @@
734 #: field:replenishment.segment,description_seg:0
735 #: field:replenishment.segment.line,product_description:0
736 #: report:addons/account/report/invoice_excel_export.mako:67
737+#: field:account.invoice.import.errors,name:0
738 #, python-format
739 msgid "Description"
740 msgstr "Description"
741@@ -8344,6 +8345,7 @@
742 #: report:addons/specific_rules/report/unconsistent_stock_report_xls.mako:98
743 #: code:addons/stock_override/report/report_stock_move.py:759
744 #: report:addons/account/report/invoice_excel_export.mako:68
745+#: report:addons/account/report/export_invoice.mako:122
746 #, python-format
747 msgid "Quantity"
748 msgstr "Quantité"
749@@ -8680,7 +8682,7 @@
750 msgid "The currency used to enter statement"
751 msgstr "Devise utilisée pour entrer les relevés"
752
753-#. modules: register_accounting, account_hq_entries, msf_homere_interface, msf_doc_import
754+#. modules: register_accounting, account_hq_entries, msf_homere_interface, msf_doc_import, account
755 #: field:msf.doc.import.accounting,filename:0
756 #: field:hq.entries.import,filename:0
757 #: field:hr.expat.employee.import,filename:0
758@@ -8688,6 +8690,7 @@
759 #: field:hr.payroll.employee.import,filename:0
760 #: field:hr.payroll.import,filename:0
761 #: field:wizard.register.import,filename:0
762+#: field:account.invoice.import,filename:0
763 msgid "Imported filename"
764 msgstr "Nom du fichier importé"
765
766@@ -13212,7 +13215,7 @@
767 msgid "Line %s of the imported file: UoM [%s] not found ! Details: %s"
768 msgstr "Line %s of the imported file: UoM [%s] not found ! Details: %s"
769
770-#. modules: msf_budget, register_accounting, msf_homere_interface, supplier_catalogue, consumption_calculation, account_hq_entries, msf_doc_import, analytic_distribution, stock, msf_doc_import
771+#. modules: msf_budget, register_accounting, msf_homere_interface, supplier_catalogue, consumption_calculation, account_hq_entries, msf_doc_import, analytic_distribution, stock, msf_doc_import, account
772 #: code:addons/msf_doc_import/msf_import_export.py:368
773 #: code:addons/stock/physical_inventory.py:662
774 #: code:addons/stock/physical_inventory.py:877
775@@ -13237,6 +13240,7 @@
776 #: code:addons/register_accounting/wizard/wizard_register_import.py:260
777 #: code:addons/supplier_catalogue/supplier_catalogue.py:627
778 #: code:addons/supplier_catalogue/wizard/catalogue_import_lines.py:45
779+#: code:addons/account/wizard/account_invoice_import.py:75
780 #, python-format
781 msgid "Nothing to import."
782 msgstr "Rien à importer."
783@@ -18775,10 +18779,11 @@
784 msgid " with warning"
785 msgstr "avec avertissement"
786
787-#. modules: msf_doc_import, register_accounting, account_override
788+#. modules: msf_doc_import, register_accounting, account_override, account
789 #: code:addons/msf_doc_import/account.py:618
790 #: code:addons/register_accounting/wizard/wizard_register_import.py:669
791 #: code:addons/account_override/finance_export.py:241
792+#: code:addons/account/wizard/account_invoice_import.py:239
793 #, python-format
794 msgid "An error occurred: %s"
795 msgstr "Une erreur est survenue : %s"
796@@ -19909,13 +19914,14 @@
797 msgid "Some entries are already reconciled !"
798 msgstr "Certaines écritures sont déjà lettrées !"
799
800-#. modules: msf_doc_import, register_accounting, consumption_calculation
801+#. modules: msf_doc_import, register_accounting, consumption_calculation, account
802 #: field:weekly.forecast.report,progress:0
803 #: field:abstract.wizard.import,progression:0
804 #: field:msf.doc.import.accounting,progression:0
805 #: field:msf.import.export,progression:0
806 #: field:wizard.import.batch,progression:0
807 #: field:wizard.register.import,progression:0
808+#: field:account.invoice.import,progression:0
809 msgid "Progression"
810 msgstr "Progression"
811
812@@ -21236,9 +21242,10 @@
813 msgid "Display accounts?"
814 msgstr "Display accounts?"
815
816-#. modules: msf_doc_import, register_accounting
817+#. modules: msf_doc_import, register_accounting, account
818 #: code:addons/msf_doc_import/account.py:601
819 #: code:addons/register_accounting/wizard/wizard_register_import.py:653
820+#: code:addons/account/wizard/account_invoice_import.py:225
821 #, python-format
822 msgid "Import successful."
823 msgstr "Import réussi."
824@@ -22569,9 +22576,10 @@
825 msgid "The bank statement used for bank reconciliation"
826 msgstr "Relevé bancaire utilisé pour la reconciliation bancaire"
827
828-#. modules: msf_doc_import, register_accounting
829+#. modules: msf_doc_import, register_accounting, account
830 #: code:addons/msf_doc_import/account.py:587
831 #: code:addons/register_accounting/wizard/wizard_register_import.py:639
832+#: code:addons/account/wizard/account_invoice_import.py:216
833 #, python-format
834 msgid "Import FAILED."
835 msgstr "L'import a ÉCHOUÉ."
836@@ -26636,8 +26644,9 @@
837 msgid "Paid"
838 msgstr "Payé"
839
840-#. module: register_accounting
841+#. modules: register_accounting, account
842 #: code:addons/register_accounting/wizard/wizard_register_import.py:268
843+#: code:addons/account/wizard/account_invoice_import.py:81
844 #, python-format
845 msgid "No content."
846 msgstr "Aucun contenu."
847@@ -30071,7 +30080,7 @@
848 msgid "Operator '%s' not suported"
849 msgstr "Operator '%s' not suported"
850
851-#. 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
852+#. 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
853 #: view:account.line.csv.export:0
854 #: field:account.line.csv.export,message:0
855 #: field:import.commitment.wizard,last_error:0
856@@ -30120,6 +30129,7 @@
857 #: view:sync.client.register_entity:0
858 #: field:sync.client.register_entity,message:0
859 #: selection:sync.client.register_entity,state:0
860+#: field:account.invoice.import,message:0
861 msgid "Message"
862 msgstr "Message"
863
864@@ -41935,7 +41945,7 @@
865 msgid "Contract code/name:"
866 msgstr "Contrat - Code/Nom:"
867
868-#. modules: sales_followup, register_accounting, import_data, sync_client, base, purchase_followup, msf_doc_import, stock, product
869+#. modules: sales_followup, register_accounting, import_data, sync_client, base, purchase_followup, msf_doc_import, stock, product, account
870 #: view:base.module.update:0
871 #: view:base.update.translations:0
872 #: selection:import_data,import_mode:0
873@@ -41962,6 +41972,7 @@
874 #: view:product.product:0
875 #: view:sync.client.update_entity:0
876 #: view:stock.expired.damaged.report:0
877+#: view:account.invoice.import:0
878 msgid "Update"
879 msgstr "Mettre à jour"
880
881@@ -43288,11 +43299,12 @@
882 msgid "Monthly Budget (XLS)"
883 msgstr "Budget Mensuel (XLS)"
884
885-#. modules: msf_doc_import, procurement_request
886+#. modules: msf_doc_import, procurement_request, account
887 #: field:abstract.wizard.import,info_message:0
888 #: view:wizard.import.batch:0
889 #: field:wizard.import.batch,info_message:0
890 #: view:internal.request.import:0
891+#: view:account.invoice.import.errors:0
892 msgid "Information"
893 msgstr "Informations"
894
895@@ -45001,7 +45013,7 @@
896 msgid "Output Out"
897 msgstr "Modèles de Taxe"
898
899-#. 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
900+#. 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
901 #: field:wizard.split.invoice.lines,wizard_id:0
902 #: view:ir.actions.wizard:0
903 #: field:wizard.ir.model.menu.create.line,wizard_id:0
904@@ -45045,6 +45057,7 @@
905 #: field:stock.move.processor,wizard_id:0
906 #: field:warning.import.currencies.lines,wizard_id:0
907 #: field:sale.order.leave.close,wizard_id:0
908+#: field:account.invoice.import.errors,wizard_id:0
909 msgid "Wizard"
910 msgstr "Assistant"
911
912@@ -49381,6 +49394,7 @@
913 #: field:account.invoice.tax,partner_id:0
914 #: field:account.tax,partner_id:0
915 #: report:addons/account/report/invoice_excel_export.mako:80
916+#: report:addons/account/report/export_invoice.mako:100
917 #, python-format
918 msgid "Partner"
919 msgstr "Partenaire"
920@@ -53657,6 +53671,7 @@
921 #: report:sale.order.allocation.report:0
922 #: report:addons/account/report/free_allocation_report.mako:199
923 #: report:addons/account/report/invoice_excel_export.mako:73
924+#: report:addons/account/report/export_invoice.mako:0
925 #, python-format
926 msgid "Account"
927 msgstr "Compte"
928@@ -54637,15 +54652,28 @@
929 msgid " value amount: 0.02"
930 msgstr " valeur du montant : 0,02"
931
932-#. modules: msf_doc_import, register_accounting
933+#. modules: msf_doc_import, register_accounting, account
934 #: code:addons/msf_doc_import/account.py:201
935 #: code:addons/msf_doc_import/account.py:254
936 #: code:addons/register_accounting/wizard/wizard_register_import.py:257
937 #: code:addons/register_accounting/wizard/wizard_register_import.py:355
938+#: code:addons/account/wizard/account_invoice_import.py:73
939 #, python-format
940 msgid "Checking file…"
941 msgstr "Vérification du fichier…"
942
943+#. module: account
944+#: code:addons/account/wizard/account_invoice_import.py:85
945+#, python-format
946+msgid "Checking header…"
947+msgstr "Vérification de l'en-tête…"
948+
949+#. module: account
950+#: code:addons/account/wizard/account_invoice_import.py:134
951+#, python-format
952+msgid "Checking lines…"
953+msgstr "Vérification des lignes…"
954+
955 #. modules: tender_flow, purchase_allocation_report, register_accounting, return_claim, transport_mgmt, res_currency_tables, stock_override, stock_forecast, analytic, stock, msf_order_date, reason_types_moves, procurement_request, consumption_calculation, purchase_override, kit, out_step, purchase, account, msf_outgoing, sale, sales_followup, procurement
956 #: selection:account.account,type:0
957 #: selection:account.account.template,type:0
958@@ -57361,6 +57389,7 @@
959 #: field:wizard.register.creation.lines,journal_id:0
960 #: view:stock.picking:0
961 #: model:ir.model,name:sync_so.model_account_journal
962+#: report:addons/account/report/export_invoice.mako:92
963 #, python-format
964 msgid "Journal"
965 msgstr "Journal"
966@@ -58287,6 +58316,7 @@
967 #: field:replenishment.inventory.review.line,warning_html:0
968 #: field:replenishment.order_calc.line,warning_html:0
969 #: view:product.ask.activate.wizard:0
970+#: code:addons/account/wizard/account_invoice_import.py:81
971 #, python-format
972 msgid "Warning"
973 msgstr "Avertissement"
974@@ -64591,6 +64621,7 @@
975 #: field:internal.request.import.error.line,line_number:0
976 #: report:addons/msf_supply_doc_export/report/supplier_performance_report_xls.mako:232
977 #: report:addons/account/report/invoice_excel_export.mako:65
978+#: report:addons/account/report/export_invoice.mako:119
979 #, python-format
980 msgid "Line number"
981 msgstr "Numéro de ligne"
982@@ -64970,6 +65001,7 @@
983 #: field:hq.entries.split,date:0
984 #: selection:integrity.finance.wizard,filter:0
985 #: code:addons/account_override/res_company.py:40
986+#: report:addons/account/report/export_invoice.mako:108
987 #, python-format
988 msgid "Posting Date"
989 msgstr "Date de Comptabilisation"
990@@ -68641,7 +68673,7 @@
991 msgid "Kit Composition"
992 msgstr "Kit - Composition"
993
994-#. modules: register_accounting, msf_homere_interface, account_override, base, msf_doc_import, msf_profile, sync_client, msf_supply_doc_export
995+#. modules: register_accounting, msf_homere_interface, account_override, base, msf_doc_import, msf_profile, sync_client, msf_supply_doc_export, account
996 #: view:ir.attachment:0
997 #: view:ir.attachment:0
998 #: selection:msf.doc.import.accounting,state:0
999@@ -68654,6 +68686,7 @@
1000 #: field:account.direct.invoice.wizard.line,create_date:0
1001 #: selection:sync.client.log_sale_purchase,action_type:0
1002 #: code:addons/msf_supply_doc_export/msf_supply_doc_export.py:896
1003+#: selection:account.invoice.import,state:0
1004 msgid "Created"
1005 msgstr "Créé"
1006
1007@@ -73483,6 +73516,8 @@
1008 #: code:addons/account/wizard/account_report_liquidity_balance.py:75
1009 #: code:addons/account_override/period.py:148
1010 #: code:addons/account_override/account.py:1256
1011+#: code:addons/account/wizard/account_invoice_import.py:0
1012+#: selection:account.invoice.import,state:0
1013 #, python-format, python-format
1014 msgid "Error"
1015 msgstr "Erreur"
1016@@ -73909,7 +73944,7 @@
1017 msgid "Do you want to update the Date of Stock Take of all/selected Order lines ?"
1018 msgstr "Voulez-vous mettre à jour la Date de Prise de Stock sur toutes les lignes de la Commande ou les lignes sélectionnées ?"
1019
1020-#. modules: register_accounting, msf_homere_interface, documents_done, consumption_calculation, msf_button_access_rights, mission_stock, msf_doc_import, analytic_distribution, sourcing, sale
1021+#. modules: register_accounting, msf_homere_interface, documents_done, consumption_calculation, msf_button_access_rights, mission_stock, msf_doc_import, analytic_distribution, sourcing, sale, account
1022 #: field:mass.reallocation.verification.wizard,error_ids:0
1023 #: field:monthly.review.consumption.line,text_error:0
1024 #: field:real.average.consumption.line,text_error:0
1025@@ -73926,6 +73961,7 @@
1026 #: field:wizard.register.import,error_ids:0
1027 #: field:msf.import.export,error_message:0
1028 #: code:addons/sourcing/wizard/multiple_sourcing.py:252
1029+#: field:account.invoice.import,error_ids:0
1030 #, python-format
1031 msgid "Errors"
1032 msgstr "Erreurs"
1033@@ -74080,6 +74116,7 @@
1034 #: selection:res.request,ref_doc1:0
1035 #: selection:res.request,ref_doc2:0
1036 #: view:account.direct.invoice.wizard:0
1037+#: field:account.invoice.import,invoice_id:0
1038 msgid "Invoice"
1039 msgstr "Facture"
1040
1041@@ -75812,8 +75849,9 @@
1042 msgid "Asset Follow Up"
1043 msgstr "Actif - Suivi"
1044
1045-#. module: register_accounting
1046+#. modules: register_accounting, account
1047 #: view:wizard.register.import:0
1048+#: view:account.invoice.import:0
1049 msgid "Select file to import"
1050 msgstr "Sélectionner le fichier à importer"
1051
1052@@ -76471,6 +76509,7 @@
1053 #: code:addons/consumption_calculation/weekly_forecast_report.py:506
1054 #: report:order.type.donation.certificate:0
1055 #: report:addons/stock/report/stock_delivery_report_xls.mako:220
1056+#: report:addons/account/report/export_invoice.mako:123
1057 #, python-format
1058 msgid "Unit Price"
1059 msgstr "Prix Unitaire"
1060@@ -81011,7 +81050,7 @@
1061 msgid "Wizard lines for internal picking processor"
1062 msgstr "Wizard lines for internal picking processor"
1063
1064-#. modules: vertical_integration, register_accounting, res_currency_tables, account_hq_entries, update_client, msf_tools, msf_doc_import, analytic_distribution
1065+#. modules: vertical_integration, register_accounting, res_currency_tables, account_hq_entries, update_client, msf_tools, msf_doc_import, analytic_distribution, account
1066 #: view:hq.entries.import:0
1067 #: view:import.commitment.wizard:0
1068 #: view:msf.doc.import.accounting:0
1069@@ -81024,6 +81063,7 @@
1070 #: view:import.table.currencies:0
1071 #: view:sync_client.upgrade:0
1072 #: view:wizard.import.mapping:0
1073+#: view:account.invoice.import:0
1074 msgid "Import"
1075 msgstr "Importer"
1076
1077@@ -81703,6 +81743,7 @@
1078 #: field:replenishment.inventory.review,state:0
1079 #: field:replenishment.order_calc,state:0
1080 #: field:replenishment.segment,state:0
1081+#: field:account.invoice.import,state:0
1082 #, python-format
1083 msgid "State"
1084 msgstr "Statut"
1085@@ -82633,6 +82674,7 @@
1086 #: view:products.situation.report:0
1087 #: field:replenishment.product.list,product_id:0
1088 #: report:addons/account/report/invoice_excel_export.mako:66
1089+#: report:addons/account/report/export_invoice.mako:120
1090 #, python-format
1091 msgid "Product"
1092 msgstr "Produit"
1093@@ -82803,6 +82845,7 @@
1094 #: selection:wizard.import.ppl.to.create.ship,state:0
1095 #: selection:wizard.import.product.line,state:0
1096 #: selection:product.mass.update,state:0
1097+#: selection:account.invoice.import,state:0
1098 #, python-format
1099 msgid "Done"
1100 msgstr "Terminé"
1101@@ -82862,7 +82905,7 @@
1102 msgid "Computation"
1103 msgstr "Calcul"
1104
1105-#. modules: register_accounting, msf_homere_interface, import_data, account_hq_entries, export_import_lang, base, msf_doc_import, mission_stock, analytic_distribution
1106+#. modules: register_accounting, msf_homere_interface, import_data, account_hq_entries, export_import_lang, base, msf_doc_import, mission_stock, analytic_distribution, account
1107 #: field:int.commitment.export.wizard,data:0
1108 #: field:import_category,file:0
1109 #: field:import_nomenclature,file:0
1110@@ -82880,6 +82923,7 @@
1111 #: field:hr.payroll.employee.import,file:0
1112 #: field:hr.payroll.import,file:0
1113 #: field:wizard.register.import,file:0
1114+#: field:account.invoice.import,file:0
1115 msgid "File"
1116 msgstr "Fichier"
1117
1118@@ -83561,7 +83605,7 @@
1119 msgid "Sourced-n line"
1120 msgstr "Ligne sourcée-n"
1121
1122-#. 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
1123+#. 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
1124 #: field:import.commitment.wizard,in_progress:0
1125 #: view:product.history.consumption:0
1126 #: selection:product.history.consumption,fake_status:0
1127@@ -83606,6 +83650,7 @@
1128 #: selection:wizard.import.product.line,state:0
1129 #: selection:product.mass.update,state:0
1130 #: selection:stock.expired.damaged.report,state:0
1131+#: selection:account.invoice.import,state:0
1132 #, python-format
1133 msgid "In Progress"
1134 msgstr "En cours"
1135@@ -90952,6 +90997,11 @@
1136 msgid "Number"
1137 msgstr "Nombre"
1138
1139+#. module: account
1140+#: report:addons/account/report/export_invoice.mako:88
1141+msgid "Number"
1142+msgstr "Numéro"
1143+
1144 #. module: msf_doc_import
1145 #: code:addons/msf_doc_import/account.py:303
1146 #, python-format
1147@@ -92851,6 +92901,7 @@
1148 #: report:order.type.donation.certificate:0
1149 #: report:addons/msf_supply_doc_export/report/supplier_performance_report_xls.mako:238
1150 #: report:addons/stock/report/stock_delivery_report_xls.mako:221
1151+#: report:addons/account/report/export_invoice.mako:96
1152 #, python-format
1153 msgid "Currency"
1154 msgstr "Devise"
1155@@ -95784,6 +95835,7 @@
1156 #: report:addons/vertical_integration/report/open_invoices_xls.mako:290
1157 #: report:account.invoice2:0
1158 #: code:addons/account_override/res_company.py:40
1159+#: report:addons/account/report/export_invoice.mako:104
1160 #, python-format
1161 msgid "Document Date"
1162 msgstr "Date du Document"
1163@@ -96495,6 +96547,7 @@
1164 #: view:replenishment.order_calc:0
1165 #: view:replenishment.segment:0
1166 #: view:product.ask.activate.wizard:0
1167+#: view:account.invoice.import:0
1168 #, python-format
1169 msgid "Cancel"
1170 msgstr "Annuler"
1171@@ -97726,6 +97779,7 @@
1172 #: selection:sync.monitor,user_rights:0
1173 #: selection:shipment.add.pack.processor.line,integrity_status:0
1174 #: selection:stock.move,integrity_error:0
1175+#: view:account.invoice.import:0
1176 #: code:addons/msf_outgoing/__init__.py:26
1177 msgid "Ok"
1178 msgstr "Ok"
1179@@ -106292,8 +106346,9 @@
1180 msgid "Impossible to retrieve the account code at line level."
1181 msgstr "Impossible de récupérer le code comptable au niveau d'une ligne."
1182
1183-#. module: account_override
1184+#. modules: account_override, account
1185 #: code:addons/account_override/account_invoice_sync.py:193
1186+#: code:addons/account/wizard/account_invoice_import.py:107
1187 #, python-format
1188 msgid "Currency %s not found or inactive."
1189 msgstr "Devise %s non trouvée ou inactive."
1190@@ -109055,6 +109110,7 @@
1191
1192 #. module: account
1193 #: report:addons/account/report/invoice_excel_export.mako:56
1194+#: report:addons/account/report/export_invoice.mako:80
1195 msgid "Sheet"
1196 msgstr "Feuille"
1197
1198@@ -109195,3 +109251,119 @@
1199 #: code:addons/account_override/invoice.py:1272
1200 msgid "Split Stock Transfer Voucher"
1201 msgstr "Fractionner Bon Client"
1202+
1203+#. modules: account_override, register_accounting
1204+#: view:account.invoice:0
1205+#: view:account.invoice:0
1206+msgid "Export Invoice"
1207+msgstr "Exporter la Facture"
1208+
1209+#. module: account
1210+#: report:addons/account/report/export_invoice.mako:9
1211+#: model:ir.actions.report.xml,name:account.export_invoice
1212+msgid "Export - Invoice"
1213+msgstr "Export - Facture"
1214+
1215+#. modules: account_override, account, register_accounting
1216+#: view:account.invoice.import:0
1217+#: code:addons/account_override/invoice.py:1652
1218+#: view:account.invoice:0
1219+#, python-format
1220+msgid "Import Invoice"
1221+msgstr "Importer la Facture"
1222+
1223+#. module: account
1224+#: code:addons/account/wizard/account_invoice_import.py:159
1225+#, python-format
1226+msgid "Line %s: the account (mandatory) is missing."
1227+msgstr "Ligne %s : il manque le compte (obligatoire)."
1228+
1229+#. module: account
1230+#: code:addons/account/wizard/account_invoice_import.py:163
1231+#, python-format
1232+msgid "Line %s: the account %s doesn't exist."
1233+msgstr "Ligne %s : le compte %s n'existe pas."
1234+
1235+#. module: account
1236+#: code:addons/account/wizard/account_invoice_import.py:115
1237+#, python-format
1238+msgid "Partner %s not found or inactive."
1239+msgstr "Partenaire %s non trouvé ou inactif."
1240+
1241+#. module: account
1242+#: code:addons/account/wizard/account_invoice_import.py:233
1243+#, python-format
1244+msgid "An error occurred: %s: %s"
1245+msgstr "Une erreur est survenue : %s : %s"
1246+
1247+#. module: account
1248+#: code:addons/account/wizard/account_invoice_import.py:177
1249+#, python-format
1250+msgid "Line %s: the account %s is not allowed."
1251+msgstr "Ligne %s : le compte %s n'est pas autorisé."
1252+
1253+#. module: account
1254+#: code:addons/account/wizard/account_invoice_import.py:168
1255+#, python-format
1256+msgid "Line %s: the account %s is inactive."
1257+msgstr "Ligne %s : le compte %s est inactif."
1258+
1259+#. module: account
1260+#: code:addons/account/wizard/account_invoice_import.py:102
1261+#, python-format
1262+msgid "No currency found."
1263+msgstr "Pas de devise trouvée."
1264+
1265+#. module: account
1266+#: code:addons/account/wizard/account_invoice_import.py:112
1267+#, python-format
1268+msgid "No partner found."
1269+msgstr "Pas de partenaire trouvé."
1270+
1271+#. module: account
1272+#: code:addons/account/wizard/account_invoice_import.py:200
1273+#, python-format
1274+msgid "Line %s: the quantity format is incorrect."
1275+msgstr "Ligne %s : le format de la quantité est incorrect."
1276+
1277+#. module: account
1278+#: code:addons/account/wizard/account_invoice_import.py:156
1279+#, python-format
1280+msgid "Line %s: the line number %s doesn't exist in the invoice."
1281+msgstr "Ligne %s : le numéro de ligne %s n'existe pas dans la facture."
1282+
1283+#. module: account
1284+#: code:addons/account/wizard/account_invoice_import.py:151
1285+#, python-format
1286+msgid "Line %s: the line number is missing."
1287+msgstr "Ligne %s : il manque le numéro de ligne."
1288+
1289+#. module: account
1290+#: code:addons/account/wizard/account_invoice_import.py:128
1291+#, python-format
1292+msgid "The combination \"Currency, Partner and Posting Date\" of the imported file doesn't match with the current invoice."
1293+msgstr "La combinaison \"Devise, Partenaire et Date de Comptabilisation\" du fichier importé ne correspond pas à la facture actuelle."
1294+
1295+#. module: account
1296+#: code:addons/account/wizard/account_invoice_import.py:121
1297+#, python-format
1298+msgid "The posting date has a wrong format."
1299+msgstr "La date de comptabilisation a un mauvais format."
1300+
1301+#. module: account
1302+#: code:addons/account/wizard/account_invoice_import.py:183
1303+#, python-format
1304+msgid "Line %s: the unit price format is incorrect."
1305+msgstr "Ligne %s : le format du prix unitaire est incorrect."
1306+
1307+#. module: account
1308+#: code:addons/account/wizard/account_invoice_import.py:194
1309+#, python-format
1310+msgid "Line %s: the product %s doesn't exist or is inactive."
1311+msgstr "Ligne %s : le produit %s n'existe pas ou est inactif."
1312+
1313+#. module: account
1314+#: code:addons/account/wizard/account_invoice_import.py:86
1315+#, python-format
1316+msgid "The import is allowed only in Draft state."
1317+msgstr "L'import est autorisé uniquement à l'état Brouillon."
1318
1319=== modified file 'bin/addons/register_accounting/account_invoice_view.xml'
1320--- bin/addons/register_accounting/account_invoice_view.xml 2020-02-26 15:14:53 +0000
1321+++ bin/addons/register_accounting/account_invoice_view.xml 2020-04-27 09:12:30 +0000
1322@@ -317,8 +317,15 @@
1323 <field name="supplier_reference"/>
1324 </field>
1325 <xpath expr="/form/notebook/page[@string='Invoice']/field[@name='invoice_line']" position="before" >
1326- <group name="import" string=" Import Lines " colspan="4" col="4" attrs="{'invisible':[('state', '!=', 'draft')]}">
1327- <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" type="object"
1328+ <group name="import" string=" Import Lines " colspan="4" col="4"
1329+ attrs="{'invisible': [('state', '!=', 'draft'), ('type', '!=', 'in_invoice')]}">
1330+ <button name="import_invoice" string="Import Invoice" icon="gtk-execute" colspan="2" type="object"
1331+ attrs="{'readonly': [('state', '!=', 'draft')],
1332+ 'invisible': [('type', '!=', 'in_invoice')]}"/>
1333+ <button name="export_invoice" string="Export Invoice" icon="gtk-execute" colspan="2" type="object"
1334+ attrs="{'invisible': [('type', '!=', 'in_invoice')]}"/>
1335+ <newline/>
1336+ <button name="wizard_import_si_line" string="Import lines" icon="gtk-dnd" colspan="4" type="object"
1337 attrs="{'invisible': [('state', '!=', 'draft')],
1338 'readonly': [('type', '=', 'in_invoice'), ('synced', '=', True)]}"/>
1339 </group>

Subscribers

People subscribed via source and target branches