Browse Source

Neue virtuelle Tabelle Stellen Besetzungen #7

master
Daniel Quathamer 3 days ago
parent
commit
1c6448a1a4
  1. 13
      src-modules/module/rpta/conf/rpta.xml
  2. 7
      src-modules/module/rpta/masken/45000_felderinfo.unl
  3. 1
      src-modules/module/rpta/masken/45000_masken_felder_bez.unl
  4. 18
      src-modules/module/rpta/masken/45000_maskeninfo.unl
  5. 35
      src-modules/module/rpta/masken/45080_felderinfo.unl
  6. 1
      src-modules/module/rpta/masken/45080_maske_system_bez.unl
  7. 20
      src-modules/module/rpta/masken/45080_masken_felder_bez.unl
  8. 210
      src-modules/module/rpta/masken/45080_maskeninfo.unl
  9. 1
      src-modules/module/rpta/masken/45080_sachgeb_maske_bez.unl
  10. 384
      src-modules/module/rpta/schluesseltabellen/rpta_column_layout_sgd_pbe_pbv_fuellen.sql
  11. 393
      src-modules/module/rpta/schluesseltabellen/stellen_besetzung_virtuell.sql

13
src-modules/module/rpta/conf/rpta.xml

@ -115,6 +115,9 @@ rightname="CS_BIA_STANDARDREPORTS_ADMIN[RPTA]" />
</rs> </rs>
</primaryKeys> </primaryKeys>
<indexes> <indexes>
<index name="ix_rpta_column_layout" type="unique">
<index-column name="uniquename"/>
</index>
</indexes> </indexes>
</table> </table>
@ -263,6 +266,12 @@ parent="Berichtsassistent">Abfragen zur Administration von Berichtsassistent </t
<path>$RPTA_PFAD/masken</path> <path>$RPTA_PFAD/masken</path>
</src> </src>
</maske> </maske>
<maske tid="45080" name="Stellenbesetzung und Beschäftigung (Liste)" thema="Berichtsassistent">
<description>Stellenbesetzung und Beschäftigung (Liste)</description>
<src>
<path>$RPTA_PFAD/masken</path>
</src>
</maske>
</masken> </masken>
<data-integrity> <data-integrity>
@ -375,8 +384,10 @@ parent="Berichtsassistent">Abfragen zur Administration von Berichtsassistent </t
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sachgebiete_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sachgebiete_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sx_stylesheets_einfuegen.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sx_stylesheets_einfuegen.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/studierende_datenblatt_virtuell.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/studierende_datenblatt_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/stellen_besetzung_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/pruefungen_nach_ppruef_virtuell.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/pruefungen_nach_ppruef_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sos_stud_astat_rsz_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sos_stud_astat_rsz_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sgd_pbe_pbv_fuellen.sqll" database=""/>
</action> </action>
</install-step> </install-step>
</install> </install>
@ -393,8 +404,10 @@ parent="Berichtsassistent">Abfragen zur Administration von Berichtsassistent </t
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sx_stylesheets_einfuegen.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/sx_stylesheets_einfuegen.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/upgrade/rpta_upgrade_man.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/upgrade/rpta_upgrade_man.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/studierende_datenblatt_virtuell.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/studierende_datenblatt_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/stellen_besetzung_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/pruefungen_nach_ppruef_virtuell.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/pruefungen_nach_ppruef_virtuell.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sos_stud_astat_rsz_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sos_stud_astat_rsz_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$RPTA_PFAD/schluesseltabellen/rpta_column_layout_sgd_pbe_pbv_fuellen.sqll" database=""/>
</action> </action>
<action> <action>

7
src-modules/module/rpta/masken/45000_felderinfo.unl

