create or replace view abrechnung1 as
  select b.jahr as jahr, 
         (b.betrag / o.flaeche * w.flaeche) as anteil,
         o.shortname as objekt,
         w.shortname as wohnung,
         concat(m.vorname, ' ', m.nachname) as mieter,
         m.id as mieter_id,
         (timestampdiff(month,
                        if (year(m.einzug) = b.jahr, m.einzug, makedate(b.jahr, 1)),
                        if (m.auszug is not null, m.auszug, last_day(makedate(b.jahr, 365)))
                       ) + 1) as nutzungszeit
     from betriebskosten_abrechnung b,
          objekt o,
          wohnung w,
          mieter m
     where b.objekt = o.id and
           w.objekt = o.id and
           m.wohnung = w.id and
           (year(m.einzug) = b.jahr or year(m.auszug) = b.jahr);

create or replace view abrechnung2 as
  select jahr,
         anteil / 12 * nutzungszeit as anteil,
         objekt,
         wohnung,
         mieter,
         mieter_id
     from abrechnung1;

create or replace view abrechnung3 as
  select a.jahr as jahr,
         a.anteil as anteil,
         a.objekt as objekt,
         a.wohnung as wohnung,
         m.vorname as vorname,
         m.nachname as nachname,
         m.anrede as anrede,
         m.strasse as strasse,
         m.plz as plz,
         m.ort as ort
     from abrechnung2 a,
          mieter m
     where m.id = a.mieter_id;

select * from abrechnung3 where jahr = '2020';


delimiter //


create or replace procedure jahresabrechnung(in p_year year)
modifies sql data
begin
    declare v_anteil_mieter_nutzungszeit decimal(20, 10);
    declare v_summe_zahlungen decimal(20, 10);
    declare v_summe_mietforderungen decimal(20, 10);
    declare v_summe_betriebskosten_zahlungen decimal(20, 10);
    declare v_betriebskosten_nachzahlung decimal(20, 10);
    declare v_error_message varchar(128);
    declare c_anteil_mieter 
        cursor (cp_year year) for
        select (b.betrag / o.flaeche * w.flaeche) as anteil,
               o.id as objekt,
               w.id as wohnung,
               m.id as mieter,
               (timestampdiff(month,
                              if (year(m.einzug) = b.jahr, m.einzug, makedate(b.jahr, 1)),
                              if  (m.auszug is not null, m.auszug, last_day(makedate(b.jahr, 365)))
                             ) + 1) as nutzungszeit
          from betriebskosten_abrechnung b,
               objekt o,
               wohnung w,
               mieter m
          where b.objekt = o.id and
                w.objekt = o.id and
                m.wohnung = w.id and
                (year(m.einzug) = b.jahr or year(m.auszug) = b.jahr) and
                b.jahr = cp_year;

    for rec in c_anteil_mieter(p_year) do
        set v_anteil_mieter_nutzungszeit = rec.anteil / 12 * rec.nutzungszeit;
        select sum(betrag) into v_summe_zahlungen
          from zahlung
          where mieter = rec.mieter and
                year(datum_soll) = p_year;
        if (v_summe_zahlungen is null) then
            set v_error_message = concat('No Zahlungen for Mieter ', rec.mieter);
            signal sqlstate '45000' set message_text = v_error_message;
        end if;
        select sum(anteil_miete) into v_summe_mietforderungen
          from forderung
          where mieter = rec.mieter and
                year(datum) = p_year;
        set v_summe_betriebskosten_zahlungen = v_summe_zahlungen - v_summe_mietforderungen;
        set v_betriebskosten_nachzahlung = v_anteil_mieter_nutzungszeit - v_summe_betriebskosten_zahlungen;

        insert into forderung (mieter, datum, betrag, anteil_betriebskosten_nachzahlung, ref_wohnung)
          values(rec.mieter, curdate(), v_betriebskosten_nachzahlung, v_betriebskosten_nachzahlung, rec.wohnung);

        call log(concat('Mieter: ',
                        cast(rec.mieter as char),
                        ', Anteil: ',
                        cast(v_anteil_mieter_nutzungszeit as char),
                        ', Zahlungen: ',
                        cast(v_summe_zahlungen as char),
                        ', Mietforderungen: ',
                        cast(v_summe_mietforderungen as char),
                        ', Betriebskostenvorauszahlung: ',
                        cast(v_summe_betriebskosten_zahlungen as char),
                        ', Rest: ',
                        cast(v_betriebskosten_nachzahlung as char)
                       )
                );
    end for;
end;
//

