diff --git a/account_export_ebp/README.rst b/account_export_ebp/README.rst new file mode 100644 index 0000000..47c3fbc --- /dev/null +++ b/account_export_ebp/README.rst @@ -0,0 +1,32 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +===================================== +GRAP - Export accounting moves to EBP +===================================== + +Custom GRAP module that allows to export accounting moves, accounts and balance +to EBP software. + +The code is based on a work made by Numérigraphe SARL. + +Roadmap / Know issues +===================== + +* rename module into ``grap_account_export_ebp`` + +Credits +======= + +Contributors +------------ + +* Numérigraphe SARL +* Julien WESTE +* Sylvain LE GAL + +Funders +------- + +* GRAP, Groupement Régional Alimentaire de Proximité diff --git a/account_export_ebp/__openerp__.py b/account_export_ebp/__openerp__.py index 0e6f517..80e5bb1 100644 --- a/account_export_ebp/__openerp__.py +++ b/account_export_ebp/__openerp__.py @@ -5,38 +5,11 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - 'name': "Export accounting moves to EBP's accounting software", - 'version': '2.3', + 'name': "GRAP - Export accounting moves to EBP", + 'version': '8.0.3.0.0', 'author': 'Numérigraphe SARL,GRAP', - 'category': 'Generic Modules/Accounting', - 'description': """ -This module lets you export accounting moves and accounts to flat text files -readable by 'EBP Comptabilité', an accounting software package widely spread -in France. -The files are in the text format for EBP's software, version 3 and above. - -The export feature is in the form of a wizard related to accounting moves, -so that the person exporting the data can select which moves to export. - -The exported moves cannot be changed or deleted anymore, but the export can -be reverted by unchecking the "exported" box. - -Three pieces of configuration need to be set: - * the company for each fiscal year; - * the URI, user name and password of to access the EBP folders as Windows - network shares (if you want to save the files directly in EBP folder); - * the number of each fiscal year in these folders; - -The files will be directly generated in the EBP network shares or can be -downloaded on the user's computer. -If those are properly set, the files should be imported automatically as -simulation moves by the EBP software next time the folder is opened. - -The python package "smbc" must be installed on the server to use this module. - -A menu allow the user to see the list of all past exports and download again -old ones if need be. -""", + 'category': 'GRAP - Custom', + 'licence': 'AGPL-3', 'depends': [ 'account_accountant', 'base_fiscal_company', @@ -49,16 +22,19 @@ 'security/ir_model_access.yml', 'security/ir_rule.xml', 'views/menu.xml', + 'wizard/view_wizard_res_partner_add_suffix.xml', + 'wizard/view_wizard_ebp_export.xml', + 'wizard/view_wizard_ebp_unexport.xml', 'views/view_account_account.xml', - 'views/view_account_add_suffix.xml', - 'views/view_account_export_ebp.xml', - 'views/view_account_unexport_ebp.xml', - 'views/view_account_fiscalyear.xml', 'views/view_account_journal.xml', 'views/view_account_move.xml', 'views/view_account_tax_code.xml', 'views/view_ebp_export.xml', - 'views/view_res_company.xml', 'views/view_res_partner.xml', + 'views/view_res_company.xml', + ], + 'demo': [ + 'demo/account_journal.xml', ], + 'installable': True, } diff --git a/account_export_ebp/demo/account_journal.xml b/account_export_ebp/demo/account_journal.xml new file mode 100644 index 0000000..a16636b --- /dev/null +++ b/account_export_ebp/demo/account_journal.xml @@ -0,0 +1,14 @@ + + + + + + TST + + + diff --git a/account_export_ebp/i18n/fr.po b/account_export_ebp/i18n/fr.po index 0d2024d..6d27d1b 100644 --- a/account_export_ebp/i18n/fr.po +++ b/account_export_ebp/i18n/fr.po @@ -1,19 +1,27 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * account_export_ebp +# * account_export_ebp # msgid "" msgstr "" "Project-Id-Version: Odoo Server 8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-07-25 16:41+0000\n" -"PO-Revision-Date: 2018-07-25 16:41+0000\n" +"POT-Creation-Date: 2018-10-15 22:53+0000\n" +"PO-Revision-Date: 2018-10-16 01:07+0200\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: \n" +"Language: fr\n" +"X-Generator: Poedit 2.0.6\n" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:110 +#, python-format +msgid "ACCOUNTS" +msgstr "COMPTES" #. module: account_export_ebp #: model:ir.model,name:account_export_ebp.model_account_account @@ -26,99 +34,99 @@ msgid "Account Entry" msgstr "Pièce comptable" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:427 +#: code:addons/account_export_ebp/models/ebp_export.py:313 +#: code:addons/account_export_ebp/models/ebp_export.py:465 +#, python-format +msgid "Account Number" +msgstr "N° Compte" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:254 #, python-format msgid "Account code '%s' is too long to be exported to EBP." -msgstr "Le code du compte '%s' est trop long pour être exporté sous EBP." +msgstr "Le code comptable '%s' est trop long pour être exporté dans EBP." #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:427 +#: code:addons/account_export_ebp/models/ebp_export.py:466 #, python-format -msgid "Account code too long" -msgstr "Code de compte trop long" +msgid "Account name" +msgstr "Nom du compte" #. module: account_export_ebp -#: field:ebp.export,data_accounts:0 +#: field:ebp.export,data_accounts:0 field:wizard.ebp.export,data_accounts:0 msgid "Accounts file" msgstr "Fichier des comptes" #. module: account_export_ebp -#: model:ir.actions.act_window,name:account_export_ebp.action_account_add_suffix -msgid "Add EBP Suffix" -msgstr "Add EBP Suffix" +#: model:ir.actions.act_window,name:account_export_ebp.action_wizard_res_partner_add_suffix +msgid "Add EBP Suffixes" +msgstr "Ajouter des suffixes EBP" #. module: account_export_ebp -#: field:account.add.suffix.line,account_add_suffix_id:0 -msgid "Add Suffix Id" -msgstr "Ajouter un suffixe" - -#. module: account_export_ebp -#: field:account.add.suffix,line_ids:0 -msgid "Add Suffix Lines" -msgstr "Lignes d'ajout de suffixe" +#: view:wizard.res.partner.add.suffix:account_export_ebp.view_wizard_res_partner_add_suffix_form +msgid "Affect Suffix" +msgstr "Affecter un suffixe" #. module: account_export_ebp -#: view:account.add.suffix:account_export_ebp.view_account_add_suffix_form -msgid "Affect Suffix" -msgstr "Affecter les suffixes" +#: code:addons/account_export_ebp/models/ebp_export.py:321 +#, python-format +msgid "Allow Analytic" +msgstr "Autoriser l'analytique" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -#: view:ebp.export:account_export_ebp.view_ebp_export_form -msgid "And the exported accounts file:" -msgstr "et le fichier des comptes comptables:" +#: code:addons/account_export_ebp/models/ebp_export.py:323 +#, python-format +msgid "Allow Use of Personal Datas" +msgstr "Autoriser l'utilisation de données personnelles" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -#: view:ebp.export:account_export_ebp.view_ebp_export_form -msgid "And the exported balance file:" -msgstr "Et le fichier des balances:" +#: code:addons/account_export_ebp/models/ebp_export.py:316 +#, python-format +msgid "Amount (related to the direction)" +msgstr "Montant (lié au sens)" #. module: account_export_ebp -#: help:account.export.ebp,tax_code_suffix:0 -msgid "Append Tax Code's suffix to account if the option is checked in the account" -msgstr "Ajoute le suffixe du Code de Taxe au compte si l'option est cochée pour le compte" +#: code:addons/account_export_ebp/models/ebp_export.py:320 +#, python-format +msgid "Analytic Account" +msgstr "Compte analytique" #. module: account_export_ebp -#: field:account.export.ebp,company_suffix:0 -msgid "Append company's code to accounts" -msgstr "Ajouter le code de la société aux comptes" +#: view:wizard.ebp.unexport:account_export_ebp.view_wizard_ebp_unexport_form +msgid "Are you sure you want to cancel EBP Export ?" +msgstr "Etes vous sûr d'annuler l'export EBP ?" #. module: account_export_ebp -#: field:account.export.ebp,partner_accounts:0 -msgid "Append partners' code to accounts" -msgstr "Ajouter le code partenaire au compte" +#: code:addons/account_export_ebp/models/ebp_export.py:116 +#, python-format +msgid "BALANCE" +msgstr "BALANCE" #. module: account_export_ebp -#: field:ebp.export,data_balance:0 +#: field:ebp.export,data_balance:0 field:wizard.ebp.export,data_balance:0 msgid "Balance file" msgstr "Fichier des balances" #. module: account_export_ebp -#: view:account.unexport.ebp:account_export_ebp.view_account_unexport_ebp_form -msgid "Be sure to delete the corresponding lines in EBP." -msgstr "Il est conseillé de supprimer les lignes correspondantes dans EBP pour éviter les doublons." - -#. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -#: view:account.unexport.ebp:account_export_ebp.view_account_unexport_ebp_form +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +#: view:wizard.ebp.unexport:account_export_ebp.view_wizard_ebp_unexport_form msgid "Cancel" msgstr "Annuler" #. module: account_export_ebp -#: model:ir.actions.act_window,name:account_export_ebp.action_account_unexport_ebp +#: model:ir.actions.act_window,name:account_export_ebp.action_wizard_ebp_unexport msgid "Cancel EBP Export" msgstr "Annuler l'export EBP" #. module: account_export_ebp -#: help:account.export.ebp,download_file:0 -msgid "Check this box if you want to download the result as a file on your computer. Otherwise, the file will be saved at the place defined in the company settings." -msgstr "Cocher cette case pour pouvoir télécharger les exports sur votre ordinateur. Sinon, ils seront enregistrer dans le dossier EBP défini dans la société." +#: help:res.company,ebp_analytic_enabled:0 +msgid "Check this box if you want to enable the analytic when exporting in EBP. Note that this setting has will not been taken into account for Companies that belong to a CAE" +msgstr "Cochez cette case si vous voulez activer l'analytique quand vous exportez dans EBP. Notez que ce paramétrage sera ignoré pour les sociétés appartenant à une CAE." #. module: account_export_ebp -#: help:account.export.ebp,ignore_exported:0 -msgid "Check this box unless you want to re-export moves to EBP" -msgstr "Cochez cette case sauf si vous voulez réexporter des pièces" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "Close" +msgstr "Fermer" #. module: account_export_ebp #: model:ir.model,name:account_export_ebp.model_res_company @@ -126,75 +134,110 @@ msgid "Companies" msgstr "Sociétés" #. module: account_export_ebp -#: field:account.add.suffix.line,company_id:0 #: view:ebp.export:account_export_ebp.view_ebp_export_search #: field:ebp.export,company_id:0 -#: view:res.partner:account_export_ebp.view_res_partner_search +#: field:wizard.res.partner.add.suffix.line,company_id:0 msgid "Company" msgstr "Société" #. module: account_export_ebp -#: view:res.company:account_export_ebp.view_res_company_form -msgid "Configuration" -msgstr "Configuration" - -#. module: account_export_ebp -#: view:res.partner:account_export_ebp.view_res_partner_search -msgid "Country" -msgstr "Pays" - -#. module: account_export_ebp -#: field:account.add.suffix,create_uid:0 -#: field:account.add.suffix.line,create_uid:0 -#: field:account.export.ebp,create_uid:0 -#: field:account.unexport.ebp,create_uid:0 -#: field:ebp.export,create_uid:0 +#: field:ebp.export,create_uid:0 field:wizard.ebp.export,create_uid:0 +#: field:wizard.ebp.unexport,create_uid:0 +#: field:wizard.res.partner.add.suffix,create_uid:0 +#: field:wizard.res.partner.add.suffix.line,create_uid:0 msgid "Created by" msgstr "Created by" #. module: account_export_ebp -#: field:account.add.suffix,create_date:0 -#: field:account.add.suffix.line,create_date:0 -#: field:account.export.ebp,create_date:0 -#: field:account.unexport.ebp,create_date:0 -#: field:ebp.export,create_date:0 +#: field:ebp.export,create_date:0 field:wizard.ebp.export,create_date:0 +#: field:wizard.ebp.unexport,create_date:0 +#: field:wizard.res.partner.add.suffix,create_date:0 +#: field:wizard.res.partner.add.suffix.line,create_date:0 msgid "Created on" msgstr "Created on" #. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:468 +#, python-format +msgid "Credit" +msgstr "Crédit" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:470 +#, python-format +msgid "Credit Balance" +msgstr "Balance Crédit" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:319 +#, python-format +msgid "Currency" +msgstr "Monnaie" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:311 #: field:ebp.export,date:0 +#, python-format msgid "Date" msgstr "Date" #. module: account_export_ebp -#: field:account.export.ebp,description:0 -#: field:ebp.export,description:0 +#: code:addons/account_export_ebp/models/ebp_export.py:467 +#, python-format +msgid "Debit" +msgstr "Débit" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:469 +#, python-format +msgid "Debit Balance" +msgstr "Balance Débit" + +#. module: account_export_ebp +#: field:res.company,ebp_default_analytic_account_id:0 +msgid "Default Analytic Account for EBP" +msgstr "Compte analytique par défaut pour EBP" + +#. module: account_export_ebp +#: view:ebp.export:account_export_ebp.view_ebp_export_form +#: field:ebp.export,description:0 field:wizard.ebp.export,description:0 msgid "Description" msgstr "Description" #. module: account_export_ebp -#: field:account.add.suffix,display_name:0 -#: field:account.add.suffix.line,display_name:0 -#: field:account.export.ebp,display_name:0 -#: field:account.unexport.ebp,display_name:0 -#: field:ebp.export,display_name:0 +#: code:addons/account_export_ebp/models/ebp_export.py:317 +#, python-format +msgid "Direction" +msgstr "Direction" + +#. module: account_export_ebp +#: field:ebp.export,display_name:0 field:wizard.ebp.export,display_name:0 +#: field:wizard.ebp.unexport,display_name:0 +#: field:wizard.res.partner.add.suffix,display_name:0 +#: field:wizard.res.partner.add.suffix.line,display_name:0 msgid "Display Name" msgstr "Display Name" #. module: account_export_ebp -#: field:account.export.ebp,download_file:0 -msgid "Download file" -msgstr "Télécharger le fichier" +#: selection:wizard.ebp.export,state:0 +msgid "Done" +msgstr "Terminé" #. module: account_export_ebp -#: model:ir.ui.menu,name:account_export_ebp.menu_export_ebp -msgid "EBP" -msgstr "EBP" +#: selection:wizard.ebp.export,state:0 +msgid "Draft" +msgstr "En brouillon" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:318 +#, python-format +msgid "Due Date" +msgstr "Date d'échéance" #. module: account_export_ebp -#: view:res.company:account_export_ebp.view_res_company_form -msgid "EBP Accounting Software" -msgstr "EBP Comptabilité" +#: model:ir.ui.menu,name:account_export_ebp.menu_ebp +msgid "EBP" +msgstr "EBP" #. module: account_export_ebp #: field:account.journal,ebp_code:0 @@ -202,118 +245,79 @@ msgid "EBP Code" msgstr "Code EBP" #. module: account_export_ebp +#: field:account.move,ebp_export_id:0 #: view:ebp.export:account_export_ebp.view_ebp_export_form -#: view:ebp.export:account_export_ebp.view_ebp_export_tree +#: field:wizard.ebp.export,ebp_export_id:0 msgid "EBP Export" msgstr "Export EBP" #. module: account_export_ebp #: model:ir.actions.act_window,name:account_export_ebp.action_ebp_export +#: model:ir.ui.menu,name:account_export_ebp.menu_ebp_export msgid "EBP Exports" -msgstr "EBP Exports" - -#. module: account_export_ebp -#: field:account.fiscalyear,ebp_nb:0 -msgid "EBP Fiscal Year Number" -msgstr "Numéro d'exercice EBP" - -#. module: account_export_ebp -#: field:res.company,ebp_uri:0 -msgid "EBP Share URI" -msgstr "URI du partage EBP" - -#. module: account_export_ebp -#: field:res.company,ebp_trigram:0 -msgid "EBP Trigram" -msgstr "Trigramme EBP" - -#. module: account_export_ebp -#: field:res.company,ebp_domain:0 -msgid "EBP User Domain" -msgstr "Domaine de l'utilisateur EBP" - -#. module: account_export_ebp -#: field:res.company,ebp_username:0 -msgid "EBP User Name" -msgstr "Nom d'utilisateur EBP" +msgstr "Exports EBP" #. module: account_export_ebp -#: field:res.company,ebp_password:0 -msgid "EBP User Password" -msgstr "Mot de passe de l'utilisateur EBP" +#: field:ebp.export,ebp_move_ids:0 +msgid "EBP Moves" +msgstr "EBP Moves" #. module: account_export_ebp -#: model:ir.ui.menu,name:account_export_ebp.menu_account_ebp_export -msgid "EBP exports" -msgstr "Exports EBP" +#: field:ebp.export,ebp_move_qty:0 +msgid "EBP Moves Quantity" +msgstr "EBP Moves Quantity" #. module: account_export_ebp -#: field:account.export.ebp,empty_suffixes_partner:0 -msgid "Empty Suffixes Partners" -msgstr "Suffixes Partenaires vides" +#: field:wizard.res.partner.add.suffix.line,ebp_suffix:0 +msgid "EBP Suffix" +msgstr "Suffixe EBP" #. module: account_export_ebp -#: field:account.export.ebp,empty_suffixes_tax:0 -msgid "Empty Suffixes Taxes" -msgstr "Suffixes de Taxes vides" +#: field:res.company,ebp_analytic_enabled:0 +msgid "Enable Analytic in EBP" +msgstr "Activer l'analytique dans EBP" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form msgid "Export" msgstr "Export" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "Export Complete" -msgstr "Export Terminé" - -#. module: account_export_ebp -#: selection:account.export.ebp,state:0 -msgid "Export Done" -msgstr "Export Terminé" - -#. module: account_export_ebp -#: field:account.account,export_tax_code:0 -#: field:account.export.ebp,tax_code_suffix:0 -msgid "Export according to Tax Codes" -msgstr "Exporter selon le Code de Taxe" +#: model:ir.actions.act_window,name:account_export_ebp.action_wizard_ebp_export +msgid "Export to EBP" +msgstr "Exporter dans EBP" #. module: account_export_ebp -#: model:ir.actions.act_window,name:account_export_ebp.action_account_export_ebp -msgid "Export to EBP" -msgstr "Export to EBP" +#: field:account.account,ebp_export_tax_code:0 +msgid "Export to EBP according to Tax Codes" +msgstr "Exporter dans EBP selon les codes de taxes" #. module: account_export_ebp -#: field:ebp.export,exported_moves_ids:0 +#: field:wizard.ebp.export,exported_move_ids:0 msgid "Exported Moves" msgstr "Pièces exportées" #. module: account_export_ebp -#: code:addons/account_export_ebp/model/account_move.py:42 -#: code:addons/account_export_ebp/model/account_move.py:55 -#, python-format -msgid "Exported move!" -msgstr "Pièce exportée!" - -#. module: account_export_ebp -#: help:account.export.ebp,description:0 -#: help:ebp.export,description:0 +#: help:ebp.export,description:0 help:wizard.ebp.export,description:0 msgid "Extra Description for Accountant Manager." msgstr "Description supplémentaire pour le comptable." #. module: account_export_ebp -#: field:account.export.ebp,data_accounts:0 -#: field:account.export.ebp,data_balance:0 -#: field:account.export.ebp,data_moves:0 -msgid "File" -msgstr "Fichier" +#: field:ebp.export,file_name_accounts:0 +#: field:wizard.ebp.export,file_name_accounts:0 +msgid "File name accounts" +msgstr "File name accounts" #. module: account_export_ebp -#: field:account.export.ebp,name_accounts:0 -#: field:account.export.ebp,name_balance:0 -#: field:account.export.ebp,name_moves:0 -msgid "File Name" -msgstr "Nom du fichier" +#: field:ebp.export,file_name_balance:0 +#: field:wizard.ebp.export,file_name_balance:0 +msgid "File name balance" +msgstr "File name balance" + +#. module: account_export_ebp +#: field:ebp.export,file_name_moves:0 field:wizard.ebp.export,file_name_moves:0 +msgid "File name moves" +msgstr "File name moves" #. module: account_export_ebp #: view:ebp.export:account_export_ebp.view_ebp_export_form @@ -321,66 +325,67 @@ msgid "Files" msgstr "Fichiers" #. module: account_export_ebp -#: model:ir.model,name:account_export_ebp.model_account_fiscalyear -msgid "Fiscal Year" -msgstr "Exercice comptable" - -#. module: account_export_ebp -#: field:account.export.ebp,fiscalyear_id:0 -#: field:ebp.export,fiscalyear_id:0 +#: field:ebp.export,fiscalyear_id:0 field:wizard.ebp.export,fiscalyear_id:0 msgid "Fiscal year" msgstr "Exercice fiscal" #. module: account_export_ebp -#: view:ebp.export:account_export_ebp.view_ebp_export_search -msgid "Group by..." -msgstr "Regrouper par ..." +#: field:account.tax.code,has_ebp_move_line:0 +#: field:res.partner,has_ebp_move_line:0 +msgid "Has Account Move Lines exportable in EBP" +msgstr "A des écritures comptables exportables dans EBP" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -#: view:ebp.export:account_export_ebp.view_ebp_export_form -msgid "Here is the exported moves file:" -msgstr "Voici le fichier des écritures comptables:" - -#. module: account_export_ebp -#: field:account.add.suffix,id:0 -#: field:account.add.suffix.line,id:0 -#: field:account.export.ebp,id:0 -#: field:account.unexport.ebp,id:0 -#: field:ebp.export,id:0 +#: field:ebp.export,id:0 field:wizard.ebp.export,id:0 +#: field:wizard.ebp.unexport,id:0 field:wizard.res.partner.add.suffix,id:0 +#: field:wizard.res.partner.add.suffix.line,id:0 msgid "ID" msgstr "ID" #. module: account_export_ebp -#: help:account.account,export_tax_code:0 +#: help:account.account,ebp_export_tax_code:0 msgid "If checked, when you export moves from this account, it will create one account for each Tax Code" -msgstr "Si cette case est cochée, quand vous exportez les écriture de ce compte vers EBP, cela va créer un compte pour chaque code de taxe." +msgstr "Si coché, quand vous exportez des écritures comptables liées à ce compte, cela créera un compte pour chaque code de taxe" #. module: account_export_ebp -#: field:account.export.ebp,ignore_draft:0 -msgid "Ignore draft moves" -msgstr "Ignorer les pièces en brouillon" +#: field:wizard.ebp.export,ignored_draft_move_qty:0 +msgid "Ignored draft move qty" +msgstr "Ignored draft move qty" #. module: account_export_ebp -#: field:account.export.ebp,ignore_exported:0 -msgid "Ignore moves already exported" -msgstr "Ignorer les pièces déjà exportées" +#: field:wizard.ebp.export,ignored_exported_move_qty:0 +msgid "Ignored exported move qty" +msgstr "Ignored exported move qty" #. module: account_export_ebp -#: field:account.export.ebp,ignore_unchecked:0 -msgid "Ignore unchecked moves" -msgstr "Ignorer les pièces non contrôlées" +#: field:wizard.ebp.export,ignored_journal_code_move_qty:0 +msgid "Ignored journal code move qty" +msgstr "Ignored journal code move qty" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:397 -#, python-format -msgid "Incorrect Setting" -msgstr "Paramétrage incorrect" +#: field:wizard.ebp.export,ignored_partner_move_qty:0 +msgid "Ignored partner move qty" +msgstr "Ignored partner move qty" #. module: account_export_ebp -#: help:account.move,exported_ebp_id:0 +#: field:wizard.ebp.export,ignored_period_move_qty:0 +msgid "Ignored period move qty" +msgstr "Ignored period move qty" + +#. module: account_export_ebp +#: field:wizard.ebp.export,ignored_tax_code_move_qty:0 +msgid "Ignored tax code move qty" +msgstr "Ignored tax code move qty" + +#. module: account_export_ebp +#: field:wizard.ebp.export,ignored_to_check_move_qty:0 +msgid "Ignored to check move qty" +msgstr "Ignored to check move qty" + +#. module: account_export_ebp +#: help:account.move,ebp_export_id:0 msgid "Indicates whether the move has already been exported to EBP or not. It is changed automatically." -msgstr "Indique si la pièce comptable a été exportée vers EBP. Automatiquement actualisé." +msgstr "Indiquer si la pièce a déjà été exportées dans EBP ou pas. Valeur changée automatiquement." #. module: account_export_ebp #: model:ir.model,name:account_export_ebp.model_account_journal @@ -388,10 +393,10 @@ msgid "Journal" msgstr "Journal" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:415 +#: code:addons/account_export_ebp/models/ebp_export.py:312 #, python-format -msgid "Journal '%s' has no EBP Code defined." -msgstr "Le journal '%s' n'a pas de code EBP défini." +msgid "Journal Code" +msgstr "Code Journal" #. module: account_export_ebp #: view:account.move:account_export_ebp.view_account_move_search @@ -399,69 +404,60 @@ msgid "Journal Entries not yet exported to EBP" msgstr "Pièces comptables non exportées vers EBP" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:420 -#, python-format -msgid "Journal code '%s' is too long to be exported to EBP." -msgstr "Le code du journal '%s' est trop long pour être exporter vers EBP." - -#. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:414 -#, python-format -msgid "Journal code Undefined" -msgstr "Code du journal non défini" - -#. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:419 -#, python-format -msgid "Journal code too long" -msgstr "Code de journal trop long" +#: view:ebp.export:account_export_ebp.view_ebp_export_form +#: model:ir.actions.act_window,name:account_export_ebp.action_account_move_from_ebp_export +msgid "Journal Items" +msgstr "Écritures comptables" #. module: account_export_ebp -#: field:account.add.suffix,__last_update:0 -#: field:account.add.suffix.line,__last_update:0 -#: field:account.export.ebp,__last_update:0 -#: field:account.unexport.ebp,__last_update:0 -#: field:ebp.export,__last_update:0 +#: field:ebp.export,__last_update:0 field:wizard.ebp.export,__last_update:0 +#: field:wizard.ebp.unexport,__last_update:0 +#: field:wizard.res.partner.add.suffix,__last_update:0 +#: field:wizard.res.partner.add.suffix.line,__last_update:0 msgid "Last Modified on" msgstr "Last Modified on" #. module: account_export_ebp -#: field:account.add.suffix,write_uid:0 -#: field:account.add.suffix.line,write_uid:0 -#: field:account.export.ebp,write_uid:0 -#: field:account.unexport.ebp,write_uid:0 -#: field:ebp.export,write_uid:0 +#: field:ebp.export,write_uid:0 field:wizard.ebp.export,write_uid:0 +#: field:wizard.ebp.unexport,write_uid:0 +#: field:wizard.res.partner.add.suffix,write_uid:0 +#: field:wizard.res.partner.add.suffix.line,write_uid:0 msgid "Last Updated by" msgstr "Last Updated by" #. module: account_export_ebp -#: field:account.add.suffix,write_date:0 -#: field:account.add.suffix.line,write_date:0 -#: field:account.export.ebp,write_date:0 -#: field:account.unexport.ebp,write_date:0 -#: field:ebp.export,write_date:0 +#: field:ebp.export,write_date:0 field:wizard.ebp.export,write_date:0 +#: field:wizard.ebp.unexport,write_date:0 +#: field:wizard.res.partner.add.suffix,write_date:0 +#: field:wizard.res.partner.add.suffix.line,write_date:0 msgid "Last Updated on" msgstr "Last Updated on" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:431 +#: code:addons/account_export_ebp/models/ebp_export.py:310 #, python-format -msgid "Move name '%s' is too long to be exported to EBP." -msgstr "Le nom de l'écriture '%s' est trop long pour être exporter vers EBP." +msgid "Line" +msgstr "Ligne" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:431 +#: field:wizard.res.partner.add.suffix,line_ids:0 +msgid "Lines" +msgstr "Lignes" + +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:104 #, python-format -msgid "Move name too long" -msgstr "Nom d'écriture trop long" +msgid "MOVES" +msgstr "ECRITURES" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "Moves exported to EBP" -msgstr "Pièces exportées vers EBP" +#: code:addons/account_export_ebp/models/ebp_export.py:315 +#, python-format +msgid "Move Number" +msgstr "N° Pièce" #. module: account_export_ebp -#: field:ebp.export,data_moves:0 +#: field:ebp.export,data_moves:0 field:wizard.ebp.export,data_moves:0 msgid "Moves file" msgstr "Fichier des écritures comptables" @@ -470,107 +466,71 @@ msgstr "Fichier des écritures comptables" msgid "My Partners" msgstr "Mes partenaires" +#. module: account_export_ebp +#: code:addons/account_export_ebp/models/ebp_export.py:314 +#: field:ebp.export,name:0 +#, python-format +msgid "Name" +msgstr "Nom" + #. module: account_export_ebp #: view:account.move:account_export_ebp.view_account_move_search msgid "Not Exported" msgstr "Non transféré" #. module: account_export_ebp -#: help:res.partner,nb_moves:0 -msgid "Number of account moves for this partner" -msgstr "Nombre de pièces comptables pour ce partenaire" - -#. module: account_export_ebp -#: help:account.tax.code,nb_moves:0 -msgid "Number of account moves for this tax code" -msgstr "Nombre de pièces comptables pour ce code de taxe" - -#. module: account_export_ebp -#: field:account.export.ebp,exported_accounts:0 -#: field:ebp.export,exported_accounts:0 -msgid "Number of accounts exported" -msgstr "Nombre de comptes exportés" - -#. module: account_export_ebp -#: field:account.export.ebp,exported_lines:0 -#: field:ebp.export,exported_lines:0 -msgid "Number of lines exported" -msgstr "Nombre de lignes exportées" - -#. module: account_export_ebp -#: field:account.tax.code,nb_moves:0 -#: field:res.partner,nb_moves:0 -msgid "Number of moves" -msgstr "Nombre de pièces comptables" - -#. module: account_export_ebp -#: field:account.export.ebp,exported_moves:0 -#: field:ebp.export,exported_moves:0 -msgid "Number of moves exported" -msgstr "Nombre de pièces exportées" - -#. module: account_export_ebp -#: field:account.export.ebp,ignored_moves:0 -#: field:ebp.export,ignored_moves:0 -msgid "Number of moves ignored" -msgstr "Nombre de pièces ignorées" - -#. module: account_export_ebp -#: help:account.export.ebp,fiscalyear_id:0 +#: help:wizard.ebp.export,fiscalyear_id:0 msgid "Only the moves in this fiscal will be exported" -msgstr "Seuls les pièces appartenant à cette exercice fiscal seront exportée" - -#. module: account_export_ebp -#: view:res.partner:account_export_ebp.view_res_partner_search -msgid "Parent" -msgstr "Parent" +msgstr "Seulement les pièces de cet exercice seront exportées" #. module: account_export_ebp -#: field:account.add.suffix.line,partner_id:0 #: model:ir.model,name:account_export_ebp.model_res_partner -#: view:res.partner:account_export_ebp.view_res_partner_tree_suffix +#: view:res.partner:account_export_ebp.view_res_partner_tree +#: field:wizard.res.partner.add.suffix.line,partner_id:0 msgid "Partner" msgstr "Partenaire" #. module: account_export_ebp +#: model:ir.actions.act_window,name:account_export_ebp.action_res_partner #: model:ir.ui.menu,name:account_export_ebp.menu_partner_suffix -msgid "Partner Suffix" -msgstr "Suffixe du partenaire" - -#. module: account_export_ebp -#: model:ir.actions.act_window,name:account_export_ebp.action_res_partner_suffix msgid "Partner Suffixes" msgstr "Suffixes de partenaires" #. module: account_export_ebp -#: field:res.partner,ref_nb:0 -msgid "Partner's Account suffix in EBP" -msgstr "Suffixe du compte de tiers dans EBP" +#: code:addons/account_export_ebp/models/ebp_export.py:322 +#, python-format +msgid "Payment Mode" +msgstr "Mode de paiement" #. module: account_export_ebp -#: help:account.export.ebp,ignore_draft:0 -msgid "Please be aware that draft moves do not not have a move number attached to them. As a consequence, they might not be imported correctly into EBP accounting software" -msgstr "Gardez à l'esprit que les pièces en brouillon n'ont pas de numéro. Elle peuvent donc ne pas être importées correctement dans EBP." +#: view:account.move:account_export_ebp.view_account_move_search +msgid "Posted" +msgstr "Validé" #. module: account_export_ebp -#: help:account.export.ebp,ignore_unchecked:0 -msgid "Please be aware that unchecked moves belong maybe some errors." -msgstr "Gardez à l'esprit que les pièces non contrôlées peuvent contenir des erreurs." +#: field:wizard.ebp.export,exported_move_qty:0 +msgid "Quantity of Exported Moves" +msgstr "Nombre de pièces exportées" #. module: account_export_ebp -#: view:account.move:account_export_ebp.view_account_move_search -msgid "Posted" -msgstr "Validé" +#: field:ebp.export,exported_move_qty:0 +msgid "Quantity of Moves Exported" +msgstr "Nombre de pièces exportées" + +#. module: account_export_ebp +#: field:wizard.ebp.export,selected_move_qty:0 +msgid "Quantity of Selected Moves" +msgstr "Nombre de pièces sélectionnées" #. module: account_export_ebp -#: selection:account.export.ebp,state:0 -msgid "Prepare Export" -msgstr "Preparation Export" +#: field:ebp.export,exported_account_qty:0 +msgid "Quantity of accounts exported" +msgstr "Nombre de comptes exportés" #. module: account_export_ebp -#: selection:account.export.ebp,state:0 -msgid "Ready to download" -msgstr "Prêt à télécharger" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "Results" +msgstr "Résultats" #. module: account_export_ebp #: view:account.tax.code:account_export_ebp.view_account_tax_code_search @@ -578,91 +538,78 @@ msgid "Search Tax Code" msgstr "Chercher un Code de Taxe" #. module: account_export_ebp -#: field:account.add.suffix.line,suffix:0 -msgid "Suggested EBP Suffix" -msgstr "Suffixe suggéré" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "Settings" +msgstr "Paramétrages" + +#. module: account_export_ebp +#: field:wizard.ebp.export,state:0 +msgid "State" +msgstr "Etat" #. module: account_export_ebp -#: view:account.tax.code:account_export_ebp.view_account_tax_code_tree_suffix +#: field:account.tax.code,ebp_suffix:0 field:res.partner,ebp_suffix:0 +msgid "Suffix in EBP" +msgstr "Suffix in EBP" + +#. module: account_export_ebp +#: view:account.tax.code:account_export_ebp.view_account_tax_code_tree #: model:ir.model,name:account_export_ebp.model_account_tax_code msgid "Tax Code" msgstr "Code de taxe" #. module: account_export_ebp -#: model:ir.ui.menu,name:account_export_ebp.menu_account_tax_code_suffix -msgid "Tax Code Suffix" -msgstr "Suffixe de Code de Taxe" - -#. module: account_export_ebp -#: model:ir.actions.act_window,name:account_export_ebp.action_account_tax_code_suffix +#: model:ir.actions.act_window,name:account_export_ebp.action_account_tax_code msgid "Tax Code Suffix View" msgstr "Tax Code Suffix View" #. module: account_export_ebp -#: field:account.tax.code,ref_nb:0 -msgid "Tax Code's Account suffix in EBP" -msgstr "Suffixe du Code Taxe dans EBP" +#: field:account.account,ebp_code_no_tax:0 +msgid "Tax Code Suffix in EBP (if no tax)" +msgstr "Suffixe de code de taxe dans EBP (si pas de taxe)" #. module: account_export_ebp -#: field:account.account,ebp_code_no_tax:0 -msgid "Tax Code's Account suffix in EBP (if no tax)" -msgstr "Suffixe du Code Taxe dans EBP (si pas de taxe)" +#: model:ir.ui.menu,name:account_export_ebp.menu_account_tax_code +msgid "Tax Code Suffixes" +msgstr "Suffixes de code de taxe" #. module: account_export_ebp -#: help:res.company,ebp_uri:0 -msgid "The URI of the network share containing the company's EBP folder. Format: smb://SERVER/SHARE/DIR" -msgstr "The URI of the network share containing the company's EBP folder. Format: smb://SERVER/SHARE/DIR" +#: sql_constraint:res.partner:0 +msgid "The EBP suffix must be unique per company!" +msgstr "Le suffixe EBP doit être unique par société" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:400 +#: code:addons/account_export_ebp/models/ebp_export.py:244 #, python-format -msgid "The account %s - %s is set 'export with tax suffix' but no tax suffix is defined for the account.\n" +msgid "" +"The account %s - %s is set 'export with tax suffix' but no tax suffix is defined for the account.\n" +" Move %s" +msgstr "" +"The account %s - %s is set 'export with tax suffix' but no tax suffix is defined for the account.\n" " Move %s" -msgstr "Le compte %s - %s est paramétré avec l'option 'Exporter avec le suffixe de taxe' mais aucun suffixe de taxe n'est défini.\n" -" Pièce comptable : %s" - -#. module: account_export_ebp -#: constraint:account.account:0 -msgid "The account code for a partner account cannot exceed\n" -" * 3 characters for Fiscal Mother Company (Regular Case);\n" -" * 6 characters for Fiscal Mother Company (Intercompany Trade);\n" -" * 6 characters for Normal Company ; \n" -" so as to permit the EBP export" -msgstr "Le code pour un partenaire ne peut pas excéder\n" -" * 3 caractères pour les sociétés intégrées (Cas normal);\n" -" * 6 caractères pour les sociétés intégrées (Achat Inter société);\n" -" * 6 caractères pour les sociétés normales ; \n" -" cela, pour permettre l'export EBP" - -#. module: account_export_ebp -#: help:res.company,ebp_domain:0 -msgid "The domain of the user to access the company's EBP folder." -msgstr "Le domaine de l'utilisateur pour accéder au dossier EBP de la société." - -#. module: account_export_ebp -#: view:account.unexport.ebp:account_export_ebp.view_account_unexport_ebp_form -msgid "The export will be canceled for the selected moves." -msgstr "L'export sera annulé pour les pièces sélectionnées." #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "The file was saved in the EBP folder." -msgstr "Le fichier a été enregistré dans le répertoire EBP." +#: code:addons/account_export_ebp/models/account_account.py:47 +#, python-format +msgid "The account code for a partner account cannot exceed 3 characters for Fiscal Mother Company (Regular Case) so as to permit the EBP export" +msgstr "The account code for a partner account cannot exceed 3 characters for Fiscal Mother Company (Regular Case) so as to permit the EBP export" #. module: account_export_ebp -#: help:res.company,ebp_username:0 -msgid "The name of the user to access the company's EBP folder." -msgstr "Le nom de l'utilisateur pour accéder au dossier EBP." +#: code:addons/account_export_ebp/models/account_account.py:39 +#, python-format +msgid "The account code for a partner account cannot exceed 6 characters for Fiscal Mother Company (Intercompany Trade) so as to permit the EBP export" +msgstr "The account code for a partner account cannot exceed 6 characters for Fiscal Mother Company (Intercompany Trade) so as to permit the EBP export" #. module: account_export_ebp -#: sql_constraint:res.partner:0 -msgid "The partner suffix must be unique per company!" -msgstr "Le suffixe du partenaire doit être unique pour une société!" +#: code:addons/account_export_ebp/models/account_account.py:55 +#, python-format +msgid "The account code for a partner account cannot exceed 6 characters for Normal Company so as to permit the EBP export" +msgstr "The account code for a partner account cannot exceed 6 characters for Normal Company so as to permit the EBP export" #. module: account_export_ebp -#: help:res.company,ebp_password:0 -msgid "The password of the user to access the company's EBP folder." -msgstr "Le mot de passe pour accéder au dossier EBP de la société." +#: view:wizard.ebp.unexport:account_export_ebp.view_wizard_ebp_unexport_form +msgid "The export will be canceled for the selected moves. Be sure to delete the corresponding lines in EBP." +msgstr "The export will be canceled for the selected moves. Be sure to delete the corresponding lines in EBP." #. module: account_export_ebp #: help:account.journal,ebp_code:0 @@ -670,109 +617,85 @@ msgid "This code will be used when exporting entries in the journal column" msgstr "Ce code sera utilisé lors de l'export des écritures dans la colonne journal" #. module: account_export_ebp -#: help:account.fiscalyear,ebp_nb:0 -msgid "This value should reflect the number of the fiscal year as used by the EBP accounting software. This should be set to the number of fiscal years recorded in EBP accounting before this one - So for the first year the number is 0, for the second year the number is 1 and so on. This is used for exporting accounting moves to EBP." -msgstr "Cette valeur doit refléter le numéro d'exercice utilisé dans EBP Comptabilité. Indiquez le nombre d'exercice enregistrés dans EBP avant celui-ci : ainsi pour le premier exercice indiquez 0 ; pour le second indiquez 1 etc. Cette information est utilisée lors de l'exportation des écritures vers EBP." - -#. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:302 -#, python-format -msgid "This wizard should only be used on accounting moves" -msgstr "Cet assistant ne peut être utilisé que sur des écritures comptables" - -#. module: account_export_ebp -#: field:account.move,exported_ebp_id:0 -msgid "Transfer id" -msgstr "Export" - -#. module: account_export_ebp -#: view:account.unexport.ebp:account_export_ebp.view_account_unexport_ebp_form +#: view:wizard.ebp.unexport:account_export_ebp.view_wizard_ebp_unexport_form msgid "Unexport" -msgstr "Annuler l'export" - -#. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "Warning! Some Tax Codes don't have a suffix." -msgstr "Attention! Certains Codes de Taxe utilisés n'ont pas de suffixe." - -#. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "Warning! Some partners don't have a suffix." -msgstr "Attention! Certains partenaires n'ont pas de suffixe." +msgstr "Unexport" #. module: account_export_ebp -#: help:res.partner,ref_nb:0 +#: help:res.partner,ebp_suffix:0 msgid "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a Partner Account." -msgstr "Lors de l'export d'écriture vers EBP, le suffixe sera ajouté au numéro de compte pour créer le numéro de compte du partenaire." +msgstr "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a Partner Account." #. module: account_export_ebp #: help:account.account,ebp_code_no_tax:0 -msgid "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a new Account, if Export according to tax Codes is checked, and if no taxes is defined on the account move line." -msgstr "Lors de l'export d'écriture vers EBP, ce suffixe sera ajouté au numéro de compte pour créer le numéro de compte, si l'export selon les taxes est activés et qu'aucune taxe n'est définie sur l'écriture comptable." +msgid "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a new Account, if 'Export to EBP according to Tax Codes' is checked, and if no taxes is defined on the account move line." +msgstr "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a new Account, if 'Export to EBP according to Tax Codes' is checked, and if no taxes is defined on the account move line." #. module: account_export_ebp -#: help:account.tax.code,ref_nb:0 +#: help:account.tax.code,ebp_suffix:0 msgid "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a new Account." -msgstr "Lors de l'export d'écriture vers EBP, le suffixe sera ajouté au numéro de compte pour créer un nouveau numéro de compte." +msgstr "When exporting Entries to EBP, this suffix will be appended to the Account Number to make it a new Account." #. module: account_export_ebp -#: help:account.export.ebp,company_suffix:0 -msgid "When this is checked, the company's code will be appended to the receivable and payable accounts' numbers in the exported files on every move line." -msgstr "Si cette case est cochée, le code de la société sera ajouté au code du compte pour l'export." - -#. module: account_export_ebp -#: help:account.export.ebp,partner_accounts:0 -msgid "When this is checked, the partner's special code will be appended to the receivable and payable accounts' numbers in the exported files on every move line where a partner has been specified." -msgstr "Si cette case est cochée, le suffixe du partenaire sera ajouté au compte pour toutes les pièces associées à un partenaire." +#: view:account.tax.code:account_export_ebp.view_account_tax_code_search +#: view:res.partner:account_export_ebp.view_res_partner_search +msgid "With Lines Moves exportable into EBP" +msgstr "With Lines Moves exportable into EBP" #. module: account_export_ebp #: view:account.tax.code:account_export_ebp.view_account_tax_code_search #: view:res.partner:account_export_ebp.view_res_partner_search -msgid "With moves" -msgstr "Avec écritures" +msgid "Without EBP Suffix" +msgstr "Without EBP Suffix" #. module: account_export_ebp #: view:account.tax.code:account_export_ebp.view_account_tax_code_search #: view:res.partner:account_export_ebp.view_res_partner_search -msgid "Without suffix" -msgstr "Sans suffixe" +msgid "Without Suffixes And with Exportable Move Lines into EBP" +msgstr "Without Suffixes And with Exportable Move Lines into EBP" #. module: account_export_ebp -#: code:addons/account_export_ebp/wizard/wizard_ebp.py:301 -#, python-format -msgid "Wrong Object" -msgstr "Objet incorrect" +#: field:wizard.res.partner.add.suffix.line,wizard_id:0 +msgid "Wizard id" +msgstr "Wizard id" #. module: account_export_ebp -#: code:addons/account_export_ebp/model/account_move.py:56 +#: code:addons/account_export_ebp/models/account_move.py:40 #, python-format -msgid "You cannot delete exported moves: %s!" -msgstr "Vous ne pouvez pas supprimer des pièces exportées: %s!" +msgid "You cannot modify or delete exported moves: %s!" +msgstr "You cannot modify or delete exported moves: %s!" #. module: account_export_ebp -#: code:addons/account_export_ebp/model/account_move.py:43 -#, python-format -msgid "You cannot modify exported moves: %s!" -msgstr "Vous ne pouvez pas modifier des pièces exportées: %s!" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "You have selected" +msgstr "Vous avez sélectionné" #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "You may need to close and reopen the folder for EBP to detect the new data files." -msgstr "Redémarrez EBP pour prendre en compte ces fichiers." +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "draft moves." +msgstr "pièces en brouillon." #. module: account_export_ebp -#: view:account.export.ebp:account_export_ebp.view_account_export_ebp_form -msgid "You should run the wizard to populate them before exporting." -msgstr "Vous devriez lancer l'utilitaire pour les remplir avant d'exporter." +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "moves related to partners without EBP suffixes defined." +msgstr "pièces liées à des partenaires sans suffixes EBP définis." #. module: account_export_ebp -#: field:account.move,exported_ebp:0 -msgid "export id" -msgstr "# export" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "moves that are marked as 'To check'." +msgstr "pièces qui sont marquées \"à vérifier\"." #. module: account_export_ebp -#: field:account.export.ebp,state:0 -#: field:ebp.export,name:0 -msgid "unknown" -msgstr "Nom" +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "moves that belong to a journal that doesn't have a correct 'EBP code' set." +msgstr "pièces qui appartiennent à un journal qui n'a pas de code EBP défini." +#. module: account_export_ebp +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "moves that doesn't belong to the selected fiscal year." +msgstr "pièces qui n'appartiennent pas à l'année fiscale sélectionnée." + +#. module: account_export_ebp +#: view:wizard.ebp.export:account_export_ebp.view_wizard_ebp_export_form +msgid "moves that have already been exported in EBP." +msgstr "pièces qui ont déjà été exportées dans EBP" diff --git a/account_export_ebp/models/__init__.py b/account_export_ebp/models/__init__.py index 3ecde81..ef1652e 100644 --- a/account_export_ebp/models/__init__.py +++ b/account_export_ebp/models/__init__.py @@ -1,10 +1,9 @@ # coding: utf-8 -from . import res_partner -from . import res_company from . import account_account from . import account_journal from . import account_move -from . import account_fiscalyear -from . import ebp_export from . import account_tax_code +from . import ebp_export +from . import res_company +from . import res_partner diff --git a/account_export_ebp/models/account_account.py b/account_export_ebp/models/account_account.py index 297b6e0..aa048fe 100644 --- a/account_export_ebp/models/account_account.py +++ b/account_export_ebp/models/account_account.py @@ -5,58 +5,54 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model +from openerp import _, api, fields, models +from openerp.exceptions import Warning as UserError -class account_account(Model): + +class AccountAccount(models.Model): _inherit = 'account.account' # Columns section - _columns = { - 'code': fields.char('Code', size=10, required=True, select=1), - 'export_tax_code': fields.boolean( - 'Export according to Tax Codes', - help="""If checked, when you export moves from this account,""" - """ it will create one account for each Tax Code"""), - 'ebp_code_no_tax': fields.char( - 'Tax Code\'s Account suffix in EBP (if no tax)', size=4, - help="When exporting Entries to EBP, this suffix will be" - " appended to the Account Number to make it a new Account," - " if Export according to tax Codes is checked, and" - " if no taxes is defined on the account move line."), - } + ebp_export_tax_code = fields.Boolean( + oldname='export_tax_code', + string='Export to EBP according to Tax Codes', + help="If checked, when you export moves from this account," + " it will create one account for each Tax Code") - # Defaults section - _defaults = { - 'export_tax_code': False, - } + ebp_code_no_tax = fields.Char( + string='Tax Code Suffix in EBP (if no tax)', + help="When exporting Entries to EBP, this suffix will be" + " appended to the Account Number to make it a new Account," + " if 'Export to EBP according to Tax Codes' is checked, and" + " if no taxes is defined on the account move line.") # Constraints section - def _check_code_length(self, cr, uid, ids, context=None): - for account in self.browse(cr, uid, ids, context=context): + @api.constrains( + 'code', 'type', 'company_id.fiscal_type', + 'is_intercompany_trade_fiscal_company') + def _constrains_code_length(self): + for account in self: if account.company_id.fiscal_type == 'fiscal_mother': if account.is_intercompany_trade_fiscal_company and\ len(account.code) > 6: - return False + raise UserError(_( + "The account code for a partner account cannot" + " exceed 6 characters for Fiscal Mother Company" + " (Intercompany Trade) so as to permit the EBP" + " export")) elif not account.is_intercompany_trade_fiscal_company and\ account.type in ('receivable', 'payable') and\ len(account.code) > 3: - return False - elif account.company_id.fiscal_type == 'normal': - if account.type in ('receivable', 'payable') and\ - len(account.code) > 6: - return False - return True - - _constraints = [ - ( - _check_code_length, - "The account code for a partner account cannot exceed\n" - " * 3 characters for Fiscal Mother Company (Regular Case);\n" - " * 6 characters for Fiscal Mother Company (Intercompany Trade);\n" - " * 6 characters for Normal Company ; \n" - " so as to permit the EBP export", - ['code', 'type', 'company_id', - 'is_intercompany_trade_fiscal_company']), - ] + raise UserError(_( + "The account code for a partner account cannot" + " exceed 3 characters for Fiscal Mother Company" + " (Regular Case) so as to permit the EBP" + " export")) + elif account.company_id.fiscal_type == 'normal': + if account.type in ('receivable', 'payable') and\ + len(account.code) > 6: + raise UserError(_( + "The account code for a partner account cannot" + " exceed 6 characters for Normal Company" + " so as to permit the EBP export")) diff --git a/account_export_ebp/models/account_fiscalyear.py b/account_export_ebp/models/account_fiscalyear.py deleted file mode 100644 index cf04a04..0000000 --- a/account_export_ebp/models/account_fiscalyear.py +++ /dev/null @@ -1,22 +0,0 @@ -# coding: utf-8 -# Copyright (C) 2010 - 2015: Numérigraphe SARL -# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) -# @author: Julien WESTE -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from openerp import fields, models - - -class AccountFiscalyear(models.Model): - _inherit = "account.fiscalyear" - - # TODO Set default, by computing the last number + 1 - ebp_nb = fields.Integer( - string='EBP Fiscal Year Number', default=0, - help="This value should reflect the number of the fiscal year" - " as used by the EBP accounting software. This should be set" - " to the number of fiscal years recorded in EBP accounting" - " before this one - So for the first year the number is 0," - " for the second year the number is 1 and so on. This is used" - " for exporting accounting moves to EBP.") diff --git a/account_export_ebp/models/account_move.py b/account_export_ebp/models/account_move.py index 3f5c8d6..ab352d8 100644 --- a/account_export_ebp/models/account_move.py +++ b/account_export_ebp/models/account_move.py @@ -5,63 +5,38 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields, osv -from openerp.tools.translate import _ +from openerp import _, api, fields, models +from openerp.exceptions import Warning as UserError -class account_move(osv.osv): - _inherit = "account.move" +class AccountMove(models.Model): + _inherit = 'account.move' - # Columns section - def _export_name(self, cr, uid, ids, field_name, arg, context=None): - result = {} - for move in self.browse(cr, uid, ids, context=context): - result[move.id] = move.exported_ebp_id\ - and 'export_' + str(move.exported_ebp_id.id) or '' - return result - - _columns = { - 'exported_ebp_id': fields.many2one( - 'ebp.export', 'Transfer id', - help="""Indicates whether the move has already been exported""" - """ to EBP or not. It is changed automatically."""), - 'exported_ebp': fields.function( - _export_name, type='char', string='export id', store=False), - } + # Column Section + ebp_export_id = fields.Many2one( + comodel_name='ebp.export', old_name='exported_ebp_id', + string='EBP Export', copy=False, + help="Indicates whether the move has already been exported" + " to EBP or not. It is changed automatically.") # Override section - def write(self, cr, uid, ids, vals, context=None): - """Refuse to change changes exported Moves""" - if 'exported_ebp_id' not in vals: - exported_move_ids = self.search( - cr, uid, [('exported_ebp_id', '!=', False), ('id', 'in', ids)]) - if exported_move_ids: - exported_moves = self.browse( - cr, uid, exported_move_ids, context=context) - raise osv.except_osv( - _('Exported move!'), - _('You cannot modify exported moves: %s!') + @api.multi + def write(self, vals): + self._check_exported_moves() + return super(AccountMove, self).write(vals) + + @api.multi + def unlink(self): + self._check_exported_moves() + return super(AccountMove, self).unlink() + + # Custom section + @api.multi + def _check_exported_moves(self): + if not self.env.context.get('force_write_ebp_exported', False): + exported_moves =\ + self.filtered(lambda x: x.ebp_export_id.id is not False) + if exported_moves: + raise UserError(_( + "You cannot modify or delete exported moves: %s!") % ', '.join([m.name for m in exported_moves])) - return super(osv.osv, self).write(cr, uid, ids, vals, context=context) - - def unlink(self, cr, uid, ids, context=None, check=True): - """Refuse to delete exported Moves""" - exported_move_ids = self.search( - cr, uid, [('exported_ebp_id', '!=', False), ('id', 'in', ids)]) - if exported_move_ids: - exported_moves = self.browse( - cr, uid, exported_move_ids, context=context) - raise osv.except_osv( - _('Exported move!'), - _('You cannot delete exported moves: %s!') - % ', '.join([m.name for m in exported_moves])) - return super(account_move, self).unlink(cr, uid, ids, context) - - def copy(self, cr, uid, pId, default=None, context=None): - if not default: - default = {} - default.update({ - 'exported_ebp_id': False, - }) - return super(account_move, self).copy( - cr, uid, pId, default, context=context) diff --git a/account_export_ebp/models/account_tax_code.py b/account_export_ebp/models/account_tax_code.py index 4adbe81..fcde9d0 100644 --- a/account_export_ebp/models/account_tax_code.py +++ b/account_export_ebp/models/account_tax_code.py @@ -5,54 +5,53 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model +from openerp import api, fields, models -class account_tax_code(Model): + +class AccountTaxCode(models.Model): _inherit = 'account.tax.code' - def _get_nb_moves(self, cr, uid, ids, name, arg, context=None): - res = {} - aml_obj = self.pool.get('account.move.line') - for aId in ids: - aml_ids = aml_obj.search(cr, uid, [ - ('tax_code_id', '=', aId), ('date', '>=', '01/12/2012')], - context=context) - res[aId] = len(aml_ids) - return res - - def _search_nb_moves(self, cr, uid, obj, name, args, context=None): - if not args: - return [] - query, query_args = self._get_search_moves_query( - cr, uid, args, overdue_only=False, context=context) - cr.execute(query, query_args) - res = cr.fetchall() - if not res: - return [('id', '=', '0')] - return [('id', 'in', [x[0] for x in res])] + # Columns section + ebp_suffix = fields.Char( + string="Suffix in EBP", oldname="ref_nb", + help="When exporting Entries to EBP, this suffix will be" + " appended to the Account Number to make it a new Account.") + + # TODO, check if usefull + # has_ebp_no_suffix = fields.Boolean( + # string='No EBP Suffix', help="Check this box if you want to ignore" + # " the warning, when exporting into EBP move lines that have this" + # " tax code.") + + has_ebp_move_line = fields.Boolean( + compute='_compute_has_ebp_move_line', + search='_search_has_ebp_move_line', + string='Has Account Move Lines exportable in EBP') # Columns section - _columns = { - 'ref_nb': fields.char( - 'Tax Code\'s Account suffix in EBP', size=4, - help="""When exporting Entries to EBP, this suffix will be""" - """ appended to the Account Number to make it a new Account."""), - 'nb_moves': fields.function( - _get_nb_moves, string='Number of moves', - fnct_search=_search_nb_moves, type='integer', - help="Number of account moves for this tax code"), - } - - # Private section - def _get_search_moves_query( - self, cr, uid, args, overdue_only=False, context=None): - having_where_clause = ' AND '.join( - map(lambda x: '(COUNT(*) %s %%s)' % (x[1]), args)) - having_values = [x[2] for x in args] - return "SELECT tax_code_id, count(*) \ - FROM account_move_line \ - WHERE date >= '01/12/2012' \ - GROUP BY tax_code_id \ - HAVING " + having_where_clause, having_values + @api.multi + def _compute_has_ebp_move_line(self): + AccountMoveLine = self.env['account.move.line'] + for tax_code in self: + tax_code.has_ebp_move_line = len(AccountMoveLine.search([ + ('tax_code_id', '=', tax_code.id), + ('date', '>=', self._SEARCH_DATE_BEGIN)])) + + @api.model + def _search_has_ebp_move_line(self, operator, value): + assert operator in ('=', '!='), 'Invalid domain operator' + assert value in (True, False), 'Invalid domain value' + + with_line = ( + (operator == '=' and value is True) or + (operator == '!=' and value is False)) + + self._cr.execute( + "SELECT tax_code_id, count(*)" + " FROM account_move_line" + " WHERE date >= '01/12/2012'" + " GROUP BY tax_code_id" + " HAVING count(*) > 0") + res = self._cr.fetchall() + return [('id', with_line and 'in' or 'not in', [x[0] for x in res])] diff --git a/account_export_ebp/models/ebp_export.py b/account_export_ebp/models/ebp_export.py index 95966e4..e69aefa 100644 --- a/account_export_ebp/models/ebp_export.py +++ b/account_export_ebp/models/ebp_export.py @@ -5,50 +5,536 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model - - -class ebp_export(Model): - _name = "ebp.export" - - def _get_name(self, cr, uid, ids, name, args, context): - return {x: 'export_' + str(x) for x in ids} - - _columns = { - 'company_id': fields.many2one( - 'res.company', 'Company', required=True, readonly=True), - 'fiscalyear_id': fields.many2one( - 'account.fiscalyear', 'Fiscal year', required=True, readonly=True), - 'exported_moves': fields.integer( - 'Number of moves exported', readonly=True), - 'ignored_moves': fields.integer( - 'Number of moves ignored', readonly=True), - 'exported_lines': fields.integer( - 'Number of lines exported', readonly=True), - 'exported_accounts': fields.integer( - 'Number of accounts exported', readonly=True), - 'exported_moves_ids': fields.one2many( - 'account.move', 'exported_ebp_id', 'Exported Moves', - readonly=True), - 'data_moves': fields.binary( - 'Moves file', readonly=True), - 'data_accounts': fields.binary( - 'Accounts file', readonly=True), - 'data_balance': fields.binary( - 'Balance file', readonly=True), - 'date': fields.date( - 'Date', required=True, readonly=True), - 'name': fields.function( - _get_name, 'Name', type='char', store=True, readonly=True), - 'description': fields.text( - 'Description', readonly=True, - help="Extra Description for Accountant Manager."), - } - _defaults = { - 'exported_moves': lambda * a: 0, - 'ignored_moves': lambda * a: 0, - 'exported_lines': lambda * a: 0, - 'exported_accounts': lambda * a: 0, - 'date': lambda * a: fields.date.today() - } +import base64 +import cStringIO +import logging + +from openerp import _, api, fields, models +from openerp.exceptions import Warning as UserError + +_logger = logging.getLogger(__name__) + +try: + from unidecode import unidecode +except ImportError: + unidecode = False + _logger.debug("account_export_ebp - 'unidecode' librairy not found") + + +class EbpExport(models.Model): + _name = 'ebp.export' + _order = 'date desc' + + _EBP_REMOVE_CHAR_LIST = ['\n;', ';', ',', '"'] + + # Column Section + company_id = fields.Many2one( + comodel_name='res.company', string='Company', required=True, + readonly=True, default=lambda s: s._default_company_id()) + + fiscalyear_id = fields.Many2one( + comodel_name='account.fiscalyear', string='Fiscal year', required=True, + readonly=True) + + date = fields.Datetime( + string='Date', required=True, readonly=True, + default=lambda s: s._default_date()) + + name = fields.Char( + compute='_compute_name', string='Name', store=True, readonly=True) + + description = fields.Text( + string='Description', readonly=True, + help="Extra Description for Accountant Manager.") + + exported_move_qty = fields.Integer( + oldname='exported_moves', + string='Quantity of Moves Exported', readonly=True) + + exported_account_qty = fields.Integer( + oldname='exported_accounts', + string='Quantity of accounts exported', readonly=True) + + ebp_move_ids = fields.One2many( + comodel_name='account.move', inverse_name='ebp_export_id', + string='EBP Moves', readonly=True) + + ebp_move_qty = fields.Integer( + compute='_compute_ebp_move_qty', string='EBP Moves Quantity', + store=True) + + data_moves = fields.Binary( + string='Moves file', readonly=True) + + data_accounts = fields.Binary( + string='Accounts file', readonly=True) + + data_balance = fields.Binary( + string='Balance file', readonly=True) + + file_name_moves = fields.Char( + readonly=True, compute='_compute_file_name_moves') + + file_name_accounts = fields.Char( + readonly=True, compute='_compute_file_name_accounts') + + file_name_balance = fields.Char( + readonly=True, compute='_compute_file_name_balance') + + # Default Section + @api.model + def _default_company_id(self): + return self.env.user.company_id.id + + @api.model + def _default_date(self): + return fields.Datetime.now() + + # Compute Section + @api.multi + @api.depends('date') + def _compute_name(self): + for export in self: + export.name = 'export_%d' % export.id + + @api.multi + @api.depends('ebp_move_ids.ebp_export_id') + def _compute_ebp_move_qty(self): + for export in self: + export.ebp_move_qty = len(export.ebp_move_ids) + + @api.multi + def _compute_file_name_moves(self): + for export in self: + export.file_name_moves =\ + 'export_%d_%s.csv' % (export.id, _("MOVES")) + + @api.multi + def _compute_file_name_accounts(self): + for export in self: + export.file_name_accounts =\ + 'export_%d_%s.csv' % (export.id, _("ACCOUNTS")) + + @api.multi + def _compute_file_name_balance(self): + for export in self: + export.file_name_balance =\ + 'export_%d_%s.csv' % (export.id, _("BALANCE")) + + # Custom Section + @api.model + def _normalize(self, text): + res = text + for char in self._EBP_REMOVE_CHAR_LIST: + res = res.replace(char, " ") + return res + + @api.multi + def export(self, moves): + """Export moves into 3 files and mark the moves as exported""" + self.ensure_one() + # Create files + moves_file = cStringIO.StringIO() + accounts_file = cStringIO.StringIO() + balance_file = cStringIO.StringIO() + + # Export into files + self._write_header_into_moves_file(moves_file) + self._write_header_into_accounts_file(accounts_file) + self._write_header_into_balance_file(balance_file) + + vals = self._export_to_files( + moves, moves_file, accounts_file, balance_file) + data_moves = base64.encodestring(moves_file.getvalue()) + data_accounts = base64.encodestring(accounts_file.getvalue()) + data_balance = base64.encodestring(balance_file.getvalue()) + moves_file.close() + accounts_file.close() + balance_file.close() + + # Save Datas + vals.update({ + 'data_moves': data_moves, + 'data_accounts': data_accounts, + 'data_balance': data_balance, + }) + self.write(vals) + + # Mark moves as exported + moves.write({ + 'ebp_export_id': self.id, + }) + + @api.model + def _export_to_files( + self, moves, moves_file, accounts_file, balance_file): + # dictionary to store accounts while we loop through move lines + accounts_data = {} + # Line counter + i = 0 + + for move in moves: + # dictionary to summarize the lines of the move by account + moves_data = {} + for line in move.line_id: + if line.credit == line.debit: + # Ignoring line with null debit and credit + continue + + account_code = self._get_account_code(move, line) + + # Collect data for the file of move lines + if account_code not in moves_data.keys(): + moves_data[account_code] = self._prepare_move_line_dict( + move, line) + else: + moves_data[account_code]['credit'] += line.credit + moves_data[account_code]['debit'] += line.debit + # Keep the earliest maturity date + if (line.date_maturity < + moves_data[account_code]['date_maturity']): + moves_data[account_code]['date_maturity'] =\ + line.date_maturity + + # Collect data for the file of accounts + if account_code not in accounts_data.keys(): + accounts_data[account_code] = self._prepare_account_dict( + move, line) + accounts_data[account_code]['credit'] += line.credit + accounts_data[account_code]['debit'] += line.debit + + # Write to file + self._write_into_moves_file(i, moves_data, moves_file) + i += len(moves_data) + + # Write the accounts into the file + self._write_into_accounts_file(i, accounts_data, accounts_file) + + # Write the balance of accounts into the file + self._write_into_balance_file(i, accounts_data, balance_file) + + return { + 'exported_move_qty': len(moves), + 'exported_account_qty': len(accounts_data), + } + + @api.model + def _get_account_code(self, move, line): + account = line.account_id + company = line.company_id + partner = line.partner_id + res = account.code + + # Company Suffix + if company.fiscal_company.fiscal_type == 'fiscal_mother'\ + and account.type in ('payable', 'receivable')\ + and not account.is_intercompany_trade_fiscal_company: + res += company.code + + # Partner Suffix + if partner and partner.ebp_suffix\ + and account.type in ('payable', 'receivable')\ + and not account.is_intercompany_trade_fiscal_company: + res += partner.ebp_suffix + + # Tax Suffix + if account.ebp_export_tax_code: + if line.tax_code_id.ebp_suffix: + # Tax code is defined + res += line.tax_code_id.ebp_suffix + else: + if not account.ebp_code_no_tax: + raise UserError(_( + "The account %s - %s is set 'export with tax" + " suffix' but no tax suffix is defined for" + " the account.\n Move %s" % ( + account.code, + account.name, + move.name))) + else: + res += account.ebp_code_no_tax + if len(res) > 10: + # The docs from EBP state that account codes may be up to + # 15 characters but "EBP Comptabilité" v13 will refuse anything + # longer than 10 characters + raise UserError(_( + "Account code '%s' is too long to be exported to" + " EBP.") % res) + return res + + @api.model + def _prepare_move_line_dict(self, move, line): + analytic_user_type_ids = [ + self.env.ref('account.data_account_type_income').id, + self.env.ref('account.data_account_type_expense').id, + ] + if move.partner_id.intercompany_trade: + ref = ' (' + move.partner_id.name + ')' + else: + ref = ( + line.name + + ((' (' + move.ref + ')') + if move.ref else '')) + + # Manage analytic cases + if line.company_id.fiscal_company.fiscal_type == 'fiscal_mother': + allow_analytic = True + analytic_code = line.company_id.code + ref = line.company_id.code + ' ' + ref + + elif line.company_id.ebp_analytic_enabled: + allow_analytic =\ + line.account_id.user_type in analytic_user_type_ids + if allow_analytic: + if line.analytic_account_id: + analytic_code = line.analytic_account_id.code + elif line.company_id.ebp_default_analytic_account_id: + analytic_code =\ + line.company_id.ebp_default_analytic_account_id + + else: + allow_analytic = False + analytic_code = '' + + return { + 'date': move.date, + 'journal': move.journal_id.ebp_code, + 'ref': self._normalize(ref), + 'name': self._normalize(move.name), + 'credit': line.credit, + 'debit': line.debit, + 'date_maturity': line.date_maturity, + 'currency_name': move.company_id.currency_id.name, + 'analytic_code': analytic_code, + 'allow_analytic': allow_analytic and '1' or '', + } + + @api.model + def _write_header_into_moves_file(self, moves_file): + # Move File header + data = [ + _("Line"), + _("Date"), + _("Journal Code"), + _("Account Number"), + _("Name"), + _("Move Number"), + _("Amount (related to the direction)"), + _("Direction"), + _("Due Date"), + _("Currency"), + _("Analytic Account"), + _("Allow Analytic"), + _("Payment Mode"), + _("Allow Use of Personal Datas"), + ] + self._write_into_file(data, moves_file) + + @api.model + def _write_into_moves_file(self, count, moves_data, moves_file): + i = count + + for account_code, line in moves_data.iteritems(): + i += 1 + # TODO SLG : refactorer le if / else + data = [ + # Line number + '%d' % i, + # Date (ddmmyy) + '%s/%s/%s' % ( + line['date'][8:10], line['date'][5:7], + line['date'][2:4]), + # Journal + line['journal'].replace(',', '')[:4], + # Account number + # (possibly with the partner code appended to it) + account_code.replace(',', ''), + # Manual title + '"%s"' % line['ref'][:40], + # Accountable receipt number + '"%s"' % line['name'][:15], + ] + if line['credit']: + data += [ + # Amount + '%f' % abs(line['credit']), + # [C]redit or [D]ebit + 'C', + ] + else: + data += [ + # Amount + '%f' % abs(line['debit']), + # [C]redit or [D]ebit + 'D', + ] + data += [ + # Date of maturity (ddmmyy) + line['date_maturity'] and '%s%s%s' % ( + line['date_maturity'][8:10], + line['date_maturity'][5:7], + line['date_maturity'][2:4]) or '', + # Currency + line['currency_name'], + ] + data += [ + line['analytic_code'], + line['allow_analytic'], + "CH30", + "N", + ] + self._write_into_file(data, moves_file) + + @api.model + def _prepare_account_dict(self, move, line): + res = { + 'name': '', + 'partner_name': '', + 'address': '', + 'zip': '', + 'city': '', + 'country': '', + 'contact': '', + 'phone': '', + 'fax': '', + 'credit': 0, + 'debit': 0, + } + # TODO CHECK Camille E + partner_accounts = True + tax_code_suffix = True + + if (partner_accounts and + line.partner_id and line.partner_id.ebp_suffix and + line.account_id.type in ('payable', 'receivable')): + # Partner account + if line.account_id.\ + is_intercompany_trade_fiscal_company: + partner = line.company_id.partner_id + else: + partner = line.partner_id + res.update({ + 'name': self._normalize(partner.name), + 'partner_name': self._normalize(partner.name), + 'address': self._normalize( + (partner.street or '') + + (partner.street2 and + (' ' + partner.street2) or '')), + 'zip': partner.zip or '', + 'city': self._normalize(partner.city or ''), + 'country': self._normalize( + partner.country_id.name or ''), + 'contact': self._normalize(partner.email or ''), + 'phone': partner.phone or partner.mobile or '', + 'fax': partner.fax or '', + }) + elif (tax_code_suffix and + line.account_id.ebp_export_tax_code and + line.tax_code_id.ebp_suffix): + res.update({ + 'name': ( + self._normalize(line.account_id.name) + + '(' + self._normalize(line.tax_code_id.name) + ')'), + }) + else: + # Normal account + res.update({ + 'name': self._normalize(line.account_id.name), + }) + return res + + @api.model + def _write_header_into_accounts_file(self, accounts_file): + pass + + @api.model + def _write_into_accounts_file(self, count, accounts_data, accounts_file): + for account_code, account_data in accounts_data.iteritems(): + data = [ + account_code.replace(',', ''), + (account_data['name'] or '').replace(',', '')[:60], + (account_data['partner_name'] or '').replace(',', '')[:30], + (account_data['address'] or '').replace(',', '')[:100], + (account_data['zip'] or '').replace(',', '')[:5], + (account_data['city'] or '').replace(',', '')[:30], + (account_data['country'] or '').replace(',', '')[:35], + (account_data['contact'] or '').replace(',', '')[:35], + (account_data['phone'] or '').replace(',', '')[:20], + (account_data['fax'] or '').replace(',', '')[:20], + ] + self._write_into_file(data, accounts_file) + + @api.model + def _write_header_into_balance_file(self, balance_file): + # Move File header + data = [ + _("Account Number"), + _("Account name"), + _("Debit"), + _("Credit"), + _("Debit Balance"), + _("Credit Balance"), + ] + self._write_into_file(data, balance_file) + + @api.model + def _write_into_balance_file(self, count, accounts_data, balance_file): + for account_code, account_data in accounts_data.iteritems(): + credit = (account_data['credit'] or 0) + debit = (account_data['debit'] or 0) + if credit > debit: + credit_balance = credit - debit + debit_balance = 0 + else: + credit_balance = 0 + debit_balance = debit - credit + data = [ + account_code.replace(',', ''), + (account_data['name'] or '').replace(',', '')[:60], + str(debit), + str(credit), + str(debit_balance), + str(credit_balance), + ] + self._write_into_file(data, balance_file) + + @api.model + def _write_into_file(self, data_list, file): + tmp = ','.join(data_list) + file.write(unidecode(tmp)) + file.write('\r\n') + + # _logger.debug( + # "%d accounts(s) exported to COMPTES.TXT" % len(accounts_data)) + + # self.write(cr, uid, ids, { + # 'exported_moves': len(exported_move_ids), + # 'ignored_moves': len(ignored_move_ids), + # 'exported_lines': l, + # 'exported_accounts': len(accounts_data), + # }, context=context) + # if export_id: + # export_obj.write(cr, uid, export_id, { + # 'exported_moves': len(exported_move_ids), + # 'ignored_moves': len(ignored_move_ids), + # 'exported_lines': l, + # 'exported_accounts': len(accounts_data), + # }, context=context) + # return export_id + +# FILE +# FUCK ANALYTIC + + # is_analytic_column = False + # for move in moves: + # if move.company_id.ebp_trigram != '': + # is_analytic_column = True + + # if is_analytic_column: + # move_line += ',Poste analytique' + + # AH BON ???? + # if len(move.name) > 15: + # raise osv.except_osv(_('Move name too long'), _( + # """Move name '%s' is too long to be exported to""" + # """ EBP.""") % move.name) diff --git a/account_export_ebp/models/res_company.py b/account_export_ebp/models/res_company.py index 4101021..ed2e13b 100644 --- a/account_export_ebp/models/res_company.py +++ b/account_export_ebp/models/res_company.py @@ -5,41 +5,20 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model +from openerp import fields, models -class res_company(Model): - """Add parameters to export accounting moves to EBP's software""" + +class ResCompany(models.Model): _inherit = 'res.company' - # Columns section - def _get_ebp_trigram(self, cr, uid, ids, field_name, arg, context=None): - res = {} - for rc in self.browse(cr, uid, ids, context=context): - if rc.fiscal_type in ['fiscal_child', 'fiscal_mother']: - res[rc.id] = rc.code - else: - res[rc.id] = '' - return res + # Column Section + ebp_analytic_enabled = fields.Boolean( + string='Enable Analytic in EBP', default=False, + help="Check this box if you want to enable the analytic when" + " exporting in EBP. Note that this setting has will not been" + " taken into account for Companies that belong to a CAE") - _columns = { - 'ebp_trigram': fields.function( - _get_ebp_trigram, type='char', string='EBP Trigram', store=True), - 'ebp_uri': fields.char( - 'EBP Share URI', size=256, - help="""The URI of the network share containing the company's""" - """ EBP folder. Format: smb://SERVER/SHARE/DIR"""), - 'ebp_domain': fields.char( - 'EBP User Domain', size=256, - help="""The domain of the user to access the company's EBP""" - """ folder."""), - 'ebp_username': fields.char( - 'EBP User Name', size=256, - help="""The name of the user to access the company's EBP""" - """ folder."""), - 'ebp_password': fields.char( - 'EBP User Password', size=256, - help="""The password of the user to access the company's""" - """ EBP folder."""), - } + ebp_default_analytic_account_id = fields.Many2one( + string="Default Analytic Account for EBP", + comodel_name='account.analytic.account') diff --git a/account_export_ebp/models/res_partner.py b/account_export_ebp/models/res_partner.py index b4852da..2398051 100644 --- a/account_export_ebp/models/res_partner.py +++ b/account_export_ebp/models/res_partner.py @@ -5,73 +5,57 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model +from openerp import api, fields, models -class res_partner(Model): + +class ResPartner(models.Model): _inherit = 'res.partner' - # Columns section - def _nb_moves(self, cr, uid, ids, name, arg, context=None): - res = {} - aml_obj = self.pool.get('account.move.line') - for aId in ids: - aml_ids = aml_obj.search(cr, uid, [ - ('partner_id', '=', aId), ('date', '>=', '01/12/2012')], - context=context) - res[aId] = len(aml_ids) - return res + _SEARCH_DATE_BEGIN = '01/12/2012' - def _search_nb_moves(self, cr, uid, obj, name, args, context=None): - if not args: - return [] - query, query_args = self._get_search_moves_query( - cr, uid, args, overdue_only=False, context=context) - cr.execute(query, query_args) - res = cr.fetchall() - if not res: - return [('id', '=', '0')] - return [('id', 'in', [x[0] for x in res])] + # Columns section + ebp_suffix = fields.Char( + string="Suffix in EBP", oldname="ref_nb", + help="When exporting Entries to EBP, this suffix will be" + " appended to the Account Number to make it a Partner Account.") - _columns = { - # Partner's account number in EBP - 'ref_nb': fields.char( - 'Partner\'s Account suffix in EBP', - help="""When exporting Entries to EBP, this suffix will be""" - """ appended to the Account Number to make it a Partner""" - """ Account."""), - 'nb_moves': fields.function( - _nb_moves, string='Number of moves', - fnct_search=_search_nb_moves, type='integer', - help="Number of account moves for this partner"), - } + has_ebp_move_line = fields.Boolean( + compute='_compute_has_ebp_move_line', + search='_search_has_ebp_move_line', + string='Has Account Move Lines exportable in EBP') # Constraints section _sql_constraints = [ ( - 'partner_suffix_uniq', - 'unique (ref_nb, company_id)', - 'The partner suffix must be unique per company!') + 'ebp_suffix_company_id_uniq', + 'unique (ebp_suffix, company_id)', + 'The EBP suffix must be unique per company!') ] - # Overloading section - def write(self, cr, uid, ids, vals, context=None): - ref_nb = vals.get('ref_nb', False) - if ref_nb: - vals['ref_nb'] = ref_nb.upper() - return super(res_partner, self).write( - cr, uid, ids, vals, context=context) - - # Private section - def _get_search_moves_query( - self, cr, uid, args, overdue_only=False, context=None): - having_where_clause = ' AND '.join( - map(lambda x: '(COUNT(*) %s %%s)' % (x[1]), args)) - having_values = [x[2] for x in args] - return """ - SELECT partner_id, count(*) - FROM account_move_line - WHERE date >= '01/12/2012' - GROUP BY partner_id - HAVING """ + having_where_clause, having_values + # Columns section + @api.multi + def _compute_has_ebp_move_line(self): + AccountMoveLine = self.env['account.move.line'] + for partner in self: + partner.has_ebp_move_line = len(AccountMoveLine.search([ + ('partner_id', '=', partner.id), + ('date', '>=', self._SEARCH_DATE_BEGIN)])) + + @api.model + def _search_has_ebp_move_line(self, operator, value): + assert operator in ('=', '!='), 'Invalid domain operator' + assert value in (True, False), 'Invalid domain value' + + with_line = ( + (operator == '=' and value is True) or + (operator == '!=' and value is False)) + + self._cr.execute( + "SELECT partner_id, count(*)" + " FROM account_move_line" + " WHERE date >= '01/12/2012'" + " GROUP BY partner_id" + " HAVING count(*) > 0") + res = self._cr.fetchall() + return [('id', with_line and 'in' or 'not in', [x[0] for x in res])] diff --git a/account_export_ebp/security/ir_rule.xml b/account_export_ebp/security/ir_rule.xml index 03d8b91..bdf1b9e 100644 --- a/account_export_ebp/security/ir_rule.xml +++ b/account_export_ebp/security/ir_rule.xml @@ -1,14 +1,17 @@ - - - + - - EBP Export - - - ['|',('company_id','=',False), ('company_id','child_of',[user.company_id.id])] - + + EBP Export + + + ['|',('company_id','=',False), ('company_id','child_of',[user.company_id.id])] + diff --git a/account_export_ebp/tests/__init__.py b/account_export_ebp/tests/__init__.py index cfa007d..17b8206 100644 --- a/account_export_ebp/tests/__init__.py +++ b/account_export_ebp/tests/__init__.py @@ -1,24 +1,2 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Pos Invoicing module for OpenERP -# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) -# @author Julien WESTE -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from . import test_account_export_ebp +# coding: utf-8 +from . import test_module diff --git a/account_export_ebp/tests/test_account_export_ebp.py b/account_export_ebp/tests/test_account_export_ebp.py deleted file mode 100644 index 7b4812f..0000000 --- a/account_export_ebp/tests/test_account_export_ebp.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Export to EBP module for OpenERP -# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) -# @author Julien WESTE -# based on a Numerigraphe module -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from openerp.tests.common import TransactionCase - - -class TestAccountExportEBP(TransactionCase): - """Tests for Account Export EBP Module""" - - def setUp(self): - super(TestAccountExportEBP, self).setUp() - self.imd_obj = self.registry('ir.model.data') - self.ai_obj = self.registry('account.invoice') - self.am_obj = self.registry('account.move') - self.aml_obj = self.registry('account.move.line') - self.webp_obj = self.registry('account.export.ebp') - self.afy_obj = self.registry('account.fiscalyear') - - # Test Section - def test_01_export_ref_null(self): - """Test the export if move ref is null""" - cr, uid = self.cr, self.uid - # Get a demo account move - ai_id = self.imd_obj.get_object_reference( - cr, uid, 'account', 'test_invoice_1')[1] - ai = self.ai_obj.browse(cr, uid, ai_id) - am = ai.move_id - afy_id = self.imd_obj.get_object_reference( - cr, uid, 'account', 'data_fiscalyear')[1] - - # Setting 'ref' field to Null - aml_ids = [aml.id for aml in am.line_id] - self.aml_obj.write(cr, uid, aml_ids, {'ref': False}) - - # Call wizard to export lines - vals = { - 'fiscalyear_id': afy_id, - 'download_file': True, - } - ctx = { - 'active_model': 'account.move', - 'active_ids': [ai.move_id.id], - 'ignore_draft': True, - } - webp_id = self.webp_obj.create(cr, uid, vals) - self.webp_obj.export(cr, uid, [webp_id], context=ctx) diff --git a/account_export_ebp/tests/test_module.py b/account_export_ebp/tests/test_module.py new file mode 100644 index 0000000..05cb126 --- /dev/null +++ b/account_export_ebp/tests/test_module.py @@ -0,0 +1,29 @@ +# coding: utf-8 +# Copyright (C) 2018 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase + + +class TestModule(TransactionCase): + + def setUp(self): + super(TestModule, self).setUp() + self.WizardEbpExport = self.env['wizard.ebp.export'] + self.move_1 = self.env.ref('account.invoice_1').move_id + + # Test Section + def test_01_export_move(self): + wizard = self.WizardEbpExport.with_context( + active_ids=[self.move_1.id]).create({}) + + wizard.button_export() + + self.assertNotEqual( + wizard.ebp_export_id.id, False, + "Export a move should create an ebp export") + + self.assertEqual( + wizard.ebp_export_id, self.move_1.ebp_export_id, + "Exporting a move should link it to the ebp export created.") diff --git a/account_export_ebp/views/menu.xml b/account_export_ebp/views/menu.xml index ad689ab..ce86c36 100644 --- a/account_export_ebp/views/menu.xml +++ b/account_export_ebp/views/menu.xml @@ -6,7 +6,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - + diff --git a/account_export_ebp/views/view_account_export_ebp.xml b/account_export_ebp/views/view_account_export_ebp.xml deleted file mode 100644 index 14901b6..0000000 --- a/account_export_ebp/views/view_account_export_ebp.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - account.export.ebp - -
- - - -

