has_many :enfants
has_many :classrooms
has_many :prestations, through: :enfants
+ has_many :factures
validates :nom, presence: true
class Facture < ApplicationRecord
+
belongs_to :compte
+
+ has_many :facture_lignes
+
+ validates :réf, presence: true
+ validates_uniqueness_of :réf, scope: [:compte_id]
+
+ def self.fabrique_une_référence_facture(index)
+ "#{Date.today.month}-#{Date.today.year}/#{index}"
+ end
+
end
--- /dev/null
+class FactureChrono < ApplicationRecord
+ belongs_to :organisation
+end
--- /dev/null
+class FactureLigne < ApplicationRecord
+ belongs_to :facture
+ belongs_to :prestation_type
+end
has_many :users
has_many :prestation_types, inverse_of: :organisation
has_many :tarif_types
+ has_many :facture_chronos
has_many :tarifs, through: :tarif_types
has_many :comptes, through: :structures
has_many :enfants, through: :comptes
validates_uniqueness_of :enfant_id, scope: [:date, :prestation_type_id], message: "Il existe déjà une prestation pour cet enfant et ce jour)"
+ scope :à_facturer, -> { where(facture_id: nil) }
+
end
--- /dev/null
+class CreateFactureChronos < ActiveRecord::Migration[5.2]
+ def change
+ create_table :facture_chronos do |t|
+ t.references :organisation, foreign_key: true
+ t.integer :index, null: false, default: 0
+
+ t.timestamps
+ end
+ end
+end
--- /dev/null
+class CreateFactureLignes < ActiveRecord::Migration[5.2]
+ def change
+ create_table :facture_lignes do |t|
+ t.references :facture, foreign_key: true
+ t.references :prestation_type, foreign_key: true
+ t.decimal :qté, :precision => 4, :scale => 2, null: false, default: 0
+ t.decimal :prix, :precision => 4, :scale => 2, null:false, default: 0
+ t.decimal :total, :precision => 4, :scale => 2, null: false, default: 0
+
+ t.timestamps
+ end
+ end
+end
--- /dev/null
+class AddFactureReferenceToPrestation < ActiveRecord::Migration[5.2]
+ def change
+ add_reference :prestations, :facture, foreign_key: true
+ end
+end
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_09_10_094837) do
+ActiveRecord::Schema.define(version: 2019_09_10_130428) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
t.index ["tarif_type_id"], name: "index_enfants_on_tarif_type_id"
end
+ create_table "facture_chronos", force: :cascade do |t|
+ t.bigint "organisation_id"
+ t.integer "index", default: 0, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["organisation_id"], name: "index_facture_chronos_on_organisation_id"
+ end
+
+ create_table "facture_lignes", force: :cascade do |t|
+ t.bigint "facture_id"
+ t.bigint "prestation_type_id"
+ t.decimal "qté", precision: 4, scale: 2, default: "0.0", null: false
+ t.decimal "prix", precision: 4, scale: 2, default: "0.0", null: false
+ t.decimal "total", precision: 4, scale: 2, default: "0.0", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["facture_id"], name: "index_facture_lignes_on_facture_id"
+ t.index ["prestation_type_id"], name: "index_facture_lignes_on_prestation_type_id"
+ end
+
create_table "factures", force: :cascade do |t|
t.bigint "compte_id"
t.string "réf"
t.decimal "qté", precision: 3, scale: 2, default: "0.0", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.bigint "facture_id"
t.index ["enfant_id"], name: "index_prestations_on_enfant_id"
+ t.index ["facture_id"], name: "index_prestations_on_facture_id"
t.index ["prestation_type_id"], name: "index_prestations_on_prestation_type_id"
end
add_foreign_key "enfants", "classrooms"
add_foreign_key "enfants", "comptes"
add_foreign_key "enfants", "tarif_types"
+ add_foreign_key "facture_chronos", "organisations"
+ add_foreign_key "facture_lignes", "factures"
+ add_foreign_key "facture_lignes", "prestation_types"
add_foreign_key "factures", "comptes"
add_foreign_key "prestation_types", "organisations"
add_foreign_key "prestations", "enfants"
+ add_foreign_key "prestations", "factures"
add_foreign_key "prestations", "prestation_types"
add_foreign_key "reservations", "enfants"
add_foreign_key "reservations", "prestation_types"
date_début = Date.today.beginning_of_week
date_fin = Date.today.end_of_week
+ puts "Facturation des prestations du #{date_début} au #{date_fin}"
# quels sont les comptes ayants de prestations consommées durant la période ?
comptes = Prestation
+ .à_facturer
.where("date BETWEEN DATE(?) AND (?)", date_début, date_fin)
.joins(:enfant)
.group("enfants.compte_id")
.count(:id)
+ # pour chaque compte, faire le chiffrage des prestations consommées
comptes.each do |id, count|
compte = Compte.find(id)
puts "Compte: #{compte.nom} (#{compte.id}) = #{count} prestations consommées"
- # les prestations consommées par ce compte durant la période
- compte.prestations.where("date BETWEEN DATE(?) AND (?)", date_début, date_fin).each do |presta|
- tarif = presta.prestation_type.tarifs.find_by(tarif_type_id: presta.enfant.tarif_type_id)
- puts "#{presta.enfant.nom_et_prénom} = #{presta.qté} #{presta.prestation_type.nom} à #{tarif.prix}"
+ # incrémenter le numéro de chrono de facture
+ chrono = compte.structure.organisation.facture_chronos.last
+ index = chrono.index + 1
+
+ # créer l'entête de facture
+ facture = compte.factures.create(réf: Facture.fabrique_une_référence_facture(index), date: DateTime.now, échéance: Date.today + 1.month)
+
+ # totaliser les prestations consommées par ce compte durant la période
+ montant_total = 0.0
+ compte.prestations.à_facturer.where("date BETWEEN DATE(?) AND (?)", date_début, date_fin).each do |presta|
+ prix = presta.prestation_type.tarifs.find_by(tarif_type_id: presta.enfant.tarif_type_id).prix
+ puts "#{presta.date} #{presta.enfant.nom_et_prénom} = #{presta.qté} #{presta.prestation_type.nom} à #{prix}€ = #{prix * presta.qté} €"
+ montant_total += prix * presta.qté
+
+ # créer les lignes de facture
+ facture.facture_lignes.create(prestation_type: presta.prestation_type, qté: presta.qté, prix: prix, total: prix * presta.qté)
+
+ # MAJ du prestation.facture_id pour indiquer que cette prestation a été facturée
+ presta.update(facture_id: facture.id)
end
+ puts "Montant total: #{montant_total} €"
+ facture.montant = montant_total
- end
+ # Finalisation facture et enregistrement du chrono facture si la facture est enregistrée
+ if facture.valid?
+ facture.save
+
+ # MAJ du Chrono N° de facture
+ chrono.index = index
+ chrono.save
+ puts "OK => #{facture.inspect}"
+ puts "OK => #{facture.facture_lignes.size} lignes créées"
+ puts "- " * 60
+ else
+ puts "KO !!"
+ end
+ end
end
-end
-
\ No newline at end of file
+end
\ No newline at end of file