9.7 KiB
Padding facture provisoire vente - notes comptables
Statut: draft
Derniere mise a jour: 2026-04-26
Scope: lot.invoice -> account.invoice -> validation comptable.
1) Objectif metier
Le padding sert a augmenter temporairement la quantite facturee sur une facture provisoire cote vente, afin de constituer une provision avant la facture finale.
Exemple:
- 2 lots factures ensemble
- padding global saisi dans le wizard:
1000 - repartition actuelle:
500par lot - chaque ligne facture affiche:
quantity = quantite reelle du lot + padding du lotInc. padding = padding du lot
Le padding ne modifie pas la quantite physique du lot. Il doit rester visible et traçable comme ecart entre la facture provisoire et le lot.
2) Donnees creees ou utilisees
lot.lot
- Champ:
sale_invoice_padding - Role: memoire de la part de padding appliquee au lot pour la facture provisoire vente.
- UI: readonly sur le lot.
account.invoice.line
- Champ fonctionnel:
included_padding - Label UI:
Inc. padding - Role: affichage de
line.lot.sale_invoice_paddingsur la ligne facture. - La valeur n'est pas stockee sur la ligne; elle lit le padding du lot.
Wizard lot.invoice
- Champ:
sale_padding(Global padding) - Visible seulement pour:
type = saleaction = prov
- Repartition actuelle:
- padding global / nombre de lots selectionnes
3) Flux de creation de facture avec padding
- L'utilisateur ouvre le wizard
lot.invoicedepuis les lots physiques. - Le wizard prepare deux listes:
lot_ppour achatlot_spour vente
- En mode vente provisoire, l'utilisateur saisit
Global padding. - Au clic
Invoice, le wizard:- calcule la part de padding par lot
- ecrit cette part dans
lot.sale_invoice_padding - appelle
sale.sale._process_invoice(..., action='prov')
sale.line.get_invoice_line(lots, action)cree une ligne facture par lot physique.- Pour chaque ligne positive
out/Pro forma, le module ajoute le padding du lot ainvoice_line.quantity. - L'amount de la ligne augmente naturellement via:
quantity * unit_price
4) Ce qui se passe actuellement lors de Validate d'une facture
Bouton UI: Validate sur account.invoice.
Code principal:
modules/account_invoice/invoice.pyInvoice.validate_invoiceInvoice.get_moveInvoiceLine.get_move_linesInvoice.do_lot_invoicingInvoice.cleanMoves
Etapes de validate_invoice
- Verifie les taxes avec
_check_taxes. - Attribue le numero via
set_number. - Stocke les caches de montants via
_store_cache. - Pour chaque facture:
- appelle
invoice.get_move() - affecte le move a
invoice.moves'il est nouveau - appelle
invoice.do_lot_invoicing()
- appelle
- Sauvegarde les moves crees.
- Nettoie certaines lignes de move via
cleanMoves. - Sauvegarde les factures.
Note importante deja actee dans le projet:
Validatecree deja leaccount.moveet attribue lenumberaussi pour les factures client (type = out).Postne doit plus etre le premier moment ou ces donnees apparaissent cote client.
get_move()
get_move() construit le move comptable principal de la facture:
- appelle
update_taxes(exception=True) - parcourt
invoice.lines - pour chaque ligne, appelle
line.get_move_lines() - ajoute les lignes de taxes via
tax.get_move_lines() - ajoute la ligne tiers / receivable-payable via
_get_move_line - ajoute eventuellement une ligne de change via
_get_exchange_move_line - cree un
account.moveavec:journal = invoice.journalperiodtrouve depuis la date comptableorigin = invoicelines = move_lines
account.invoice.line.get_move_lines()
Pour une ligne facture type = line:
- cree une ligne
account.move.line - rattache
line.lot = self.invoice.lines[0].lot- attention: comportement existant, pas forcement la ligne courante
- convertit le montant si devise differente
- pour une facture client (
type = out):- montant positif => credit du compte de revenu de la ligne
- montant negatif => debit
- met
line.account = self.account - met
line.origin = self - calcule les lignes de taxe
Pour le padding actuel, comme il augmente invoice_line.quantity, il est deja
inclus dans le montant de revenu du move principal.
do_lot_invoicing()
do_lot_invoicing() traite des ajustements lies aux lots:
- groupe les lignes facture par
i.lot - calcule:
var_pricevar_qt
- retrouve le mouvement stock:
- fournisseur pour
type = in - client pour
type = out
- fournisseur pour
- declenche des actions stock / shipment si necessaire
- calcule le COG du lot
- prepare des lignes d'ajustement via
_get_move_lines - actuellement, le move d'ajustement n'est cree/poste que si:
adjust_move_linesexisteself.type == 'in'
Consequence importante pour le padding:
- les ajustements de quantite/prix existants sont principalement effectifs cote
achat (
type = in) - une facture client provisoire avec padding augmente deja le move principal de vente, mais ne genere pas encore d'ecritures specifiques padding separees
_get_move_lines(gl, amount, drop, IsUsd=False, stock_move=None)
Helper existant pour creer des paires de lignes de move liees au stock/COG:
- rattache
lot,fee,origin - gere la conversion devise / second currency
- choisit les comptes stock / stock out / stock in / COG selon le signe, fee et contexte
- peut creer une variante
drop
Ce helper est un candidat possible pour reutilisation partielle, mais il est aujourd'hui pense pour des ajustements stock/COG, pas pour isoler un padding de facture provisoire vente.
5) Question comptable a trancher pour le padding
Le besoin restant est: au Validate d'une facture provisoire vente avec padding,
generer des ecritures propres a ce padding.
Points a definir avant implementation:
- Le move padding doit-il etre:
- integre dans le move principal de facture ?
- cree comme
additional_move? - cree comme move separe avec
origin = invoice?
- Quels comptes utiliser ?
- compte de revenu temporaire / provision ?
- compte de contrepartie padding ?
- compte lie au produit ?
- compte de configuration dedie ?
- Faut-il neutraliser une partie du revenu principal deja augmente par la quantity, ou seulement ajouter une ecriture analytique/stock parallele ?
- Le padding doit-il impacter:
- revenu client ?
- stock out ?
- COG ?
- PnL / valuation ?
- Que doit faire la facture finale ?
- reprendre le padding provisoire ?
- le contrepasser ?
- ne rien faire si la finale facture la vraie quantite ?
- Le montant padding a utiliser est:
lot.sale_invoice_padding * invoice_line.unit_price- dans la devise de facture
- a convertir si devise societe differente selon la logique standard
5.1) Decision comptable cible
Comptes de configuration ajoutes sur account.configuration:
default_sale_padding_account- label UI:
Default Sale Padding - compte attendu metier:
80021 - nature: revenu
- label UI:
default_accrual_padding_account- label UI:
Default Accrual Padding - compte attendu metier:
42021 - nature: bilan / accrual
- label UI:
Facture provisoire vente:
- condition:
invoice.type = outinvoice.reference = Provisionalinvoice_line.description = Pro formainvoice_line.lot.sale_invoice_padding > 0
- montant:
padding_amount = lot.sale_invoice_padding * invoice_line.unit_price- le prix est celui de la facture provisoire, pas un prix recalcule plus tard
- ecriture attendue:
- couple
80021 / 42021 - rattachement au lot obligatoire sur les lignes si possible
- couple
Facture finale vente:
- condition:
- lot deja facture en provisoire avec padding
- la finale doit inverser le padding deja provisionne
- montant:
- exactement le montant comptabilise lors de la provisoire
- ne pas recalculer avec le prix de la finale
- ecriture attendue:
- couple inverse
42021 / 80021
- couple inverse
Decision technique retenue:
- ne pas ajouter de nouveau champ montant pour l'instant
- utiliser le lien deja ecrit sur le lot:
lot.sale_invoice_line_prov
- au moment de la finale, retrouver la ligne provisoire via ce champ
- calculer le montant a extourner avec:
lot.sale_invoice_padding * lot.sale_invoice_line_prov.unit_price
- utiliser la devise, le taux et la date de la facture provisoire pour obtenir le meme montant societe que l'ecriture initiale
- garder le rattachement comptable par
account.move.line.lot
Raison:
- evite les ecarts si le prix final change
- reutilise le lien direct deja maintenu entre le lot et la ligne provisoire
- rend la reprise finale audit-friendly
- garde le pivot comptable lot coherent
6) Invariants a preserver
- Le padding ne change pas la quantite physique du lot.
- Le padding est uniquement pour facture provisoire vente:
invoice.type = outinvoice.reference = Provisional- lignes
description = Pro forma
- L'utilisateur doit voir clairement l'ecart:
QuantityInc. padding
- Le lien principal reste:
account.invoice.line.lotlot.sale_invoice_padding
- Les futures ecritures doivent etre rattachees au lot autant que possible pour rester visibles dans le pivot comptable du lot.
7) Tests a prevoir pour la suite
- Validation d'une facture provisoire vente avec padding:
- move principal existe
- montant facture inclut le padding
- ecritures specifiques padding creees selon la regle retenue
- lignes rattachees au bon lot
- Facture provisoire vente sans padding:
- aucun move padding specifique
- Facture finale vente:
- aucun nouveau padding applique automatiquement
- comportement de reprise/contrepassation selon decision metier
- Facture achat:
- aucun impact padding vente
- Multi-lots:
- padding reparti correctement
- ecritures detaillees par lot si la regle comptable l'exige