Warning! Some partners don't have a suffix.

-

You should run the wizard to populate them before exporting.

-
- - -

Warning! Some Tax Codes don't have a suffix.

-

You should run the wizard to populate them before exporting.

-
- - - - - - - - - - - - -
-
-
- -

Export Complete

- - - - - -
-
-
- - - -

Here is the exported moves file:

-

And the exported accounts file:

-

And the exported balance file:

-
- -
-
- - - Export to EBP - ir.actions.act_window - account.export.ebp - form - form - - new - - -
diff --git a/account_export_ebp/views/view_account_fiscalyear.xml b/account_export_ebp/views/view_account_fiscalyear.xml deleted file mode 100644 index 2089304..0000000 --- a/account_export_ebp/views/view_account_fiscalyear.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - account.fiscalyear - - - - - - - - - diff --git a/account_export_ebp/views/view_account_move.xml b/account_export_ebp/views/view_account_move.xml index 2673de3..70c4267 100644 --- a/account_export_ebp/views/view_account_move.xml +++ b/account_export_ebp/views/view_account_move.xml @@ -11,16 +11,17 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + + account.move - + @@ -30,27 +31,27 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + + domain="[('ebp_export_id', '=', False)]" help="Journal Entries not yet exported to EBP" /> - - + + Export to EBP client_action_multi - + action account.move - - + + Cancel EBP Export client_action_multi - + action account.move diff --git a/account_export_ebp/views/view_account_tax_code.xml b/account_export_ebp/views/view_account_tax_code.xml index 0779d0b..5bee0bf 100644 --- a/account_export_ebp/views/view_account_tax_code.xml +++ b/account_export_ebp/views/view_account_tax_code.xml @@ -10,15 +10,16 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). account.tax.code - - - + + + @@ -28,48 +29,38 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + - account.tax.code - - - - - - - - - account.tax.code - - + + - + Tax Code Suffix View ir.actions.act_window account.tax.code form tree - - {'search_default_with_moves': 1, 'search_default_no_suffix': 1} + + {'search_default_without_suffix_with_move_line_ebp': 1} -
diff --git a/account_export_ebp/views/view_ebp_export.xml b/account_export_ebp/views/view_ebp_export.xml index 48ed791..83356aa 100644 --- a/account_export_ebp/views/view_ebp_export.xml +++ b/account_export_ebp/views/view_ebp_export.xml @@ -1,15 +1,27 @@ + + + + Journal Items + account.move + {'search_default_ebp_export_id': [active_id], 'default_ebp_export_id': active_id} + + + ebp.export - - - - + + @@ -17,13 +29,14 @@ ebp.export - + - - - - + + + + + @@ -32,25 +45,30 @@ ebp.export -
+ +
+ +

