Project

General

Profile

Development #69728

Modèle facture, ligne de facture

Added by Emmanuel Cazenave 2 months ago. Updated 2 months ago.

Status:
Nouveau
Priority:
Normal
Target version:
-
Start date:
29 September 2022
Due date:
% Done:

0%

Estimated time:
Patch proposed:
No
Planning:
No

Description

Commençons par le minimum syndical :

Facture :

  • un numéro de facture (on prend la primary key ou une colonne en plus dédiée ?)
  • un libellé
  • un montant (Decimal)
  • une date d'émission
  • un payeur (je dirais un text field pour commencer)
  • un foreign key vers une régie

Une ligne de facture :

  • un montant unitaire
  • une quantité
  • un montant total
  • un libellé
  • une foreignkey vers une facture

Avec les histoires de génération de trains de facturation, quoi doivent pouvoir être acceptés/amendés/rejetés, je partirais bien sur des modèles abstrait pour bien séparer les choses:

class AbstractInvoice(models.Model):

   ... ici les champs ...
    class Meta:
        abstract = True

class Invoice(AbstractInvoice):
  ..

class DraftInvoice(AbstractInvoice):
 ...

Histoire de ne pas faire ticket avec juste un modèle et rien d'autre, j’inclurais bien webservice de création d'une ligne de facturation.
(cas d'usage : paiement de 156 euros pour l'inscription au séjour au ski, paiement qui se fait avant la facturation finale, voir https://pad.libre-entreprise.org/p/eo-famille-facturation "Ajout de lignes de facture hors-calcul").


Related issues

Related to Lingo - Development #71528: facturation: générer des lignes de facturation sur un cas "simple" (prestation d'un enfant pour une période)Solution proposée21 November 2022

Actions

History

#1

Updated by Emmanuel Cazenave 2 months ago

Emmanuel Cazenave a écrit :

Facture :

  • un numéro de facture (on prend la primary key ou une colonne en plus dédiée ?)

Il va falloir faire autrement :

https://www.cybertec-postgresql.com/en/gaps-in-sequences-postgresql/ une piste ? (j'ai lu en diagonale). Je vais mettre ce problème mettre de coté, on demandera à notre DBA.

#2

Updated by Emmanuel Cazenave 2 months ago

Emmanuel Cazenave a écrit :

Il va falloir faire autrement

On ne peut pas se reposer sur la clé primaire.

#3

Updated by Benjamin Dauvergne 2 months ago

Le plus simple c'est de créer un modèle Counter, et de faire :

class Counter(model):
    name = CharField(max_length=128, primary_key=True)
    value = PositiveIntegerField(default=0)

def get_count(name):
    with transaction.atomic(savepoint=False):
         created, counter = Counter.objects.get_or_create(name=name)
         if not created:
            counter = Counter.objects.select_for_update().get(pk=counter.pk)
         counter.value += 1
         counter.save()
         return counter.value

ça suppose un index d'unicité sur name et ça s'utiliserait ainsi :
invoice.number = get_count(f'invoice-{now().year}') # compteur de l'année de la facture

#4

Updated by Benjamin Dauvergne 2 months ago

Plutôt qu'un nom le compteur peut-être relié à un objet parent des factures, la régie ou mieux l'année comptable elle même relié à la régie (je pense que ce serait fait comme ça dans un ERP classique).

class AccountingYear(Model):
     regie = ForeignKey(Regie)
     year = PositiveInteger()
     value = PositiveInteger(default=0)

     class Meta:
         unique_together = (('regie', 'year'),)
#5

Updated by Lauréline Guérin 18 days ago

  • Related to Development #71528: facturation: générer des lignes de facturation sur un cas "simple" (prestation d'un enfant pour une période) added

Also available in: Atom PDF