@ -1,10 +1,10 @@
45000^Spaltenlayout^3000^350^-1^140^180^1^integer^30^1^1^<<SQL>>SELECT tid,\ 45000^Spaltenlayout^3000^350^-1^140^180^1^char^30^1^1^<<SQL>>SELECT uniquename,\
caption\ caption\
FROM rpta_column_layout \ FROM rpta_column_layout \
where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sos_stud_astat'\ where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sos_stud_astat'\
and R.systeminfo_id=7)\ and R.systeminfo_id=7)\
order by sortnr, caption\ order by sortnr, caption\
;^^<<SQL>>SELECT tid,\ ;^^<<SQL>>SELECT uniquename,\
caption\ caption\
FROM rpta_column_layout \ FROM rpta_column_layout \
where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sos_stud_astat'\ where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sos_stud_astat'\
@ -13,6 +13,7 @@ and R.systeminfo_id=7) and uniquename='sos_stud_astat_rsz';^
45002^Fächer^30^0^0^130^200^6^char^1000^0^12^<<SQL>> select tid,name,sortnr from sichten where art='Fächer-Sicht' order by 3,2;^ ^ ^ 45002^Fächer^30^0^0^130^200^6^char^1000^0^12^<<SQL>> select tid,name,sortnr from sichten where art='Fächer-Sicht' order by 3,2;^ ^ ^
45003^Abschluss^40^0^0^100^200^3^char^1500^0^1^<<SQL>> select apnr, druck from cifx where key=35 order by 2;^ ^ ^ 45003^Abschluss^40^0^0^100^200^3^char^1500^0^1^<<SQL>> select apnr, druck from cifx where key=35 order by 2;^ ^ ^
45004^bis Fachsemester^1000^300^-1^200^100^1^integer^30^0^0^^ ^ ^ 45004^bis Fachsemester^1000^300^-1^200^100^1^integer^30^0^0^^ ^ ^
45005^Semestertyp^22^350^-1^140^80^1^integer^255^0^1^<<SQL>> select 1,'nur Sommersemester' from xdummy union select 2,'nur Wintersemester' from xdummy^Eintrag^<<SQL>> select 2,'nur Wintersemester' from xdummy^
45006^Hochschulzugangsberechtigung^120^300^-1^200^200^1^sql^30^0^1^hs_zugangsber^apnr, eintrag^ ^ 45006^Hochschulzugangsberechtigung^120^300^-1^200^200^1^sql^30^0^1^hs_zugangsber^apnr, eintrag^ ^
45007^Bis Semester^20^350^-1^140^80^1^integer^30^0^1^<<SQL>> select tid, eintrag from semester order by tid DESC;^ ^<<SQL>> select tid,eintrag from semester where today() between sem_beginn and sem_ende;^ 45007^Bis Semester^20^350^-1^140^80^1^integer^30^0^1^<<SQL>> select tid, eintrag from semester order by tid DESC;^ ^<<SQL>> select tid,eintrag from semester where today() between sem_beginn and sem_ende;^
45008^Staatsangehörigkeit^150^0^0^140^150^10^char^30^0^12^<<SQL>> select tid,name,sortnr from sichten where art='SOS-Staaten-Sicht' order by 3,2;^ ^ ^ 45008^Staatsangehörigkeit^150^0^0^140^150^10^char^30^0^12^<<SQL>> select tid,name,sortnr from sichten where art='SOS-Staaten-Sicht' order by 3,2;^ ^ ^
@ -23,4 +24,4 @@ and R.systeminfo_id=7) and uniquename='sos_stud_astat_rsz';^
45022^Geschlecht^110^0^0^140^80^1^integer^30^0^1^<<SQL>> SELECT apnr,druck FROM cif where key = 9003 and apnr between 1 and 4 order by 1;^ ^ ^ 45022^Geschlecht^110^0^0^140^80^1^integer^30^0^1^<<SQL>> SELECT apnr,druck FROM cif where key = 9003 and apnr between 1 and 4 order by 1;^ ^ ^
45023^Spalten^3001^0^0^150^190^10^char^30^0^1^<<SQL>>\ 45023^Spalten^3001^0^0^150^190^10^char^30^0^1^<<SQL>>\
select C.uniquename, C.caption ,L.layout_id from rpta_column C, rpta_column2layout L where C.tid=L.column_id and layout_id in\ select C.uniquename, C.caption ,L.layout_id from rpta_column C, rpta_column2layout L where C.tid=L.column_id and layout_id in\
(select tid from rpta_column_layout where tid=<<Spaltenlayout>>) order by 2;^^^ (select tid from rpta_column_layout where uniquename=<<Spaltenlayout>>) order by 2;^^^

1
src-modules/module/rpta/masken/45000_masken_felder_bez.unl

@ -3,6 +3,7 @@
45000^45002^ 45000^45002^
45000^45003^ 45000^45003^
45000^45004^ 45000^45004^
45000^45005^
45000^45006^ 45000^45006^
45000^45007^ 45000^45007^
45000^45008^ 45000^45008^

18
src-modules/module/rpta/masken/45000_maskeninfo.unl