- - - - + + - - -

Here is the exported moves file:

-

And the exported accounts file:

-

And the exported balance file:

+ + + +
+ +
@@ -65,11 +83,10 @@ tree,form
- -
diff --git a/account_export_ebp/views/view_res_company.xml b/account_export_ebp/views/view_res_company.xml index e22e4d2..81945f3 100644 --- a/account_export_ebp/views/view_res_company.xml +++ b/account_export_ebp/views/view_res_company.xml @@ -1,6 +1,6 @@ @@ -10,14 +10,11 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). res.company - - - - - - - - + + + + diff --git a/account_export_ebp/views/view_res_partner.xml b/account_export_ebp/views/view_res_partner.xml index ef7d67a..b2dcac0 100644 --- a/account_export_ebp/views/view_res_partner.xml +++ b/account_export_ebp/views/view_res_partner.xml @@ -6,14 +6,12 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - res.partner - + @@ -24,33 +22,28 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - - - - - - - - - - + + + - + res.partner - - + + + @@ -58,27 +51,27 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + Partner Suffixes ir.actions.act_window res.partner form tree - - {'search_default_with_moves': 1,'search_default_no_suffix': 1} + + {'search_default_without_suffix_with_move_line_ebp': 1} - - - Add EBP Suffix + + + Add EBP Suffixes client_action_multi - + action res.partner diff --git a/account_export_ebp/wizard/__init__.py b/account_export_ebp/wizard/__init__.py index 2eb4230..830bf5a 100644 --- a/account_export_ebp/wizard/__init__.py +++ b/account_export_ebp/wizard/__init__.py @@ -1,4 +1,5 @@ # coding: utf-8 -from . import wizard_ebp -from . import wizard_unexport -from . import wizard_add_suffix +from . import wizard_ebp_export +from . import wizard_ebp_unexport +from . import wizard_res_partner_add_suffix +from . import wizard_res_partner_add_suffix_line diff --git a/account_export_ebp/wizard/view_wizard_ebp_export.xml b/account_export_ebp/wizard/view_wizard_ebp_export.xml new file mode 100644 index 0000000..5ac7435 --- /dev/null +++ b/account_export_ebp/wizard/view_wizard_ebp_export.xml @@ -0,0 +1,63 @@ + + + + + + wizard.ebp.export + +
+
+ +
+ + + +

