From 093fbf55f508b97b871c1ea937fba117b40e6e75 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Wed, 14 May 2025 12:22:00 +0200 Subject: [PATCH 01/10] [ADD] add some fields for import --- models/product_category.py | 1 + models/product_template.py | 3 +++ models/sale_intervention_plant_sequence.py | 8 +++++++ models/sale_project.py | 27 +++++++++++++++++++++- views/product_template_views.xml | 13 +++++++++++ views/sale_intervention_view.xml | 1 + views/sale_project_view.xml | 6 +++++ 7 files changed, 58 insertions(+), 1 deletion(-) diff --git a/models/product_category.py b/models/product_category.py index c2330f9..169a514 100644 --- a/models/product_category.py +++ b/models/product_category.py @@ -12,6 +12,7 @@ class ProductCategory(models.Model): # ------------------------------------------------------ symbol = fields.Char("Symbole") accessory_label = fields.Char("Nom de l'accessoire associé") + nurseryman_id = fields.Char("Numéro de pépinieriste") # ------------------------------------------------------ # SQL Constraints diff --git a/models/product_template.py b/models/product_template.py index 79224d0..ece02f6 100644 --- a/models/product_template.py +++ b/models/product_template.py @@ -13,6 +13,9 @@ class ProductTemplate(models.Model): nb_accesories = fields.Float("Nombre d'accessoires") accessory_label = fields.Char(related="categ_id.accessory_label", readonly=True) mulch_quantity_multiplier = fields.Float("Multiplicateur paillage", default=1.0) + latin_name = fields.Char( + string="Nom latin" + ) # ------------------------------------------------------ # SQL Constraints diff --git a/models/sale_intervention_plant_sequence.py b/models/sale_intervention_plant_sequence.py index 32984f1..6fea647 100644 --- a/models/sale_intervention_plant_sequence.py +++ b/models/sale_intervention_plant_sequence.py @@ -46,6 +46,14 @@ class SaleInterventionPlantSequence(models.Model): qty = fields.Integer("Qté par espèces") sequence = fields.Integer(string="Ordre dans la séquence", default=10) is_list = fields.Boolean("Est une construction liste") + scale = fields.Selection( + [ + ("little", "Petit"), + ("middle", "Moyen"), + ("big", "grand"), + ], + string="Taille", + ) # ------------------------------------------------------ # SQL Constraints diff --git a/models/sale_project.py b/models/sale_project.py index 0883c19..19ca8dd 100644 --- a/models/sale_project.py +++ b/models/sale_project.py @@ -124,7 +124,14 @@ class SaleProject(models.Model): readonly=True, states={"draft": [("readonly", False)], "sent": [("readonly", False)]}, ) - + plant_sector_id = fields.Many2one( + comodel_name="res.partner.geo.sector", string="Secteur de plantation" + ) + delivery_sector_id = fields.Many2one( + comodel_name="res.partner.geo.sector", string="Secteur de livraison" + ) + bark_supplier = fields.Char("Fournisseur de copeaux/écorce") + comment = fields.Text("Commentaires") saison_id = fields.Many2one( "sale.project.saison", "Saison", @@ -132,6 +139,24 @@ class SaleProject(models.Model): ondelete="restrict", ) date_visit = fields.Date("Date de visite") + delivery_month = fields.Selection( + [ + ("jan", "Janvier"), + ("feb", "Février"), + ("mar", "Mars"), + ("apr", "Avril"), + ("may", "Mai"), + ("jun", "Juin"), + ("jul", "Juillet"), + ("aug", "Août"), + ("sep", "Septembre"), + ("oct", "Octobre"), + ("nov", "Novembre"), + ("dec", "Décembre"), + ], + string="Moi de livraison", + ) + is_demo = fields.Boolean("Accueil démo") intervention_ids = fields.One2many( comodel_name="sale.intervention", diff --git a/views/product_template_views.xml b/views/product_template_views.xml index 31b5080..eb69be6 100644 --- a/views/product_template_views.xml +++ b/views/product_template_views.xml @@ -10,6 +10,19 @@ <field name="symbol" /> <field name="accessory_label" /> <field name="name" /> + <field name="nurseryman_id" /> + </field> + </field> + </record> + + + <record id="product_template_form_view" model="ir.ui.view"> + <field name="name">product.template.form.inherit</field> + <field name="model">product.template</field> + <field name="inherit_id" ref="product.product_template_form_view" /> + <field name="arch" type="xml"> + <field name="type" position="after"> + <field name="latin_name" /> </field> </field> </record> diff --git a/views/sale_intervention_view.xml b/views/sale_intervention_view.xml index d844bcc..2e2ba1b 100644 --- a/views/sale_intervention_view.xml +++ b/views/sale_intervention_view.xml @@ -240,6 +240,7 @@ options="{'no_open': True, 'no_create': True}" /> <field name="is_local" /> + <field name="scale" /> </tree> </field> <group diff --git a/views/sale_project_view.xml b/views/sale_project_view.xml index 1c4da6f..cbee72f 100644 --- a/views/sale_project_view.xml +++ b/views/sale_project_view.xml @@ -38,11 +38,17 @@ <group> <field name="project_subvention_id" readonly="True" /> <field name="geo_sector_id" /> + <field name="plant_sector_id" /> + <field name="delivery_sector_id" /> <field name="user_id" /> + <field name="bark_supplier" /> </group> <group> <field name="saison_id" /> <field name="date_visit" /> + <field name="comment" /> + <field name="delivery_month" /> + <field name="is_demo" /> <field name="state" invisible="1" /> </group> </group> -- GitLab From 74938b5ff7b2e8d57e0f3ef79d4ae0ff821b9304 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Wed, 14 May 2025 14:12:45 +0200 Subject: [PATCH 02/10] [UPD] review --- models/sale_intervention.py | 8 +++++ models/sale_project.py | 51 +++++++++++++++++++++++--------- views/product_template_views.xml | 1 - views/sale_intervention_view.xml | 1 + views/sale_project_view.xml | 4 ++- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/models/sale_intervention.py b/models/sale_intervention.py index e90e6bb..d23508b 100644 --- a/models/sale_intervention.py +++ b/models/sale_intervention.py @@ -439,6 +439,14 @@ class SaleIntervention(models.Model): inverse_name="sale_intervention_id", string="Articles à déstocker", ) + location = fields.Selection( + [ + ("in_field", "Plein champ"), + ("near_facility", "Bord de bâtiment"), + ("border", "Bordure"), + ], + string="Implantation", + ) # ------------------------------------------------------ # SQL Constraints diff --git a/models/sale_project.py b/models/sale_project.py index 19ca8dd..3f3ac28 100644 --- a/models/sale_project.py +++ b/models/sale_project.py @@ -141,22 +141,45 @@ class SaleProject(models.Model): date_visit = fields.Date("Date de visite") delivery_month = fields.Selection( [ - ("jan", "Janvier"), - ("feb", "Février"), - ("mar", "Mars"), - ("apr", "Avril"), - ("may", "Mai"), - ("jun", "Juin"), - ("jul", "Juillet"), - ("aug", "Août"), - ("sep", "Septembre"), - ("oct", "Octobre"), - ("nov", "Novembre"), - ("dec", "Décembre"), + ("1", "Janvier"), + ("2", "Février"), + ("3", "Mars"), + ("4", "Avril"), + ("5", "Mai"), + ("6", "Juin"), + ("7", "Juillet"), + ("8", "Août"), + ("9", "Septembre"), + ("10", "Octobre"), + ("11", "Novembre"), + ("12", "Décembre"), ], - string="Moi de livraison", + string="Mois de livraison", + ) + demo = fields.Selection( + [ + ("yes", "Oui"), + ("no", "Non"), + ], + string="Accueil démo", + ) + + online = fields.Selection( + [ + ("yes", "Oui"), + ("no", "Non"), + ], + string="Diffusion sur site internet", + ) + + plant_goal = fields.Selection( + [ + ("landscape", "Enjeu paysage"), + ("fence", "Clôture"), + ("biodiversity", "Préservation biodiversité"), + ], + string="Objectif plantation", ) - is_demo = fields.Boolean("Accueil démo") intervention_ids = fields.One2many( comodel_name="sale.intervention", diff --git a/views/product_template_views.xml b/views/product_template_views.xml index eb69be6..35e7c26 100644 --- a/views/product_template_views.xml +++ b/views/product_template_views.xml @@ -9,7 +9,6 @@ <field name="parent_id" position="after"> <field name="symbol" /> <field name="accessory_label" /> - <field name="name" /> <field name="nurseryman_id" /> </field> </field> diff --git a/views/sale_intervention_view.xml b/views/sale_intervention_view.xml index 2e2ba1b..d1f79f8 100644 --- a/views/sale_intervention_view.xml +++ b/views/sale_intervention_view.xml @@ -25,6 +25,7 @@ name="intervention_type_id" options="{'no_open': True, 'no_create': True}" /> + <field name="location" /> <field name="intervention_uom_name" invisible="True" /> </group> <group> diff --git a/views/sale_project_view.xml b/views/sale_project_view.xml index cbee72f..7c55e82 100644 --- a/views/sale_project_view.xml +++ b/views/sale_project_view.xml @@ -48,7 +48,9 @@ <field name="date_visit" /> <field name="comment" /> <field name="delivery_month" /> - <field name="is_demo" /> + <field name="demo" /> + <field name="plant_goal" /> + <field name="online" /> <field name="state" invisible="1" /> </group> </group> -- GitLab From 898ab92763f658ef9d52c8d674708dc5c14811b9 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Wed, 14 May 2025 15:52:03 +0200 Subject: [PATCH 03/10] [UPD] review add some models --- __manifest__.py | 2 ++ models/sale_intervention.py | 19 +++++++---- models/sale_project.py | 19 +++++++---- security/ir.model.access.csv | 2 ++ views/sale_intervention_location_view.xml | 41 +++++++++++++++++++++++ views/sale_intervention_view.xml | 2 +- views/sale_project_plant_goal_view.xml | 41 +++++++++++++++++++++++ views/sale_project_view.xml | 2 +- 8 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 views/sale_intervention_location_view.xml create mode 100644 views/sale_project_plant_goal_view.xml diff --git a/__manifest__.py b/__manifest__.py index 2bf177e..c68871e 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -23,6 +23,8 @@ "views/sale_project_admin_state_views.xml", "views/product_template_views.xml", "views/res_partner_views.xml", + "views/sale_intervention_location_view.xml", + "views/sale_project_plant_goal_view.xml", # views menu # wizard ], diff --git a/models/sale_intervention.py b/models/sale_intervention.py index d23508b..e49b24c 100644 --- a/models/sale_intervention.py +++ b/models/sale_intervention.py @@ -439,13 +439,10 @@ class SaleIntervention(models.Model): inverse_name="sale_intervention_id", string="Articles à déstocker", ) - location = fields.Selection( - [ - ("in_field", "Plein champ"), - ("near_facility", "Bord de bâtiment"), - ("border", "Bordure"), - ], - string="Implantation", + location_id = fields.Many2one( + "sale.intervention.location", + "Implantation", + ondelete="restrict", ) # ------------------------------------------------------ @@ -1049,3 +1046,11 @@ class SaleIntervention(models.Model): res = super().unlink() project_id.update_order_lines() return res + + +class SaleInterventionLocation(models.Model): + _name = "sale.intervention.location" + _description = "Implantation" + _order = "name" + + name = fields.Char(string="Implantation", required=True) diff --git a/models/sale_project.py b/models/sale_project.py index 3f3ac28..26981a6 100644 --- a/models/sale_project.py +++ b/models/sale_project.py @@ -172,13 +172,10 @@ class SaleProject(models.Model): string="Diffusion sur site internet", ) - plant_goal = fields.Selection( - [ - ("landscape", "Enjeu paysage"), - ("fence", "Clôture"), - ("biodiversity", "Préservation biodiversité"), - ], - string="Objectif plantation", + plant_goal_id = fields.Many2one( + "sale.project.plant.goal", + "Objectif plantation", + ondelete="restrict", ) intervention_ids = fields.One2many( @@ -433,6 +430,14 @@ class SaleProjectSaison(models.Model): end_date = fields.Date("Date de fin", required=True) +class SaleProjectPlantGoal(models.Model): + _name = "sale.project.plant.goal" + _description = "Objectif plantation" + _order = "name" + + name = fields.Char(string="Objectif plantation", required=True) + + class SaleProjectAdminState(models.Model): _name = "sale.project.admin.state" _description = "Étapes du projet" diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 997ea40..26c8623 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -8,4 +8,6 @@ sale_financial_help_salesteam,sale_financial_help_salesteam,model_sale_financial sale_intervention_salesteam,sale_intervention_salesteam,model_sale_intervention,sales_team.group_sale_salesman,1,1,1,1 sale_intervention_stock_salesteam,sale_intervention_stock_salesteam,model_sale_intervention_stock,sales_team.group_sale_salesman,1,1,1,1 sale_intervention_plant_sequence_salesteam,sale_intervention_plant_sequence_salesteam,model_sale_intervention_plant_sequence,sales_team.group_sale_salesman,1,1,1,1 +sale_intervention_location_salesteam,sale_intervention_location_salesteam,model_sale_intervention_location,sales_team.group_sale_salesman,1,1,1,1 sale_project_subvention_salesteam,sale_project_subvention_salesteam,model_sale_project_subvention,sales_team.group_sale_salesman,1,1,1,1 +sale_project_saison_salesteam,sale_project_plant_goal_salesteam,model_sale_project_plant_goal,sales_team.group_sale_salesman,1,1,1,1 diff --git a/views/sale_intervention_location_view.xml b/views/sale_intervention_location_view.xml new file mode 100644 index 0000000..5344251 --- /dev/null +++ b/views/sale_intervention_location_view.xml @@ -0,0 +1,41 @@ +<odoo> + + <!-- Form View--> + <record id="sale_intervention_admin_location_view_form" model="ir.ui.view"> + <field name="name">Implantation</field> + <field name="model">sale.intervention.location</field> + <field name="arch" type="xml"> + <form> + <field name="name" /> + </form> + </field> + </record> + + <!-- List View--> + <record id="sale_intervention_admin_location_view_list" model="ir.ui.view"> + <field name="name">Implantation</field> + <field name="model">sale.intervention.location</field> + <field name="arch" type="xml"> + <tree> + <field name="name" /> + </tree> + </field> + </record> + + <!-- Actions opening views on models --> + <record model="ir.actions.act_window" id="sale_intervention_admin_location_act_window"> + <field name="name">Implantation</field> + <field name="res_model">sale.intervention.location</field> + <field name="view_mode">tree,form</field> + </record> + + <!-- Menu Items --> + <menuitem + id="menu_sale_intervention_admin_goal" + name="Implantation" + parent="ap_sale_project.menu_sale_project_config" + action="sale_intervention_admin_location_act_window" + sequence="22" + /> + +</odoo> diff --git a/views/sale_intervention_view.xml b/views/sale_intervention_view.xml index d1f79f8..162d249 100644 --- a/views/sale_intervention_view.xml +++ b/views/sale_intervention_view.xml @@ -25,7 +25,7 @@ name="intervention_type_id" options="{'no_open': True, 'no_create': True}" /> - <field name="location" /> + <field name="location_id" /> <field name="intervention_uom_name" invisible="True" /> </group> <group> diff --git a/views/sale_project_plant_goal_view.xml b/views/sale_project_plant_goal_view.xml new file mode 100644 index 0000000..c41b2ee --- /dev/null +++ b/views/sale_project_plant_goal_view.xml @@ -0,0 +1,41 @@ +<odoo> + + <!-- Form View--> + <record id="sale_project_admin_goal_view_form" model="ir.ui.view"> + <field name="name">Objectif plantation</field> + <field name="model">sale.project.plant.goal</field> + <field name="arch" type="xml"> + <form> + <field name="name" /> + </form> + </field> + </record> + + <!-- List View--> + <record id="sale_project_admin_goal_view_list" model="ir.ui.view"> + <field name="name">Objectif plantation</field> + <field name="model">sale.project.plant.goal</field> + <field name="arch" type="xml"> + <tree> + <field name="name" /> + </tree> + </field> + </record> + + <!-- Actions opening views on models --> + <record model="ir.actions.act_window" id="sale_project_admin_location_act_window"> + <field name="name">Objectif plantation</field> + <field name="res_model">sale.project.plant.goal</field> + <field name="view_mode">tree,form</field> + </record> + + <!-- Menu Items --> + <menuitem + id="menu_sale_project_admin_goal" + name="Objectif plantation" + parent="ap_sale_project.menu_sale_project_config" + action="sale_project_admin_location_act_window" + sequence="21" + /> + +</odoo> diff --git a/views/sale_project_view.xml b/views/sale_project_view.xml index 7c55e82..0ec7675 100644 --- a/views/sale_project_view.xml +++ b/views/sale_project_view.xml @@ -49,7 +49,7 @@ <field name="comment" /> <field name="delivery_month" /> <field name="demo" /> - <field name="plant_goal" /> + <field name="plant_goal_id" /> <field name="online" /> <field name="state" invisible="1" /> </group> -- GitLab From 195258d56ea44d92ab538ee36494d06d0db52dcb Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Wed, 14 May 2025 16:14:38 +0200 Subject: [PATCH 04/10] [UPD] review add some models --- views/sale_intervention_location_view.xml | 16 ++-------------- views/sale_project_plant_goal_view.xml | 15 ++------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/views/sale_intervention_location_view.xml b/views/sale_intervention_location_view.xml index 5344251..04b672c 100644 --- a/views/sale_intervention_location_view.xml +++ b/views/sale_intervention_location_view.xml @@ -1,22 +1,11 @@ <odoo> - <!-- Form View--> - <record id="sale_intervention_admin_location_view_form" model="ir.ui.view"> - <field name="name">Implantation</field> - <field name="model">sale.intervention.location</field> - <field name="arch" type="xml"> - <form> - <field name="name" /> - </form> - </field> - </record> - <!-- List View--> <record id="sale_intervention_admin_location_view_list" model="ir.ui.view"> <field name="name">Implantation</field> <field name="model">sale.intervention.location</field> <field name="arch" type="xml"> - <tree> + <tree editable="bottom"> <field name="name" /> </tree> </field> @@ -26,7 +15,7 @@ <record model="ir.actions.act_window" id="sale_intervention_admin_location_act_window"> <field name="name">Implantation</field> <field name="res_model">sale.intervention.location</field> - <field name="view_mode">tree,form</field> + <field name="view_mode">tree</field> </record> <!-- Menu Items --> @@ -37,5 +26,4 @@ action="sale_intervention_admin_location_act_window" sequence="22" /> - </odoo> diff --git a/views/sale_project_plant_goal_view.xml b/views/sale_project_plant_goal_view.xml index c41b2ee..aeaceee 100644 --- a/views/sale_project_plant_goal_view.xml +++ b/views/sale_project_plant_goal_view.xml @@ -1,22 +1,11 @@ <odoo> - <!-- Form View--> - <record id="sale_project_admin_goal_view_form" model="ir.ui.view"> - <field name="name">Objectif plantation</field> - <field name="model">sale.project.plant.goal</field> - <field name="arch" type="xml"> - <form> - <field name="name" /> - </form> - </field> - </record> - <!-- List View--> <record id="sale_project_admin_goal_view_list" model="ir.ui.view"> <field name="name">Objectif plantation</field> <field name="model">sale.project.plant.goal</field> <field name="arch" type="xml"> - <tree> + <tree editable="bottom"> <field name="name" /> </tree> </field> @@ -26,7 +15,7 @@ <record model="ir.actions.act_window" id="sale_project_admin_location_act_window"> <field name="name">Objectif plantation</field> <field name="res_model">sale.project.plant.goal</field> - <field name="view_mode">tree,form</field> + <field name="view_mode">tree</field> </record> <!-- Menu Items --> -- GitLab From 77880c6dfa3bc424b7d63276028b99a523a0f017 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Thu, 15 May 2025 11:29:33 +0200 Subject: [PATCH 05/10] [FIX] typo un security csv --- security/ir.model.access.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 26c8623..861182d 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -10,4 +10,4 @@ sale_intervention_stock_salesteam,sale_intervention_stock_salesteam,model_sale_i sale_intervention_plant_sequence_salesteam,sale_intervention_plant_sequence_salesteam,model_sale_intervention_plant_sequence,sales_team.group_sale_salesman,1,1,1,1 sale_intervention_location_salesteam,sale_intervention_location_salesteam,model_sale_intervention_location,sales_team.group_sale_salesman,1,1,1,1 sale_project_subvention_salesteam,sale_project_subvention_salesteam,model_sale_project_subvention,sales_team.group_sale_salesman,1,1,1,1 -sale_project_saison_salesteam,sale_project_plant_goal_salesteam,model_sale_project_plant_goal,sales_team.group_sale_salesman,1,1,1,1 +sale_project_plant_goal_salesteam,sale_project_plant_goal_salesteam,model_sale_project_plant_goal,sales_team.group_sale_salesman,1,1,1,1 -- GitLab From bcb5b82ec0aac18a476890ebc5ab0be0fd6ed17c Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Thu, 15 May 2025 17:34:18 +0200 Subject: [PATCH 06/10] [ADD] add export data --- __init__.py | 2 + __manifest__.py | 1 + controllers/__init__.py | 1 + controllers/export.py | 216 +++++++++++++++++++++ models/sale_intervention.py | 2 + models/sale_intervention_plant_sequence.py | 2 +- security/ir.model.access.csv | 2 + views/sale_intervention_view.xml | 1 + wizard/__init__.py | 1 + wizard/ap_export_wizard.py | 27 +++ wizard/ap_export_wizard_views.xml | 50 +++++ 11 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 controllers/__init__.py create mode 100644 controllers/export.py create mode 100644 wizard/__init__.py create mode 100644 wizard/ap_export_wizard.py create mode 100644 wizard/ap_export_wizard_views.xml diff --git a/__init__.py b/__init__.py index e0e3732..39bfba2 100644 --- a/__init__.py +++ b/__init__.py @@ -2,3 +2,5 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from . import models +from . import wizard +from . import controllers diff --git a/__manifest__.py b/__manifest__.py index c68871e..a4a1454 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -27,6 +27,7 @@ "views/sale_project_plant_goal_view.xml", # views menu # wizard + "wizard/ap_export_wizard_views.xml", ], "qweb": [ # "static/src/xml/*.xml", diff --git a/controllers/__init__.py b/controllers/__init__.py new file mode 100644 index 0000000..4435ea7 --- /dev/null +++ b/controllers/__init__.py @@ -0,0 +1 @@ +from . import export diff --git a/controllers/export.py b/controllers/export.py new file mode 100644 index 0000000..b9558b1 --- /dev/null +++ b/controllers/export.py @@ -0,0 +1,216 @@ +from odoo import http +from odoo.http import request +from odoo.addons.web.controllers.main import ExcelExport +import io +import xlsxwriter + + +def export_xlsx(data_by_sheet): + """ + Génère un fichier XLSX avec plusieurs feuilles. + + :param data_by_sheet: dict où chaque clé est un nom de feuille, + et chaque valeur est une liste de dictionnaires. + Exemple : + { + 'Feuille1': [{'Nom': 'Alice', 'Age': 30}], + 'Feuille2': [{'Produit': 'Widget', 'Prix': 20.5}] + } + :return: binary XLSX content + """ + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {"in_memory": True}) + + for sheet_name, rows in data_by_sheet.items(): + sheet = workbook.add_worksheet(sheet_name[:31]) # Excel limite à 31 caractères + + if not rows: + continue + + headers = list(rows[0].keys()) + for col_idx, header in enumerate(headers): + sheet.write(0, col_idx, header) + + for row_idx, row in enumerate(rows, start=1): + for col_idx, header in enumerate(headers): + sheet.write(row_idx, col_idx, row.get(header, "")) + + workbook.close() + output.seek(0) + return output.read() + + +class ApExportController(http.Controller): + + def get_filename(self, type, saison): + prefix = { + "order": "suivi_commande", + "fin": "suivi_financeurs", + "tech": "suivi_technique", + } + + return f"{prefix.get(type, 'fichier')}_{saison.name}.xlsx" + + def get_nb_staples(self, inter_id): + staples = 0 + if inter_id.mulch_has_staples: + staples += inter_id.mulch_staples_qty * inter_id.mulch_qty + if inter_id.mulch2_has_staples: + staples += inter_id.mulch2_staples_qty * inter_id.mulch2_qty + + def get_linked_contact(self, partner_id): + if partner_id.child_ids: + return ",".join([child.name for child in partner_id.child_ids]) + return "" + + def get_financial_help(self, inter): + if inter.financial_help_ids: + return ",".join([h.name for h in inter.financial_help_ids]) + return "" + + def get_nb_tree(self, inter_id): + + if inter_id.plant_sequence_ids: + to_count = inter_id.plant_sequence_ids + else: + to_count = inter_id.plant_list_ids + + trees = to_count.search([("scale", "=", "big")]) + return len(trees) + + def get_order_data(self, saison): + """ + export commande + """ + projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) + file = {} + + for project in projects: + file[project.name] = [{"test": "test"}] + + return file + + def get_fin_data(self, saison): + """ + export suivi financeurs + """ + sheet_name = "suivi financeurs" + file = {sheet_name: []} + + projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) + + for project in projects: + if project.intervention_ids: + for inter in project.intervention_ids: + project_data = { + "Saison": saison.name or "", + "Programme": project.project_subvention_id.name or "", + "Numéro client": project.partner_id.ref or "", + "Secteur de plantation": project.plant_sector_id.name or "", + "Secteur de livraison": project.delivery_sector_id.name or "", + "Réferent": project.user_id.name or "", + "Planteur": project.partner_id.name or "", + "Contacts": self.get_linked_contact(project.partner_id), + "Adresse (rue)": project.partner_id.street or "", + "Adresse (rue 2)": project.partner_id.street2 or "", + "Code postal": project.partner_id.zip or "", + "Ville": project.partner_id.city or "", + "Télephone": project.partner_id.phone or "", + "Email": project.partner_id.email or "", + "Commune intervention": inter.city or "", + "Geo latitude": str(inter.latitude).replace(',', '.'), + "Geo longitude": str(inter.longitude).replace(',', '.'), + "Bord de départementale": inter.near_road or "", + "Forme juridique": project.partner_id.partner_company_type_id.name or "", + "Type de culture": project.partner_id.culture_type_id.name or "", + #todo format date + "Date de première adhésion": project.partner_id.year_1st_membership or "", + "Diffusion sur site internet": project.online or "", + "Longueur de haie": inter.intervention_length or "", + "Nombre de plants": inter.plant_qty or "", + "Surface (en m²)": inter.surface or "", + "Dont nombre total d'arbres": self.get_nb_tree(inter), + "Type d'intervention": inter.intervention_type_id.name or "", + "Implantation": inter.location_id.name or "", + "Objectif plantation": project.plant_goal_id.name or "", + "Avancement": project.admin_state_id.name, + "Aides financières": self.get_financial_help(inter) + } + + file.get(sheet_name).append(project_data) + + return file + + def get_tech_data(self, saison): + """ + export suivi technique + """ + sheet_name = "suivi technique" + file = {sheet_name: []} + projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) + + for project in projects: + if project.intervention_ids: + for inter in project.intervention_ids: + project_data = { + "Saison": saison.name or "", + "Programme": project.project_subvention_id.name or "", + "Client": project.partner_id.ref or "", + "Secteur de plantation": project.plant_sector_id.name or "", + "Secteur de livraison": project.delivery_sector_id.name or "", + "Réferent": project.user_id.name or "", + "Planteur": project.partner_id.name or "", + "Contacts": self.get_linked_contact(project.partner_id), + "Adresse (rue)": project.partner_id.street or "", + "Adresse (rue 2)": project.partner_id.street2 or "", + "Code postal": project.partner_id.zip or "", + "Ville": project.partner_id.city or "", + "Télephone": project.partner_id.phone or "", + "Email": project.partner_id.email or "", + "Commune intervention": inter.city or "", + "Longueur de haie": inter.intervention_length or "", + "Nombre de plants": inter.plant_qty or "", + "Surface (en m²)": inter.surface or "", + "Dont nombre total d'arbres": self.get_nb_tree(inter), + "Type d'intervention": inter.intervention_type_id.name or "", + "Paillage 1": inter.mulch_id.name or "", + "Paillage 2": inter.mulch2_id.name or "", + "Qté paillage 1": inter.mulch_qty or "", + "Qté paillage 2": inter.mulch2_qty or "", + "Nom fournisseur copeaux/écorce": project.bark_supplier or "", + "Qté protegée haut": inter.high_protection_qty or "", + "Qté piquets": inter.stake_qty or "", + "Qté protegée bas": inter.low_protection_qty or "", + "Qté bambous": inter.bamboo_qty or "", + "Nombre d'agrafes": self.get_nb_staples(inter), + "Nombre de collerettes": inter.collarette_qty or "", + "Mois livraison": project.delivery_month or "", + "Accueil démo": project.demo or "", + "Commentaires": project.comment or "", + } + + file.get(sheet_name).append(project_data) + + return file + + @http.route("/ap_export/xlsx_download", type="http", auth="user") + def download_xlsx(self, wizard_id, **kwargs): + wizard = request.env["ap.export.wizard"].sudo().browse(int(wizard_id)) + filename = self.get_filename(wizard.export_type, wizard.saison_id) + + data_methods = { + "order": self.get_order_data, + "fin": self.get_fin_data, + "tech": self.get_tech_data, + } + + xlsx_data = export_xlsx(data_methods.get(wizard.export_type)(wizard.saison_id)) + + headers = [ + ( + "Content-Type", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ), + ("Content-Disposition", 'attachment; filename="%s"' % filename), + ] + return request.make_response(xlsx_data, headers) diff --git a/models/sale_intervention.py b/models/sale_intervention.py index e49b24c..098f22f 100644 --- a/models/sale_intervention.py +++ b/models/sale_intervention.py @@ -445,6 +445,8 @@ class SaleIntervention(models.Model): ondelete="restrict", ) + near_road = fields.Char("Bord de départementale") + # ------------------------------------------------------ # SQL Constraints # ------------------------------------------------------ diff --git a/models/sale_intervention_plant_sequence.py b/models/sale_intervention_plant_sequence.py index 6fea647..d9703ff 100644 --- a/models/sale_intervention_plant_sequence.py +++ b/models/sale_intervention_plant_sequence.py @@ -50,7 +50,7 @@ class SaleInterventionPlantSequence(models.Model): [ ("little", "Petit"), ("middle", "Moyen"), - ("big", "grand"), + ("big", "Grand"), ], string="Taille", ) diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 861182d..bb3e919 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -11,3 +11,5 @@ sale_intervention_plant_sequence_salesteam,sale_intervention_plant_sequence_sale sale_intervention_location_salesteam,sale_intervention_location_salesteam,model_sale_intervention_location,sales_team.group_sale_salesman,1,1,1,1 sale_project_subvention_salesteam,sale_project_subvention_salesteam,model_sale_project_subvention,sales_team.group_sale_salesman,1,1,1,1 sale_project_plant_goal_salesteam,sale_project_plant_goal_salesteam,model_sale_project_plant_goal,sales_team.group_sale_salesman,1,1,1,1 +access_ap_export_wizard,access_ap_export_wizard,model_ap_export_wizard,sales_team.group_sale_salesman,1,1,1,0 + diff --git a/views/sale_intervention_view.xml b/views/sale_intervention_view.xml index 162d249..01f55dd 100644 --- a/views/sale_intervention_view.xml +++ b/views/sale_intervention_view.xml @@ -26,6 +26,7 @@ options="{'no_open': True, 'no_create': True}" /> <field name="location_id" /> + <field name="near_road" /> <field name="intervention_uom_name" invisible="True" /> </group> <group> diff --git a/wizard/__init__.py b/wizard/__init__.py new file mode 100644 index 0000000..3ae425c --- /dev/null +++ b/wizard/__init__.py @@ -0,0 +1 @@ +from . import ap_export_wizard diff --git a/wizard/ap_export_wizard.py b/wizard/ap_export_wizard.py new file mode 100644 index 0000000..c9945fc --- /dev/null +++ b/wizard/ap_export_wizard.py @@ -0,0 +1,27 @@ +from odoo import models, fields + + +class ApExportWizard(models.TransientModel): + _name = "ap.export.wizard" + _description = "Export de données" + + export_type = fields.Selection( + [ + ("order", "Commandes"), + ("fin", "Suivi financeurs"), + ("tech", "Suivi technique"), + ], + required=True, + default="order", + ) + + saison_id = fields.Many2one( + comodel_name="sale.project.saison", string="Saison", required=True + ) + + def action_exporter(self): + return { + "type": "ir.actions.act_url", + "url": f"/ap_export/xlsx_download?wizard_id={self.id}", + "target": "self", + } diff --git a/wizard/ap_export_wizard_views.xml b/wizard/ap_export_wizard_views.xml new file mode 100644 index 0000000..eca1364 --- /dev/null +++ b/wizard/ap_export_wizard_views.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" ?> +<!-- Copyright 2025 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> +<odoo> + <data> + <record id="view_ap_export_wizard_form" model="ir.ui.view"> + <field name="name">ap.export.wizard.form</field> + <field name="model">ap.export.wizard</field> + <field name="arch" type="xml"> + <form string="Export de données"> + <group> + <field name="export_type"/> + </group> + <group> + <field name="saison_id"/> + </group> + <footer> + <button string="Valider" type="object" name="action_exporter" class="btn-primary"/> + <button string="Annuler" class="btn-secondary" special="cancel"/> + </footer> + </form> + </field> + </record> + + <record id="action_ap_export_wizard" model="ir.actions.act_window"> + <field name="name">Export de données</field> + <field name="res_model">ap.export.wizard</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + + <menuitem + id="menu_export_root" + name="Export de données" + parent="sale.sale_menu_root" + sequence="7" + groups="base.group_system" + /> + + <menuitem + id="menu_export_wizard" + parent="menu_export_root" + name="Exporter" + action="action_ap_export_wizard" + sequence="10" + groups="base.group_system" + /> + + </data> +</odoo> -- GitLab From 91bd2cfb433b66bd3fd986d5886ca577518d5e6f Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Mon, 19 May 2025 17:19:52 +0200 Subject: [PATCH 07/10] [ADD] add order export data --- controllers/export.py | 95 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 12 deletions(-) diff --git a/controllers/export.py b/controllers/export.py index b9558b1..a4bbf75 100644 --- a/controllers/export.py +++ b/controllers/export.py @@ -29,7 +29,12 @@ def export_xlsx(data_by_sheet): headers = list(rows[0].keys()) for col_idx, header in enumerate(headers): - sheet.write(0, col_idx, header) + if header[:3] == "ROT": + cell_format = workbook.add_format() + cell_format.set_rotation(90) + sheet.write(0, col_idx, header[3:], cell_format) + else: + sheet.write(0, col_idx, header) for row_idx, row in enumerate(rows, start=1): for col_idx, header in enumerate(headers): @@ -82,12 +87,73 @@ class ApExportController(http.Controller): """ export commande """ - projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) - file = {} + # un onglet par programme (subvention) + programmes = request.env["sale.project.subvention"].search([]) - for project in projects: - file[project.name] = [{"test": "test"}] + file = {} + for programme in programmes: + # on créer l onglet du programme + file[programme.name] = [] + page = file.get(programme.name) + + # tout les projets sous ce programme pour la saison dont le devis est signé + projects = request.env["sale.project"].search( + [ + ("saison_id", "=", saison.id), + ("project_subvention_id", "=", programme.id), + ("sale_order_id.state", "=", "sale"), + ] + ) + interventions = request.env["sale.intervention"].search( + [("project_id", "in", projects.ids)] + ) + plant_data = {} + seeders_list = [] + for intervention in interventions: + seeders_list.append(intervention.partner_id) + for sequence in intervention.plant_sequence_ids: + plant = plant_data.setdefault(sequence.product_id, {}) + if plant.get(f"ROT{intervention.partner_id.name}"): + plant[f"ROT{intervention.partner_id.name}"] += sequence.qty + else: + plant[f"ROT{intervention.partner_id.name}"] = sequence.qty + + # format data for xls + + # premiere ligne on va chercher les secteurs de plantation + + first_line = { + "Article": "Secteur plantation", + "Nom latin": "", + "Nom de la catégorie": "", + "Numéro de pépiniesriste": "", + } + + for seeder in set(seeders_list): + secteur_plat = ( + request.env["sale.project"] + .search([("partner_id", "=", seeder.id)]) + .mapped("plant_sector_id") + .mapped("name") + ) + first_line[f"ROT{seeder.name}"] = ",".join(secteur_plat) + page.append(first_line) + + for plant in plant_data: + line = {} + line.update( + { + "Article": plant.name, + "Nom latin": plant.latin_name or "", + "Nom de la catégorie": plant.categ_id.name or "", + "Numéro de pépiniériste": plant.categ_id.nurseryman_id or "", + } + ) + qty = plant_data.get(plant) + for seeder in qty: + line[seeder] = qty[seeder] + page.append(line) return file def get_fin_data(self, saison): @@ -118,13 +184,18 @@ class ApExportController(http.Controller): "Télephone": project.partner_id.phone or "", "Email": project.partner_id.email or "", "Commune intervention": inter.city or "", - "Geo latitude": str(inter.latitude).replace(',', '.'), - "Geo longitude": str(inter.longitude).replace(',', '.'), + "Geo latitude": str(inter.latitude).replace(",", "."), + "Geo longitude": str(inter.longitude).replace(",", "."), "Bord de départementale": inter.near_road or "", - "Forme juridique": project.partner_id.partner_company_type_id.name or "", - "Type de culture": project.partner_id.culture_type_id.name or "", - #todo format date - "Date de première adhésion": project.partner_id.year_1st_membership or "", + "Forme juridique": project.partner_id.partner_company_type_id.name + or "", + "Type de culture": project.partner_id.culture_type_id.name + or "", + "Date de première adhésion": ( + project.partner_id.year_1st_membership.strftime("%d-%m-%Y") + if project.partner_id.year_1st_membership + else "" + ), "Diffusion sur site internet": project.online or "", "Longueur de haie": inter.intervention_length or "", "Nombre de plants": inter.plant_qty or "", @@ -134,7 +205,7 @@ class ApExportController(http.Controller): "Implantation": inter.location_id.name or "", "Objectif plantation": project.plant_goal_id.name or "", "Avancement": project.admin_state_id.name, - "Aides financières": self.get_financial_help(inter) + "Aides financières": self.get_financial_help(inter), } file.get(sheet_name).append(project_data) -- GitLab From ed548b39e611563ea661cf359d011bea84d2f7df Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Tue, 20 May 2025 11:07:19 +0200 Subject: [PATCH 08/10] [ADD] finalisation --- controllers/export.py | 63 +++++++++++++++++-------------- wizard/ap_export_wizard.py | 3 ++ wizard/ap_export_wizard_views.xml | 4 +- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/controllers/export.py b/controllers/export.py index a4bbf75..4a3206b 100644 --- a/controllers/export.py +++ b/controllers/export.py @@ -1,8 +1,11 @@ -from odoo import http -from odoo.http import request -from odoo.addons.web.controllers.main import ExcelExport +# Copyright 2021 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + import io import xlsxwriter +from odoo import http +from odoo.http import request + def export_xlsx(data_by_sheet): @@ -74,7 +77,6 @@ class ApExportController(http.Controller): return "" def get_nb_tree(self, inter_id): - if inter_id.plant_sequence_ids: to_count = inter_id.plant_sequence_ids else: @@ -90,12 +92,12 @@ class ApExportController(http.Controller): # un onglet par programme (subvention) programmes = request.env["sale.project.subvention"].search([]) + # fichier final file = {} for programme in programmes: - # on créer l onglet du programme - file[programme.name] = [] - page = file.get(programme.name) + + page = [] # tout les projets sous ce programme pour la saison dont le devis est signé projects = request.env["sale.project"].search( @@ -109,6 +111,7 @@ class ApExportController(http.Controller): [("project_id", "in", projects.ids)] ) plant_data = {} + # sauvegarde de la liste des planteurs pour la premiere ligne seeders_list = [] for intervention in interventions: seeders_list.append(intervention.partner_id) @@ -120,26 +123,6 @@ class ApExportController(http.Controller): plant[f"ROT{intervention.partner_id.name}"] = sequence.qty # format data for xls - - # premiere ligne on va chercher les secteurs de plantation - - first_line = { - "Article": "Secteur plantation", - "Nom latin": "", - "Nom de la catégorie": "", - "Numéro de pépiniesriste": "", - } - - for seeder in set(seeders_list): - secteur_plat = ( - request.env["sale.project"] - .search([("partner_id", "=", seeder.id)]) - .mapped("plant_sector_id") - .mapped("name") - ) - first_line[f"ROT{seeder.name}"] = ",".join(secteur_plat) - page.append(first_line) - for plant in plant_data: line = {} line.update( @@ -154,6 +137,30 @@ class ApExportController(http.Controller): for seeder in qty: line[seeder] = qty[seeder] page.append(line) + + # si on des commandes pour ce programe on l ajoute au fichier + if page: + # on construit la premier ligne avec les secteurs + # de plantation par planteur + + first_line = { + "Article": "Secteur plantation", + "Nom latin": "", + "Nom de la catégorie": "", + "Numéro de pépiniesriste": "", + } + + for seeder in set(seeders_list): + secteur_plat = ( + request.env["sale.project"] + .search([("partner_id", "=", seeder.id)]) + .mapped("plant_sector_id") + .mapped("name") + ) + first_line[f"ROT{seeder.name}"] = ",".join(secteur_plat) + page.insert(0, first_line) + file[programme.name] = page + return file def get_fin_data(self, saison): @@ -266,7 +273,7 @@ class ApExportController(http.Controller): @http.route("/ap_export/xlsx_download", type="http", auth="user") def download_xlsx(self, wizard_id, **kwargs): - wizard = request.env["ap.export.wizard"].sudo().browse(int(wizard_id)) + wizard = request.env["ap.export.wizard"].browse(int(wizard_id)) filename = self.get_filename(wizard.export_type, wizard.saison_id) data_methods = { diff --git a/wizard/ap_export_wizard.py b/wizard/ap_export_wizard.py index c9945fc..59f3f6f 100644 --- a/wizard/ap_export_wizard.py +++ b/wizard/ap_export_wizard.py @@ -1,3 +1,6 @@ +# Copyright 2021 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from odoo import models, fields diff --git a/wizard/ap_export_wizard_views.xml b/wizard/ap_export_wizard_views.xml index eca1364..abe37f5 100644 --- a/wizard/ap_export_wizard_views.xml +++ b/wizard/ap_export_wizard_views.xml @@ -34,7 +34,7 @@ name="Export de données" parent="sale.sale_menu_root" sequence="7" - groups="base.group_system" + groups="sales_team.group_sale_salesman" /> <menuitem @@ -43,7 +43,7 @@ name="Exporter" action="action_ap_export_wizard" sequence="10" - groups="base.group_system" + groups="sales_team.group_sale_salesman" /> </data> -- GitLab From 2188bbaa636d7c5d23a736b571a3f858fc7b4188 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Wed, 21 May 2025 09:47:06 +0200 Subject: [PATCH 09/10] [FIX] typo --- controllers/export.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/export.py b/controllers/export.py index 4a3206b..87c8926 100644 --- a/controllers/export.py +++ b/controllers/export.py @@ -147,7 +147,7 @@ class ApExportController(http.Controller): "Article": "Secteur plantation", "Nom latin": "", "Nom de la catégorie": "", - "Numéro de pépiniesriste": "", + "Numéro de pépiniériste": "", } for seeder in set(seeders_list): -- GitLab From e7e269bc8eb19a06a65d55d28d518f57f0aa8616 Mon Sep 17 00:00:00 2001 From: Julien Ortet <julien@le-filament.com> Date: Mon, 2 Jun 2025 11:56:27 +0200 Subject: [PATCH 10/10] [FIX] review --- controllers/export.py | 54 ++++++++++++++++++++++++-------- views/sale_intervention_view.xml | 1 + wizard/ap_export_wizard.py | 1 + 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/controllers/export.py b/controllers/export.py index 87c8926..d056e26 100644 --- a/controllers/export.py +++ b/controllers/export.py @@ -7,7 +7,6 @@ from odoo import http from odoo.http import request - def export_xlsx(data_by_sheet): """ Génère un fichier XLSX avec plusieurs feuilles. @@ -62,9 +61,24 @@ class ApExportController(http.Controller): def get_nb_staples(self, inter_id): staples = 0 if inter_id.mulch_has_staples: - staples += inter_id.mulch_staples_qty * inter_id.mulch_qty + + if inter_id.mulch_id: + if inter_id.mulch_id.nb_accesories and inter_id.mulch_id.nb_accesories > 0.0: + mulch_qty = inter_id.mulch_id.nb_accesories + else: + mulch_qty = 2 + staples += inter_id.mulch_qty * mulch_qty + if inter_id.mulch2_has_staples: - staples += inter_id.mulch2_staples_qty * inter_id.mulch2_qty + + if inter_id.mulch2_id: + if inter_id.mulch2_id.nb_accesories and inter_id.mulch2_id.nb_accesories > 0.0: + mulch2_qty = inter_id.mulch2_id.nb_accesories + else: + mulch2_qty = 2 + staples += inter_id.mulch2_qty * mulch2_qty + + return staples if staples > 0 else "" def get_linked_contact(self, partner_id): if partner_id.child_ids: @@ -76,14 +90,14 @@ class ApExportController(http.Controller): return ",".join([h.name for h in inter.financial_help_ids]) return "" - def get_nb_tree(self, inter_id): + def get_nb_big_trees(self, inter_id): if inter_id.plant_sequence_ids: to_count = inter_id.plant_sequence_ids else: to_count = inter_id.plant_list_ids trees = to_count.search([("scale", "=", "big")]) - return len(trees) + return len(trees) if len(trees) > 0 else "" def get_order_data(self, saison): """ @@ -170,7 +184,9 @@ class ApExportController(http.Controller): sheet_name = "suivi financeurs" file = {sheet_name: []} - projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) + projects = request.env["sale.project"].search( + [("saison_id", "=", saison.id), ("state", "=", "sale")] + ) for project in projects: if project.intervention_ids: @@ -203,11 +219,16 @@ class ApExportController(http.Controller): if project.partner_id.year_1st_membership else "" ), - "Diffusion sur site internet": project.online or "", + "Diffusion sur site internet": dict( + project._fields["online"].selection + ).get(project.online) + or "", "Longueur de haie": inter.intervention_length or "", "Nombre de plants": inter.plant_qty or "", "Surface (en m²)": inter.surface or "", - "Dont nombre total d'arbres": self.get_nb_tree(inter), + "Dont nombre total d'arbres (grands)": self.get_nb_big_trees( + inter + ), "Type d'intervention": inter.intervention_type_id.name or "", "Implantation": inter.location_id.name or "", "Objectif plantation": project.plant_goal_id.name or "", @@ -215,7 +236,7 @@ class ApExportController(http.Controller): "Aides financières": self.get_financial_help(inter), } - file.get(sheet_name).append(project_data) + file.get(sheet_name).append(project_data) return file @@ -225,7 +246,9 @@ class ApExportController(http.Controller): """ sheet_name = "suivi technique" file = {sheet_name: []} - projects = request.env["sale.project"].search([("saison_id", "=", saison.id)]) + projects = request.env["sale.project"].search( + [("saison_id", "=", saison.id), ("state", "=", "sale")] + ) for project in projects: if project.intervention_ids: @@ -249,7 +272,9 @@ class ApExportController(http.Controller): "Longueur de haie": inter.intervention_length or "", "Nombre de plants": inter.plant_qty or "", "Surface (en m²)": inter.surface or "", - "Dont nombre total d'arbres": self.get_nb_tree(inter), + "Dont nombre total d'arbres (grands)": self.get_nb_big_trees( + inter + ), "Type d'intervention": inter.intervention_type_id.name or "", "Paillage 1": inter.mulch_id.name or "", "Paillage 2": inter.mulch2_id.name or "", @@ -263,11 +288,14 @@ class ApExportController(http.Controller): "Nombre d'agrafes": self.get_nb_staples(inter), "Nombre de collerettes": inter.collarette_qty or "", "Mois livraison": project.delivery_month or "", - "Accueil démo": project.demo or "", + "Accueil démo": dict(project._fields["demo"].selection).get( + project.demo + ) + or "", "Commentaires": project.comment or "", } - file.get(sheet_name).append(project_data) + file.get(sheet_name).append(project_data) return file diff --git a/views/sale_intervention_view.xml b/views/sale_intervention_view.xml index 01f55dd..4b08390 100644 --- a/views/sale_intervention_view.xml +++ b/views/sale_intervention_view.xml @@ -217,6 +217,7 @@ /> <field name="qty" /> <field name="is_local" /> + <field name="scale" /> </tree> </field> <field diff --git a/wizard/ap_export_wizard.py b/wizard/ap_export_wizard.py index 59f3f6f..0b36c9d 100644 --- a/wizard/ap_export_wizard.py +++ b/wizard/ap_export_wizard.py @@ -16,6 +16,7 @@ class ApExportWizard(models.TransientModel): ], required=True, default="order", + string="Type d'export" ) saison_id = fields.Many2one( -- GitLab