693 lines
23 KiB
Markdown
693 lines
23 KiB
Markdown
# Spécifications du module batch_picking_create_one_bill
|
||
|
||
## Objectif
|
||
Créer un module Odoo 18.0 permettant de générer une seule facture fournisseur (vendor bill) consolidée pour tous les bons de commande (Purchase Orders) associés à un batch picking, en utilisant la méthode standard de création de factures d'Odoo basée sur les réceptions.
|
||
|
||
## Fonctionnalités principales
|
||
|
||
### 1. Modification du comportement des Batch Pickings
|
||
|
||
#### Héritage du modèle `stock.picking.batch`
|
||
|
||
##### Champs ajoutés
|
||
```python
|
||
# Dans stock_picking_batch.py
|
||
class StockPickingBatch(models.Model):
|
||
_inherit = 'stock.picking.batch'
|
||
|
||
zero_quantity_default = fields.Boolean(
|
||
string='Quantités à zéro par défaut',
|
||
default=True,
|
||
help='Initialiser les quantités à zéro lors de la création du batch'
|
||
)
|
||
invoice_count = fields.Integer(
|
||
compute='_compute_invoice_count',
|
||
string='Nombre de factures'
|
||
)
|
||
invoice_ids = fields.Many2many(
|
||
'account.move',
|
||
string='Factures associées',
|
||
compute='_compute_invoice_ids',
|
||
store=True
|
||
)
|
||
```
|
||
|
||
##### Surcharge des méthodes
|
||
|
||
###### Initialisation des quantités
|
||
```python
|
||
def _prepare_move_line_vals(self, **kwargs):
|
||
vals = super()._prepare_move_line_vals(**kwargs)
|
||
if self.zero_quantity_default:
|
||
vals['quantity'] = 0.0
|
||
return vals
|
||
```
|
||
|
||
###### Calcul des factures associées
|
||
```python
|
||
@api.depends('picking_ids', 'picking_ids.purchase_id.invoice_ids')
|
||
def _compute_invoice_ids(self):
|
||
for batch in self:
|
||
invoices = batch.picking_ids.mapped('purchase_id.invoice_ids')
|
||
batch.invoice_ids = invoices
|
||
batch.invoice_count = len(invoices)
|
||
```
|
||
|
||
##### Actions et boutons
|
||
```python
|
||
def action_view_invoices(self):
|
||
self.ensure_one()
|
||
action = self.env['ir.actions.act_window']._for_xml_id(
|
||
'account.action_move_in_invoice_type'
|
||
)
|
||
if self.invoice_count == 1:
|
||
action['views'] = [(False, 'form')]
|
||
action['res_id'] = self.invoice_ids.id
|
||
else:
|
||
action['domain'] = [('id', 'in', self.invoice_ids.ids)]
|
||
return action
|
||
```
|
||
|
||
#### Modification des vues
|
||
|
||
##### Vue formulaire du batch picking
|
||
```xml
|
||
<record id="view_picking_batch_form_inherit" model="ir.ui.view">
|
||
<field name="name">stock.picking.batch.form.inherit</field>
|
||
<field name="model">stock.picking.batch</field>
|
||
<field name="inherit_id" ref="stock.view_picking_batch_form"/>
|
||
<field name="arch" type="xml">
|
||
<xpath expr="//header" position="inside">
|
||
<button name="%(action_create_batch_bill_wizard)d"
|
||
string="Créer Facture"
|
||
type="action"
|
||
class="btn-primary"
|
||
attrs="{'invisible': [('state', '!=', 'done')]}"/>
|
||
</xpath>
|
||
<xpath expr="//div[@name='button_box']" position="inside">
|
||
<button class="oe_stat_button"
|
||
name="action_view_invoices"
|
||
type="object"
|
||
icon="fa-pencil-square-o">
|
||
<field name="invoice_count" widget="statinfo" string="Factures"/>
|
||
</button>
|
||
</xpath>
|
||
<xpath expr="//group[@name='group_misc']" position="inside">
|
||
<field name="zero_quantity_default"/>
|
||
</xpath>
|
||
</field>
|
||
</record>
|
||
```
|
||
|
||
#### Gestion des mouvements de stock
|
||
|
||
##### Modification du comportement des move lines
|
||
```python
|
||
def _update_move_lines_values(self, moves):
|
||
res = super()._update_move_lines_values(moves)
|
||
if self.zero_quantity_default:
|
||
for move in moves:
|
||
for line in move.move_line_ids:
|
||
line.qty_done = 0.0
|
||
return res
|
||
```
|
||
|
||
##### Validation des quantités
|
||
```python
|
||
def _check_received_quantities(self):
|
||
self.ensure_one()
|
||
for move in self.move_lines:
|
||
if move.quantity_done > move.product_uom_qty:
|
||
raise ValidationError(
|
||
_('La quantité reçue ne peut pas être supérieure '
|
||
'à la quantité commandée pour le produit %s')
|
||
% move.product_id.display_name
|
||
)
|
||
```
|
||
|
||
### 2. Critères de regroupement
|
||
- Regroupement uniquement des PO du même fournisseur
|
||
- Facturation basée uniquement sur les quantités réellement reçues dans le batch picking
|
||
- Les lignes de PO non reçues ne seront pas incluses dans la facture
|
||
|
||
### 2. Processus de création de facture
|
||
- Un bouton dédié sera ajouté sur le batch picking après sa validation
|
||
- Pour chaque PO du batch :
|
||
1. Utilisation de la méthode standard d'Odoo `action_create_invoice` pour créer les factures basées sur les réceptions
|
||
2. Les factures sont créées selon la politique 'Sur réception' (On received quantities)
|
||
3. Création automatique de factures partielles pour les quantités reçues
|
||
- Fusion automatique de toutes les factures créées en une seule facture
|
||
1. Regroupement des lignes par produit
|
||
2. Conservation des liens avec les PO d'origine
|
||
3. Suppression des factures individuelles après fusion
|
||
|
||
### 3. Gestion des cas particuliers
|
||
- Vérification des quantités reçues vs commandées
|
||
- Validation que toutes les réceptions sont bien effectuées avant la création de la facture
|
||
- Gestion des écarts entre les quantités commandées et reçues
|
||
|
||
### 4. Sécurité et droits d'accès
|
||
- Restriction aux utilisateurs du groupe 'Invoicing user'
|
||
- Vérification des droits d'accès sur les documents liés (PO, réceptions)
|
||
|
||
### 5. Interface utilisateur
|
||
- Ajout d'un bouton sur la vue form du batch picking
|
||
- Rapports spécifiques pour le suivi des factures groupées [À PRÉCISER]
|
||
- Messages de confirmation/erreur clairs pour l'utilisateur
|
||
|
||
### 6. Aspects techniques
|
||
- Pas de règles spécifiques pour la numérotation des factures (utilisation du système standard)
|
||
- Intégration avec les modules stock_picking_batch et purchase
|
||
- Respect des règles de facturation basées sur les réceptions
|
||
|
||
## Workflow
|
||
1. Création et traitement normal du batch picking
|
||
2. Validation du batch picking
|
||
3. Utilisation du nouveau bouton pour créer la facture groupée
|
||
4. Pour chaque PO impliqué dans le batch picking :
|
||
- Utilisation de la méthode standard `action_create_invoice` d'Odoo
|
||
- Création automatique des factures basées sur les quantités reçues
|
||
- Les quantités non reçues restent en attente de facturation
|
||
5. Fusion automatique de toutes les factures créées en une seule facture fournisseur
|
||
- Regroupement des lignes par produit
|
||
- Maintien des références aux PO d'origine
|
||
- Conservation des taxes et comptes analytiques
|
||
- Suppression des factures individuelles après fusion réussie
|
||
6. Traitement normal de la facture fusionnée
|
||
|
||
## Impact sur les processus existants
|
||
- Les utilisateurs devront entrer manuellement les quantités reçues au lieu de les ajuster
|
||
- Réduction des erreurs de réception dues aux quantités pré-remplies
|
||
- Meilleure traçabilité des quantités réellement reçues vs commandées
|
||
|
||
## Détails techniques d'implémentation
|
||
|
||
### 1. Modification du comportement des Batch Pickings
|
||
- Héritage du modèle `stock.picking.batch`
|
||
- Surcharge de la méthode de création pour initialiser les quantités à 0
|
||
- Modification des champs de quantité dans `stock.move.line`
|
||
|
||
### 2. Gestion des factures
|
||
|
||
#### Wizard de création de facture (`create_merged_bill.py`)
|
||
|
||
##### 1. Modèles
|
||
|
||
###### Modèle principal : `batch.picking.create.bill.wizard`
|
||
- Champs principaux :
|
||
- `batch_id`: Many2one vers stock.picking.batch (readonly)
|
||
- Batch picking source pour la création de la facture
|
||
- `purchase_order_ids`: Many2many vers purchase.order (computed, readonly)
|
||
- Liste des PO associés au batch
|
||
- Calculé automatiquement depuis le batch
|
||
- `partner_id`: Many2one vers res.partner (computed, readonly)
|
||
- Fournisseur commun à tous les PO
|
||
- Vérification d'unicité du fournisseur
|
||
- `invoice_ids`: Many2many vers account.move (computed)
|
||
- Factures créées par le processus standard d'Odoo
|
||
- Utilisé temporairement avant la fusion
|
||
- `merged_invoice_id`: Many2one vers account.move
|
||
- Facture finale fusionnée
|
||
- `preview_available`: Boolean (computed)
|
||
- Indique si la prévisualisation est possible
|
||
|
||
###### Modèle temporaire : `batch.picking.create.bill.line.preview`
|
||
- Champs :
|
||
- `wizard_id`: Many2one vers le wizard principal
|
||
- `product_id`: Many2one vers product.product
|
||
- `description`: Char (nom du produit + description)
|
||
- `quantity`: Float (quantité reçue)
|
||
- `uom_id`: Many2one vers uom.uom
|
||
- `price_unit`: Float
|
||
- `price_subtotal`: Float
|
||
- `purchase_line_ids`: Many2many vers purchase.order.line
|
||
- `picking_ids`: Many2many vers stock.picking
|
||
|
||
##### 2. Fonctions principales
|
||
|
||
###### Calculs et vérifications
|
||
- `_compute_purchase_orders()`:
|
||
```python
|
||
def _compute_purchase_orders(self):
|
||
for wizard in self:
|
||
pickings = wizard.batch_id.picking_ids
|
||
purchase_orders = pickings.mapped('purchase_id')
|
||
wizard.purchase_order_ids = purchase_orders
|
||
```
|
||
|
||
- `_compute_partner()`:
|
||
```python
|
||
def _compute_partner(self):
|
||
for wizard in self:
|
||
partners = wizard.purchase_order_ids.mapped('partner_id')
|
||
if len(partners) != 1:
|
||
raise ValidationError(_('Tous les PO doivent avoir le même fournisseur'))
|
||
wizard.partner_id = partners
|
||
```
|
||
|
||
###### Préparation des données
|
||
- `_prepare_invoice_lines()`:
|
||
- Regroupe les lignes par produit
|
||
- Calcule les quantités reçues
|
||
- Vérifie la cohérence des prix
|
||
- Génère les lignes de facture
|
||
|
||
- `_prepare_preview_lines()`:
|
||
- Crée les lignes de prévisualisation
|
||
- Affiche les détails des réceptions
|
||
- Calcule les sous-totaux
|
||
|
||
###### Actions
|
||
- `action_create_bill()`:
|
||
1. Vérifications préalables
|
||
2. Création des factures par PO
|
||
3. Fusion des factures
|
||
4. Liaison avec le batch picking
|
||
5. Retour vers la facture créée
|
||
|
||
##### 3. Interface utilisateur
|
||
|
||
###### Vue formulaire principale
|
||
```xml
|
||
<form>
|
||
<header>
|
||
<button name="action_create_bill"
|
||
string="Créer Facture"
|
||
type="object"
|
||
class="btn-primary"
|
||
attrs="{'invisible': [('preview_available', '=', False)]}"/>
|
||
<button special="cancel" string="Annuler" class="btn-secondary"/>
|
||
</header>
|
||
<sheet>
|
||
<group>
|
||
<group>
|
||
<field name="batch_id"/>
|
||
<field name="partner_id"/>
|
||
<field name="currency_id"/>
|
||
</group>
|
||
<group>
|
||
<field name="amount_total"/>
|
||
<field name="preview_available" invisible="1"/>
|
||
</group>
|
||
</group>
|
||
<notebook>
|
||
<page string="Ordres d'achat">
|
||
<field name="purchase_order_ids"/>
|
||
</page>
|
||
<page string="Prévisualisation des lignes">
|
||
<field name="preview_line_ids">
|
||
<tree>
|
||
<field name="product_id"/>
|
||
<field name="description"/>
|
||
<field name="quantity"/>
|
||
<field name="uom_id"/>
|
||
<field name="price_unit"/>
|
||
<field name="price_subtotal"/>
|
||
</tree>
|
||
</field>
|
||
</page>
|
||
</notebook>
|
||
</sheet>
|
||
</form>
|
||
```
|
||
|
||
##### 4. Messages et Validations
|
||
|
||
###### Messages d'erreur
|
||
- Fournisseur différent :
|
||
```python
|
||
_('Les bons de commande sélectionnés ont des fournisseurs différents : %s')
|
||
```
|
||
- Batch non validé :
|
||
```python
|
||
_('Le batch picking doit être validé avant de créer la facture')
|
||
```
|
||
- Quantités invalides :
|
||
```python
|
||
_('Certaines lignes ont des quantités reçues invalides')
|
||
```
|
||
|
||
###### Validations automatiques
|
||
- Vérification de l'état du batch
|
||
- Contrôle des quantités reçues
|
||
- Vérification des devises
|
||
- Validation des droits d'accès
|
||
|
||
### 3. Modifications de l'interface
|
||
|
||
#### Modifications des vues principales
|
||
|
||
##### 1. Vue formulaire du batch picking (`stock_picking_batch_views.xml`)
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<odoo>
|
||
<!-- Héritage de la vue form du batch picking -->
|
||
<record id="view_picking_batch_form_inherit" model="ir.ui.view">
|
||
<field name="name">stock.picking.batch.form.inherit</field>
|
||
<field name="model">stock.picking.batch</field>
|
||
<field name="inherit_id" ref="stock.view_picking_batch_form"/>
|
||
<field name="arch" type="xml">
|
||
<!-- Ajout du bouton de création de facture -->
|
||
<xpath expr="//header" position="inside">
|
||
<button name="%(action_create_batch_bill_wizard)d"
|
||
string="Créer Facture"
|
||
type="action"
|
||
class="btn-primary"
|
||
attrs="{'invisible': [('state', '!=', 'done')]}"/>
|
||
</xpath>
|
||
<!-- Ajout du smart button pour les factures -->
|
||
<div name="button_box" position="inside">
|
||
<button class="oe_stat_button"
|
||
name="action_view_invoices"
|
||
type="object"
|
||
icon="fa-pencil-square-o">
|
||
<field name="invoice_count" widget="statinfo" string="Factures"/>
|
||
</button>
|
||
</div>
|
||
<!-- Ajout de l'option quantités à zéro -->
|
||
<group name="group_misc" position="inside">
|
||
<field name="zero_quantity_default"/>
|
||
</group>
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Vue tree des batch pickings -->
|
||
<record id="view_picking_batch_tree_inherit" model="ir.ui.view">
|
||
<field name="name">stock.picking.batch.tree.inherit</field>
|
||
<field name="model">stock.picking.batch</field>
|
||
<field name="inherit_id" ref="stock.view_picking_batch_tree"/>
|
||
<field name="arch" type="xml">
|
||
<field name="state" position="after">
|
||
<field name="invoice_count"/>
|
||
</field>
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Vue search des batch pickings -->
|
||
<record id="view_picking_batch_search_inherit" model="ir.ui.view">
|
||
<field name="name">stock.picking.batch.search.inherit</field>
|
||
<field name="model">stock.picking.batch</field>
|
||
<field name="inherit_id" ref="stock.view_picking_batch_search"/>
|
||
<field name="arch" type="xml">
|
||
<filter name="to_process" position="after">
|
||
<filter string="Non facturé"
|
||
name="not_invoiced"
|
||
domain="[('invoice_count', '=', 0)]"/>
|
||
<filter string="Facturé"
|
||
name="invoiced"
|
||
domain="[('invoice_count', '>', 0)]"/>
|
||
</filter>
|
||
</field>
|
||
</record>
|
||
</odoo>
|
||
```
|
||
|
||
##### 2. Vue formulaire de la facture (`account_move_views.xml`)
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<odoo>
|
||
<record id="view_move_form_inherit" model="ir.ui.view">
|
||
<field name="name">account.move.form.inherit</field>
|
||
<field name="model">account.move</field>
|
||
<field name="inherit_id" ref="account.view_move_form"/>
|
||
<field name="arch" type="xml">
|
||
<!-- Ajout des références aux batch pickings -->
|
||
<xpath expr="//field[@name='invoice_origin']" position="after">
|
||
<field name="batch_picking_ids"
|
||
widget="many2many_tags"
|
||
readonly="1"
|
||
attrs="{'invisible': [('move_type', '!=', 'in_invoice')]}"/>
|
||
</xpath>
|
||
</field>
|
||
</record>
|
||
</odoo>
|
||
```
|
||
|
||
#### Actions et menus
|
||
|
||
##### Actions du wizard
|
||
```xml
|
||
<record id="action_create_batch_bill_wizard" model="ir.actions.act_window">
|
||
<field name="name">Créer Facture Fournisseur</field>
|
||
<field name="res_model">batch.picking.create.bill.wizard</field>
|
||
<field name="view_mode">form</field>
|
||
<field name="target">new</field>
|
||
<field name="binding_model_id" ref="model_stock_picking_batch"/>
|
||
<field name="binding_view_types">form</field>
|
||
</record>
|
||
```
|
||
|
||
#### Sécurité et droits d'accès
|
||
|
||
##### Groupes et droits
|
||
```xml
|
||
<record id="group_batch_invoice" model="res.groups">
|
||
<field name="name">Création de factures depuis batch picking</field>
|
||
<field name="category_id" ref="base.module_category_inventory"/>
|
||
<field name="implied_ids" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||
</record>
|
||
```
|
||
|
||
##### Règles d'accès
|
||
```csv
|
||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||
access_batch_bill_wizard,access.batch.picking.create.bill.wizard,model_batch_picking_create_bill_wizard,group_batch_invoice,1,1,1,0
|
||
access_batch_bill_line_preview,access.batch.picking.create.bill.line.preview,model_batch_picking_create_bill_line_preview,group_batch_invoice,1,1,1,1
|
||
```
|
||
|
||
### 4. Points techniques clés
|
||
|
||
#### Manifest du module
|
||
```python
|
||
{
|
||
'name': 'Batch Picking - Create One Bill',
|
||
'version': '18.0.1.0.0',
|
||
'category': 'Inventory/Purchase',
|
||
'summary': 'Créer une seule facture pour tous les PO d’un batch picking',
|
||
'author': 'Pneumac',
|
||
'website': 'https://www.pneumac.com',
|
||
'license': 'LGPL-3',
|
||
'depends': [
|
||
'stock_picking_batch',
|
||
'purchase',
|
||
'account',
|
||
],
|
||
'data': [
|
||
'security/security_groups.xml',
|
||
'security/ir.model.access.csv',
|
||
'views/stock_picking_batch_views.xml',
|
||
'views/account_move_views.xml',
|
||
'wizard/create_merged_bill_views.xml',
|
||
],
|
||
'demo': [],
|
||
'installable': True,
|
||
'auto_install': False,
|
||
'application': False,
|
||
}
|
||
```
|
||
|
||
#### Structure complète des fichiers
|
||
```
|
||
batch_picking_create_one_bill/
|
||
├── __init__.py # Import des sous-modules
|
||
├── __manifest__.py # Configuration du module
|
||
├── models/ # Définition des modèles
|
||
│ ├── __init__.py
|
||
│ ├── stock_picking_batch.py # Extension du modèle batch
|
||
│ └── account_move.py # Extension du modèle facture
|
||
├── wizard/ # Assistant de création de facture
|
||
│ ├── __init__.py
|
||
│ ├── create_merged_bill.py # Logique du wizard
|
||
│ └── create_merged_bill_views.xml # Vues du wizard
|
||
├── views/ # Vues des modèles
|
||
│ ├── stock_picking_batch_views.xml
|
||
│ └── account_move_views.xml
|
||
├── security/ # Sécurité et droits d'accès
|
||
│ ├── ir.model.access.csv # Règles d'accès aux modèles
|
||
│ └── security_groups.xml # Définition des groupes
|
||
├── static/ # Ressources statiques
|
||
│ └── description/
|
||
│ └── icon.png # Icône du module
|
||
└── i18n/ # Traductions
|
||
└── fr.po # Traduction française
|
||
|
||
```
|
||
|
||
#### Points techniques spécifiques
|
||
|
||
##### 1. Gestion des hooks
|
||
```python
|
||
# Dans stock_picking_batch.py
|
||
from odoo import models, fields, api, _
|
||
|
||
class StockPickingBatch(models.Model):
|
||
_inherit = 'stock.picking.batch'
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
# Hook de création pour initialiser les quantités à 0
|
||
res = super().create(vals)
|
||
if res.zero_quantity_default:
|
||
res._reset_quantities()
|
||
return res
|
||
|
||
def write(self, vals):
|
||
# Hook d'écriture pour gérer les modifications
|
||
res = super().write(vals)
|
||
if 'zero_quantity_default' in vals:
|
||
self._handle_quantity_change()
|
||
return res
|
||
```
|
||
|
||
##### 2. Gestion des contraintes
|
||
```python
|
||
@api.constrains('picking_ids', 'picking_ids.purchase_id')
|
||
def _check_purchase_orders(self):
|
||
for batch in self:
|
||
purchases = batch.picking_ids.mapped('purchase_id')
|
||
partners = purchases.mapped('partner_id')
|
||
if len(partners) > 1:
|
||
raise ValidationError(_(
|
||
'Le batch picking ne peut contenir que des PO '
|
||
'du même fournisseur.'
|
||
))
|
||
```
|
||
|
||
##### 3. Performance et optimisation
|
||
```python
|
||
# Dans create_merged_bill.py
|
||
from odoo.tools.profiler import profile
|
||
|
||
@profile
|
||
def _prepare_invoice_lines(self):
|
||
# Optimisation avec prefetch
|
||
products = self.env['product.product'].browse(
|
||
self.purchase_order_ids.mapped('order_line.product_id.id')
|
||
).exists()
|
||
products.read(['name', 'type', 'invoice_policy'])
|
||
|
||
# Traitement par lots
|
||
moves_by_product = {}
|
||
for move in self.batch_id.move_lines:
|
||
if move.product_id not in moves_by_product:
|
||
moves_by_product[move.product_id] = self.env['stock.move']
|
||
moves_by_product[move.product_id] |= move
|
||
```
|
||
|
||
##### 4. Gestion des erreurs
|
||
```python
|
||
class BatchBillError(Exception):
|
||
""" Erreur spécifique pour la création de facture depuis batch """
|
||
pass
|
||
|
||
def _handle_bill_creation_error(self, error):
|
||
if isinstance(error, BatchBillError):
|
||
# Erreur métier spécifique
|
||
return {
|
||
'type': 'ir.actions.client',
|
||
'tag': 'display_notification',
|
||
'params': {
|
||
'title': _('Erreur'),
|
||
'message': str(error),
|
||
'type': 'danger',
|
||
}
|
||
}
|
||
# Autres erreurs
|
||
raise error
|
||
```
|
||
|
||
##### 5. Tests unitaires
|
||
```python
|
||
# Dans tests/test_batch_bill.py
|
||
from odoo.tests import tagged
|
||
from odoo.tests.common import TransactionCase
|
||
|
||
@tagged('post_install', '-at_install')
|
||
class TestBatchBill(TransactionCase):
|
||
|
||
def setUp(self):
|
||
super().setUp()
|
||
# Préparation des données de test
|
||
|
||
def test_create_bill_from_batch(self):
|
||
# Test de création de facture
|
||
|
||
def test_zero_quantity_default(self):
|
||
# Test de l'initialisation des quantités
|
||
|
||
def test_merge_bills(self):
|
||
# Test de la fusion des factures
|
||
```
|
||
- Gestion des états des documents (draft, done, etc.)
|
||
- Traçabilité complète via les champs related et stored
|
||
- Gestion des droits d'accès via les groupes de sécurité
|
||
|
||
### 5. Améliorations suggérées
|
||
|
||
#### 1. Fonctionnalités supplémentaires
|
||
- **Annulation en masse** :
|
||
- Possibilité d'annuler la facture créée et de revenir à l'état précédent
|
||
- Traçabilité des annulations dans l'historique
|
||
|
||
- **Rapports et analyses** :
|
||
- Rapport de réconciliation PO/Réceptions/Factures
|
||
|
||
#### 2. Améliorations techniques
|
||
- **Cache et performance** :
|
||
- Mise en cache des calculs fréquents
|
||
- Optimisation des requêtes SQL
|
||
- Indexation des champs clés
|
||
|
||
- **Gestion des erreurs avancée** :
|
||
- Journal d'erreurs détaillé
|
||
- Mécanisme de reprise sur erreur
|
||
- Notifications utilisateur améliorées
|
||
|
||
- **Tests automatisés** :
|
||
- Tests d'intégration avec scénarios complexes
|
||
- Tests de performance
|
||
- Tests de régression
|
||
|
||
#### 3. Améliorations UX
|
||
- **Interface utilisateur** :
|
||
- Vue kanban pour les batch pickings avec statut de facturation
|
||
- Filtres et groupements avancés
|
||
- Aperçu rapide des informations clés
|
||
|
||
- **Processus utilisateur** :
|
||
- Assistant de validation en plusieurs étapes
|
||
- Suggestions automatiques basées sur l'historique
|
||
- Messages d'aide contextuels
|
||
|
||
#### 4. Personnalisation
|
||
- **Configuration avancée** :
|
||
- Paramètres par entreprise
|
||
|
||
### 5. Structure des fichiers
|
||
```
|
||
batch_picking_create_one_bill/
|
||
├── __init__.py
|
||
├── __manifest__.py
|
||
├── models/
|
||
│ ├── __init__.py
|
||
│ ├── stock_picking_batch.py
|
||
│ └── account_move.py
|
||
├── wizard/
|
||
│ ├── __init__.py
|
||
│ └── create_merged_bill.py
|
||
├── views/
|
||
│ ├── stock_picking_batch_views.xml
|
||
│ └── account_move_views.xml
|
||
├── security/
|
||
│ └── ir.model.access.csv
|
||
└── data/
|
||
└── security_groups.xml
|
||
```
|
||
|
||
## Dépendances
|
||
- stock_picking_batch
|
||
- purchase
|
||
- account
|
||
|
||
## Version
|
||
- Odoo 18.0
|