You have selected moves related to partners without EBP suffixes defined.

+ +

You have selected draft moves.

+ +

You have selected moves that doesn't belong to the selected fiscal year.

+ +

You have selected moves that belong to a journal that doesn't have a correct 'EBP code' set.

+ +

You have selected moves that are marked as 'To check'.

+ +

You have selected moves that have already been exported in EBP.

+
+ + + + + + + + + + + + + + +
+
+
+
+
+ + + Export to EBP + ir.actions.act_window + wizard.ebp.export + form + form + new + + +
diff --git a/account_export_ebp/views/view_account_unexport_ebp.xml b/account_export_ebp/wizard/view_wizard_ebp_unexport.xml similarity index 55% rename from account_export_ebp/views/view_account_unexport_ebp.xml rename to account_export_ebp/wizard/view_wizard_ebp_unexport.xml index 615382f..4ba64a9 100644 --- a/account_export_ebp/views/view_account_unexport_ebp.xml +++ b/account_export_ebp/wizard/view_wizard_ebp_unexport.xml @@ -6,27 +6,27 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - account.unexport.ebp + + wizard.ebp.unexport
-

The export will be canceled for the selected moves.

-

Be sure to delete the corresponding lines in EBP.

+

+ The export will be canceled for the selected moves. Be sure to delete the corresponding lines in EBP. +

