create or replace view betriebskosten_anteil_mieter as select (b.betrag / o.flaeche * w.flaeche) as anteil, o.id as objekt, w.id as wohnung, m.id as mieter, b.id as abrechnung, (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, b. jahr as jahr 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 table jahresabrechnung_summary ( id integer unsigned not null auto_increment, abrechnung integer unsigned not null, mieter integer unsigned not null, nutzungszeit integer not null, anteil_pro_flaeche decimal(20, 10) not null, anteil_pro_flaeche_nutzungszeit decimal(20, 10) not null, vorauszahlung decimal(20, 2) not null, nachzahlung decimal(20, 2) not null, summe_zahlungen decimal(20, 2) not null, summe_zahlungen_anteil_miete decimal(20, 2) not null, constraint primary key(id), constraint unique key uk_jahresabrechnung_summary_mieter_abrechnung (abrechnung, mieter), constraint foreign key fk_jahresabrechnung_summary_betriebskosten_abrechnung (abrechnung) references betriebskosten_abrechnung(id) on delete restrict on update cascade, constraint foreign key fk_jahresabrechnung_summary_mieter (mieter) references mieter(id) on delete restrict on update cascade ) engine=InnoDB; 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 anteil, objekt, wohnung, mieter, abrechnung, nutzungszeit, jahr from betriebskosten_anteil_mieter where 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 jahresabrechnung_summary (abrechnung, mieter, nutzungszeit, anteil_pro_flaeche, anteil_pro_flaeche_nutzungszeit, vorauszahlung, nachzahlung, summe_zahlungen, summe_zahlungen_anteil_miete) values(rec.abrechnung, rec.mieter, rec.nutzungszeit, rec.anteil, v_anteil_mieter_nutzungszeit, v_summe_betriebskosten_zahlungen, v_betriebskosten_nachzahlung, v_summe_zahlungen, v_summe_mietforderungen); end for; end; // delimiter ; alter table objekt modify column flaeche decimal(20, 2) not null; alter table wohnung modify column flaeche decimal(20, 2) not null; alter table betriebskosten_abrechnung modify column betrag decimal(20, 2) not null; create or replace view jahresabrechnung_flat_v as select o.shortname as objekt, o.flaeche as gesamt_flaeche, w.shortname as wohnung, w.flaeche as flaeche, m.anrede as anrede, m.vorname as vorname, m.nachname as nachname, m.strasse as strasse, m.plz as plz, m.ort as ort, j.nutzungszeit as nutzungszeit, j.anteil_pro_flaeche as anteil_pro_flaeche, j.anteil_pro_flaeche_nutzungszeit as anteil_pro_flaeche_nutzungszeit, j.summe_zahlungen as summe_zahlungen, j.summe_zahlungen_anteil_miete as summe_zahlungen_anteil_miete, j.vorauszahlung as vorauszahlung, j.nachzahlung as nachzahlung, b.jahr as jahr, b.betrag as gesamt_betriebskosten from objekt o, wohnung w, mieter m, jahresabrechnung_summary j, betriebskosten_abrechnung b where j.abrechnung = b.id and j.mieter = m.id and m.wohnung = w.id and w.objekt = o.id; create or replace view rueckzahlungen_v as select concat(m.vorname, ' ', m.nachname) as mieter, format_iban(m.iban) as iban, j.nachzahlung as nachzahlung, b.jahr as jahr from mieter m, jahresabrechnung_summary j, betriebskosten_abrechnung b where j.abrechnung = b.id and j.mieter = m.id and j.nachzahlung < 0; create or replace view nachzahlungen_v as select concat(m.vorname, ' ', m.nachname) as mieter, j.nachzahlung as nachzahlung, b.jahr as jahr from mieter m, jahresabrechnung_summary j, betriebskosten_abrechnung b where j.abrechnung = b.id and j.mieter = m.id and j.nachzahlung > 0;