diff --git a/l10n_fr_fec_background/README.rst b/l10n_fr_fec_background/README.rst
new file mode 100644
index 000000000..82356ae9a
--- /dev/null
+++ b/l10n_fr_fec_background/README.rst
@@ -0,0 +1,41 @@
+.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
+ :alt: License: AGPL-3
+
+=============================
+Run FEC reports in Background
+=============================
+
+Usage
+=====
+
+* This module extends the features of l10n_fr_account module.
+
+* It enables to run the FEC reports in background and after finishing the report, it will send an email to the requested/logged in user.
+
+* It adds an option to download a report in .txt format.
+
+|
+
+.. image:: /l10n_fr_fec_background/static/src/image/FEC_Report.png
+ :width: 1100px
+
+
+|
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smashing it by providing a detailed and welcomed feedback.
+
+Credits
+=======
+
+Contributors
+------------
+
+* La Louve
+* Druidoo
+* Phan Hong Phuc \<\>
diff --git a/l10n_fr_fec_background/__init__.py b/l10n_fr_fec_background/__init__.py
new file mode 100644
index 000000000..40272379f
--- /dev/null
+++ b/l10n_fr_fec_background/__init__.py
@@ -0,0 +1 @@
+from . import wizard
diff --git a/l10n_fr_fec_background/__manifest__.py b/l10n_fr_fec_background/__manifest__.py
new file mode 100644
index 000000000..5bb3cedea
--- /dev/null
+++ b/l10n_fr_fec_background/__manifest__.py
@@ -0,0 +1,16 @@
+{
+ "name": "France - FEC Custom",
+ "version": "18.0.1.0.0",
+ "category": "Localization",
+ "summary": "Fichier d'Échange Informatisé (FEC) for France",
+ "author": "Druidoo,Odoo Community Association (OCA)",
+ "website": "https://github.com/OCA/l10n-france",
+ "license": "AGPL-3",
+ "depends": ["l10n_fr_fec_oca", "queue_job"],
+ "data": [
+ "data/mail_templates.xml",
+ "wizard/account_fr_fec_view.xml",
+ ],
+ "installable": True,
+ "auto_install": True,
+}
diff --git a/l10n_fr_fec_background/data/mail_templates.xml b/l10n_fr_fec_background/data/mail_templates.xml
new file mode 100644
index 000000000..2b00c9e7e
--- /dev/null
+++ b/l10n_fr_fec_background/data/mail_templates.xml
@@ -0,0 +1,15 @@
+
+
+
+ Send FEC file
+
+ {{ object.env.user.partner_id.email }}
+ {{ object.env.user.partner_id.id }}
+ Your requested FEC file
+
+ Your requested FEC file
]]>
+
+
diff --git a/l10n_fr_fec_background/i18n/l10n_fr_fec_background.pot b/l10n_fr_fec_background/i18n/l10n_fr_fec_background.pot
new file mode 100644
index 000000000..dcd7729b2
--- /dev/null
+++ b/l10n_fr_fec_background/i18n/l10n_fr_fec_background.pot
@@ -0,0 +1,50 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * l10n_fr_fec_background
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: l10n_fr_fec_background
+#: model:mail.template,body_html:l10n_fr_fec_background.send_fec_file_mail_template
+msgid "Your requested FEC file
"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model_terms:ir.ui.view,arch_db:l10n_fr_fec_background.account_fr_fec_view_inherit
+msgid "CSV"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model_terms:ir.ui.view,arch_db:l10n_fr_fec_background.account_fr_fec_view_inherit
+msgid "CSV Background"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model:ir.model,name:l10n_fr_fec_background.model_account_fr_fec
+msgid "Ficher Echange Informatise"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model_terms:ir.ui.view,arch_db:l10n_fr_fec_background.account_fr_fec_view_inherit
+msgid "TXT"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model_terms:ir.ui.view,arch_db:l10n_fr_fec_background.account_fr_fec_view_inherit
+msgid "TXT Background"
+msgstr ""
+
+#. module: l10n_fr_fec_background
+#: model:mail.template,subject:l10n_fr_fec_background.send_fec_file_mail_template
+msgid "Your requested FEC file"
+msgstr ""
+
diff --git a/l10n_fr_fec_background/pyproject.toml b/l10n_fr_fec_background/pyproject.toml
new file mode 100644
index 000000000..4231d0ccc
--- /dev/null
+++ b/l10n_fr_fec_background/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["whool"]
+build-backend = "whool.buildapi"
diff --git a/l10n_fr_fec_background/readme/CONTRIBUTORS.md b/l10n_fr_fec_background/readme/CONTRIBUTORS.md
new file mode 100644
index 000000000..8d790d413
--- /dev/null
+++ b/l10n_fr_fec_background/readme/CONTRIBUTORS.md
@@ -0,0 +1,4 @@
+- La Louve \<\>
+- Druidoo \<\>
+- Trobz \<\>
+ - Phan Hong Phuc \<\>
diff --git a/l10n_fr_fec_background/static/description/icon.png b/l10n_fr_fec_background/static/description/icon.png
new file mode 100644
index 000000000..fd60220fb
Binary files /dev/null and b/l10n_fr_fec_background/static/description/icon.png differ
diff --git a/l10n_fr_fec_background/static/src/image/FEC_Report.png b/l10n_fr_fec_background/static/src/image/FEC_Report.png
new file mode 100644
index 000000000..b96707ae8
Binary files /dev/null and b/l10n_fr_fec_background/static/src/image/FEC_Report.png differ
diff --git a/l10n_fr_fec_background/tests/__init__.py b/l10n_fr_fec_background/tests/__init__.py
new file mode 100644
index 000000000..1ffe42d3e
--- /dev/null
+++ b/l10n_fr_fec_background/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_l10n_fr_fec_background
diff --git a/l10n_fr_fec_background/tests/test_l10n_fr_fec_background.py b/l10n_fr_fec_background/tests/test_l10n_fr_fec_background.py
new file mode 100644
index 000000000..d2703b202
--- /dev/null
+++ b/l10n_fr_fec_background/tests/test_l10n_fr_fec_background.py
@@ -0,0 +1,33 @@
+from odoo.tests.common import TransactionCase
+
+
+class TestFrFECBackground(TransactionCase):
+ def setUp(self):
+ super().setUp()
+ self.fec_wizard = self.env["l10n_fr.fec.export.wizard"].create(
+ {"date_from": "2020-01-01", "date_to": "2020-02-29"}
+ )
+
+ def test_001_csv_report_background(self):
+ self.fec_wizard.generate_fec_file_in_background("csv", "|")
+ jobs = self.env["queue.job"].search(
+ [
+ ("func_string", "like", str(self.fec_wizard)),
+ ("state", "=", "pending"),
+ ]
+ )
+ self.assertEqual(
+ len(jobs), 2, "Job for CSV Report is not created in background!"
+ )
+
+ def test_002_txt_report_background(self):
+ self.fec_wizard.generate_fec_file_in_background("txt", "\t")
+ jobs = self.env["queue.job"].search(
+ [
+ ("func_string", "like", str(self.fec_wizard)),
+ ("state", "=", "pending"),
+ ]
+ )
+ self.assertEqual(
+ len(jobs), 2, "Job for TXT Report is not created in background!"
+ )
diff --git a/l10n_fr_fec_background/wizard/__init__.py b/l10n_fr_fec_background/wizard/__init__.py
new file mode 100644
index 000000000..2cc8a2511
--- /dev/null
+++ b/l10n_fr_fec_background/wizard/__init__.py
@@ -0,0 +1 @@
+from . import account_fr_fec
diff --git a/l10n_fr_fec_background/wizard/account_fr_fec.py b/l10n_fr_fec_background/wizard/account_fr_fec.py
new file mode 100644
index 000000000..988ca80bb
--- /dev/null
+++ b/l10n_fr_fec_background/wizard/account_fr_fec.py
@@ -0,0 +1,81 @@
+from dateutil.relativedelta import relativedelta
+
+from odoo import fields, models
+
+from odoo.addons.queue_job.job import identity_exact
+
+
+class AccountFrFec(models.TransientModel):
+ _inherit = "l10n_fr.fec.export.wizard"
+
+ def write(self, vals):
+ if self._context.get("extension", "") == "txt" and vals.get("filename"):
+ vals["filename"] = vals["filename"][:-3] + "txt"
+ return super().write(vals)
+
+ def export_fec_txt(self):
+ self.ensure_one()
+ return self.with_context(extension="txt").create_fec_report_action()
+
+ def export_fec_csv_background(self):
+ self.ensure_one()
+ return self.generate_fec_file_in_background()
+
+ def export_fec_txt_background(self):
+ self.ensure_one()
+ return self.generate_fec_file_in_background("txt")
+
+ def create_attachment(self, date_from, date_to, extension):
+ self.ensure_one()
+ self.date_from = date_from
+ self.date_to = date_to
+ results = self.with_context(extension=extension).generate_fec()
+ attachment = self.env["ir.attachment"].create(
+ {
+ "name": results.get("file_name"),
+ "store_fname": self.filename,
+ "db_datas": results.get("file_content"),
+ }
+ )
+ email_template = self.env.ref(
+ "l10n_fr_fec_background.send_fec_file_mail_template"
+ )
+ email_template.send_mail(
+ self.id,
+ force_send=True,
+ email_values={"attachment_ids": [(4, attachment.id)]},
+ )
+ return True
+
+ def generate_fec_file_in_background(self, extension="csv"):
+ self.ensure_one()
+ # Prepare periods
+ date_from = fields.Date.from_string(self.date_from)
+ date_to = fields.Date.from_string(self.date_to)
+ periods = self.prepare_periods(date_from, date_to)
+
+ # Call job
+ for period_from, period_to in periods:
+ self.write_fec_lines_session_job(period_from, period_to, extension)
+ return True
+
+ def prepare_periods(self, date_from, date_to):
+ periods = []
+ current_start = date_from
+
+ while current_start <= date_to:
+ current_end = current_start + relativedelta(day=31)
+ if current_end > date_to:
+ current_end = date_to
+
+ periods.append((current_start, current_end))
+ current_start = current_end + relativedelta(days=1)
+
+ return periods
+
+ def write_fec_lines_session_job(self, date_from, date_to, extension):
+ """Job to write FEC lines per period"""
+ self.with_delay(
+ identity_key=identity_exact,
+ description="Create FEC attachment",
+ ).create_attachment(date_from, date_to, extension)
diff --git a/l10n_fr_fec_background/wizard/account_fr_fec_view.xml b/l10n_fr_fec_background/wizard/account_fr_fec_view.xml
new file mode 100644
index 000000000..dcf7533c5
--- /dev/null
+++ b/l10n_fr_fec_background/wizard/account_fr_fec_view.xml
@@ -0,0 +1,40 @@
+
+
+
+ l10n_fr.fec.export.wizard.view.inherit
+ l10n_fr.fec.export.wizard
+ 100
+
+
+
+
+
+
+
+
+ CSV
+
+
+
+
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 000000000..264906fa1
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1 @@
+odoo-addon-l10n_fr_fec_oca @ git+https://github.com/OCA/l10n-france.git@refs/pull/687/head#subdirectory=l10n_fr_fec_oca