-
- + Cancel EBP Export ir.actions.act_window - account.unexport.ebp + wizard.ebp.unexport form form - new diff --git a/account_export_ebp/views/view_account_add_suffix.xml b/account_export_ebp/wizard/view_wizard_res_partner_add_suffix.xml similarity index 57% rename from account_export_ebp/views/view_account_add_suffix.xml rename to account_export_ebp/wizard/view_wizard_res_partner_add_suffix.xml index b6845b5..4e5259e 100644 --- a/account_export_ebp/views/view_account_add_suffix.xml +++ b/account_export_ebp/wizard/view_wizard_res_partner_add_suffix.xml @@ -6,32 +6,30 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - account.add.suffix + + wizard.res.partner.add.suffix
-
- + - +
- - Add EBP Suffix + + Add EBP Suffixes ir.actions.act_window - account.add.suffix + wizard.res.partner.add.suffix form form - - {} new diff --git a/account_export_ebp/wizard/wizard_ebp.py b/account_export_ebp/wizard/wizard_ebp.py deleted file mode 100644 index eb31d44..0000000 --- a/account_export_ebp/wizard/wizard_ebp.py +++ /dev/null @@ -1,669 +0,0 @@ -# coding: utf-8 -# Copyright (C) 2010 - 2015: Numérigraphe SARL -# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) -# @author: Julien WESTE -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -import base64 -import cStringIO -import codecs -import logging - -from openerp.tools.translate import _ -from openerp.osv import fields, osv - -_logger = logging.getLogger(__name__) - -try: - from unidecode import unidecode -except ImportError: - _logger.debug("account_export_ebp - 'unidecode' librairy not found") - -try: - import smbc -except: - _logger.debug("account_export_ebp - 'smbc' librairy not found") - smbc = False - -# TODO -# We should write to a temporary file instead, for security and reliability. -# We should raise a clean exception if something goes wrong. - - -class account_export_ebp(osv.TransientModel): - _name = "account.export.ebp" - - # Columns Section - _columns = { - 'name_moves': fields.char('File Name', readonly=True), - 'name_accounts': fields.char('File Name', readonly=True), - 'name_balance': fields.char('File Name', readonly=True), - 'fiscalyear_id': fields.many2one( - 'account.fiscalyear', 'Fiscal year', - required=True, - help='Only the moves in this fiscal will be exported'), - 'company_suffix': fields.boolean( - 'Append company\'s code to accounts', - help="""When this is checked, the company's code will be""" - """ appended to the receivable and payable accounts' numbers in""" - """ the exported files on every move line."""), - 'partner_accounts': fields.boolean( - 'Append partners\' code to accounts', - help="""When this is checked, the partner's special code will""" - """ be appended to the receivable and payable accounts' numbers""" - """ in the exported files on every move line where a partner has""" - """ been specified."""), - 'tax_code_suffix': fields.boolean( - 'Export according to Tax Codes', - help="""Append Tax Code's suffix to account if the option is""" - """ checked in the account"""), - 'ignore_unchecked': fields.boolean( - 'Ignore unchecked moves', - help="""Please be aware that unchecked moves belong maybe some""" - """ errors."""), - 'ignore_draft': fields.boolean( - 'Ignore draft moves', - help="""Please be aware that draft moves do not not have a""" - """ move number attached to them. As a consequence, they might""" - """ not be imported correctly into EBP accounting software"""), - 'ignore_exported': fields.boolean( - 'Ignore moves already exported', - help="Check this box unless you want to re-export moves to EBP"), - 'download_file': fields.boolean( - 'Download file', help="""Check this box if you want to""" - """ download the result as a file on your computer. Otherwise,""" - """ the file will be saved at the place defined in the company""" - """ settings."""), - 'data_moves': fields.binary('File', readonly=True), - 'data_accounts': fields.binary('File', readonly=True), - 'data_balance': fields.binary('File', readonly=True), - 'exported_moves': fields.integer( - 'Number of moves exported', readonly=True), - 'ignored_moves': fields.integer( - 'Number of moves ignored', readonly=True), - 'exported_lines': fields.integer( - 'Number of lines exported', readonly=True), - 'exported_accounts': fields.integer( - 'Number of accounts exported', readonly=True), - 'state': fields.selection([ - ('export_ebp', 'Prepare Export'), - ('export_ebp_end', 'Export Done'), - ('export_ebp_download', 'Ready to download') - ]), - 'empty_suffixes_partner': fields.boolean( - 'Empty Suffixes Partners', readonly=True), - 'empty_suffixes_tax': fields.boolean( - 'Empty Suffixes Taxes', readonly=True), - 'description': fields.text( - 'Description', help="Extra Description for Accountant Manager."), - } - - # Defaults Section - def _get_empty_suffixes_partner(self, cr, uid, context=None): - rp_obj = self.pool.get('res.partner') - aml_obj = self.pool.get('account.move.line') - - rp_ids = rp_obj.search( - cr, uid, [('ref_nb', '=', False)], context=context) - aml_ids = aml_obj.search(cr, uid, [ - ('date', '>=', '01/12/2012'), ('partner_id', 'in', rp_ids)], - context=context) - - if aml_ids: - return True - return False - - def _get_empty_suffixes_tax(self, cr, uid, context=None): - atc_obj = self.pool.get('account.tax.code') - aml_obj = self.pool.get('account.move.line') - - atc_ids = atc_obj.search( - cr, uid, [('ref_nb', '=', False)], context=context) - aml_ids = aml_obj.search(cr, uid, [ - ('date', '>=', '01/12/2012'), ('tax_code_id', 'in', atc_ids)], - context=context) - - if aml_ids: - return True - return False - - _defaults = { - 'ignore_unchecked': lambda * a: True, - 'ignore_exported': lambda * a: True, - 'ignore_draft': lambda * a: True, - 'company_suffix': lambda * a: True, - 'partner_accounts': lambda * a: True, - 'download_file': lambda * a: True, - 'tax_code_suffix': lambda * a: True, - 'state': 'export_ebp', - 'empty_suffixes_partner': _get_empty_suffixes_partner, - 'empty_suffixes_tax': _get_empty_suffixes_tax, - } - - def export(self, cr, uid, ids, context=None): - if context is None: - context = {} - this = self.browse(cr, uid, ids, context=context)[0] - if this.download_file: - return self._download(cr, uid, ids, context=context) - else: - return self._save(cr, uid, ids, context=context) - - def _download(self, cr, uid, ids, context=None): - export_obj = self.pool.get('ebp.export') - if context is None: - context = {} - this = self.browse(cr, uid, ids)[0] - moves_file = cStringIO.StringIO() - account_file = cStringIO.StringIO() - balance_file = cStringIO.StringIO() - export_id = self._export( - cr, uid, ids, moves_file, account_file, balance_file, - context=context) - this.name_moves = "ECRITURES.csv" - this.name_accounts = "COMPTES.csv" - this.name_balance = "BALANCES.csv" - out_moves = base64.encodestring(moves_file.getvalue()) - out_accounts = base64.encodestring(account_file.getvalue()) - out_balance = base64.encodestring(balance_file.getvalue()) - moves_file.close() - account_file.close() - balance_file.close() - self.write(cr, uid, ids, { - 'state': 'export_ebp_download', - 'data_moves': out_moves, - 'data_accounts': out_accounts, - 'data_balance': out_balance, - 'name_moves': this.name_moves, - 'name_accounts': this.name_accounts, - 'name_balance': this.name_balance, - }, context=context) - export_obj.write(cr, uid, export_id, { - 'data_accounts': out_accounts, - 'data_balance': out_balance, - 'data_moves': out_moves, - }, context=context) - return { - 'type': 'ir.actions.act_window', - 'res_model': 'account.export.ebp', - 'view_mode': 'form', - 'view_type': 'form', - 'res_id': this.id, - 'views': [(False, 'form')], - 'target': 'new', - } - - def _save(self, cr, uid, ids, context): - if context is None: - context = {} - - # Stream writer to convert Unicode to Windows Latin-1 - win_writer = codecs.getwriter('cp1252') - - # Connect to the network share - company = self.pool.get('res.users').browse( - cr, uid, uid, context=context).company_id - data = {'form': self.read(cr, uid, ids, context=context)[0]} - fiscalyear = self.pool.get('account.fiscalyear').browse( - cr, uid, data['form']['fiscalyear_id'][0], context) - - path = '%s/Compta.%s' % (company.ebp_uri, fiscalyear.ebp_nb) - _logger.debug("Connecting to %s as user %s, domain %s" % ( - path, fiscalyear.company_id.ebp_username, - fiscalyear.company_id.ebp_domain)) - win_share = smbc.Context( - auth_fn=lambda server, share, workgroup, username, password: ( - fiscalyear.company_id.ebp_domain, - fiscalyear.company_id.ebp_username, - fiscalyear.company_id.ebp_password)) - moves_file = win_writer(win_share.creat('%s/ECRITURES.TXT' % path)) - account_file = win_writer(win_share.creat('%s/COMPTES.TXT' % path)) - balance_file = win_writer(win_share.creat('%s/BALANCES.TXT' % path)) - self._export( - cr, uid, ids, moves_file, account_file, context=None) - - # Close the move summaries file - moves_file.close() - account_file.close() - balance_file.close() -# _logger.debug( -# """%d line(s) representing %d move(s) exported to""" -# """ ECRITURES.TXT in %s - %d move(s) ignored""" % ( -# l, len(exported_move_ids), path, len(ignored_move_ids))) - - def _export( - self, cr, uid, ids, moves_file, account_file, balance_file, - context=None): - """ - Export moves files usable by accounting software by EBP version - 3 and above. - - 2 files will be produced : - - a file of accounting moves (ECRITURES.TXT) - - a file of accounts (COMPTES.TXT) - If stored in the right folder, these files will automatically be - imported next time you open the folder in EBP. - - Lines with an amount of 0 are not ignored even though EBP complains - about them. This is to raise the attention of the person importing - them into EBP. Also, journals with a code which does not meet EBP's - requirements are not ignored. - - Returns a dictionary containing the number of moves and lines - exported and the number of moves ignored. - """ - - def normalize(text): - # Remove tricky characters from the string - if "\n;" in text: - text = text.replace("\n;", " ") - if ";" in text: - text = text.replace(";", " ") - if "," in text: - text = text.replace(",", " ") - if "\"" in text: - text = text.replace("\"", " ") - return text - - if context is None: - context = {} - export_obj = self.pool.get('ebp.export') - - data = {'form': self.read(cr, uid, ids, context=context)[0]} - _logger.debug("Form data: %s" % data['form']) - - # Read the EBP year number name from the selected fiscal year - fiscalyear = self.pool.get('account.fiscalyear').browse( - cr, uid, data['form']['fiscalyear_id'][0], context) - user_company = self.pool.get('res.users').browse( - cr, uid, uid, context=context).company_id - - # Sanity checks - if context.get('active_model', '') != 'account.move': - raise osv.except_osv( - _('Wrong Object'), - _("This wizard should only be used on accounting moves")) - - # dictionary to store accounts while we loop through move lines - accounts_data = {} - # Line counter - l = 0 - moves = self.pool.get('account.move').browse( - cr, uid, context.get('active_ids', []), context=context) - - is_analytic_column = False - for move in moves: - if move.company_id.ebp_trigram != '': - is_analytic_column = True - - # The move summaries will be written to a CSV file encoded in - # win-latin-1 - # TODO we should report errors more cleanly to the users here - - tax_code_suffix = data['form']['tax_code_suffix'] - exported_move_ids = [] - ignored_move_ids = [] - - # Move File header - move_line = ','.join([ - "Ligne", - "Date", - "Code journal", - "N° de compte", - "Intitulé", - "Pièce", - "Montant (associé au sens)", - "Sens", - "Échéance", - "Monnaie", - ]) - if is_analytic_column: - move_line += ',Poste analytique' - - moves_file.write(move_line) - moves_file.write('\r\n') - - for move in moves: - # Ignore draft moves unless the user asked for them - ignore_draft = ( - data['form']['ignore_draft'] and move.state == 'draft') - ignore_unchecked = ( - data['form']['ignore_unchecked'] and move.to_check) - # Ignore moves in other fiscal years - ignore_year = (move.period_id.fiscalyear_id.id != - data['form']['fiscalyear_id'][0]) - # Ignore moves already exported - ignore_exported = ( - data['form']['ignore_exported'] and move.exported_ebp_id) - # Skip to next move if this one should be ignored - if ignore_draft or ignore_year or\ - ignore_exported or ignore_unchecked: - _logger.debug( - """Ignoring move %d - draft: %s, wrong year: %s,""" - """ exported: %s""" % ( - move.id, ignore_draft, ignore_year, ignore_exported)) - ignored_move_ids.append(move.id) - continue - - _logger.debug("Exporting move %d" % move.id) - # dictionary to summarize the lines of the move by account - moves_data = {} - for line in move.line_id: - _logger.debug("Examining move line %d" % line.id) - - if line.credit == line.debit: - _logger.debug( - """Move line %d has a sum equal to zero and will""" - """ not be exported.""" % line.id) - continue - # Make up the account number - account_nb = normalize(line.account_id.code) - if data['form']['company_suffix'] and line.company_id and\ - line.company_id.ebp_trigram and\ - line.account_id.type in ('payable', 'receivable')\ - and not line.account_id\ - .is_intercompany_trade_fiscal_company: - account_nb = account_nb + line.company_id.ebp_trigram - if data['form']['partner_accounts'] and line.partner_id and\ - line.partner_id.ref_nb and\ - line.account_id.type in ('payable', 'receivable')\ - and not line.account_id\ - .is_intercompany_trade_fiscal_company: - # Partner account - account_nb = account_nb + line.partner_id.ref_nb - if (tax_code_suffix and line.account_id.export_tax_code): - if line.tax_code_id.ref_nb: - account_nb = account_nb + line.tax_code_id.ref_nb - else: - if not line.account_id.ebp_code_no_tax: - raise osv.except_osv( - _('Incorrect Setting'), - _("The account %s - %s is set 'export with tax" - " suffix' but no tax suffix is defined for" - " the account.\n Move %s" % ( - line.account_id.code, - line.account_id.name, - line.move_id.name))) - else: - account_nb = account_nb +\ - line.account_id.ebp_code_no_tax - - # Check the most important fields are not above the maximum - # length so as not to export wrong data with catastrophic - # consequence - if not move.journal_id.ebp_code or\ - len(move.journal_id.ebp_code) == 0: - raise osv.except_osv( - _('Journal code Undefined'), - _("Journal '%s' has no EBP Code defined." % - move.journal_id.name)) - if len(move.journal_id.ebp_code) > 4: - raise osv.except_osv( - _('Journal code too long'), - _("Journal code '%s' is too long to be exported" - " to EBP." % move.journal_id.ebp_code)) - - # The docs from EBP state that account codes may be up to - # 15 characters but "EBP Comptabilité" v13 will refuse anything - # longer than 10 characters - if len(account_nb) > 10: - raise osv.except_osv(_('Account code too long'), _( - """Account code '%s' is too long to be exported to""" - """ EBP.""") % account_nb) - if len(move.name) > 15: - raise osv.except_osv(_('Move name too long'), _( - """Move name '%s' is too long to be exported to""" - """ EBP.""") % move.name) - - # Collect data for the file of move lines - if account_nb not in moves_data.keys(): - ref = ( - (line.company_id.ebp_trigram + ' ') - if line.company_id.ebp_trigram else '') - if move.partner_id.intercompany_trade: - ref += ' (' + move.partner_id.name + ')' - else: - ref += ( - line.name + - ((' (' + move.ref + ')') - if move.ref else '')) - moves_data[account_nb] = { - 'date': move.date, - 'journal': move.journal_id.ebp_code, - 'ref': normalize(ref), - 'name': normalize(move.name), - 'credit': line.credit, - 'debit': line.debit, - 'date_maturity': line.date_maturity, - } - if is_analytic_column: - moves_data[account_nb]['analytic'] =\ - line.company_id.ebp_trigram - else: - moves_data[account_nb]['credit'] += line.credit - moves_data[account_nb]['debit'] += line.debit - # Keep the earliest maturity date - if (line.date_maturity < - moves_data[account_nb]['date_maturity']): - moves_data[account_nb]['date_maturity'] =\ - line.date_maturity - - # Collect data for the file of accounts - # We can't just keep the account_id object because the data - # we want to export may be partner specific - if account_nb not in accounts_data.keys(): - if (data['form']['partner_accounts'] and - line.partner_id and line.partner_id.ref_nb and - line.account_id.type in ('payable', 'receivable')): - # Partner account - # Get the default address - if line.account_id.\ - is_intercompany_trade_fiscal_company: - partner = line.company_id.partner_id - else: - partner = line.partner_id - accounts_data[account_nb] = { - 'name': normalize(partner.name), - 'partner_name': normalize(partner.name), - 'address': normalize( - (partner.street or '') + - (partner.street2 and - (' ' + partner.street2) or '')), - 'zip': partner.zip or '', - 'city': normalize(partner.city or ''), - 'country': normalize( - partner.country_id.name or ''), - 'contact': normalize(partner.email or ''), - 'phone': partner.phone or partner.mobile or '', - 'fax': partner.fax or '', - } - elif (tax_code_suffix and - line.account_id.export_tax_code and - line.tax_code_id.ref_nb): - accounts_data[account_nb] = { - 'name': ( - normalize(line.account_id.name) + - '(' + normalize(line.tax_code_id.name) + ')'), - 'partner_name': '', - 'address': '', - 'zip': '', - 'city': '', - 'country': '', - 'contact': '', - 'phone': '', - 'fax': '', - } - else: - # Normal account - accounts_data[account_nb] = { - 'name': normalize(line.account_id.name), - 'partner_name': '', - 'address': '', - 'zip': '', - 'city': '', - 'country': '', - 'contact': '', - 'phone': '', - 'fax': '', - } - - accounts_data[account_nb].setdefault('credit', 0) - accounts_data[account_nb]['credit'] += line.credit - accounts_data[account_nb].setdefault('debit', 0) - accounts_data[account_nb]['debit'] += line.debit - - # Write the move summary to the file - _logger.debug("Writing the move summary to the file") - for account_nb, line in moves_data.iteritems(): - l += 1 - # TODO SLG : refactorer le if / else - if line['credit']: - move_line = ','.join([ - # Line number - '%d' % l, - # Date (ddmmyy) - '%s/%s/%s' % ( - line['date'][8:10], line['date'][5:7], - line['date'][2:4]), - # Journal - line['journal'].replace(',', '')[:4], - # Account number - # (possibly with the partner code appended to it) - account_nb.replace(',', ''), - # Manual title - '"%s"' % line['ref'][:40], - # Accountable receipt number - '"%s"' % line['name'][:15], - # Amount - '%f' % abs(line['credit']), - # [C]redit or [D]ebit - 'C', - # Date of maturity (ddmmyy) - line['date_maturity'] and '%s%s%s' % ( - line['date_maturity'][8:10], - line['date_maturity'][5:7], - line['date_maturity'][2:4]) or '', - # Currency - fiscalyear.company_id.currency_id.name.replace( - ',', ''), - ]) - if is_analytic_column: - move_line += ',' + line['analytic'] - moves_file.write(unidecode(move_line)) - moves_file.write('\r\n') - if line['debit']: - move_line = ','.join([ - # Line number - '%d' % l, - # Date (ddmmyy) - '%s/%s/%s' % ( - line['date'][8:10], line['date'][5:7], - line['date'][2:4]), - # Journal - line['journal'].replace(',', '')[:4], - # Account number - # (possibly with the partner code appended to it) - account_nb.replace(',', ''), - # Manual title - '"%s"' % line['ref'][:40], - # Accountable receipt number - '"%s"' % line['name'][:15], - # Amount - '%f' % abs(line['debit']), - # [C]redit or [D]ebit - 'D', - # Date of maturity (ddmmyy) - line['date_maturity'] and '%s%s%s' % ( - line['date_maturity'][8:10], - line['date_maturity'][5:7], - line['date_maturity'][2:4]) or '', - # Currency - fiscalyear.company_id.currency_id.name.replace( - ',', ''), - ]) - if is_analytic_column: - move_line += ',' + line['analytic'] - moves_file.write(unidecode(move_line)) - moves_file.write('\r\n') - exported_move_ids.append(move.id) - - # Mark the moves as exported to EBP - export_id = False - if len(exported_move_ids): - export_id = export_obj.create(cr, uid, { - 'fiscalyear_id': fiscalyear.id, - 'company_id': user_company.id, - 'description': data['form']['description'], - }, context=context) - self.pool.get('account.move').write(cr, uid, exported_move_ids, { - 'exported_ebp_id': export_id, - }, context=context) - - # Header for Balance File - line2 = ','.join([ - "Account number", - "Account name", - "Debit", - "Credit", - "Debit Balance", - "Credit Balance", - ]) - balance_file.write(unidecode(line2)) - balance_file.write('\r\n') - - # Write the accounts into the file - # Write the balance of accounts into the file - for account_nb, account in accounts_data.iteritems(): - line = ','.join([ - account_nb.replace(',', ''), - (account['name'] or '').replace(',', '')[:60], - (account['partner_name'] or '').replace(',', '')[:30], - (account['address'] or '').replace(',', '')[:100], - (account['zip'] or '').replace(',', '')[:5], - (account['city'] or '').replace(',', '')[:30], - (account['country'] or '').replace(',', '')[:35], - (account['contact'] or '').replace(',', '')[:35], - (account['phone'] or '').replace(',', '')[:20], - (account['fax'] or '').replace(',', '')[:20], - ]) - account_file.write(unidecode(line)) - account_file.write('\r\n') - - credit = (account['credit'] or 0) - debit = (account['debit'] or 0) - if credit > debit: - credit_balance = credit - debit - debit_balance = 0 - else: - credit_balance = 0 - debit_balance = debit - credit - - line2 = ','.join([ - account_nb.replace(',', ''), - (account['name'] or '').replace(',', '')[:60], - str(debit), - str(credit), - str(debit_balance), - str(credit_balance), - ]) - balance_file.write(unidecode(line2)) - balance_file.write('\r\n') - - _logger.debug( - "%d accounts(s) exported to COMPTES.TXT" % len(accounts_data)) - - self.write(cr, uid, ids, { - 'exported_moves': len(exported_move_ids), - 'ignored_moves': len(ignored_move_ids), - 'exported_lines': l, - 'exported_accounts': len(accounts_data), - }, context=context) - if export_id: - export_obj.write(cr, uid, export_id, { - 'exported_moves': len(exported_move_ids), - 'ignored_moves': len(ignored_move_ids), - 'exported_lines': l, - 'exported_accounts': len(accounts_data), - }, context=context) - return export_id diff --git a/account_export_ebp/wizard/wizard_ebp_export.py b/account_export_ebp/wizard/wizard_ebp_export.py new file mode 100644 index 0000000..c9d5686 --- /dev/null +++ b/account_export_ebp/wizard/wizard_ebp_export.py @@ -0,0 +1,188 @@ +# coding: utf-8 +# Copyright (C) 2010 - 2015: Numérigraphe SARL +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Julien WESTE +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import api, fields, models + + +class WizardEbpExport(models.TransientModel): + _name = "wizard.ebp.export" + + _STATE_SELECTION = [ + ('draft', 'Draft'), + ('done', 'Done'), + ] + + # Columns Section + ebp_export_id = fields.Many2one( + string='EBP Export', comodel_name='ebp.export', readonly=True) + + state = fields.Selection( + selection=_STATE_SELECTION, string='State', default='draft') + + fiscalyear_id = fields.Many2one( + comodel_name='account.fiscalyear', string='Fiscal year', + required=True, default=lambda s: s._default_fiscalyear_id(), + domain="[('state', '=', 'draft')]", + help='Only the moves in this fiscal year will be exported') + + description = fields.Text( + string='Description', + help="Extra Description for Accountant Manager.") + + file_name_moves = fields.Char( + related='ebp_export_id.file_name_moves', readonly=True) + + file_name_accounts = fields.Char( + related='ebp_export_id.file_name_accounts', readonly=True) + + file_name_balance = fields.Char( + related='ebp_export_id.file_name_balance', readonly=True) + + data_moves = fields.Binary( + related='ebp_export_id.data_moves', readonly=True) + + data_accounts = fields.Binary( + related='ebp_export_id.data_accounts', readonly=True) + + data_balance = fields.Binary( + related='ebp_export_id.data_balance', readonly=True) + + ignored_draft_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_period_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_journal_code_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_to_check_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_exported_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_partner_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + ignored_tax_code_move_qty = fields.Integer( + compute='_compute_move_selection', multi='move_selection') + + selected_move_qty = fields.Integer( + string='Quantity of Selected Moves', readonly=True, + compute='_compute_move_selection', multi='move_selection') + + exported_move_ids = fields.Many2many( + string='Exported Moves', comodel_name='account.move', + compute='_compute_move_selection', multi='move_selection') + + exported_move_qty = fields.Integer( + string='Quantity of Exported Moves', readonly=True, + compute='_compute_move_selection', multi='move_selection') + + # Default Section + @api.model + def _default_fiscalyear_id(self): + AccountMove = self.env['account.move'] + moves = AccountMove.browse(self.env.context.get('active_ids', [])) + fiscalyears = moves.mapped('period_id.fiscalyear_id') + if len(fiscalyears) == 1: + return fiscalyears[0].id + else: + return False + + @api.multi + @api.depends('fiscalyear_id') + def _compute_move_selection(self): + AccountMove = self.env['account.move'] + AccountJournal = self.env['account.journal'] + + for wizard in self: + selected_moves = AccountMove.browse( + self.env.context.get('active_ids', [])) + wizard.selected_move_qty = len(selected_moves) + + selection_domain = [ + ('id', 'in', self.env.context.get('active_ids', []))] + full_domain = selection_domain[:] + + # filter by state (remove draft) + wizard.ignored_draft_move_qty = len(AccountMove.search( + selection_domain + [('state', '=', 'draft')])) + full_domain += [('state', '!=', 'draft')] + + # Filter by partner without ebp suffix + without_correct_partner_move_lines =\ + selected_moves.mapped('line_id').filtered( + lambda x: x.partner_id and + x.partner_id.has_ebp_move_line is False) + without_correct_partner_move_ids =\ + without_correct_partner_move_lines.mapped('move_id').ids + wizard.ignored_partner_move_qty =\ + len(without_correct_partner_move_ids) + full_domain +=\ + [('id', 'not in', without_correct_partner_move_ids)] + + # Filter by tax code without ebp suffix + without_correct_tax_code_move_lines =\ + selected_moves.mapped('line_id').filtered( + lambda x: x.tax_code_id and + x.tax_code_id.has_ebp_move_line is False) + without_correct_tax_code_move_ids =\ + without_correct_tax_code_move_lines.mapped('move_id').ids + wizard.ignored_tax_code_move_qty =\ + len(without_correct_tax_code_move_ids) + full_domain +=\ + [('id', 'not in', without_correct_tax_code_move_ids)] + + # filter by period (from fiscalyear) + if self.fiscalyear_id: + periods = self.fiscalyear_id.period_ids + wizard.ignored_period_move_qty = len(AccountMove.search( + selection_domain + + [('period_id', 'not in', periods.ids)])) + full_domain += [('period_id', 'in', periods.ids)] + + # Filter by journal (ebp_code should be defined) + journals = AccountJournal.search([('ebp_code', '!=', False)]) + wizard.ignored_journal_code_move_qty = len(AccountMove.search( + selection_domain + [('journal_id', 'not in', journals.ids)])) + full_domain += [('journal_id', 'in', journals.ids)] + + # filter moves to check + wizard.ignored_to_check_move_qty = len(AccountMove.search( + selection_domain + [('to_check', '=', True)])) + full_domain += [('to_check', '=', False)] + + # filter yet exported moves + wizard.ignored_exported_move_qty = len(AccountMove.search( + selection_domain + [('ebp_export_id', '!=', False)])) + full_domain += [('ebp_export_id', '=', False)] + + wizard.exported_move_ids = AccountMove.search(full_domain) + wizard.exported_move_qty = len(wizard.exported_move_ids.ids) + + @api.multi + def button_export(self): + self.ensure_one() + EbpExport = self.env['ebp.export'] + self.ebp_export_id = EbpExport.create({ + 'fiscalyear_id': self.fiscalyear_id.id, + 'description': self.description, + }) + self._compute_move_selection() + self.ebp_export_id.export(self.exported_move_ids) + self.state = 'done' + return { + 'type': 'ir.actions.act_window', + 'res_model': 'wizard.ebp.export', + 'view_mode': 'form', + 'view_type': 'form', + 'res_id': self.id, + 'views': [(False, 'form')], + 'target': 'new', + } diff --git a/account_export_ebp/wizard/wizard_ebp_unexport.py b/account_export_ebp/wizard/wizard_ebp_unexport.py new file mode 100644 index 0000000..270092d --- /dev/null +++ b/account_export_ebp/wizard/wizard_ebp_unexport.py @@ -0,0 +1,20 @@ +# coding: utf-8 +# Copyright (C) 2010 - 2015: Numérigraphe SARL +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Julien WESTE +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from openerp import api, models + + +class WizardEbpUnexport(models.TransientModel): + _name = 'wizard.ebp.unexport' + + @api.multi + def button_unexport(self): + AccountMove = self.env['account.move'] + moves = AccountMove.browse(self.env.context.get('active_ids', False)) + moves.with_context(force_write_ebp_exported=True).write( + {'ebp_export_id': False}) diff --git a/account_export_ebp/wizard/wizard_add_suffix.py b/account_export_ebp/wizard/wizard_res_partner_add_suffix.py similarity index 59% rename from account_export_ebp/wizard/wizard_add_suffix.py rename to account_export_ebp/wizard/wizard_res_partner_add_suffix.py index 5bfbfe8..1db9708 100644 --- a/account_export_ebp/wizard/wizard_add_suffix.py +++ b/account_export_ebp/wizard/wizard_res_partner_add_suffix.py @@ -7,80 +7,75 @@ import logging -from openerp.osv.orm import TransientModel -from openerp.osv import fields +from openerp import api, fields, models -logger = logging.getLogger(__name__) +_logger = logging.getLogger(__name__) try: from unidecode import unidecode except ImportError: unidecode = False - logger.debug("account_export_ebp - 'unidecode' librairy not found") + _logger.debug("account_export_ebp - 'unidecode' librairy not found") -class account_add_suffix(TransientModel): - _name = "account.add.suffix" +class WizardResPartnerAddSuffix(models.TransientModel): + _name = 'wizard.res.partner.add.suffix' - _columns = { - 'line_ids': fields.one2many( - 'account.add.suffix.line', 'account_add_suffix_id', - 'Add Suffix Lines'), - } + line_ids = fields.One2many( + comodel_name='wizard.res.partner.add.suffix.line', + inverse_name='wizard_id', string='Lines') # View Section - def affect_suffix(self, cr, uid, ids, context=None): - if context is None: - context = {} - rp_obj = self.pool.get('res.partner') - - for suf in self.browse(cr, uid, ids, context=context): - for line in suf.line_ids: - if line.suffix: - rp_obj.write(cr, uid, [line.partner_id.id], { - 'ref_nb': line.suffix, - }, context=context) - return True + @api.multi + def button_affect_suffix(self): + for wizard in self: + for line in wizard.line_ids: + if line.ebp_suffix: + line.partner_id.write({'ebp_suffix': line.ebp_suffix}) # Overloading section - def default_get(self, cr, uid, pFields, context=None): - rp_obj = self.pool.get('res.partner') + @api.model + def default_get(self, default_fields): + ResPartner = self.env['res.partner'] + + res = super( + WizardResPartnerAddSuffix, self).default_get(default_fields) + line_ids = [] - res = super(account_add_suffix, self).default_get( - cr, uid, pFields, context=context) - partner_ids = context.get('active_ids', False) - if not partner_ids: + selected_partner_ids = self.env.context.get('active_ids', []) + if not selected_partner_ids: return res existing_suffixes = {} sql_req = """ - SELECT rp.company_id, rp.ref_nb from res_partner rp - WHERE ref_nb is not Null """ - cr.execute(sql_req) - result = cr.dictfetchall() + SELECT rp.company_id, rp.ebp_suffix from res_partner rp + WHERE ebp_suffix is not Null """ + self.env.cr.execute(sql_req) + result = self.env.cr.dictfetchall() for item in result: existing_suffixes.setdefault(item['company_id'], []) - existing_suffixes[item['company_id']] += [item['ref_nb']] + existing_suffixes[item['company_id']] += [item['ebp_suffix']] - for partner in rp_obj.browse(cr, uid, partner_ids, context=context): - if partner.ref_nb: - suffix = partner.ref_nb + for partner in ResPartner.browse(selected_partner_ids): + if partner.ebp_suffix: + ebp_suffix = partner.ebp_suffix else: - suffix = self._get_suffix( + ebp_suffix = self._get_suffix( partner.name, existing_suffixes.get( partner.company_id.id, [])) - if suffix: + if ebp_suffix: existing_suffixes.setdefault(partner.company_id.id, []) - existing_suffixes[partner.company_id.id] += [suffix] + existing_suffixes[partner.company_id.id] += [ebp_suffix] line_ids.append((0, 0, { 'partner_id': partner.id, 'company_id': partner.company_id.id, - 'suffix': suffix, + 'ebp_suffix': ebp_suffix, })) - res.update({'line_ids': line_ids}) + res.update({'line_ids': line_ids}) return res # Private Section + @api.model def _get_suffix(self, name, existing_suffixes): # remove special caracters name2 = ''.join(e for e in name if e.isalnum()) @@ -127,18 +122,3 @@ def _get_suffix(self, name, existing_suffixes): if suffix and not(suffix in existing_suffixes): return suffix return False - - -class account_add_suffix_line(TransientModel): - _name = "account.add.suffix.line" - - _columns = { - 'account_add_suffix_id': fields.many2one( - 'account.add.suffix', 'Add Suffix Id'), - 'partner_id': fields.many2one( - 'res.partner', 'Partner'), - 'company_id': fields.many2one( - 'res.company', 'Company', readonly=True), - 'suffix': fields.char( - 'Suggested EBP Suffix', size=4), - } diff --git a/account_export_ebp/wizard/wizard_res_partner_add_suffix_line.py b/account_export_ebp/wizard/wizard_res_partner_add_suffix_line.py new file mode 100644 index 0000000..18adb57 --- /dev/null +++ b/account_export_ebp/wizard/wizard_res_partner_add_suffix_line.py @@ -0,0 +1,26 @@ +# coding: utf-8 +# Copyright (C) 2010 - 2015: Numérigraphe SARL +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Julien WESTE +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from openerp import fields, models + + +class WizardResPartnerAddSuffixLine(models.TransientModel): + _name = 'wizard.res.partner.add.suffix.line' + _order = 'company_id, partner_id' + + wizard_id = fields.Many2one( + comodel_name='wizard.res.partner.add.suffix', delete='cascade') + + partner_id = fields.Many2one( + comodel_name='res.partner', string='Partner', readonly=True) + + company_id = fields.Many2one( + comodel_name='res.company', string='Company', readonly=True) + + ebp_suffix = fields.Char( + string='EBP Suffix', size=4) diff --git a/account_export_ebp/wizard/wizard_unexport.py b/account_export_ebp/wizard/wizard_unexport.py deleted file mode 100644 index 519a66c..0000000 --- a/account_export_ebp/wizard/wizard_unexport.py +++ /dev/null @@ -1,29 +0,0 @@ -# coding: utf-8 -# Copyright (C) 2010 - 2015: Numérigraphe SARL -# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) -# @author: Julien WESTE -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from openerp.osv import osv -import logging -_logger = logging.getLogger(__name__) - - -class account_unexport_ebp(osv.TransientModel): - _name = "account.unexport.ebp" - - # Columns Section - _columns = { - } - - def unexport(self, cr, uid, ids, context=None): - if context is None: - context = {} - unexport_ids = context.get('active_ids', False) - am_obj = self.pool.get('account.move') - am_obj.write(cr, uid, unexport_ids, { - 'exported_ebp_id': False, - }, context=context) - # TODO: find the file in ebp.export model and remove the move lines - return ids