-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
Ausgangslage
Basierend auf der ausgewählten Beitragsart und den Beitragssätzen und dem Sammelrechnungs-Feature aus dem Core sollen Verbandsabrechnungen gestellt werden können. Dafür sind custom Rechnungsposten für die pfadi_de-spezifische Beitragsberechnung nötig, welche auf der Grundlage im Core aufbauen.
Anforderungen
Siehe Dokument Detailbeschreibung zum Datenmodell “Beitragsstruktur” und besonders das Kapitel "Rechnungslauf Gruppierung zu Gruppierung"
- Bei der Mitgliedschafts-Abrechnung wird für jede verarbeitete Person ein Stichdatum berechnet, und die Beitragsart und Beitragssätze an diesem Datum gelten für diese Person. Das Stichdatum wird vorerst als das erste Datum der Mitgliedschaft in der Abrechnungsperiode definiert (bis wir auf Probleme damit stossen, dann könnten wir auch vereinfachen auf pauschal den ersten Tag der Abrechnungsperiode, egal wann die Person eingetreten ist).
Abgrenzungen
Der Teil "Rechnungslauf Ebene zu Mitglied" wird im separaten Ticket #25 behandelt.
Die Berechnung der Mitgliedschaftsdauer wird im separaten Ticket #21 behandelt.
Offene Fragen
- Wird auf der Sammelrechnung ein Rechnungsposten pro Beitragsart eingefügt? Oder ein einziger Rechnungsposten, der alles zusammen berechnet? -> in der Sammelrechnung soll nur ein Posten eingefügt werden, der dann beim Generieren der Rechnungen automatisch einen Rechnungsposten für jeden aktiven Beitragssatz einfügt.
Mockup
Tech-Spec
- Umsetzung im pfadi_de Wagon
- Finden aller relevanten Mitglieds-Rollen (erste Rolle die in der Sammelrechnungs-Periode aktiv ist, falls mehrere dann diejenige mit der tiefsten ID) und deren verknüpftem
FeeKind - Berechnung des Eintrags in
FeeKindund seinerparent-Hierarchie, welcher auf dem rechnungsstellenden Layer oder am nächsten darüber liegt - Berechnung des Alters zu Beginn der Sammelrechnungsperiode
- Berechnung des günstigsten Beitragssatzes, bei dem alle Bedingungen erfüllt sind (Mitgliedschaftsdauer wird erst in BEITRÄGE: Probemitgliedschaften #21 ergänzt)
ToDo
- Sammelrechnungsposten
PeriodInvoiceTemplate::FeeCalculationItem < PeriodInvoiceTemplate::Itemanlegen (enthält keine Berechnungslogik, ist nur ein Platzhalter der in Sammelrechnungen eingefügt werden kann)- views/period_invoice_template/_fee_calculation_item_fields.html.haml leer anlegen (allenfalls mit Erklärung ähnlich Mockup)
- Eingabefelder für Preis und MWSt. werden nicht gebraucht. Kostenstelle und Konto dürfen angezeigt werden oder nicht, je nach dem was einfacher ist. (Könnte auch Core-Änderung und damit SWB-Wagon-Änderung nötig machen)
- Allenfalls hidden inputs mit dummy Werten für die versteckten Felder einfügen, welche in der DB obligatorisch sind
- Rechnungsposten
Invoice::FeeCalculationItem < Invoice::PeriodItemanlegen mit einem dynamic_cost_parameterfee_rate_id - Im Core in PeriodInvoiceTemplates::InvoiceRunsController#assign_invoice_items das
mapzuflat_mapändern, sodass Wagons auch aus einem Sammelrechnungsposten mehrere oder keine Rechnungsposten generieren können. - In PeriodInvoiceTemplate::FeeCalculationItem#to_invoice_item alle aktiven FeeRates der Ebene berechnen und pro FeeRate ein Invoice::FeeCalculationItem mit der entsprechenden fee_rate_id generieren.
- In Invoice::FeeCalculationItem die Methode unit_cost überschreiben und den Betrag des verlinkten Beitragssatzes zurückgeben
- In #subject_type
Person(als Klasse, nicht als String) zurückgeben - In #base_scope
Person.joins(:roles)zurückgeben - #scope überschreiben und an
supereinefee_rate_conditionanhängen, welche nur Personen akzeptiert, welche gemäss der Domainklasse FeeCalculator (siehe unten) die richtige fee_kind_id für den Rechnungsempfängerrecipient_id_expressionhaben - Domainklasse FeeCalculator anlegen, welche mit einen Zeitraum und einem Beitragssatz eine Liste von Personen berechnen kann, bei welchen dieser Beitragssatz gilt. Wenn irgendwie möglich als SQL Query ohne etwas in Ruby Memory zu laden. Logik sollte wiederverwendbar sein, sodass auch in die andere Richtung berechnet werden kann: Gegeben eine Person, finde die dazugehörige fee_kind_id
- Aus dem Beitragssatz wird das Ziel-Layer berechnet
- Mitgliedsrolle suchen: Person <-> Rolle (nur Rollen im oder unterhalb dem Ziel-Layer, nur beitragspflichtige Rollen, nur die erste in der Rechnungsperiode aktive Rolle, tiefere Rollen-ID gewinnt)
- FeeKind der Mitgliedsrolle finden
- parent-Hierarchie des FeeKinds durchsuchen nach einem Ziel-FeeKind auf dem Ziel-Layer
- Auf Ziel-FeeKind den
#total_yearly_amount(person, MAX(membership_role.start_on, period_start_on)) / (duration_in_years)berechnen, wobeiduration_in_years = (period_end_on - period_start_on) / 1 yearist, gerundet auf das nächste Vielfache von 0.5.
- Specs schreiben
- Kunde wegen Übersetzungen informieren
- Mit angemessener Rolle "durchklicken"
- DoD geprüft und erfüllt?
- CHANGELOG-Eintrag unter "unreleased" unten hinzufügen
Reactions are currently unavailable