@ -38,7 +38,7 @@ select L.uniquename,\
from rpta_resultset R, rpta_column_layout L\ from rpta_resultset R, rpta_column_layout L\
where L.resultset_id=R.tid\ where L.resultset_id=R.tid\
and R.uniquename='${basetable.name}'\ and R.uniquename='${basetable.name}'\
and L.tid=<<Spaltenlayout>>;\ and L.uniquename=<<Spaltenlayout>>;\
\ \
]]></sqlvar>\ ]]></sqlvar>\
<sqlvar name="columns" type="hashsequence"><![CDATA[\ <sqlvar name="columns" type="hashsequence"><![CDATA[\
@ -56,7 +56,7 @@ FROM rpta_column_layout L, rpta_column2layout CL, rpta_column C, rpta_column_typ
where L.tid=CL.layout_id\ where L.tid=CL.layout_id\
and C.tid=CL.column_id\ and C.tid=CL.column_id\
and T.tid=C.column_type\ and T.tid=C.column_type\
and L.tid=<<Spaltenlayout>>\ and L.uniquename=<<Spaltenlayout>>\
/* and C.uniquename in (<<Spalten>>) */\ /* and C.uniquename in (<<Spalten>>) */\
order by CL.sortnr\ order by CL.sortnr\
;\ ;\
@ -73,6 +73,7 @@ order by CL.sortnr\
/* and abschluss in (<<Abschluss>>) */\ /* and abschluss in (<<Abschluss>>) */\
/* and geschlecht = <<Geschlecht>> */\ /* and geschlecht = <<Geschlecht>> */\
/* and fach_sem_zahl <= <<bis Fachsemester>> */\ /* and fach_sem_zahl <= <<bis Fachsemester>> */\
/* and substring('' || sem_rueck_beur_ein from 5 for 1)='<<Semestertyp>>' */\
" />\ " />\
\ \
<#assign filter = filter + " and 's_' || tid_stg in "+Studiengang.allNeededKeysList /> \ <#assign filter = filter + " and 's_' || tid_stg in "+Studiengang.allNeededKeysList /> \
@ -145,6 +146,17 @@ group by\
</#if>\ </#if>\
</#list>\ </#list>\
;\ ;\
--für Prozentwerte alle Aggregate summieren:\
select <#foreach column in columns>\
<#if column.is_aggregate==1 && column.coltype!="computedColumn">\
sum(${column.targetfieldname})::float as ${column.targetfieldname},\
</#if>\
</#foreach>\
null::char(1) as dummycol\
into temp tmp_gesamt\
from tmp_stud2\
where 1=1\
;\
\ \
<#assign number_of_visible_colums=0 />\ <#assign number_of_visible_colums=0 />\
<#foreach column in columns>\ <#foreach column in columns>\
@ -184,6 +196,8 @@ drop table if exists ${basetable.runtime_tablename};\
\ \
\ \
drop table if exists tmp_stud;\ drop table if exists tmp_stud;\
drop table if exists tmp_gesamt;\
\
\ \
</#if> --wenn columns?has_content^--Freemarker Template\ </#if> --wenn columns?has_content^--Freemarker Template\
XIL List\ XIL List\

35
src-modules/module/rpta/masken/45080_felderinfo.unl

@ -0,0 +1,35 @@
45080^Institution (Stelle)^1^0^0^150^150^0^char^30^0^12^<<SQL>>select tid,type,name,sortnr from sichten where art in ('SVA-Kostenstellen-Sicht','SVA-spez-Besch./Kostenstellen-Sicht','SVA-spez-Kostenstellen-Sicht') and aktiv=1 order by sortnr,type,name;^^^
45081^Datum^0^350^-1^150^80^1^date^10^1^0^^^<<SQL>> select today() from xdummy^
45082^Stellenkategorie^2^0^0^150^150^3^char^30^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA Kategorie' and aktiv=1 order by type,name;^hidden^^
45083^Spalten^3001^0^0^150^190^10^char^30^0^1^<<SQL>>\
select C.uniquename, C.caption ,L.layout_id from rpta_column C, rpta_column2layout L where C.tid=L.column_id and layout_id in\
(select tid from rpta_column_layout where tid=<<Spaltenlayout>>) order by 2;^^^
45084^Lehreinheit (Stelle)^4^0^0^150^150^1^char^4^0^12^<<SQL>> select tid,type,name from sichten where art ='SVA-Lehreinheiten-Sicht' and aktiv=1 order by type,name;^hidden^^
45085^Stellen-Nr.^50^350^-1^150^80^1^integer^10^0^0^^^^
45086^Amtsbezeichnung^55^0^0^150^160^3^char^30^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA Amtsdienstbez.' and aktiv=1 order by type,name;^hidden^^
45087^Beschäftigungsstelle (Person)^65^0^0^150^150^1^char^30^0^12^<<SQL>>select tid,type,name,sortnr from sichten where art in ('SVA-Kostenstellen-Sicht','SVA-spez-Besch./Kostenstellen-Sicht') and aktiv=1 order by sortnr,type,name;^hidden^^
45088^Kostenstelle (Person)^70^350^-1^150^150^1^char^30^0^12^<<SQL>> select tid,type,name,sortnr from sichten where art in ('SVA-Kostenstellen-Sicht','SVA-spez-Kostenstellen-Sicht','SVA-Kst-spezial') and aktiv=1 order by sortnr,type,name;^hidden^^
45089^Haushaltsvermerk^60^350^-1^150^200^3^char^4^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA HHV' and aktiv=1 order by type,name;^hidden^^
45090^Spaltenlayout^3000^350^-1^140^180^1^integer^50^1^1^<<SQL>>SELECT tid,\
caption\
FROM rpta_column_layout \
where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sva_pbe_aggr_sgd'\
and R.systeminfo_id=6)\
order by sortnr, caption\
;^^<<SQL>>SELECT tid,\
caption\
FROM rpta_column_layout \
where resultset_id in (select R.tid from rpta_resultset R where R.uniquename='sva_pbe_aggr_sgd'\
and R.systeminfo_id=6)\
order by sortnr, caption\
limit 1 \
;^
45091^Filter Stellen^120^350^-1^150^150^1^sql^20^0^1^<<SQL>> select id,caption from sx_repository where aktiv =1 and today() between gueltig_seit and gueltig_bis and art='SVA_STELL_FILTER' order by 2;^hidden^^
45092^Dienstart^3^350^-1^150^150^3^char^30^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA Dienstart' and aktiv=1 order by type,name;^hidden^^
45093^BVL-Gruppe (Stelle)^74^0^0^150^120^10^char^30^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA BVL-Gruppen' and aktiv=1 order by type,name;^hidden^^
45094^BVL-Gruppe (Person)^80^350^-1^150^120^10^char^30^0^12^<<SQL>>select tid,type,name from sichten where art ='SVA BVL-Gruppen' and aktiv=1 order by type,name;^hidden^^
45095^Filter Besetzung^130^0^0^150^150^1^sql^20^0^1^<<SQL>> select id,caption from sx_repository where aktiv =1 and today() between gueltig_seit and gueltig_bis and art='SVA_BESETZ_FILTER' order by 2;^hidden^^
45096^Finanzierungsquelle^302^0^0^100^200^3^char^30^0^1^<<SQL>> select id,caption from sx_repository where art='SVA_FINANZIERUNGSQUELLE' and aktiv=1 and gueltig_seit<=date_val(<<Datum>>) and gueltig_bis>=date_val(<<Datum>>) order by sort1^hidden^^
45097^Personalkategorie^310^0^0^100^200^3^char^30^0^1^<<SQL>> select id,caption from sx_repository where art='SVA_PERSONALKATEGORIE' and aktiv=1 and gueltig_seit<=date_val(<<Datum>>) and gueltig_bis>=date_val(<<Datum>>) order by sort1^hidden^^
45098^Stellenanzeige^1000^0^0^100^200^1^char^20^0^1^<<SQL>> select 'besetzt','nur besetzte' from xdummy union select 'frei','nur freie' from xdummy^hidden^^
45099^Stellen-Nr. im HHPlan^52^350^-1^150^80^1^char^25^0^0^^^^

1
src-modules/module/rpta/masken/45080_maske_system_bez.unl

@ -0,0 +1 @@
45080^6^

20
src-modules/module/rpta/masken/45080_masken_felder_bez.unl

@ -0,0 +1,20 @@
45080^45080^
45080^45081^
45080^45082^
45080^45083^
45080^45084^
45080^45085^
45080^45086^
45080^45087^
45080^45088^
45080^45089^
45080^45090^
45080^45091^
45080^45092^
45080^45093^
45080^45094^
45080^45095^
45080^45096^
45080^45097^
45080^45098^
45080^45099^

210
src-modules/module/rpta/masken/45080_maskeninfo.unl

@ -0,0 +1,210 @@
45080^Stellenbesetzung und Beschäftigung (Liste)^--Freemarker Template\
<#include "SQL_lingua_franca"/>\
<#include "SuperX_general"/>\
--\
--Autor D. Quathamer 2024\
<sqlvars>\
<sqlvar name="basetable" type="hash"><![CDATA[\
<#assign my_base_rs='sva_pbe_aggr_sgd' />\
SELECT distinct name,\
0::smallint as is_virtual,\
name as runtime_tablename\
from sx_tables\
where name in ('${my_base_rs}')\
and 0=(select count(*) from rpta_resultset R where R.uniquename='${my_base_rs}')\
union\
select R.uniquename,\
1::smallint as is_virtual,\
'tmp_' || R.uniquename as runtime_tablename\
from rpta_resultset R where R.uniquename='${my_base_rs}'\
;\
]]>\
</sqlvar>\
<sqlvar name="rpta_resultset" type="hash"><![CDATA[\
select caption,\
uniquename,\
fieldclause,\
joinclause,\
whereclause,\
systeminfo_id\
from rpta_resultset\
where uniquename='${basetable.name}';\
\
]]></sqlvar>\
<sqlvar name="rpta_column_layout" type="hash"><![CDATA[\
select L.uniquename,\
L.caption,\
L.whereclause\
from rpta_resultset R, rpta_column_layout L\
where L.resultset_id=R.tid\
and R.uniquename='${basetable.name}'\
and L.tid=<<Spaltenlayout>>;\
\
]]></sqlvar>\
<sqlvar name="columns" type="hashsequence"><![CDATA[\
SELECT C.srcfieldname,\
(case when string_not_null(C.targetfieldname)='' then C.srcfieldname else C.targetfieldname end) as targetfieldname,\
T.uniquename as coltype,\
C.is_aggregate,\
(case when string_not_null(CL.caption)='' then C.caption else CL.caption end) as caption,\
CL.is_visible,\
CL.visible_size as visible_width,\
(select F.sql_code from rpta_format_code F where F.tid=CL.format_code_id) as format_sql,\
C.col_function as colfunction,\
(case when string_not_null(CL.description)='' then C.description else CL.description end) as description\
FROM rpta_column_layout L, rpta_column2layout CL, rpta_column C, rpta_column_type T\
where L.tid=CL.layout_id\
and C.tid=CL.column_id\
and T.tid=C.column_type\
and L.tid=<<Spaltenlayout>>\
/* and C.uniquename in (<<Spalten>>) */\
order by CL.sortnr\
;\
]]></sqlvar>\
</sqlvars>\
\
<#assign filter="sva_sgd_aggr.d_gueltig_anfang <= date_val(<<Datum>>) \
and sva_sgd_aggr.d_gueltig_ende >= date_val(<<Datum>>)\
\
/* and sva_sgd_aggr.ca115_haushverm in <@printkeys .vars["Haushaltsvermerk"].allNeededKeys /> -- <<Haushaltsvermerk>> */\
/* and sva_sgd_aggr.ca107_dienstart in <@printkeys .vars["Dienstart"].allNeededKeys /> --<<Dienstart>>= */\
/* and sva_sgd_aggr.ca259_kategorie in <@printkeys .vars["Stellenkategorie"].allNeededKeys /> -- <<Stellenkategorie>> */\
/* and sva_sgd_aggr.ca108_amtsbez in <@printkeys .vars["Amtsbezeichnung"].allNeededKeys /> -- <<Amtsbezeichnung>> */\
/* and sva_sgd_aggr.lehreinheit in <@printkeys .vars["Lehreinheit (Stelle)"].allNeededKeys /> -- <<Lehreinheit (Stelle)>> */\
/* and sva_sgd_aggr.ca109_key_bvl in <@printkeys .vars["BVL-Gruppe (Stelle)"].allNeededKeys /> --<<BVL-Gruppe (Stelle)>>*/\
/* and sva_sgd_aggr.stellen_nr=<<Stellen-Nr.>> */\
/* and ${<<Filter Stellen>>} */\
" />\
\
<#if "<<Stellen-Nr. im HHPlan>>"!="">\
<#assign hn="<<Stellen-Nr. im HHPlan>>"?replace("'","")/>\
<#assign filter = filter + "and sva_sgd_aggr.haushalt_nr like '"+hn+"%'" />\
</#if>\
\
\
\
<#assign filter = filter + " and sva_sgd_aggr.ch110_besch_st in "+.vars["Institution (Stelle)"].allNeededKeysList /> \
\
<#if columns?has_content>\
\
<#if basetable.is_virtual==1>\
\
create temp table ${basetable.runtime_tablename} as\
select ${rpta_resultset.fieldclause} \
from ${rpta_resultset.joinclause} \
where 1=1\
<#if rpta_resultset.whereclause != ""> \
${rpta_resultset.whereclause} </#if>\
and ${filter}\
;\
</#if>\
\
--Daten außerhalb des Berichtszeitraums entfernen:\
delete from ${basetable.runtime_tablename}\
where sva_pbe_aggr_d_besetz_anfang > date_val(<<Datum>>)\
or sva_pbe_aggr_d_besetz_ende < date_val(<<Datum>>);\
\
select \
--zuerst die Basisdaten:\
<#foreach column in columns>\
<#if column.coltype="physicalColumn">\
${column.srcfieldname},\
<#elseif column.coltype="logicalColumn">\
${column.colfunction} as ${column.targetfieldname},\
<#elseif column.coltype="lookupColumn">\
(${column.colfunction}) as ${column.targetfieldname},\
<#elseif column.coltype="computedColumn">\
null::decimal(19,6) as ${column.targetfieldname},\
</#if>\
</#foreach>\
null::char(1) as dummycol\
into temp tmp_stud\
from ${basetable.runtime_tablename}\
<#if rpta_column_layout.whereclause !="">\
where ${rpta_column_layout.whereclause}\
</#if>\
;\
\
\
--ergebnistabelle:\
select \
--zuerst die nicht-Aggregate:\
<#assign groupby=0 />\
<#foreach column in columns>\
<#if column.is_aggregate==0>\
<#assign groupby=groupby+1 />\
${column.targetfieldname},\
</#if>\
</#foreach>\
--dann die Aggregate:\
<#foreach column in columns>\
<#if column.is_aggregate==1 && column.coltype!="computedColumn">\
sum(${column.targetfieldname}) as ${column.targetfieldname},\
</#if>\
</#foreach>\
null::char(1) as dummycol\
into temp tmp_stud2\
from tmp_stud\
where 1=1\
/* ${<<Zusatzfilter>>} */\
group by\
<#list 1..groupby as i>${i}\
<#if i != groupby>\
,\
</#if>\
</#list>\
;\
\
<#assign number_of_visible_colums=0 />\
<#foreach column in columns>\
<#if column.is_visible!=0>\
<#assign number_of_visible_colums=number_of_visible_colums+1 />\
</#if>\
</#foreach>\
<#assign colnr=0 />\
select \
<#foreach column in columns>\
<#if column.is_visible!=0>\
<#assign colnr=colnr+1 />\
<#assign format_sql="" />\
<#if column.format_sql?string != "">\
<#assign format_sql=column.format_sql />\
</#if>\
\
<#if column.coltype=="computedColumn">\
(${column.colfunction})${format_sql} as ${column.targetfieldname}\
<#else>\
${column.targetfieldname}${format_sql} as ${column.targetfieldname}\
</#if>\
\
<#if colnr &lt; number_of_visible_colums>,</#if>\
</#if> --wenn sichtbar\
</#foreach>\
from tmp_stud2\
order by <#list 1..number_of_visible_colums as i>${i}\
<#if i != number_of_visible_colums>\
,\
</#if>\
</#list>\
;\
<#if basetable.is_virtual==1>\
drop table if exists ${basetable.runtime_tablename};\
</#if>\
\
\
drop table if exists tmp_stud;\
\
</#if> --wenn columns?has_content^--Freemarker Template\
XIL List\
sizable_columns horizontal_scrolling\
drop_and_delete movable_columns \
white_space_color=COLOR_WHITE fixed_columns=1\
min_heading_height=55\
<#foreach column in columns>\
<#if column.is_visible!=0>\
Column CID=0 heading_text="${column.caption}" center_heading explanation="${column.description}"\
row_selectable heading_platform readonly\
width=${column.visible_width} text_size=60\
</#if>\
</#foreach>\
@@@^^^Informationen über Stellen und deren Besetzung zu einem bel. Zeitpunkt^drop table tmp_stud2;^^2^700^500^^1^<<SQL>> select 'Achtung: Das Datum des Buttons Institution bzw OrgEinheit (Stelle) unterscheidet sich vom ausgewählten Datum im Maskenfeld.' from xdummy where <<Institution (Stelle)-Stand>> != date_val(<<Datum>>)^

1
src-modules/module/rpta/masken/45080_sachgeb_maske_bez.unl

@ -0,0 +1 @@
100^45080^

384
src-modules/module/rpta/schluesseltabellen/rpta_column_layout_sgd_pbe_pbv_fuellen.sql

@ -0,0 +1,384 @@
--freemarker template
<sqlvars>
<sqlvar name="rpta_installed">
select count(*) from systeminfo where tid=330;
</sqlvar>
</sqlvars>
<#assign rpta_column_layout = {"uniquename":"sgd_pbe_pbv",
"caption":"Stellen, Besetzungen und Beschäftigungsverhältnisse",
"rpta_resultset":"sva_pbe_aggr_sgd",
"whereclause":"",
"description":"Stellendaten, Besetzungen und Personaldaten"
}
/>
<#assign rpta_columns = [
{"uniquename":"ch110_besch_st",
"caption":"Beschäftigungsstelle (Schlüssel)",
"srcfieldname":"ch110_besch_st",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"10",
"is_aggregate":"0",
"description":"Beschäftigungsstelle (Schlüssel)"
},
{"uniquename":"ch110_besch_st_str",
"caption":"Beschäftigungsstelle",
"srcfieldname":"ch110_besch_st_str",
"column_type":"lookupColumn",
"col_function":"select C.druck from cifx C where C.key=110 and C.apnr=ch110_besch_st",
"is_visible":"1",
"visible_size":"10",
"is_aggregate":"0",
"description":"Beschäftigungsstelle (Name)"
},
{"uniquename":"stellen_nr",
"caption":"Stellen-Nr.",
"srcfieldname":"stellen_nr",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Stellen-Nr."
},
{"uniquename":"haushalt_nr",
"caption":"Stellen-Nr. im HH-Plan",
"srcfieldname":"haushalt_nr",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Stellen-Nr. im HH-Plan"
},
{"uniquename":"widmung",
"caption":"Widmung",
"srcfieldname":"sva_sgd_widmung",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Widmung"
},
{"uniquename":"sva_sgd_von",
"caption":"Stellengültigkeit (von)",
"srcfieldname":"d_finanz_anfang",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Stellengültigkeit (von)"
},
{"uniquename":"sva_sgd_bis",
"caption":"Stellengültigkeit (bis)",
"srcfieldname":"d_finanz_ende",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Stellengültigkeit (bis)"
},
{"uniquename":"sgd_ansatz",
"caption":"Stellen-Ansatz",
"srcfieldname":"kont_proz_soll",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":"Stellen-Ansatz"
},
{"uniquename":"personal_nr",
"caption":"Personal-Nr.",
"srcfieldname":"sva_pbe_aggr_personal_nr",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":""
},
{"uniquename":"besch_verh_nr",
"caption":"Besch.-Verh Nr.",
"srcfieldname":"sva_pbe_aggr_besch_verh_nr",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":""
},
{"uniquename":"name",
"caption":"Person Name",
"srcfieldname":"sva_pbe_aggr_name",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"0",
"description":""
},
{"uniquename":"d_besetz_anfang",
"caption":"Besetzung gültig (von)",
"srcfieldname":"sva_pbe_aggr_d_besetz_anfang",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"0",
"visible_size":"5",
"is_aggregate":"0",
"description":""
} ,
{"uniquename":"d_besetz_ende",
"caption":"Besetzung gültig (bis)",
"srcfieldname":"sva_pbe_aggr_d_besetz_ende",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"0",
"visible_size":"5",
"is_aggregate":"0",
"description":""
},
{"uniquename":"pbe_von",
"caption":"Besetzungsdatum (von)",
"srcfieldname":"sva_pbe_aggr_pbe_von",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"0",
"visible_size":"5",
"is_aggregate":"0",
"description":""
} ,
{"uniquename":"pbe_bis",
"caption":"Besetzungsdatum (bis)",
"srcfieldname":"sva_pbe_aggr_pbe_bis",
"column_type":"physicalColumn",
"col_function":"",
"is_visible":"0",
"visible_size":"5",
"is_aggregate":"0",
"description":""
},
{"uniquename":"vzae",
"caption":"VZÄ (Besetzung)",
"srcfieldname":"sva_pbe_aggr_vzae",
"column_type":"physicalColumn",
"col_function":"sum",
"is_visible":"1",
"visible_size":"5",
"is_aggregate":"1",
"description":""
}
]
/>
<#if rpta_installed==1>
---ab hier nicht mehr ändern:
drop TABLE if exists tmp_rpta_column2layout;
CREATE temp TABLE tmp_rpta_column
(
uniquename varchar(255) NOT NULL,
caption varchar(255),
srcfieldname varchar(255),
targetfieldname varchar(255),
column_type integer,
col_function text,
is_visible smallint,
visible_size smallint,
is_aggregate smallint,
resultset_id integer,
sortnr integer,
description TEXT
);
CREATE temp TABLE tmp_rpta_column_layout
(
uniquename varchar(255) NOT NULL,
caption varchar(255),
resultset_id integer,
whereclause text,
description text
);
insert into tmp_rpta_column_layout(
resultset_id,
uniquename,
caption,
whereclause,
description
)
select tid,
'${rpta_column_layout.uniquename}',
'${rpta_column_layout.caption}',
'${rpta_column_layout.whereclause}',
'${rpta_column_layout.description}'
FROM rpta_resultset
where uniquename='${rpta_column_layout.rpta_resultset}';
<#assign sortnr=0 />
<#foreach column in rpta_columns>
<#assign sortnr=sortnr +1 />
INSERT INTO tmp_rpta_column
(resultset_id,
uniquename,
caption,
srcfieldname,
targetfieldname,
column_type,
col_function,
is_visible,
visible_size,
is_aggregate,
sortnr,
description
)
select R.tid,
'${column.uniquename}',
'${column.caption}',
'${column.srcfieldname}',
<#if !column.targetfieldname?exists || column.targetfieldname=="">null::varchar <#else>'${column.targetfieldname}' </#if>,
T.tid as column_type,
'${column.col_function}',
${column.is_visible},
${column.visible_size},
${column.is_aggregate},
${sortnr*10},
'${column.description}'
FROM rpta_resultset R, rpta_column_type T
where R.uniquename='${rpta_column_layout.rpta_resultset}'
and T.uniquename='${column.column_type}';
</#foreach>
select * into temp tmp_rpta_column2layout
from rpta_column2layout
where layout_id in (select L.tid
from rpta_column_layout L,rpta_resultset R
where R.tid=L.resultset_id
and R.uniquename='${rpta_column_layout.rpta_resultset}'
and L.uniquename='${rpta_column_layout.uniquename}'
)
;
select * into temp tmp_rpta_column_layout_target
from rpta_column_layout
where resultset_id in (select tid
FROM rpta_resultset
where uniquename='${rpta_column_layout.rpta_resultset}')
and uniquename in (select uniquename from tmp_rpta_column_layout)
;
insert into rpta_column_layout
(uniquename,
caption,
resultset_id,
whereclause,
description)
select uniquename,
caption,
resultset_id,
whereclause,
description
FROM tmp_rpta_column_layout T
where 0=(select count(*) from tmp_rpta_column_layout_target T2
where T.uniquename=T2.uniquename);
drop table tmp_rpta_column_layout_target;
delete from rpta_column2layout
where layout_id in (select L.tid
from rpta_column_layout L,rpta_resultset R
where R.tid=L.resultset_id
and R.uniquename='${rpta_column_layout.rpta_resultset}'
and L.uniquename='${rpta_column_layout.uniquename}'
)
;
select * into temp tmp_rpta_column2
from tmp_rpta_column T
where (resultset_id,uniquename) not in
(select resultset_id,uniquename from rpta_column);
INSERT INTO rpta_column
(resultset_id,
uniquename,
caption,
srcfieldname,
targetfieldname,
column_type,
col_function,
is_aggregate,
description,
custom
)
select
resultset_id,
uniquename,
caption,
srcfieldname,
targetfieldname,
column_type,
col_function,
is_aggregate,
description,
0 as custom
from tmp_rpta_column2;
--evtl. neuen Satz einfügen, dann alle updaten
update rpta_column set ( caption,
srcfieldname,
targetfieldname,
column_type,
col_function,
is_aggregate,
description)
= (select caption,
srcfieldname,
targetfieldname,
column_type,
col_function,
is_aggregate,
description
from tmp_rpta_column T
where T.resultset_id=rpta_column.resultset_id
and T.uniquename=rpta_column.uniquename)
where custom=0
and (resultset_id,uniquename) in
(select T.resultset_id,T.uniquename
from tmp_rpta_column T)
;
drop table tmp_rpta_column2;
insert into rpta_column2layout(column_id,
layout_id,
sortnr,
is_visible,
visible_size,
caption,
description)
select C.tid as column_id,
L.tid as layout_id,
T.sortnr,
T.is_visible,
T.visible_size,
T.caption,
T.description
FROM rpta_column C, rpta_column_layout L, tmp_rpta_column T
where C.uniquename=T.uniquename
and C.resultset_id=T.resultset_id
and L.uniquename='${rpta_column_layout.uniquename}'
and L.resultset_id=T.resultset_id
;
drop table tmp_rpta_column;
drop TABLE tmp_rpta_column_layout;
drop TABLE tmp_rpta_column2layout;
</#if>

393
src-modules/module/rpta/schluesseltabellen/stellen_besetzung_virtuell.sql

@ -0,0 +1,393 @@
--freemarker template
<sqlvars>
<sqlvar name="sva_sgd_aggr_exists">
select sp_table_exists('sva_sgd_aggr') from xdummy;
</sqlvar>
<sqlvar name="fact_table_source" type="hash">
select name
from sx_tables where name ='sva_sgd_aggr'
</sqlvar>
<sqlvar name="added_tables" type="hashsequence"><![CDATA[
select 1::smallint as sortnr,
name, trim(name) ||'_' as prefix,
caption,
'sva_sgd.sgd_join_id=sva_sgd_aggr.stellen_nr' as joinclause
from sx_tables where name in ('sva_sgd')
union
select 2::smallint as sortnr,
name, trim(name) ||'_' as prefix,
caption,
'sva_sgd_aggr.stellen_nr=sva_pbe_aggr.stellen_nr and (sva_sgd_aggr.sbst_nr=sva_pbe_aggr.soe_serial or sva_pbe_aggr.soe_serial is null )' as joinclause
from sx_tables where name in ('sva_pbe_aggr')
]]></sqlvar>
<sqlvar name="fields_target" type="hashsequence"><![CDATA[
select tid, table_name,
name,
name as targetname
from sx_fields where table_name ='${fact_table_source.name}'
and currentlyused=1
union
select tid,table_name,
name,
'sva_sgd_' || name as targetname
from sx_fields where table_name ='sva_sgd'
and currentlyused=1
union
select tid,table_name,
name,
'sva_pbe_aggr_' || name as targetname
from sx_fields where table_name ='sva_pbe_aggr'
and currentlyused=1
order by 1
]]>
</sqlvar>
</sqlvars>
<#if sva_sgd_aggr_exists==1>
<#assign fact_table_target = {"name":"sva_pbe_aggr_sgd", "caption":"Stellen, Besetzungen, Personen"}
/>
CREATE temp table tmp_tables(
name CHAR(255) ,
caption CHAR(255) ,
description CHAR(255) ,
table_type CHAR(255) ,
systeminfo_id INTEGER ,
systeminfo_orig INTEGER ,
thema CHAR(255) ,
sachgebiete_id CHAR(255)
);
CREATE temp TABLE tmp_fields(
tid serial NOT NULL,
table_name VARCHAR(255) not null,
name VARCHAR(255) not null,
caption VARCHAR(255) ,
description VARCHAR(255) ,
field_type VARCHAR(255) not null,
field_size VARCHAR(255) ,
field_not_null smallint,
currentlyused SMALLINT ,
is_primarykey SMALLINT default 0 ,
foreignkey_tab VARCHAR(255) ,
foreignkey_col VARCHAR(255) ,
foreignkey_int VARCHAR(255) ,
foreignkey_cap VARCHAR(255) ,
foreignkey_cond VARCHAR(255) ,
foreignkey_func VARCHAR(255) ,
check_integrity SMALLINT,
is_sum SMALLINT default 1,
foreignkey_uniquename VARCHAR(255)
);
update sx_fields set
is_sum=0
where table_name='sva_sgd_aggr'
and name!='vzae';
update sx_fields set
is_sum=1
where table_name='sva_sgd_aggr'
and name='vzae';
insert into tmp_tables (
name,
caption,
description,
table_type,
systeminfo_id,
thema,
sachgebiete_id
)
select
'${fact_table_target.name}',
'${fact_table_target.caption}',
description,
table_type,
systeminfo_id,
thema,
sachgebiete_id
from sx_tables where name='${fact_table_source.name}'
;
insert into tmp_fields (table_name,
name,
caption,
description,
field_type,
field_size,
field_not_null,
currentlyused,
is_primarykey,
foreignkey_tab,
foreignkey_col,
foreignkey_int,
foreignkey_cap,
foreignkey_cond,
foreignkey_func,
check_integrity,
is_sum,
foreignkey_uniquename)
select '${fact_table_target.name}' as table_name,
name,
caption,
description,
field_type,
field_size,
field_not_null,
currentlyused,
is_primarykey,
foreignkey_tab,
foreignkey_col,
foreignkey_int,
foreignkey_cap,
foreignkey_cond,
foreignkey_func,
check_integrity,
is_sum,
foreignkey_uniquename
from sx_fields where table_name ='${fact_table_source.name}'
and currentlyused=1;
<#foreach added_table in added_tables>
insert into tmp_fields (table_name,
name,
caption,
description,
field_type,
field_size,
field_not_null,
currentlyused,
is_primarykey,
foreignkey_tab,
foreignkey_col,
foreignkey_int,
foreignkey_cap,
foreignkey_cond,
foreignkey_func,
check_integrity,
is_sum,
foreignkey_uniquename)
select '${fact_table_target.name}' as table_name,
'${added_table.prefix}' || name,
'${added_table.caption}: ' || caption,
description,
field_type,
field_size,
field_not_null,
currentlyused,
is_primarykey,
foreignkey_tab,
foreignkey_col,
foreignkey_int,
foreignkey_cap,
foreignkey_cond,
foreignkey_func,
check_integrity,
is_sum,
foreignkey_uniquename
from sx_fields where table_name ='${added_table.name}'
and currentlyused=1;
</#foreach>
CREATE temp TABLE tmp_rpta_resultset
(
caption varchar(255),
uniquename varchar(255),
fieldclause text,
joinclause text,
whereclause text,
systeminfo_id integer
);
insert into tmp_rpta_resultset(caption,
uniquename,
systeminfo_id)
select '${fact_table_target.caption}',
'${fact_table_target.name}',
6
;
update tmp_rpta_resultset set fieldclause='
<#foreach field_target in fields_target>
${field_target.table_name}.${field_target.name} as ${field_target.targetname},
</#foreach>
null::varchar as dummy',
joinclause='${fact_table_source.name}
<#foreach added_table in added_tables>
left outer join ${added_table.name} on (${added_table.joinclause})
</#foreach>';
select * into temp tmp_rs1
from rpta_resultset
;
update rpta_resultset set caption=T.caption,
fieldclause=T.fieldclause,
joinclause=T.joinclause,
whereclause=T.whereclause
from tmp_rpta_resultset T
where T.systeminfo_id=rpta_resultset.systeminfo_id
and T.uniquename=rpta_resultset.uniquename
;
insert into rpta_resultset(caption,
uniquename,
fieldclause,
joinclause,
whereclause,
systeminfo_id)
select caption,
uniquename,
fieldclause,
joinclause,
whereclause,
systeminfo_id
from tmp_rpta_resultset
where 0=(select count(*)
from tmp_rs1 T
where T.systeminfo_id=tmp_rpta_resultset.systeminfo_id
and T.uniquename=tmp_rpta_resultset.uniquename)
;
drop table tmp_rpta_resultset;
drop table tmp_rs1;
delete from sx_tables where name
in (select T.name from tmp_tables T);
insert into sx_tables (name,caption,description,table_type,systeminfo_id,systeminfo_orig,thema,sachgebiete_id)
select name,caption,description,table_type,systeminfo_id,systeminfo_orig,thema,sachgebiete_id
from tmp_tables;
delete from sx_fields where table_name
in (select T.table_name from tmp_fields T);
insert into sx_fields (table_name,name,caption,description,field_type,
field_size,
field_not_null,
currentlyUsed,
foreignkey_tab,
foreignkey_col,
foreignkey_cap,
foreignkey_int,
foreignkey_cond,
foreignkey_func,
check_integrity,
is_sum,
foreignkey_uniquename
)
select
F.table_name,F.name,F.caption,F.description,F.field_type,
F.field_size,
F.field_not_null,
F.currentlyUsed,
F.foreignkey_tab,
F.foreignkey_col,
F.foreignkey_cap,
F.foreignkey_int,
F.foreignkey_cond,
F.foreignkey_func,
F.check_integrity,
F.is_sum,
F.foreignkey_uniquename
from tmp_fields F;
drop table tmp_fields;
drop table tmp_tables;
--rpta_column füllen:
select * into temp tmp_rc1
from rpta_column;
create temp table tmp_rpta_column(
uniquename varchar(255) NOT NULL,
caption varchar(255),
srcfieldname varchar(255),
column_type integer,
col_function text,
is_aggregate smallint,
resultset_id integer,
description text,
custom integer default 0
);
insert into tmp_rpta_column( uniquename,
caption,
srcfieldname,
column_type,
col_function,
is_aggregate,
resultset_id,
description)
select F.name as uniquename,
coalesce(T.caption,T.name) || ' - ' || F.caption,
F.name as srcfieldname,
1 as column_type,
(case when F.is_sum=1 then 'sum' else null::varchar end) as col_function,
(case when F.is_sum=1 then 1 else 0 end) as is_aggregate,
R.tid as resultset_id,
F.description
from rpta_resultset R, sx_fields F left outer join sx_tables T on (T.name=F.table_name)
where F.table_name='${fact_table_target.name}'
and R.uniquename='${fact_table_target.name}'
and F.currentlyused=1
;
update rpta_column set
caption=T.caption,
srcfieldname=T.srcfieldname,
column_type=T.column_type,
col_function=T.col_function,
is_aggregate=T.is_aggregate,
resultset_id=R.tid,
description=T.description,
custom=T.custom
from tmp_rpta_column T, rpta_resultset R
where T.uniquename=rpta_column.uniquename
and rpta_column.resultset_id=R.tid
and R.uniquename='${fact_table_target.name}'
;
insert into rpta_column( uniquename,
caption,
srcfieldname,
column_type,
col_function,
is_aggregate,
resultset_id,
description,
custom)
select T.uniquename,
T.caption,
T.srcfieldname,
T.column_type,
T.col_function,
T.is_aggregate,
R.tid as resultset_id,
T.description,
T.custom
from tmp_rpta_column T, rpta_resultset R
where R.uniquename='${fact_table_target.name}'
and 0=(select count(*) from tmp_rc1 C
where C.uniquename=T.uniquename
and C.resultset_id=R.tid)
;
drop table tmp_rpta_column;
drop table tmp_rc1;
</#if> --wenn sva_sgd_aggr_exists=1
Loading…
Cancel
Save